chore: dynamic statusbar WIP

This commit is contained in:
aclist committed 2026-01-24 08:51:22 +09:00
1 parent 936bc074a5
commit e794aa82dc
6 files changed
+49 -87

No files matched your search

+1 -24
View File
@@ -81,11 +81,9 @@ class AppNavigation:
filters: "FilterPanel" filters: "FilterPanel"
class Controller: class Controller(GObject.GObject):
def __init__(self) -> None: def __init__(self) -> None:
self.dist_cache: dict[str, "Haversine", "ServerTab"] = {} self.dist_cache: dict[str, "Haversine", "ServerTab"] = {}
# TODO: store in crumbs class
self.crumbs_cache = ""
self.mediator = AppNavigation() self.mediator = AppNavigation()
self.prefs: UserPrefs self.prefs: UserPrefs
@@ -100,13 +98,6 @@ class Controller:
except AttributeError: except AttributeError:
logger.critical(f"{attr} is not a valid AppNavigation attribute.") 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)
def get_crumbs(self) -> str:
return self.mediator.grid.get_breadcrumbs()
def get_help_store(self) -> Gtk.ListStore: def get_help_store(self) -> Gtk.ListStore:
return self.model_man.get_help_store() return self.model_man.get_help_store()
@@ -363,16 +354,8 @@ class Controller:
case ButtonType.MODS: case ButtonType.MODS:
# TODO: reload using refresh button, rather than on demand # TODO: reload using refresh button, rather than on demand
self.load_mods() self.load_mods()
case ButtonType.HELP:
pass
case ButtonType.SERVERS:
# TODO: drop after fixing crumbs signal
self.mediator.notebook.set_page_by_enum(button.opens)
return
self.mediator.notebook.set_page_by_enum(button.opens) self.mediator.notebook.set_page_by_enum(button.opens)
# TODO: set crumbs by signal
self.set_crumbs(button.get_label())
def get_help_row(self) -> str: def get_help_row(self) -> str:
tv = self.mediator.menu tv = self.mediator.menu
@@ -697,12 +680,6 @@ class Controller:
def propagate_column_width(self, col: Gtk.TreeViewColumn) -> None: def propagate_column_width(self, col: Gtk.TreeViewColumn) -> None:
GLib.idle_add(self.mediator.servers.update_tab_widths, col) GLib.idle_add(self.mediator.servers.update_tab_widths, col)
def set_crumbs_cache(self, text: str) -> None:
self.crumbs_cache = text
def get_crumbs_cache(self) -> str:
return self.crumbs_cache
def refresh_tree(self) -> None: def refresh_tree(self) -> None:
treeview = self.get_active_treeview() treeview = self.get_active_treeview()
treeview.set_loaded(False) treeview.set_loaded(False)
+2 -1
View File
@@ -67,13 +67,14 @@ class CalcDist(multiprocessing.Process):
self.result_queue.put([self.addr, dist, self.enum]) self.result_queue.put([self.addr, dist, self.enum])
def compare(self, remote: str) -> int | None: def compare(self, remote: str) -> int | None:
# TODO: cache this
prefs = self.controller.get_prefs() prefs = self.controller.get_prefs()
local = prefs.coords local = prefs.coords
if local is None: if local is None:
return None return None
try: try:
remote = get_coords(prefs.paths.ips, remote) remote = get_coords(prefs.paths.ips, remote)
except GeolocationError: except Exception:
return None return None
# TODO: handle failed remote dist # TODO: handle failed remote dist
+18 -20
View File
@@ -2,6 +2,7 @@ import a2s
import requests import requests
import shutil import shutil
import subprocess import subprocess
from warnings import deprecated
from dataclasses import dataclass from dataclasses import dataclass
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
@@ -14,6 +15,7 @@ from dzgui.const.endpoints import COORDS_API, IP_ECHO
if TYPE_CHECKING: if TYPE_CHECKING:
from pathlib import Path from pathlib import Path
@dataclass @dataclass
class Coords: class Coords:
lat: float lat: float
@@ -51,11 +53,11 @@ def get_coords(ips: "Path", ip: str) -> Coords:
prefix = f"^{split[0]}.{split[1]}." prefix = f"^{split[0]}.{split[1]}."
proc = subprocess.run( if shutil.which("rg") is not None:
["/usr/bin/grep", "-E", prefix, ips], args = ["/usr/bin/rg", prefix, ips]
capture_output=True, else:
text=True args = ["/usr/bin/grep", "-E", prefix, ips]
) proc = subprocess.run(args, capture_output=True, text=True)
if proc.returncode != 0: if proc.returncode != 0:
raise GeolocationError("Failed to split records") raise GeolocationError("Failed to split records")
@@ -80,9 +82,9 @@ def get_coords(ips: "Path", ip: str) -> Coords:
return Coords(float(fields[-2]), float(fields[-1])) return Coords(float(fields[-2]), float(fields[-1]))
raise GeolocationError("No matching records found") raise GeolocationError("No matching records found")
def get_local_ip() -> str: def get_local_ip() -> str:
ip = "" ip = ""
# TODO: use shlex
if shutil.which("dig") is not None: if shutil.which("dig") is not None:
proc = subprocess.run( proc = subprocess.run(
[ [
@@ -90,10 +92,10 @@ def get_local_ip() -> str:
"-4", "-4",
"+short", "+short",
"myip.opendns.com", "myip.opendns.com",
"@resolver1.opendns.com" "@resolver1.opendns.com",
], ],
capture_output=True, capture_output=True,
text=True text=True,
) )
if proc.returncode == 0: if proc.returncode == 0:
@@ -110,7 +112,7 @@ def resolve_ip(address: Record) -> Record:
""" """
Multiple game modes may be hosted on the same IP and query port, Multiple game modes may be hosted on the same IP and query port,
but resolve to different game ports. The canonical record must but resolve to different game ports. The canonical record must
contain the real game port. This is merely used when saving a contain the real game port. This is merely used when saving a
record as a UUID. record as a UUID.
""" """
res = a2s.info((address.ip, address.qport)) res = a2s.info((address.ip, address.qport))
@@ -121,17 +123,13 @@ def resolve_ip(address: Record) -> Record:
def is_valid_port(port: str) -> bool: def is_valid_port(port: str) -> bool:
if len(port) < 1: if len(port) < 1:
return True return True
if ( if not port.isdigit() or int(port) == 0 or int(port[0]) == 0 or int(port) > 65535:
not port.isdigit()
or int(port) == 0
or int(port[0]) == 0
or int(port) > 65535
):
return True return True
return False return False
# TODO: deprecated
#def get_local_coords(ip: str): @deprecated("use ips.csv")
# url = COORDS_API + "/" + ip def get_local_coords(ip: str):
# #local res=$(curl -Ls "$url" | jq -r '"\(.lat)\n\(.lon)"') url = COORDS_API + "/" + ip
# return url # local res=$(curl -Ls "$url" | jq -r '"\(.lat)\n\(.lon)"')
return url
+23 -21
View File
@@ -300,22 +300,20 @@ class Notebook(ScrollableMixin, Gtk.Notebook): # type: ignore
def _on_page_changed( def _on_page_changed(
self, notebook: "Notebook", page: Gtk.Widget, page_num: int self, notebook: "Notebook", page: Gtk.Widget, page_num: int
) -> None: ) -> None:
enum = self.get_page_by_enum() return
# enum = self.get_page_by_enum()
# TODO: crumbs signal # TODO: crumbs signal
if enum is not None: # if enum is not None:
crumbs = enum.dict["crumbs"] # crumbs = enum.dict["crumbs"]
MainController.set_crumbs(crumbs) # MainController.set_crumbs(crumbs)
if self.is_return is True: # if self.is_return is True:
MainController.mediator.statusbar.emit( # MainController.mediator.statusbar.emit(
"notebook_page_returned", self.prior_page # "notebook_page_returned", self.prior_page
) # )
else: # else:
MainController.mediator.statusbar.emit("notebook_page_changed", enum) # MainController.mediator.statusbar.emit("notebook_page_changed", enum)
# self.is_return = False
self.is_return = False
#if enum is NotebookPage.SERVERS:
# MainController.present_servers()
class Grid(Gtk.Grid): class Grid(Gtk.Grid):
@@ -331,17 +329,21 @@ class Grid(Gtk.Grid):
self.statusbar = Statusbar(MainController) self.statusbar = Statusbar(MainController)
self.right_panel = RightPanel(MainController) self.right_panel = RightPanel(MainController)
self.breadcrumbs = Gtk.Label(halign=Gtk.Align.START) # self.breadcrumbs = Gtk.Label(halign=Gtk.Align.START)
self.set_breadcrumbs(strings.label_main_menu) # self.set_breadcrumbs(strings.label_main_menu)
self.bu = Gtk.Button(label="Shrink to fit", halign=Gtk.Align.END) # self.bu = Gtk.Button(label="Shrink to fit", halign=Gtk.Align.END)
self.crumb_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL) # self.bu.connect("clicked", self._shrink)
self.crumb_box.add(self.breadcrumbs)
self.crumb_box.add(self.bu) # self.crumb_box.add(self.bu)
self.bu.connect("clicked", self._shrink)
self.notebook = Notebook() self.notebook = Notebook()
self.conpan = ConnectPanel(MainController) self.conpan = ConnectPanel(MainController)
from dzgui.views.components.crumbs import Breadcrumbs
self.breadcrumbs = Breadcrumbs(MainController)
self.crumb_box = Gtk.Box(orientation=Gtk.Orientation.HORIZONTAL)
self.crumb_box.add(self.breadcrumbs)
self.attach(self.notebook, 0, 0, MAX_COLS, SINGLE_ROW) self.attach(self.notebook, 0, 0, MAX_COLS, SINGLE_ROW)
+4 -21
View File
@@ -21,7 +21,6 @@ class ServerNotebook(Gtk.ScrolledWindow):
def __init__(self, controller: "Controller"): def __init__(self, controller: "Controller"):
super().__init__() super().__init__()
self.tab_cache = ""
self.controller = controller self.controller = controller
self.controller.register_widget("servers", self) self.controller.register_widget("servers", self)
self.notebook = Gtk.Notebook(show_tabs=True) self.notebook = Gtk.Notebook(show_tabs=True)
@@ -56,9 +55,6 @@ class ServerNotebook(Gtk.ScrolledWindow):
self.connect("map", self._on_map) self.connect("map", self._on_map)
self.connect("unmap", self._on_unmap) self.connect("unmap", self._on_unmap)
# TODO: strings
self.set_crumbs("Server browser")
def _on_map(self, widget: Self) -> None: def _on_map(self, widget: Self) -> None:
self.controller.toggle_server_panels(True) self.controller.toggle_server_panels(True)
@@ -77,10 +73,10 @@ class ServerNotebook(Gtk.ScrolledWindow):
return return
self.get_active_treeview().grab_focus() self.get_active_treeview().grab_focus()
def set_crumbs(self, text: str) -> None: def get_current_tab_text(self) -> None:
string = f"Servers > {text}" ind = self.notebook.get_current_page()
self.controller.set_crumbs(string) child = self.notebook.get_nth_page(ind)
self.set_cached_label(string) return self.notebook.get_tab_label_text(child)
def _on_page_changed( def _on_page_changed(
self, notebook: Gtk.Notebook, child: Gtk.Widget, index: int self, notebook: Gtk.Notebook, child: Gtk.Widget, index: int
@@ -88,10 +84,6 @@ class ServerNotebook(Gtk.ScrolledWindow):
if self.controller.loaded is False: if self.controller.loaded is False:
return return
# TODO :signals
# emit signal to crumbs
# emit signal to statusbar
# TODO: abstract
label = self.notebook.get_tab_label_text(child) label = self.notebook.get_tab_label_text(child)
if label is None: if label is None:
return return
@@ -99,17 +91,8 @@ class ServerNotebook(Gtk.ScrolledWindow):
# TODO: strings # TODO: strings
text = label.strip("*") text = label.strip("*")
self.notebook.set_tab_label_text(child, text) self.notebook.set_tab_label_text(child, text)
self.set_crumbs(text)
#self.controller.present_servers()
self.controller.populate_model() self.controller.populate_model()
def set_cached_label(self, label: str) -> None:
self.tab_cache = label
def get_cached_label(self) -> str:
return self.tab_cache
def get_active_treeview(self) -> ServerTreeView: def get_active_treeview(self) -> ServerTreeView:
index = self.notebook.get_current_page() index = self.notebook.get_current_page()
scrollable = self.notebook.get_nth_page(index) scrollable = self.notebook.get_nth_page(index)
+1
View File
@@ -65,6 +65,7 @@ build-backend = "setuptools.build_meta"
line-length = 88 line-length = 88
indent-width = 4 indent-width = 4
extend-exclude = ["tree_servers.py", "tree_server_mods.py", "dialogs", "right_panel.py", "filter_panel.py", "base.py", "*lib/a2s", "dist.py"] extend-exclude = ["tree_servers.py", "tree_server_mods.py", "dialogs", "right_panel.py", "filter_panel.py", "base.py", "*lib/a2s", "dist.py"]
lint.unfixable = ["F401"]
[tool.ruff.format] [tool.ruff.format]
quote-style = "double" quote-style = "double"