diff --git a/dzgui/controllers/mc.py b/dzgui/controllers/mc.py index 19412b2..43641a1 100644 --- a/dzgui/controllers/mc.py +++ b/dzgui/controllers/mc.py @@ -2,6 +2,7 @@ import logging import shutil import threading import traceback +from warnings import deprecated from pathlib import Path from typing import Any, Callable, Literal, TYPE_CHECKING @@ -83,6 +84,7 @@ class AppNavigation: class Controller: def __init__(self) -> None: self.dist_cache: dict[str, "Haversine", "ServerTab"] = {} + # TODO: store in crumbs class self.crumbs_cache = "" self.mediator = AppNavigation() self.prefs: UserPrefs @@ -98,6 +100,7 @@ class Controller: except AttributeError: logger.critical(f"{attr} is not a valid AppNavigation attribute.") + # TODO: relegate to crumbs class def set_crumbs(self, text: str) -> None: self.mediator.grid.set_breadcrumbs(text) @@ -231,29 +234,29 @@ class Controller: def get_statusbar(self) -> str: return self.mediator.statusbar.get_text() + @deprecated("use statusbar internal contexts") def remove_statusbar(self, context: str) -> None: c = self.mediator.statusbar.statusbar.get_context_id(context) self.mediator.statusbar.statusbar.pop(c) + # TODO: use set_by_context() def set_statusbar(self, text: str, context: str) -> int: msg_id = self.mediator.statusbar.set_text(text, context) return msg_id - def set_statusbar_placeholder(self, text: str) -> None: - # TODO: use statusbar stacks instead - self.statusbar_placeholder = text - def set_statusbar_dist(self, haversine: "Haversine", enum: "ServerTab") -> None: - # NOTE: prevent race condition where page was changed before distance was written - if self.mediator.notebook.get_page_by_enum() is not NotebookPage.SERVERS: - cid = self.mediator.statusbar.statusbar.get_context_id(str(enum)) - self.mediator.statusbar.statusbar.pop(cid) + tv = self.get_active_treeview() + context = tv.get_enum() + page = self.mediator.notebook.get_page_by_enum() + """ + NOTE: prevents race condition when notebook page changed, + but allows caching the distance in the background + """ + if page != NotebookPage.SERVERS: self.mediator.statusbar.spinner.stop() return - - tv = self.get_active_treeview() - if tv.get_enum() != enum: - self.mediator.statusbar.spinner.stop() + if enum != context: + self.mediator.statusbar.emit("distcalc_ended", None, context) return # NOTE: user may have changed km/mi toggle, so recalculate @@ -269,10 +272,8 @@ class Controller: raw = round(haversine.as_kilometers()) separated = number(raw) dist = str(separated) + " km" - text = self.statusbar_placeholder - # TODO: abstract - self.set_statusbar(f"{text} | Distance: {dist}", "Servers") - self.mediator.statusbar.spinner.stop() + + self.mediator.statusbar.emit("distcalc_ended", dist, context) def delete_multiple_mods(self) -> None: sel = self.mediator.modtreeview.get_selection() @@ -334,6 +335,8 @@ class Controller: def toggle_server_panels(self, state: bool) -> None: # TODO: this is going to be signal dependent now + # cf. map/unmap + #self.mediator.grid.emit("toggle panels", state) self.mediator.grid.toggle_filter_panel(state) self.mediator.grid.toggle_connect_panel(state) self.mediator.grid.toggle_refresh_button(state) @@ -343,8 +346,6 @@ class Controller: def show_developers_page(self) -> None: self.open_page(NotebookPage.DEVELOPERS) - # TODO: put cursor on first row - # self.mediator.developers.focus_first_row() def open_page(self, page: NotebookPage) -> None: self.mediator.grid.notebook.set_page_by_enum(page) @@ -599,10 +600,11 @@ class Controller: for row in data: manager.append_row(row) treeview.set_loaded(True) - self.update_server_status() + self.mediator.statusbar.emit("server_page_changed", context) treeview.grab_focus() treeview = self.get_active_treeview() + context = treeview.get_enum() manager = treeview.get_filter_man() data = self.data @@ -707,30 +709,15 @@ class Controller: treeview.set_loaded(False) self.populate_model() - def update_server_status(self) -> None: - # TODO: emit signal on statusbar only if page changed + def get_player_count(self) -> str: treeview = self.get_active_treeview() - context = str(treeview.enum) + context = treeview.get_enum() model = treeview.get_model() status = format_player_count(model) + return status - self.set_statusbar_placeholder(status) - self.set_statusbar(status, context) - #if len(model) >= 1: - # self.mediator.statusbar.spinner.start() - - def start_spinner(self) -> None: - # TODO: use signal instead - self.mediator.statusbar.start_spinner() - - def notify_statusbar_of_notebook_change(self) -> None: - enum = self.mediator.notebook.get_page_by_enum() - self.mediator.statusbar.emit("notebook_page_changed", enum) - - def notify_statusbar(self) -> None: - tv = self.get_active_treeview() - enum = tv.get_enum() - self.mediator.statusbar.emit("server_page_changed", enum) + def get_statusbar(self) -> None: + return self.mediator.statusbar def populate_model(self) -> None: treeview = self.get_active_treeview() @@ -748,15 +735,14 @@ class Controller: self.mediator.right_panel.focus_button_box() def present_servers(self) -> None: - # TODO: abstract - self.update_server_status() + treeview = self.get_active_treeview() + context = treeview.get_enum() + + self.mediator.statusbar.emit("server_page_changed", context) # TODO: signal for crumbs crumbs = self.mediator.servers.get_cached_label() self.set_crumbs(crumbs) - tree = self.get_active_treeview() - tree.emit("on_distcalc_started") - def toggle_check(self, event: Gdk.EventKey) -> None | Literal[False]: mappings = { Gdk.KEY_1: 0, diff --git a/dzgui/util/dist.py b/dzgui/util/dist.py index 70da21f..2eb6be3 100644 --- a/dzgui/util/dist.py +++ b/dzgui/util/dist.py @@ -1,5 +1,6 @@ import logging import multiprocessing + from math import radians, cos, sin, asin, sqrt from typing import TYPE_CHECKING diff --git a/dzgui/views/components/statusbar.py b/dzgui/views/components/statusbar.py index 394ab40..e11fa85 100644 --- a/dzgui/views/components/statusbar.py +++ b/dzgui/views/components/statusbar.py @@ -19,6 +19,8 @@ class Statusbar(Gtk.Grid): "server_page_changed": (GObject.SignalFlags.RUN_FIRST, None, (object,)), "notebook_page_changed": (GObject.SignalFlags.RUN_FIRST, None, (object,)), "notebook_page_returned": (GObject.SignalFlags.RUN_FIRST, None, (object,)), + "distcalc_ended": (GObject.SignalFlags.RUN_FIRST, None, (object, str)), + "server_row_changed": (GObject.SignalFlags.RUN_FIRST, None, ()), } def __init__(self, controller: "Controller") -> None: @@ -29,7 +31,7 @@ class Statusbar(Gtk.Grid): help_text = strings.statusbar_helptext - self.context: int + self.playercount = "" self.statusbar = Gtk.Statusbar() self.spinner = Gtk.Spinner() @@ -49,9 +51,11 @@ class Statusbar(Gtk.Grid): self.set_text(help_text, "Help") self.players = "" + self.connect("server_row_changed", self._on_server_row_changed) self.connect("server_page_changed", self._on_server_page_changed) self.connect("notebook_page_changed", self._on_notebook_page_changed) self.connect("notebook_page_returned", self._on_notebook_page_returned) + self.connect("distcalc_ended", self._on_distcalc_ended) def _on_notebook_page_changed( self, statusbar: Self, context: "NotebookPage" @@ -67,21 +71,39 @@ class Statusbar(Gtk.Grid): bar = self.controller.format_mod_statusbar() case NotebookPage.HELP: bar = self.controller.get_help_text() + case NotebookPage.SERVERS: + pass + self.set_by_context(context, bar) def _on_notebook_page_returned( - self, statusbar: Self, prior_context: "NotebookPage" + self, statusbar: Self, prior_context: NotebookPage ) -> None: self.pop(prior_context) - def _on_server_page_changed(self, statusbar: Self, context: "ServerTab") -> None: - self.pop(context) - - def start_spinner(self) -> None: + def _on_server_row_changed(self, statusbar: Self) -> None: self.spinner.start() - def stop_spinner(self) -> None: + def _on_distcalc_ended( + self, + statusbar: Self, + dist: Union[str, None], + context: Union["ServerTab", NotebookPage], + ) -> None: self.spinner.stop() + if dist is None: + self.set_by_context(context, self.playercount) + else: + pretty = f"{self.playercount} | Distance: {dist}" + self.set_by_context(context, pretty) + + def _on_server_page_changed(self, statusbar: Self, context: "ServerTab") -> None: + c = self.controller.get_player_count() + self.playercount = c + + self.set_by_context(context, c) + tree = self.controller.get_active_treeview() + tree.emit("on_distcalc_started") def pop(self, context: Union["ServerTab", "NotebookPage"]) -> None: cid = self.statusbar.get_context_id(str(context)) diff --git a/dzgui/views/trees/tree_servers.py b/dzgui/views/trees/tree_servers.py index d53519b..384fcb1 100644 --- a/dzgui/views/trees/tree_servers.py +++ b/dzgui/views/trees/tree_servers.py @@ -213,27 +213,26 @@ class ServerTreeView(TreeView): self.current_proc.terminate() def _on_distcalc_started(self, treeview: Self): + bar = self.controller.get_statusbar() + record = self.get_record() if record is None: return + bar.emit("server_row_changed") cache = self.controller.get_dist_cache() if record.ip in cache: haversine = cache[record.ip] - self.controller.set_statusbar_dist(haversine, None) + self.controller.set_statusbar_dist(haversine, self.get_enum()) return - if len(self.get_model()) > 1: - self.controller.start_spinner() - self.current_proc = CalcDist( record.ip, self.get_enum(), self.queue, self.controller ) self.current_proc.start() def _check_result_queue(self) -> Literal[True]: - # TODO: trigger signal when changing page contexts # TODO: delegate to controller latest_result = None while not self.queue.empty():