From d4dc972c6da0750beb59ced8ac5493b0d39dc539 Mon Sep 17 00:00:00 2001 From: itdominator <1itdominator@gmail.com> Date: Mon, 16 Feb 2026 23:52:03 -0600 Subject: [PATCH] Aded context menu to tabs widget; registered other widgets to registery --- src/core/containers/base_container.py | 2 + src/core/containers/body_container.py | 2 + src/core/containers/center_container.py | 2 + src/core/containers/code/code_container.py | 10 +-- src/core/containers/footer_container.py | 2 + src/core/containers/header_container.py | 2 + src/core/containers/left_container.py | 2 +- src/core/containers/right_container.py | 2 + .../commands/update_info_bar.py | 2 +- .../code/controllers/tabs_controller.py | 9 +- src/core/widgets/code/tab_widget.py | 34 +++++--- src/core/widgets/code/tabs_widget.py | 82 ++++++++++++++++++- 12 files changed, 118 insertions(+), 33 deletions(-) diff --git a/src/core/containers/base_container.py b/src/core/containers/base_container.py index c355999..588265e 100644 --- a/src/core/containers/base_container.py +++ b/src/core/containers/base_container.py @@ -38,6 +38,8 @@ class BaseContainer(Gtk.Box): event_system.subscribe("remove-transparency", self._remove_transparency) def _load_widgets(self): + widget_registery.expose_object("base-container", self) + self.add( HeaderContainer() ) self.add( BodyContainer() ) self.add( FooterContainer() ) diff --git a/src/core/containers/body_container.py b/src/core/containers/body_container.py index e31ccda..8d56db5 100644 --- a/src/core/containers/body_container.py +++ b/src/core/containers/body_container.py @@ -38,6 +38,8 @@ class BodyContainer(Gtk.Box): ... def _load_widgets(self): + widget_registery.expose_object("body-container", self) + self.add( LeftContainer() ) self.add( CenterContainer() ) self.add( RightContainer() ) \ No newline at end of file diff --git a/src/core/containers/center_container.py b/src/core/containers/center_container.py index aa0dbb2..9546af3 100644 --- a/src/core/containers/center_container.py +++ b/src/core/containers/center_container.py @@ -38,6 +38,8 @@ class CenterContainer(Gtk.Box): ... def _load_widgets(self): + widget_registery.expose_object("center-container", self) + glade_box = widget_registery.get_object("glade_box") button = Gtk.Button(label = "Click Me!") diff --git a/src/core/containers/code/code_container.py b/src/core/containers/code/code_container.py index f0ae232..16b8ddf 100644 --- a/src/core/containers/code/code_container.py +++ b/src/core/containers/code/code_container.py @@ -43,15 +43,7 @@ class CodeContainer(Gtk.Box): self.add( self._create_editor_widget(code_base) ) def _create_tabs_widgets(self, code_base: CodeBase): - scrolled_window = Gtk.ScrolledWindow() - viewport = Gtk.Viewport() - - scrolled_window.set_overlay_scrolling(False) - - viewport.add( code_base.get_tabs_widget() ) - scrolled_window.add( viewport ) - - return scrolled_window + return code_base.get_tabs_widget() def _create_editor_widget(self, code_base: CodeBase): editors_container = Gtk.Box() diff --git a/src/core/containers/footer_container.py b/src/core/containers/footer_container.py index e2dff80..d7c70eb 100644 --- a/src/core/containers/footer_container.py +++ b/src/core/containers/footer_container.py @@ -36,4 +36,6 @@ class FooterContainer(Gtk.Box): ... def _load_widgets(self): + widget_registery.expose_object("footer-container", self) + self.add( CodeContainer() ) diff --git a/src/core/containers/header_container.py b/src/core/containers/header_container.py index 042aca7..b554bdd 100644 --- a/src/core/containers/header_container.py +++ b/src/core/containers/header_container.py @@ -37,6 +37,8 @@ class HeaderContainer(Gtk.Box): event_system.subscribe("tggl-top-main-menubar", self.tggl_top_main_menubar) def _load_widgets(self): + widget_registery.expose_object("header-container", self) + button = Gtk.Button(label = "Interactive Debug") button.connect("clicked", self._interactive_debug) diff --git a/src/core/containers/left_container.py b/src/core/containers/left_container.py index e367020..1efc156 100644 --- a/src/core/containers/left_container.py +++ b/src/core/containers/left_container.py @@ -35,4 +35,4 @@ class LeftContainer(Gtk.Box): ... def _load_widgets(self): - ... \ No newline at end of file + widget_registery.expose_object("left-container", self) diff --git a/src/core/containers/right_container.py b/src/core/containers/right_container.py index dc26763..532e8ac 100644 --- a/src/core/containers/right_container.py +++ b/src/core/containers/right_container.py @@ -36,5 +36,7 @@ class RightContainer(Gtk.Box): ... def _load_widgets(self): + widget_registery.expose_object("right-container", self) + vte_widget = VteWidget() self.add( vte_widget ) \ No newline at end of file diff --git a/src/core/widgets/code/command_system/commands/update_info_bar.py b/src/core/widgets/code/command_system/commands/update_info_bar.py index 4852570..1a641d3 100644 --- a/src/core/widgets/code/command_system/commands/update_info_bar.py +++ b/src/core/widgets/code/command_system/commands/update_info_bar.py @@ -16,10 +16,10 @@ def execute( ): logger.debug("Command: Update Info Bar") file = view.command.get_file(view) - buffer = file.buffer if not file: return + buffer = file.buffer iter = buffer.get_iter_at_mark( buffer.get_insert() ) line = iter.get_line() + 1 column = iter.get_line_offset() diff --git a/src/core/widgets/code/controllers/tabs_controller.py b/src/core/widgets/code/controllers/tabs_controller.py index cb3302e..4e639b6 100644 --- a/src/core/widgets/code/controllers/tabs_controller.py +++ b/src/core/widgets/code/controllers/tabs_controller.py @@ -20,14 +20,12 @@ class TabsController(ControllerBase): def __init__(self): super(TabsController, self).__init__() - self.active_view: SourceView = None self.tabs_widget: TabsWidget = TabsWidget() self.tabs_widget.message = self.message def _controller_message(self, event: Code_Event_Types.CodeEvent): if isinstance(event, Code_Event_Types.FocusedViewEvent): - self.active_view = event.view self.tabs_widget.view_changed( event.view.get_buffer() ) @@ -53,13 +51,12 @@ class TabsController(ControllerBase): break def add_tab(self, event: Code_Event_Types.AddedNewFileEvent): - box = Gtk.Separator() - tab = TabWidget() - + tab = TabWidget() tab.file = event.file + tab.label.set_label(event.file.fname) - self.tabs_widget.append_page(box, tab) + self.tabs_widget.append_page(Gtk.Separator(), tab) tab.show_all() def remove_tab(self, event: Code_Event_Types.RemovedFileEvent): diff --git a/src/core/widgets/code/tab_widget.py b/src/core/widgets/code/tab_widget.py index e677a61..46e10fa 100644 --- a/src/core/widgets/code/tab_widget.py +++ b/src/core/widgets/code/tab_widget.py @@ -15,7 +15,11 @@ class TabWidget(Gtk.Box): def __init__(self): super(TabWidget, self).__init__() - self._close_tab = None + self.file = None + + self._close_tab = None + self._handler_id = None + self._eve_handler_id = None self._setup_styling() self._setup_signals() @@ -33,13 +37,15 @@ class TabWidget(Gtk.Box): ... def _load_widgets(self): - self.label = Gtk.Label() - self.close_btn = Gtk.Button() - icon = Gtk.Image(stock = Gtk.STOCK_CLOSE) + self.event_box = Gtk.EventBox() + self.label = Gtk.Label() + self.close_bttn = Gtk.Button() + icon = Gtk.Image(stock = Gtk.STOCK_CLOSE) + self.event_box.set_above_child(True) ctx = self.label.get_style_context() ctx.add_class("tab-label") - ctx = self.close_btn.get_style_context() + ctx = self.close_bttn.get_style_context() ctx.add_class("tab-close-bttn") self.label.set_xalign(0.0) @@ -47,16 +53,18 @@ class TabWidget(Gtk.Box): self.label.set_margin_right(25) self.label.set_hexpand(True) - self.close_btn.add(icon) - self.add(self.label) - self.add(self.close_btn) + self.close_bttn.add(icon) + self.event_box.add(self.label) + self.add(self.event_box) + self.add(self.close_bttn) self.show_all() def clear_signals_and_data(self): - self.close_btn.disconnect(self._handler_id) - self._close_tab = None - self._handler_id = None + self.close_bttn.disconnect(self._handler_id) + self.event_box.disconnect(self._eve_handler_id) + self._close_tab = None + self._handler_id = None for child in self.get_children(): child.unparent() @@ -64,8 +72,8 @@ class TabWidget(Gtk.Box): child.destroy() def set_close_signal(self, callback): - self._handler_id = self.close_btn.connect( - 'button-release-event', + self._handler_id = self.close_bttn.connect( + 'clicked', callback, self.file ) diff --git a/src/core/widgets/code/tabs_widget.py b/src/core/widgets/code/tabs_widget.py index bd16986..58bcd9d 100644 --- a/src/core/widgets/code/tabs_widget.py +++ b/src/core/widgets/code/tabs_widget.py @@ -3,7 +3,9 @@ # Lib imports import gi gi.require_version('Gtk', '3.0') +gi.require_version('Gdk', '3.0') from gi.repository import Gtk +from gi.repository import Gdk # Application imports from libs.event_factory import Event_Factory, Code_Event_Types @@ -23,7 +25,7 @@ class TabsWidget(Gtk.Notebook): def _setup_styling(self): - ... + self.set_scrollable(True) def _setup_signals(self): self.connect("page-added", self._page_added) @@ -40,14 +42,16 @@ class TabsWidget(Gtk.Notebook): tab = self.get_tab_label(page_widget) tab.set_close_signal(self._close_tab) + self._bind_tab_menu(tab, page_widget) + page_widget.show() self.set_tab_detachable(page_widget, True) self.set_tab_reorderable(page_widget, True) - def _close_tab(self, tab, eve, file): + def _close_tab(self, button, file): event = Event_Factory.create_event( "remove_file", - buffer = tab.get_parent().file.buffer + buffer = file.buffer ) self.message(event) @@ -73,3 +77,75 @@ class TabsWidget(Gtk.Notebook): ) self.handler_unblock(self.switch_page_id) + + def _bind_tab_menu(self, tab, page_widget): + def do_context_menu(tab, eve, page_widget): + if eve.type == Gdk.EventType.BUTTON_RELEASE and eve.button == 3: # r-click + menu = self.create_menu(page_widget) + menu.popup_at_pointer(eve) + + tab._eve_handler_id = \ + tab.event_box.connect( + "button-release-event", + do_context_menu, + page_widget + ) + + def create_menu(self, page_widget) -> Gtk.Menu: + context_menu = Gtk.Menu() + + close_item = Gtk.MenuItem(label = "Close Tab") + close_left_item = Gtk.MenuItem(label = "Close Tabs Left") + close_right_item = Gtk.MenuItem(label = "Close Tabs Right") + close_other_item = Gtk.MenuItem(label = "Close Other Tabs") + close_all_item = Gtk.MenuItem(label = "Close All Tabs") + + close_item.connect("activate", self.close_item, page_widget) + close_left_item.connect("activate", self.close_left_items, page_widget) + close_right_item.connect("activate", self.close_right_items, page_widget) + close_other_item.connect("activate", self.close_other_items, page_widget) + close_all_item.connect("activate", self.close_all_items, page_widget) + + context_menu.append(close_item) + context_menu.append(close_left_item) + context_menu.append(close_right_item) + context_menu.append(close_other_item) + context_menu.append(close_all_item) + + context_menu.show_all() + + return context_menu + + + def close_item(self, menu_item, page_widget): + tab = self.get_tab_label(page_widget) + tab.close_bttn.clicked() + + def close_left_items(self, menu_item, page_widget): + children = self.get_children() + i = children.index(page_widget) + + if i == 0: return + + for widget in children[ : i]: + tab = self.get_tab_label(widget) + tab.close_bttn.clicked() + + def close_right_items(self, menu_item, page_widget): + children = self.get_children() + i = children.index(page_widget) + 1 + + if i == len(children): return + + for widget in children[i : ]: + tab = self.get_tab_label(widget) + tab.close_bttn.clicked() + + def close_other_items(self, menu_item, page_widget): + self.close_left_items(menu_item, page_widget) + self.close_right_items(menu_item, page_widget) + + def close_all_items(self, menu_item, page_widget): + for widget in children[ : ]: + tab = self.get_tab_label(widget) + tab.close_bttn.clicked()