diff --git a/dzgui/controllers/emitter.py b/dzgui/controllers/emitter.py index 292f613..2ed26d9 100644 --- a/dzgui/controllers/emitter.py +++ b/dzgui/controllers/emitter.py @@ -10,6 +10,7 @@ if TYPE_CHECKING: # TODO: rename signals to e.g. maps_keybinding_pressed + class Emitter(GObject.GObject): def __init__(self) -> None: super().__init__() @@ -56,10 +57,6 @@ class Emitter(GObject.GObject): def distcalc_started(self) -> None: pass - @GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=(object,)) - def servers_loaded(self, tag: "ServerTab") -> None: - pass - @GObject.Signal( flags=GObject.SignalFlags.RUN_LAST, arg_types=( @@ -71,3 +68,19 @@ class Emitter(GObject.GObject): self, dist: Union[str, None], context: Union["ServerTab", "NotebookPage"] ) -> None: pass + + @GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=(object,)) + def servers_loaded(self, tag: "ServerTab") -> None: + pass + + # @GObject.Signal( + # flags=GObject.SignalFlags.RUN_LAST, + # arg_types=( + # object, + # object, + # ), + # ) + # def distcalc_ended( + # self, dist: Union[str, None], context: Union["ServerTab", "NotebookPage"] + # ) -> None: + # pass diff --git a/dzgui/controllers/mc.py b/dzgui/controllers/mc.py index 1194be5..6f81d19 100644 --- a/dzgui/controllers/mc.py +++ b/dzgui/controllers/mc.py @@ -253,16 +253,18 @@ class Controller(GObject.GObject): def set_statusbar_dist(self, haversine: "Haversine", enum: "ServerTab") -> None: context = self.get_active_context() + print(context) page = self.mediator.notebook.get_page_by_enum() """ NOTE: prevents race condition when server tab changed, but allows caching the distance in the background """ if page != NotebookPage.SERVERS: - self.mediator.statusbar.spinner.stop() + self.emitter.emit("distcalc_ended" , None, context) + #self.mediator.statusbar.spinner.stop() return if enum != context: - self.mediator.statusbar.emit("distcalc_ended", None, context) + self.emitter.emit("distcalc_ended" , None, context) return # NOTE: user may have changed km/mi toggle, so recalculate @@ -280,7 +282,7 @@ class Controller(GObject.GObject): separated = number(raw) dist = str(separated) + " km" - self.mediator.statusbar.emit("distcalc_ended", dist, context) + self.emitter.emit("distcalc_ended", dist, context) def delete_multiple_mods(self) -> None: sel = self.mediator.modtreeview.get_selection() @@ -781,13 +783,13 @@ class Controller(GObject.GObject): self.emitter.emit("servers_loaded", treeview.get_enum()) return + treeview.set_model(None) func = treeview.get_query_func() if func is None: self.emitter.emit("servers_loaded", treeview.get_enum()) return # TODO: on legacy version, model clearing happens in thread # (compare) - treeview.set_model(None) # manager = treeview.get_filter_man() # manager.clear_model() self.set_callback(None, None) diff --git a/dzgui/views/components/right_panel.py b/dzgui/views/components/right_panel.py index 9e44dba..28f0064 100644 --- a/dzgui/views/components/right_panel.py +++ b/dzgui/views/components/right_panel.py @@ -1,5 +1,6 @@ from typing import Optional, TYPE_CHECKING +from dzgui.const.enum import ServerTab from dzgui.views.components.buttonbox import ButtonBox from dzgui.views.components.filter_panel import FilterPanel from dzgui.views.components.mod_panel import ModSelectionPanel @@ -30,6 +31,7 @@ class RightPanel(Gtk.Box): self.filters_vbox = FilterPanel(controller) self.sel_panel = ModSelectionPanel(controller) + emitter.connect("servers_loaded", self.toggle_refresh_button) self.refresh_button = RefreshButton(controller) self.keys = KeysButton(controller) @@ -38,6 +40,14 @@ class RightPanel(Gtk.Box): self.pack_start(self.sel_panel, NO_EXPAND, NO_FILL, NO_PADDING) + def toggle_refresh_button(self, emitter: "Emitter", context: "ServerTab") -> None: + # TODO: when a row is added, make sure "servers_loaded" signal is emitted + self.refresh_button.set_sensitive(True) + model = self.controller.get_active_treeview().get_model() + if model is None: + if context in (ServerTab.RECENT, ServerTab.SAVED): + self.refresh_button.set_sensitive(False) + # TODO: move to filter panel def reinit_maps(self, rows: list) -> None: self.controller.reinit_map_store() diff --git a/dzgui/views/components/statusbar.py b/dzgui/views/components/statusbar.py index 09892fe..cd4a909 100644 --- a/dzgui/views/components/statusbar.py +++ b/dzgui/views/components/statusbar.py @@ -1,3 +1,4 @@ +from datetime import datetime from typing import Self, Union, TYPE_CHECKING from dzgui.const.enum import NotebookPage, ServerTab @@ -47,23 +48,25 @@ class Statusbar(Gtk.Grid): controller.mediator.notebook.connect_after( "switch-page", self._on_notebook_page_changed ) + # TODO: - self.emitter.connect("distcalc_started", lambda _: self.spinner.start()) + self.emitter.connect("distcalc_started", self._on_distcalc_started) + self.emitter.connect("distcalc_ended", self._on_distcalc_ended) self.emitter.connect("servers_loaded", self._on_servers_loaded) - self.connect("distcalc_ended", self._on_distcalc_ended) + # self.connect("distcalc_ended", self._on_distcalc_ended) - @GObject.Signal( - flags=GObject.SignalFlags.RUN_LAST, - arg_types=( - object, - object, - ), - ) - def distcalc_ended( - self, dist: Union[str, None], context: Union["ServerTab", NotebookPage] - ) -> None: - pass + # @GObject.Signal( + # flags=GObject.SignalFlags.RUN_LAST, + # arg_types=( + # object, + # object, + # ), + # ) + # def distcalc_ended( + # self, dist: Union[str, None], context: Union["ServerTab", NotebookPage] + # ) -> None: + # pass def _on_notebook_page_changed( self, notebook: "Notebook", child: Gtk.Widget, index: int @@ -107,6 +110,9 @@ class Statusbar(Gtk.Grid): def _on_server_row_changed(self, statusbar: Self) -> None: self.spinner.start() + def _on_distcalc_started(self, e) -> None: + self.spinner.start() + def _on_distcalc_ended( self, statusbar: Self, diff --git a/dzgui/views/mixins/context_mixin.py b/dzgui/views/mixins/context_mixin.py index 4cd12b0..c9e5079 100644 --- a/dzgui/views/mixins/context_mixin.py +++ b/dzgui/views/mixins/context_mixin.py @@ -20,27 +20,27 @@ class ContextMixin(TreeView): ) -> None: if self.is_selection_empty(): - return + return False if event.type is Gdk.EventType.BUTTON_PRESS: if event.button != 3: - return + return False try: pathinfo = self.get_path_at_pos(int(event.x), int(event.y)) if pathinfo is None: - return + return True (path, col, cellx, celly) = pathinfo if path is None: - return + return True self.set_cursor(path, col, False) except AttributeError: pass if event.type is Gdk.EventType.KEY_PRESS: if event.state is not Gdk.ModifierType.CONTROL_MASK: - return + return False if event.keyval is not Gdk.KEY_l: - return + return False group = self.menu self.context_menu = Gtk.Menu() @@ -83,30 +83,30 @@ class ContextMixin(TreeView): self.controller.menu_action(enum, path) def _on_key(self, menu: Gtk.Menu, event: Gdk.EventKey) -> bool | None: - if not is_navkey(event.keyval): - return False - menu = self.context_menu - sel = menu.get_selected_item() - children = menu.get_children() - for i, child in enumerate(children): - if sel is child: - ind = i - break + if not is_navkey(event.keyval): + return False + menu = self.context_menu + sel = menu.get_selected_item() + children = menu.get_children() + for i, child in enumerate(children): + if sel is child: + ind = i + break - match event.keyval: - case Gdk.KEY_j: - if ind == len(children) - 1: - return True - menu.select_item(children[ind + 1]) - case Gdk.KEY_k: - if ind - 1 < 0: - return True - menu.select_item(children[ind - 1]) - case Gdk.KEY_g: - menu.select_item(children[0]) - case Gdk.KEY_G: - ind = len(children) - 1 - menu.select_item(children[ind]) - case _: - return False - return True + match event.keyval: + case Gdk.KEY_j: + if ind == len(children) - 1: + return True + menu.select_item(children[ind + 1]) + case Gdk.KEY_k: + if ind - 1 < 0: + return True + menu.select_item(children[ind - 1]) + case Gdk.KEY_g: + menu.select_item(children[0]) + case Gdk.KEY_G: + ind = len(children) - 1 + menu.select_item(children[ind]) + case _: + return False + return True diff --git a/dzgui/views/pages/servers.py b/dzgui/views/pages/servers.py index f23ab1a..d9125f8 100644 --- a/dzgui/views/pages/servers.py +++ b/dzgui/views/pages/servers.py @@ -59,6 +59,8 @@ class ServerNotebook(Gtk.ScrolledWindow): def _on_map(self, widget: Self) -> None: self.emitter.emit("server_page_toggled", True) + print("page changed, starting queue checker") + self.get_active_treeview().start_timeout() def _on_unmap(self, widget: Self) -> None: self.emitter.emit("server_page_toggled", False) diff --git a/dzgui/views/trees/tree_servers.py b/dzgui/views/trees/tree_servers.py index 1cc87a6..cb3bba7 100644 --- a/dzgui/views/trees/tree_servers.py +++ b/dzgui/views/trees/tree_servers.py @@ -26,6 +26,8 @@ if TYPE_CHECKING: from dzgui.controllers.mc import Controller from dzgui.controllers.emitter import Emitter +QUEUE_CHECK_DELAY = 200 + class ServerTreeView(ContextMixin, TreeView): def __init__( @@ -33,8 +35,6 @@ class ServerTreeView(ContextMixin, TreeView): ) -> None: super().__init__(controller, menu=ContextMenuGroup.SERVER_BROWSER) - QUEUE_CHECK_DELAY = 200 - self.controller = controller self.emitter = controller.get_emitter() self.enum = enum @@ -49,6 +49,8 @@ class ServerTreeView(ContextMixin, TreeView): self.set_fixed_height_mode(True) self.set_headers_visible(True) + self.queue_id: int = 0 + self.current_proc = None self.queue = multiprocessing.Queue() @@ -103,9 +105,14 @@ class ServerTreeView(ContextMixin, TreeView): self.connect("key-press-event", self.present_menu) self.connect("button-press-event", self.present_menu) - self.emitter.connect("statusbar_loaded", self._on_distcalc_started) - self.emitter.connect("distcalc_started", self._on_distcalc_started) - GLib.timeout_add(QUEUE_CHECK_DELAY, self._check_result_queue) + # TODO: simplify this + self.emitter.connect("statusbar_loaded", self.start_distcalc) + # self.emitter.connect("distcalc_started", self._on_distcalc_started) + + def start_timeout(self) -> None: + if self.queue_id: + GLib.Source.remove(self.queue_id) + self.queue_id = GLib.timeout_add(QUEUE_CHECK_DELAY, self._check_result_queue) def get_filter_man(self) -> FilteredModelManager: return self.filter_man @@ -163,9 +170,15 @@ class ServerTreeView(ContextMixin, TreeView): if self.current_proc and self.current_proc.is_alive(): self.current_proc.terminate() - def _on_distcalc_started(self, emitter: "Emitter"): + from typing import Optional + + def start_distcalc(self, emitter: Optional["Emitter"] = None): + self.terminate_process() + self.emitter.emit("distcalc_started") record = self.get_record() if record is None: + context = self.get_enum() + self.emitter.emit("distcalc_ended", None, context) return cache = self.controller.get_dist_cache() @@ -250,13 +263,12 @@ class ServerTreeView(ContextMixin, TreeView): def _parent_row_activated( self, tree: TreeView, path: Gtk.TreePath, column: Gtk.TreeViewColumn ) -> None: - # TODO: process server connection - # TODO: get record print(self.get_value_at_index(0)) def _parent_selection_changed(self, base_class: TreeView, sel: Gtk.TreeSelection): - self.terminate_process() - self.emitter.emit("distcalc_started") + if self.loaded is False: + return + self.start_distcalc() def get_record_string(self) -> str: addr = self.get_value_at_index(7)