mirror of
https://github.com/aclist/dztui.git
synced 2026-10-30 14:42:54 +01:00
fix: dynamic statusbar WIP
This commit is contained in:
1 parent
934ff91f05
commit
61f2d35f16
4 files changed
+64
-56
No files matched your search
+30
-44
@@ -2,6 +2,7 @@ import logging
|
|||||||
import shutil
|
import shutil
|
||||||
import threading
|
import threading
|
||||||
import traceback
|
import traceback
|
||||||
|
from warnings import deprecated
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Any, Callable, Literal, TYPE_CHECKING
|
from typing import Any, Callable, Literal, TYPE_CHECKING
|
||||||
@@ -83,6 +84,7 @@ class AppNavigation:
|
|||||||
class Controller:
|
class Controller:
|
||||||
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.crumbs_cache = ""
|
||||||
self.mediator = AppNavigation()
|
self.mediator = AppNavigation()
|
||||||
self.prefs: UserPrefs
|
self.prefs: UserPrefs
|
||||||
@@ -98,6 +100,7 @@ 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:
|
def set_crumbs(self, text: str) -> None:
|
||||||
self.mediator.grid.set_breadcrumbs(text)
|
self.mediator.grid.set_breadcrumbs(text)
|
||||||
|
|
||||||
@@ -231,29 +234,29 @@ class Controller:
|
|||||||
def get_statusbar(self) -> str:
|
def get_statusbar(self) -> str:
|
||||||
return self.mediator.statusbar.get_text()
|
return self.mediator.statusbar.get_text()
|
||||||
|
|
||||||
|
@deprecated("use statusbar internal contexts")
|
||||||
def remove_statusbar(self, context: str) -> None:
|
def remove_statusbar(self, context: str) -> None:
|
||||||
c = self.mediator.statusbar.statusbar.get_context_id(context)
|
c = self.mediator.statusbar.statusbar.get_context_id(context)
|
||||||
self.mediator.statusbar.statusbar.pop(c)
|
self.mediator.statusbar.statusbar.pop(c)
|
||||||
|
|
||||||
|
# TODO: use set_by_context()
|
||||||
def set_statusbar(self, text: str, context: str) -> int:
|
def set_statusbar(self, text: str, context: str) -> int:
|
||||||
msg_id = self.mediator.statusbar.set_text(text, context)
|
msg_id = self.mediator.statusbar.set_text(text, context)
|
||||||
return msg_id
|
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:
|
def set_statusbar_dist(self, haversine: "Haversine", enum: "ServerTab") -> None:
|
||||||
# NOTE: prevent race condition where page was changed before distance was written
|
tv = self.get_active_treeview()
|
||||||
if self.mediator.notebook.get_page_by_enum() is not NotebookPage.SERVERS:
|
context = tv.get_enum()
|
||||||
cid = self.mediator.statusbar.statusbar.get_context_id(str(enum))
|
page = self.mediator.notebook.get_page_by_enum()
|
||||||
self.mediator.statusbar.statusbar.pop(cid)
|
"""
|
||||||
|
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()
|
self.mediator.statusbar.spinner.stop()
|
||||||
return
|
return
|
||||||
|
if enum != context:
|
||||||
tv = self.get_active_treeview()
|
self.mediator.statusbar.emit("distcalc_ended", None, context)
|
||||||
if tv.get_enum() != enum:
|
|
||||||
self.mediator.statusbar.spinner.stop()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
# NOTE: user may have changed km/mi toggle, so recalculate
|
# NOTE: user may have changed km/mi toggle, so recalculate
|
||||||
@@ -269,10 +272,8 @@ class Controller:
|
|||||||
raw = round(haversine.as_kilometers())
|
raw = round(haversine.as_kilometers())
|
||||||
separated = number(raw)
|
separated = number(raw)
|
||||||
dist = str(separated) + " km"
|
dist = str(separated) + " km"
|
||||||
text = self.statusbar_placeholder
|
|
||||||
# TODO: abstract
|
self.mediator.statusbar.emit("distcalc_ended", dist, context)
|
||||||
self.set_statusbar(f"{text} | Distance: {dist}", "Servers")
|
|
||||||
self.mediator.statusbar.spinner.stop()
|
|
||||||
|
|
||||||
def delete_multiple_mods(self) -> None:
|
def delete_multiple_mods(self) -> None:
|
||||||
sel = self.mediator.modtreeview.get_selection()
|
sel = self.mediator.modtreeview.get_selection()
|
||||||
@@ -334,6 +335,8 @@ class Controller:
|
|||||||
|
|
||||||
def toggle_server_panels(self, state: bool) -> None:
|
def toggle_server_panels(self, state: bool) -> None:
|
||||||
# TODO: this is going to be signal dependent now
|
# 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_filter_panel(state)
|
||||||
self.mediator.grid.toggle_connect_panel(state)
|
self.mediator.grid.toggle_connect_panel(state)
|
||||||
self.mediator.grid.toggle_refresh_button(state)
|
self.mediator.grid.toggle_refresh_button(state)
|
||||||
@@ -343,8 +346,6 @@ class Controller:
|
|||||||
|
|
||||||
def show_developers_page(self) -> None:
|
def show_developers_page(self) -> None:
|
||||||
self.open_page(NotebookPage.DEVELOPERS)
|
self.open_page(NotebookPage.DEVELOPERS)
|
||||||
# TODO: put cursor on first row
|
|
||||||
# self.mediator.developers.focus_first_row()
|
|
||||||
|
|
||||||
def open_page(self, page: NotebookPage) -> None:
|
def open_page(self, page: NotebookPage) -> None:
|
||||||
self.mediator.grid.notebook.set_page_by_enum(page)
|
self.mediator.grid.notebook.set_page_by_enum(page)
|
||||||
@@ -599,10 +600,11 @@ class Controller:
|
|||||||
for row in data:
|
for row in data:
|
||||||
manager.append_row(row)
|
manager.append_row(row)
|
||||||
treeview.set_loaded(True)
|
treeview.set_loaded(True)
|
||||||
self.update_server_status()
|
self.mediator.statusbar.emit("server_page_changed", context)
|
||||||
treeview.grab_focus()
|
treeview.grab_focus()
|
||||||
|
|
||||||
treeview = self.get_active_treeview()
|
treeview = self.get_active_treeview()
|
||||||
|
context = treeview.get_enum()
|
||||||
|
|
||||||
manager = treeview.get_filter_man()
|
manager = treeview.get_filter_man()
|
||||||
data = self.data
|
data = self.data
|
||||||
@@ -707,30 +709,15 @@ class Controller:
|
|||||||
treeview.set_loaded(False)
|
treeview.set_loaded(False)
|
||||||
self.populate_model()
|
self.populate_model()
|
||||||
|
|
||||||
def update_server_status(self) -> None:
|
def get_player_count(self) -> str:
|
||||||
# TODO: emit signal on statusbar only if page changed
|
|
||||||
treeview = self.get_active_treeview()
|
treeview = self.get_active_treeview()
|
||||||
context = str(treeview.enum)
|
context = treeview.get_enum()
|
||||||
model = treeview.get_model()
|
model = treeview.get_model()
|
||||||
status = format_player_count(model)
|
status = format_player_count(model)
|
||||||
|
return status
|
||||||
|
|
||||||
self.set_statusbar_placeholder(status)
|
def get_statusbar(self) -> None:
|
||||||
self.set_statusbar(status, context)
|
return self.mediator.statusbar
|
||||||
#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 populate_model(self) -> None:
|
def populate_model(self) -> None:
|
||||||
treeview = self.get_active_treeview()
|
treeview = self.get_active_treeview()
|
||||||
@@ -748,15 +735,14 @@ class Controller:
|
|||||||
self.mediator.right_panel.focus_button_box()
|
self.mediator.right_panel.focus_button_box()
|
||||||
|
|
||||||
def present_servers(self) -> None:
|
def present_servers(self) -> None:
|
||||||
# TODO: abstract
|
treeview = self.get_active_treeview()
|
||||||
self.update_server_status()
|
context = treeview.get_enum()
|
||||||
|
|
||||||
|
self.mediator.statusbar.emit("server_page_changed", context)
|
||||||
# TODO: signal for crumbs
|
# TODO: signal for crumbs
|
||||||
crumbs = self.mediator.servers.get_cached_label()
|
crumbs = self.mediator.servers.get_cached_label()
|
||||||
self.set_crumbs(crumbs)
|
self.set_crumbs(crumbs)
|
||||||
|
|
||||||
tree = self.get_active_treeview()
|
|
||||||
tree.emit("on_distcalc_started")
|
|
||||||
|
|
||||||
def toggle_check(self, event: Gdk.EventKey) -> None | Literal[False]:
|
def toggle_check(self, event: Gdk.EventKey) -> None | Literal[False]:
|
||||||
mappings = {
|
mappings = {
|
||||||
Gdk.KEY_1: 0,
|
Gdk.KEY_1: 0,
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import logging
|
import logging
|
||||||
import multiprocessing
|
import multiprocessing
|
||||||
|
|
||||||
from math import radians, cos, sin, asin, sqrt
|
from math import radians, cos, sin, asin, sqrt
|
||||||
from typing import TYPE_CHECKING
|
from typing import TYPE_CHECKING
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ class Statusbar(Gtk.Grid):
|
|||||||
"server_page_changed": (GObject.SignalFlags.RUN_FIRST, None, (object,)),
|
"server_page_changed": (GObject.SignalFlags.RUN_FIRST, None, (object,)),
|
||||||
"notebook_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,)),
|
"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:
|
def __init__(self, controller: "Controller") -> None:
|
||||||
@@ -29,7 +31,7 @@ class Statusbar(Gtk.Grid):
|
|||||||
|
|
||||||
help_text = strings.statusbar_helptext
|
help_text = strings.statusbar_helptext
|
||||||
|
|
||||||
self.context: int
|
self.playercount = ""
|
||||||
self.statusbar = Gtk.Statusbar()
|
self.statusbar = Gtk.Statusbar()
|
||||||
|
|
||||||
self.spinner = Gtk.Spinner()
|
self.spinner = Gtk.Spinner()
|
||||||
@@ -49,9 +51,11 @@ class Statusbar(Gtk.Grid):
|
|||||||
self.set_text(help_text, "Help")
|
self.set_text(help_text, "Help")
|
||||||
self.players = ""
|
self.players = ""
|
||||||
|
|
||||||
|
self.connect("server_row_changed", self._on_server_row_changed)
|
||||||
self.connect("server_page_changed", self._on_server_page_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_changed", self._on_notebook_page_changed)
|
||||||
self.connect("notebook_page_returned", self._on_notebook_page_returned)
|
self.connect("notebook_page_returned", self._on_notebook_page_returned)
|
||||||
|
self.connect("distcalc_ended", self._on_distcalc_ended)
|
||||||
|
|
||||||
def _on_notebook_page_changed(
|
def _on_notebook_page_changed(
|
||||||
self, statusbar: Self, context: "NotebookPage"
|
self, statusbar: Self, context: "NotebookPage"
|
||||||
@@ -67,21 +71,39 @@ class Statusbar(Gtk.Grid):
|
|||||||
bar = self.controller.format_mod_statusbar()
|
bar = self.controller.format_mod_statusbar()
|
||||||
case NotebookPage.HELP:
|
case NotebookPage.HELP:
|
||||||
bar = self.controller.get_help_text()
|
bar = self.controller.get_help_text()
|
||||||
|
case NotebookPage.SERVERS:
|
||||||
|
pass
|
||||||
|
|
||||||
self.set_by_context(context, bar)
|
self.set_by_context(context, bar)
|
||||||
|
|
||||||
def _on_notebook_page_returned(
|
def _on_notebook_page_returned(
|
||||||
self, statusbar: Self, prior_context: "NotebookPage"
|
self, statusbar: Self, prior_context: NotebookPage
|
||||||
) -> None:
|
) -> None:
|
||||||
self.pop(prior_context)
|
self.pop(prior_context)
|
||||||
|
|
||||||
def _on_server_page_changed(self, statusbar: Self, context: "ServerTab") -> None:
|
def _on_server_row_changed(self, statusbar: Self) -> None:
|
||||||
self.pop(context)
|
|
||||||
|
|
||||||
def start_spinner(self) -> None:
|
|
||||||
self.spinner.start()
|
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()
|
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:
|
def pop(self, context: Union["ServerTab", "NotebookPage"]) -> None:
|
||||||
cid = self.statusbar.get_context_id(str(context))
|
cid = self.statusbar.get_context_id(str(context))
|
||||||
|
|||||||
@@ -213,27 +213,26 @@ class ServerTreeView(TreeView):
|
|||||||
self.current_proc.terminate()
|
self.current_proc.terminate()
|
||||||
|
|
||||||
def _on_distcalc_started(self, treeview: Self):
|
def _on_distcalc_started(self, treeview: Self):
|
||||||
|
bar = self.controller.get_statusbar()
|
||||||
|
|
||||||
record = self.get_record()
|
record = self.get_record()
|
||||||
if record is None:
|
if record is None:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
bar.emit("server_row_changed")
|
||||||
cache = self.controller.get_dist_cache()
|
cache = self.controller.get_dist_cache()
|
||||||
|
|
||||||
if record.ip in cache:
|
if record.ip in cache:
|
||||||
haversine = cache[record.ip]
|
haversine = cache[record.ip]
|
||||||
self.controller.set_statusbar_dist(haversine, None)
|
self.controller.set_statusbar_dist(haversine, self.get_enum())
|
||||||
return
|
return
|
||||||
|
|
||||||
if len(self.get_model()) > 1:
|
|
||||||
self.controller.start_spinner()
|
|
||||||
|
|
||||||
self.current_proc = CalcDist(
|
self.current_proc = CalcDist(
|
||||||
record.ip, self.get_enum(), self.queue, self.controller
|
record.ip, self.get_enum(), self.queue, self.controller
|
||||||
)
|
)
|
||||||
self.current_proc.start()
|
self.current_proc.start()
|
||||||
|
|
||||||
def _check_result_queue(self) -> Literal[True]:
|
def _check_result_queue(self) -> Literal[True]:
|
||||||
# TODO: trigger signal when changing page contexts
|
|
||||||
# TODO: delegate to controller
|
# TODO: delegate to controller
|
||||||
latest_result = None
|
latest_result = None
|
||||||
while not self.queue.empty():
|
while not self.queue.empty():
|
||||||
|
|||||||
Reference in new issue
Block a user