fix: statusbar signals

This commit is contained in:
aclist 2026-02-07 23:18:25 +09:00
parent fc294bcede
commit 2ef62416c0
7 changed files with 108 additions and 63 deletions

View File

@ -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

View File

@ -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)

View File

@ -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()

View File

@ -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,

View File

@ -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

View File

@ -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)

View File

@ -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)