diff --git a/src/core/widgets/code/commands/close_file.py b/src/core/widgets/code/commands/close_file.py index ec985f7..5af1140 100644 --- a/src/core/widgets/code/commands/close_file.py +++ b/src/core/widgets/code/commands/close_file.py @@ -17,10 +17,10 @@ def execute( logger.debug("Close File Command") buffer = view.get_buffer() - sibling_file = view.files_manager.remove_file(buffer) - if not sibling_file: + next_file = view.files_manager.remove_file(buffer) + if not next_file: view.command.exec("new_file") else: - view.set_buffer(sibling_file.buffer) + view.set_buffer(next_file.buffer) view.command.exec("update_info_bar") diff --git a/src/core/widgets/code/commands/move_to_left_sibling.py b/src/core/widgets/code/commands/move_to_left_sibling.py index aa49b10..5edf5bc 100644 --- a/src/core/widgets/code/commands/move_to_left_sibling.py +++ b/src/core/widgets/code/commands/move_to_left_sibling.py @@ -18,16 +18,15 @@ def execute( if not view.sibling_left: return buffer = view.get_buffer() - popped_file, sibling_file = view.files_manager.swap_file(buffer) - - if sibling_file: - sibling_file.add_observer(view) - view.set_buffer(sibling_file.buffer) - else: - sibling_file = view.command.exec("new_file") + popped_file, next_file = view.files_manager.swap_file(buffer) popped_file.remove_observer(view) popped_file.add_observer(view.sibling_left) - view.sibling_left.set_buffer(buffer) view.sibling_left.grab_focus() + + if next_file: + next_file.add_observer(view) + view.set_buffer(next_file.buffer) + else: + view.command.exec("new_file") diff --git a/src/core/widgets/code/commands/move_to_right_sibling.py b/src/core/widgets/code/commands/move_to_right_sibling.py index bb66efb..806f7c5 100644 --- a/src/core/widgets/code/commands/move_to_right_sibling.py +++ b/src/core/widgets/code/commands/move_to_right_sibling.py @@ -18,17 +18,15 @@ def execute( if not view.sibling_right: return buffer = view.get_buffer() - popped_file, sibling_file = view.files_manager.swap_file(buffer) - - if sibling_file: - sibling_file.add_observer(view) - view.set_buffer(sibling_file.buffer) - else: - sibling_file = view.command.exec("new_file") + popped_file, next_file = view.files_manager.swap_file(buffer) popped_file.remove_observer(view) popped_file.add_observer(view.sibling_right) - view.sibling_right.set_buffer(buffer) view.sibling_right.grab_focus() + if next_file: + next_file.add_observer(view) + view.set_buffer(next_file.buffer) + else: + view.command.exec("new_file") diff --git a/src/core/widgets/code/commands/set_buffer.py b/src/core/widgets/code/commands/set_buffer.py new file mode 100644 index 0000000..a03e120 --- /dev/null +++ b/src/core/widgets/code/commands/set_buffer.py @@ -0,0 +1,36 @@ +# Python imports + + +# Lib imports +import gi + +gi.require_version('GtkSource', '4') + +from gi.repository import GtkSource + +# Application imports +from ..source_file import SourceFile + + + +def execute( + view: GtkSource.View, + file: SourceFile +): + logger.debug("Set Buffer Command") + + buffer = view.get_buffer() + _file = view.files_manager.get_file(buffer) + _file.remove_observer(view) + + if not file: + view.command.exec("new_file") + return + + view.set_buffer(file.buffer) + file.add_observer(view) + + has_focus = view.command.exec("has_focus") + if has_focus: + view.command.exec("update_info_bar") + diff --git a/src/core/widgets/code/mixins/source_view_events_mixin.py b/src/core/widgets/code/mixins/source_view_events_mixin.py index 1dd4b1e..5e070e0 100644 --- a/src/core/widgets/code/mixins/source_view_events_mixin.py +++ b/src/core/widgets/code/mixins/source_view_events_mixin.py @@ -37,11 +37,17 @@ class SourceViewEventsMixin: return True def notification(self, event: CodeEvent): - has_focus = self.command.exec("has_focus") - if not has_focus: return + if not hasattr(self, "command"): return + + has_focus = self.command.exec("has_focus") + if not has_focus and not event.ignore_focus: return - self.command.exec("update_info_bar") match event.etype: + case "removed_file": + logger.debug("SourceFileManager.remove_file") + if not event.file.buffer == self.get_buffer(): return + self.command.exec_with_args("set_buffer", (self, event.next_file)) + return case "changed": logger.debug("SourceFile._changed") case "modified_changed": @@ -54,3 +60,4 @@ class SourceViewEventsMixin: case _: ... + self.command.exec("update_info_bar") diff --git a/src/core/widgets/code/source_files_manager.py b/src/core/widgets/code/source_files_manager.py index 245099e..0e9c9f0 100644 --- a/src/core/widgets/code/source_files_manager.py +++ b/src/core/widgets/code/source_files_manager.py @@ -29,8 +29,8 @@ class SourceFilesManager(Singleton, list, ObservableMixin): super().append(file) event = CodeEvent() - event.file = file event.etype = "appended_file" + event.file = file self.notify_observers(event) @@ -47,23 +47,17 @@ class SourceFilesManager(Singleton, list, ObservableMixin): for i, file in enumerate(self): if not buffer == file.buffer: continue - popped_file = self.pop(i) - sibling_file = None - size = len(self) - - if size == 0: - return popped_file, sibling_file - - j = 0 if size == 1 else i - 1 if i > 1 else i + 1 - sibling_file = self[j] - - event = CodeEvent() - event.file = popped_file - event.etype = "popped_file" + j = self.next_index(i) + next_file = self[j] if not j == -1 else None + popped_file = self.pop(i) + event = CodeEvent() + event.etype = "popped_file" + event.file = popped_file + event.next_file = next_file self.notify_observers(event) - return popped_file, sibling_file + return popped_file, next_file def swap_file(self, buffer: SourceBuffer): if not buffer: return @@ -71,38 +65,42 @@ class SourceFilesManager(Singleton, list, ObservableMixin): for i, file in enumerate(self): if not buffer == file.buffer: continue - swapped_file = self[i] - sibling_file = None - size = len(self) + j = self.next_index(i) + next_file = self[j] + swapped_file = self[j] if not j == -1 else None - if size == 0: - return swapped_file, sibling_file - - j = 0 if size == 1 else i - 1 if i > 1 else i + 1 - sibling_file = self[j] - - return swapped_file, sibling_file + return swapped_file, next_file def remove_file(self, buffer: SourceBuffer): if not buffer: return for i, file in enumerate(self): if not buffer == file.buffer: continue - self.remove(file) - - event = CodeEvent() - event.file = file - event.etype = "removed_file" + j = self.next_index(i) + next_file = self[j] if not j == -1 else None + event = CodeEvent() + event.etype = "removed_file" + event.ignore_focus = True + event.file = file + event.next_file = next_file self.notify_observers(event) - size = len(self) - if size == 0: - return None - - j = 0 if size == 1 else i - 1 if i > 1 else i + 1 - sibling_file = self[j] - + self.remove(file) file.close() - return sibling_file + return next_file + + def next_index(self, i): + size = len(self) + + if (i == 0) & (size >= 2): + j = i + 1 + elif (i == (size - 1)) & (size >= 2): + j = i - 1 + elif (size - 1) == 0: + j = -1 + else: + j = i + 1 + + return j \ No newline at end of file diff --git a/src/core/widgets/code/tab_widget.py b/src/core/widgets/code/tab_widget.py index f98abfb..8e5ea63 100644 --- a/src/core/widgets/code/tab_widget.py +++ b/src/core/widgets/code/tab_widget.py @@ -13,7 +13,8 @@ class TabWidget(Gtk.Box): def __init__(self): super(TabWidget, self).__init__() - self.file = None + self._handler_ids: list = [] + self.file = None self._setup_styling() self._setup_signals() @@ -34,8 +35,9 @@ class TabWidget(Gtk.Box): ... def _load_widgets(self): - self.label = Gtk.Label(label="") - self.close_btn = Gtk.Button(label="X") + self._label_eve_box = Gtk.EventBox() + self.label = Gtk.Label(label = "") + self.close_btn = Gtk.Button(label = "X") ctx = self.label.get_style_context() ctx.add_class("tab-label") @@ -44,10 +46,19 @@ class TabWidget(Gtk.Box): self.label.set_hexpand(True) - self.add(self.label) + self._label_eve_box.add(self.label) + self.add(self._label_eve_box) self.add(self.close_btn) def __del__(self): - # for handle_id in self._handler_ids: - # self.disconnect(handle_id) - ... \ No newline at end of file + for handle_id in self._handler_ids: + self.disconnect(handle_id) + del self.file + + def set_select_signal(self, callback): + _id = self._label_eve_box.connect('button-release-event', callback, self.file) + self._handler_ids.append(_id) + + def set_close_signal(self, callback): + _id = self.close_btn.connect('button-release-event', callback, self.file) + self._handler_ids.append(_id) diff --git a/src/core/widgets/code/tabs_widget.py b/src/core/widgets/code/tabs_widget.py index 19fb810..8e7c865 100644 --- a/src/core/widgets/code/tabs_widget.py +++ b/src/core/widgets/code/tabs_widget.py @@ -20,7 +20,7 @@ class TabsWidget(Gtk.ScrolledWindow): def __init__(self): super(TabsWidget, self).__init__() - self.active_view: SourceView = None + self.active_view: SourceView = None self._setup_styling() self._setup_signals() @@ -77,8 +77,16 @@ class TabsWidget(Gtk.ScrolledWindow): tab.label.set_label(event.file.fname) event.file.add_observer(self) + def select_signal(widget, eve, file): + self.active_view.command.exec_with_args("set_buffer", (self.active_view, file)) + + def close_signal(widget, eve, file): + self.files_manager.remove_file(file.buffer) + + tab.set_select_signal(select_signal) + tab.set_close_signal(close_signal) + self.tabs.add(tab) - tab.show() def remove_tab(self, event: CodeEvent): for child in self.tabs.get_children(): @@ -86,8 +94,6 @@ class TabsWidget(Gtk.ScrolledWindow): child.file.remove_observer(self) self.tabs.remove(child) - - del child.file del child return diff --git a/src/core/widgets/code/view.py b/src/core/widgets/code/view.py index fefb7b8..e21f359 100644 --- a/src/core/widgets/code/view.py +++ b/src/core/widgets/code/view.py @@ -110,4 +110,4 @@ class SourceView(GtkSource.View, ObservableMixin, SourceViewEventsMixin, SourceV def set_files_manager(self, files_manager: SourceFilesManager): self.files_manager = files_manager - # self.files_manager.add_observer(self) + self.files_manager.add_observer(self) diff --git a/src/libs/dto/code_event.py b/src/libs/dto/code_event.py index d3b0d90..0e87976 100644 --- a/src/libs/dto/code_event.py +++ b/src/libs/dto/code_event.py @@ -10,7 +10,9 @@ from .observable_event import ObservableEvent @dataclass class CodeEvent(ObservableEvent): - etype: str = "" - view: any = None - file: any = None - buffer: any = None \ No newline at end of file + etype: str = "" + ignore_focus: bool = False + view: any = None + file: any = None + next_file: any = None + buffer: any = None \ No newline at end of file