mirror of
https://github.com/aclist/dztui.git
synced 2026-10-30 14:42:54 +01:00
feat: mediator rewrite (WIP)
This commit is contained in:
1 parent
69cde11e8e
commit
aba00f732a
7 files changed
+163
-180
No files matched your search
+59
-9
@@ -56,18 +56,49 @@ logger = logging.getLogger(__name__)
|
|||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from dzgui.views.components.buttonbox import ContextualButton
|
from dzgui.views.components.buttonbox import ContextualButton
|
||||||
from dzgui.views.base import AppNavigation
|
|
||||||
from dzgui.views.base import OuterWindow
|
from dzgui.views.base import OuterWindow
|
||||||
|
from dzgui.views.trees.tree_base import TreeView
|
||||||
|
from dzgui.views.trees.tree_mods import ModTreeView
|
||||||
|
from dzgui.views.trees.tree_servers import ServerTreeView
|
||||||
|
from dzgui.views.trees.tree_log import LogTreeView
|
||||||
|
from dzgui.views.base import Notebook, Grid, OuterWindow
|
||||||
|
from dzgui.views.components.statusbar import Statusbar
|
||||||
|
from dzgui.views.components.right_panel import RightPanel
|
||||||
|
from dzgui.views.pages.servers import ServerNotebook
|
||||||
|
|
||||||
|
class AppNavigation:
|
||||||
|
window: "OuterWindow"
|
||||||
|
grid: "Grid"
|
||||||
|
right_panel: "RightPanel"
|
||||||
|
statusbar: "Statusbar"
|
||||||
|
notebook: "Notebook"
|
||||||
|
modtreeview: "ModTreeView"
|
||||||
|
menu: "MenuTreeView"
|
||||||
|
servers: "ServerNotebook"
|
||||||
|
browser: "ServerTreeView"
|
||||||
|
saved: "ServerTreeView"
|
||||||
|
recent: "ServerTreeView"
|
||||||
|
lan: "ServerTreeView"
|
||||||
|
modtreeview: "ModTreeView"
|
||||||
|
logtreeview: "LogTreeView"
|
||||||
|
|
||||||
|
# TODO: most server contexts can be dropped from this struct
|
||||||
|
|
||||||
class Controller:
|
class Controller:
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.crumbs_cache = ""
|
self.crumbs_cache = ""
|
||||||
self.mediator: AppNavigation
|
self.mediator = AppNavigation()
|
||||||
self.prefs: UserPrefs
|
self.prefs: UserPrefs
|
||||||
self.cooldown = 0
|
self.cooldown = 0
|
||||||
|
|
||||||
self.model_manager = ModelManager()
|
self.model_manager = ModelManager()
|
||||||
|
|
||||||
|
def register_widget(self, attr: str, widget: Gtk.Widget) -> None:
|
||||||
|
try:
|
||||||
|
setattr(self.mediator, attr, widget)
|
||||||
|
except AttributeError:
|
||||||
|
logger.critical(f"{attr} is not a valid AppNavigation attribute.")
|
||||||
|
|
||||||
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)
|
||||||
|
|
||||||
@@ -124,11 +155,12 @@ class Controller:
|
|||||||
def append_map(self, map_row: list) -> None:
|
def append_map(self, map_row: list) -> None:
|
||||||
self.model_manager.append_map(map_row)
|
self.model_manager.append_map(map_row)
|
||||||
|
|
||||||
def set_mediator(self, mediator: "AppNavigation") -> None:
|
# TODO: drop
|
||||||
self.mediator = mediator
|
# def set_mediator(self, mediator: "AppNavigation") -> None:
|
||||||
|
# self.mediator = mediator
|
||||||
|
|
||||||
def get_mediator(self) -> "AppNavigation":
|
# def get_mediator(self) -> "AppNavigation":
|
||||||
return self.mediator
|
# return self.mediator
|
||||||
|
|
||||||
def unblock_signals(self) -> None:
|
def unblock_signals(self) -> None:
|
||||||
self.block_signals(False)
|
self.block_signals(False)
|
||||||
@@ -170,8 +202,14 @@ class Controller:
|
|||||||
def toggle_debug_mode(self) -> None:
|
def toggle_debug_mode(self) -> None:
|
||||||
self.toggle_config(Preferences.DEBUG)
|
self.toggle_config(Preferences.DEBUG)
|
||||||
|
|
||||||
|
def get_active_treeview(self) -> "TreeView":
|
||||||
|
return self.mediator.notebook.servers.get_active_treeview()
|
||||||
|
|
||||||
|
def grab_active_treeview(self) -> None:
|
||||||
|
self.get_active_treeview().grab_focus()
|
||||||
|
|
||||||
def save_res_and_quit(self, *args: Any) -> None:
|
def save_res_and_quit(self, *args: Any) -> None:
|
||||||
treeview = self.mediator.notebook.servers.get_active_treeview()
|
treeview = self.get_active_treeview()
|
||||||
columns = treeview.get_columns()
|
columns = treeview.get_columns()
|
||||||
|
|
||||||
columns_file = self.prefs.paths.columns
|
columns_file = self.prefs.paths.columns
|
||||||
@@ -295,8 +333,12 @@ class Controller:
|
|||||||
def set_statusbar_by_row(self, row: "RowType") -> None:
|
def set_statusbar_by_row(self, row: "RowType") -> None:
|
||||||
self.mediator.grid.statusbar.refresh(row)
|
self.mediator.grid.statusbar.refresh(row)
|
||||||
|
|
||||||
|
def toggle_server_panels(self, state: bool) -> None:
|
||||||
|
self.mediator.grid.toggle_filter_panel(state)
|
||||||
|
self.mediator.grid.toggle_connect_panel(state)
|
||||||
|
|
||||||
def toggle_mod_panel(self, state: bool) -> None:
|
def toggle_mod_panel(self, state: bool) -> None:
|
||||||
self.mediator.grid.sel_panel.set_visible(state)
|
self.mediator.grid.right_panel.sel_panel.set_visible(state)
|
||||||
|
|
||||||
def show_developers_page(self) -> None:
|
def show_developers_page(self) -> None:
|
||||||
self.open_page(NotebookPage.DEVELOPERS)
|
self.open_page(NotebookPage.DEVELOPERS)
|
||||||
@@ -314,7 +356,6 @@ class Controller:
|
|||||||
return
|
return
|
||||||
case ButtonType.OPTIONS:
|
case ButtonType.OPTIONS:
|
||||||
self.mediator.grid.notebook.settings.populate_settings()
|
self.mediator.grid.notebook.settings.populate_settings()
|
||||||
self.set_statusbar("")
|
|
||||||
case ButtonType.MODS:
|
case ButtonType.MODS:
|
||||||
self.load_mods()
|
self.load_mods()
|
||||||
case ButtonType.HELP:
|
case ButtonType.HELP:
|
||||||
@@ -606,3 +647,12 @@ class Controller:
|
|||||||
treeview.set_loaded(True)
|
treeview.set_loaded(True)
|
||||||
self.update_server_status()
|
self.update_server_status()
|
||||||
treeview.grab_focus()
|
treeview.grab_focus()
|
||||||
|
|
||||||
|
def focus_button_box(self) -> None:
|
||||||
|
self.mediator.right_panel.focus_button_box()
|
||||||
|
|
||||||
|
def present_servers(self) -> None:
|
||||||
|
self.grab_active_treeview()
|
||||||
|
self.update_server_status()
|
||||||
|
crumbs = self.mediator.servers.get_cached_label()
|
||||||
|
self.set_crumbs(crumbs)
|
||||||
@@ -45,7 +45,9 @@ def format_mods(size: int, mods: int) -> str:
|
|||||||
return no_mods
|
return no_mods
|
||||||
l_size = number(size)
|
l_size = number(size)
|
||||||
plural = pluralize("mods", mods)
|
plural = pluralize("mods", mods)
|
||||||
return f"Found {mods:n} {plural} taking up {l_size} MiB"
|
# TODO: strings
|
||||||
|
suffix = "Ctrl-click to select multiple."
|
||||||
|
return f"Found {mods:n} {plural} taking up {l_size} MiB. {suffix}"
|
||||||
|
|
||||||
|
|
||||||
def format_player_count(model: Gtk.TreeModel | None) -> str:
|
def format_player_count(model: Gtk.TreeModel | None) -> str:
|
||||||
|
|||||||
+53
-123
@@ -33,6 +33,7 @@ from dzgui.views.components.connect_panel import ConnectPanel
|
|||||||
from dzgui.views.pages.devs import Developers
|
from dzgui.views.pages.devs import Developers
|
||||||
from dzgui.views.pages.help import Help
|
from dzgui.views.pages.help import Help
|
||||||
from dzgui.views.pages.keys import Keybindings
|
from dzgui.views.pages.keys import Keybindings
|
||||||
|
from dzgui.views.pages.mods import Mods
|
||||||
from dzgui.views.pages.options import Options
|
from dzgui.views.pages.options import Options
|
||||||
from dzgui.views.pages.servers import ServerNotebook
|
from dzgui.views.pages.servers import ServerNotebook
|
||||||
from dzgui.views.pages.thanks import Thanks
|
from dzgui.views.pages.thanks import Thanks
|
||||||
@@ -203,15 +204,14 @@ class OuterWindow(Gtk.Window):
|
|||||||
super().__init__(title=APP_NAME, border_width=10, icon_name=APP_NAME_LOWER)
|
super().__init__(title=APP_NAME, border_width=10, icon_name=APP_NAME_LOWER)
|
||||||
|
|
||||||
self.hb = AppHeaderBar()
|
self.hb = AppHeaderBar()
|
||||||
MainController.set_mediator(AppNav)
|
MainController.register_widget("window", self)
|
||||||
AppNav.window = self
|
|
||||||
|
|
||||||
# NOTE: steam deck taskbar may occlude elements
|
# NOTE: steam deck taskbar may occlude elements
|
||||||
if MainController.get_prefs().is_steam_deck is False:
|
if MainController.get_prefs().is_steam_deck is False:
|
||||||
self.set_titlebar(self.hb)
|
self.set_titlebar(self.hb)
|
||||||
|
|
||||||
self.connect("delete-event", self._on_delete_event)
|
self.connect("delete-event", self._on_delete_event)
|
||||||
self.connect("key-press-event", self._on_keypress)
|
#self.connect("key-press-event", self._on_keypress)
|
||||||
|
|
||||||
self.grid = Grid()
|
self.grid = Grid()
|
||||||
self.add(self.grid)
|
self.add(self.grid)
|
||||||
@@ -219,24 +219,8 @@ class OuterWindow(Gtk.Window):
|
|||||||
MainController.set_resolution(self)
|
MainController.set_resolution(self)
|
||||||
self.show_all()
|
self.show_all()
|
||||||
|
|
||||||
self.grid.sel_panel.set_visible(False)
|
|
||||||
|
|
||||||
# TODO:
|
|
||||||
#self.grid.right_panel.enable_ping_button(False)
|
|
||||||
|
|
||||||
css.load_css()
|
css.load_css()
|
||||||
# TODO: call controller directly
|
MainController.open_page(NotebookPage.SERVERS)
|
||||||
AppNav.grid.notebook.set_page_by_enum(NotebookPage.SERVERS)
|
|
||||||
|
|
||||||
# TODO: deprecated
|
|
||||||
def _on_keypress(self, widget: Gtk.Widget, event: Gdk.EventKey) -> None:
|
|
||||||
if event.state is Gdk.ModifierType.CONTROL_MASK \
|
|
||||||
and event.keyval is Gdk.KEY_d:
|
|
||||||
if AppNav.right_panel.filters_vbox.keyword_entry.is_focus():
|
|
||||||
return
|
|
||||||
if AppNav.right_panel.filters_vbox.maps_entry.is_focus():
|
|
||||||
return
|
|
||||||
AppNav.right_panel.toggle_debug()
|
|
||||||
|
|
||||||
def _on_delete_event(
|
def _on_delete_event(
|
||||||
self, window: "OuterWindow", event: Gdk.EventKey
|
self, window: "OuterWindow", event: Gdk.EventKey
|
||||||
@@ -280,47 +264,35 @@ class ScrollableNote(ScrollableMixin, Gtk.Box):
|
|||||||
self.add(self.gutter)
|
self.add(self.gutter)
|
||||||
|
|
||||||
def _on_back_clicked(self, button: Gtk.Button) -> None:
|
def _on_back_clicked(self, button: Gtk.Button) -> None:
|
||||||
AppNav.notebook.return_prior()
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Notebook(ScrollableMixin, Gtk.Notebook):
|
class Notebook(ScrollableMixin, Gtk.Notebook):
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
super().__init__(show_tabs=False)
|
super().__init__(show_tabs=False)
|
||||||
|
|
||||||
AppNav.notebook = self
|
|
||||||
self.prior_page: NotebookPage
|
self.prior_page: NotebookPage
|
||||||
self.prior_status: str
|
self.prior_status: str
|
||||||
|
|
||||||
self.help = Help(MainController)
|
MainController.register_widget("notebook", self)
|
||||||
view = self.help.get_treeview()
|
|
||||||
AppNav.menu = view
|
|
||||||
|
|
||||||
|
self.help = Help(MainController)
|
||||||
self.change = Changelog(MainController)
|
self.change = Changelog(MainController)
|
||||||
self.clog = ScrollableNote(self.change, back_button=False)
|
self.clog = ScrollableNote(self.change, back_button=False)
|
||||||
self.clog.scrollable.set_propagate_natural_width(False)
|
self.clog.scrollable.set_propagate_natural_width(False)
|
||||||
|
|
||||||
# TODO: scrollable internally
|
# TODO: scrollable internally
|
||||||
|
# TODO: make all treeviews internally scrollable in base class
|
||||||
self.keys = ScrollableNote(Keybindings())
|
self.keys = ScrollableNote(Keybindings())
|
||||||
self.settings = Options(MainController)
|
self.settings = Options(MainController)
|
||||||
|
|
||||||
# TODO: make all treeviews internally scrollable in base class
|
|
||||||
# NOTE: server and quad tables should have hexpand property set to True
|
# NOTE: server and quad tables should have hexpand property set to True
|
||||||
# add all treeviews as page and register them to AppNav and self.indexes
|
|
||||||
# when switching to a treeview, update relevant view and just pop that page
|
|
||||||
# instead of loading/unloading the model each time
|
|
||||||
self.servers = ServerNotebook(MainController)
|
self.servers = ServerNotebook(MainController)
|
||||||
AppNav.servers = self.servers
|
self.mods = Mods(MainController)
|
||||||
|
|
||||||
self.scroll_mod = Gtk.ScrolledWindow()
|
|
||||||
# TODO: register this table
|
|
||||||
self.quad_table = ModTreeView(MainController)
|
|
||||||
AppNav.modtreeview = self.quad_table
|
|
||||||
self.scroll_mod.add(self.quad_table)
|
|
||||||
|
|
||||||
self.scroll_log = Gtk.ScrolledWindow()
|
self.scroll_log = Gtk.ScrolledWindow()
|
||||||
self.scroll_log.set_hexpand(True)
|
self.scroll_log.set_hexpand(True)
|
||||||
self.log_table = LogTreeView(MainController)
|
self.log_table = LogTreeView(MainController)
|
||||||
AppNav.logtreeview = self.log_table
|
|
||||||
self.scroll_log.add(self.log_table)
|
self.scroll_log.add(self.log_table)
|
||||||
|
|
||||||
self.thanks = ScrollableNote(Thanks(), back_button=False)
|
self.thanks = ScrollableNote(Thanks(), back_button=False)
|
||||||
@@ -334,7 +306,7 @@ class Notebook(ScrollableMixin, Gtk.Notebook):
|
|||||||
self.keys: NotebookPage.KEYS,
|
self.keys: NotebookPage.KEYS,
|
||||||
self.settings: NotebookPage.OPTIONS,
|
self.settings: NotebookPage.OPTIONS,
|
||||||
self.servers: NotebookPage.SERVERS,
|
self.servers: NotebookPage.SERVERS,
|
||||||
self.scroll_mod: NotebookPage.MODS,
|
self.mods: NotebookPage.MODS,
|
||||||
self.scroll_log: NotebookPage.LOG,
|
self.scroll_log: NotebookPage.LOG,
|
||||||
self.thanks: NotebookPage.THANKS,
|
self.thanks: NotebookPage.THANKS,
|
||||||
self.developers: NotebookPage.DEVELOPERS,
|
self.developers: NotebookPage.DEVELOPERS,
|
||||||
@@ -350,45 +322,38 @@ class Notebook(ScrollableMixin, Gtk.Notebook):
|
|||||||
page.show_all()
|
page.show_all()
|
||||||
index = self.append_page(page)
|
index = self.append_page(page)
|
||||||
enum = self.pages[page]
|
enum = self.pages[page]
|
||||||
crumbs = enum.dict["crumbs"]
|
|
||||||
self.indexes[enum] = index
|
self.indexes[enum] = index
|
||||||
|
|
||||||
self.connect_after("switch-page", self._on_page_changed)
|
self.connect_after("switch-page", self._on_page_changed)
|
||||||
self.connect("key-press-event", self._on_keypress)
|
self.connect("key-press-event", self._on_keypress)
|
||||||
|
|
||||||
def _on_mods_focus_change(self, widget: ModTreeView, event: Gdk.EventFocus) -> None:
|
|
||||||
MainController.toggle_mod_panel(event.in_)
|
|
||||||
|
|
||||||
def _on_keypress(self, widget: Gtk.Widget, event: Gdk.EventKey) -> None:
|
def _on_keypress(self, widget: Gtk.Widget, event: Gdk.EventKey) -> None:
|
||||||
page = self.get_page()
|
page = self.get_page()
|
||||||
|
|
||||||
match event.keyval:
|
match event.keyval:
|
||||||
case Gdk.KEY_Return:
|
|
||||||
page = self.get_page()
|
|
||||||
if page:
|
|
||||||
page.back_button.clicked()
|
|
||||||
case Gdk.KEY_Right | Gdk.KEY_l:
|
case Gdk.KEY_Right | Gdk.KEY_l:
|
||||||
if event.state is Gdk.ModifierType.CONTROL_MASK:
|
if event.state is Gdk.ModifierType.CONTROL_MASK:
|
||||||
return
|
return
|
||||||
AppNav.right_panel.focus_button_box()
|
MainController.focus_button_box()
|
||||||
case Gdk.KEY_question:
|
case Gdk.KEY_question:
|
||||||
self.toggle_keybindings()
|
self.toggle_keybindings()
|
||||||
|
|
||||||
# NOTE: abort on non scrollable pages
|
# NOTE: abort on non scrollable pages
|
||||||
# TODO: this should be an internal property of those pages
|
# TODO: deprecated
|
||||||
allowed = (NotebookPage.KEYS, NotebookPage.CHANGELOG, NotebookPage.THANKS)
|
#allowed = (NotebookPage.KEYS, NotebookPage.CHANGELOG, NotebookPage.THANKS)
|
||||||
if self.pages[page] not in allowed:
|
#if self.pages[page] not in allowed:
|
||||||
return
|
# return
|
||||||
|
|
||||||
match event.keyval:
|
# FIXME: may already be delegated to some pages (e.g. keys)
|
||||||
case Gdk.KEY_k | Gdk.KEY_Up:
|
#match event.keyval:
|
||||||
page._set_adjustment(VAdjustment.UP)
|
# case Gdk.KEY_k | Gdk.KEY_Up:
|
||||||
case Gdk.KEY_Down | Gdk.KEY_j:
|
# page._set_adjustment(VAdjustment.UP)
|
||||||
page._set_adjustment(VAdjustment.DOWN)
|
# case Gdk.KEY_Down | Gdk.KEY_j:
|
||||||
case Gdk.KEY_g:
|
# page._set_adjustment(VAdjustment.DOWN)
|
||||||
page._set_adjustment(VAdjustment.TOP)
|
# case Gdk.KEY_g:
|
||||||
case Gdk.KEY_G:
|
# page._set_adjustment(VAdjustment.TOP)
|
||||||
page._set_adjustment(VAdjustment.BOTTOM)
|
# case Gdk.KEY_G:
|
||||||
|
# page._set_adjustment(VAdjustment.BOTTOM)
|
||||||
|
|
||||||
def return_prior(self) -> None:
|
def return_prior(self) -> None:
|
||||||
"""
|
"""
|
||||||
@@ -428,8 +393,7 @@ class Notebook(ScrollableMixin, Gtk.Notebook):
|
|||||||
return
|
return
|
||||||
|
|
||||||
if widget is self.servers:
|
if widget is self.servers:
|
||||||
view = self.servers.get_active_treeview()
|
MainController.grab_active_treeview()
|
||||||
view.grab_focus()
|
|
||||||
return
|
return
|
||||||
|
|
||||||
w = widget.get_children()[0]
|
w = widget.get_children()[0]
|
||||||
@@ -447,37 +411,33 @@ class Notebook(ScrollableMixin, Gtk.Notebook):
|
|||||||
return widget
|
return widget
|
||||||
|
|
||||||
def set_page_by_enum(self, enum: NotebookPage) -> None:
|
def set_page_by_enum(self, enum: NotebookPage) -> None:
|
||||||
self.prior_page = self.get_page_by_enum()
|
prior = self.get_page_by_enum()
|
||||||
|
if prior is not None:
|
||||||
|
self.prior_page = prior
|
||||||
self.set_current_page(self.indexes[enum])
|
self.set_current_page(self.indexes[enum])
|
||||||
self.focus_current()
|
self.focus_current()
|
||||||
|
|
||||||
# TODO: should be an internal property of those pages
|
|
||||||
match enum:
|
|
||||||
case NotebookPage.KEYS:
|
|
||||||
MainController.set_statusbar("")
|
|
||||||
AppNav.grid.hide_connect_panel()
|
|
||||||
case NotebookPage.SERVERS:
|
|
||||||
# TODO: consolidate in mc.py
|
|
||||||
AppNav.grid.show_connect_panel()
|
|
||||||
AppNav.grid.show_filter_panel()
|
|
||||||
self.servers.get_active_treeview().grab_focus()
|
|
||||||
MainController.update_server_status()
|
|
||||||
crumbs = self.servers.get_cached_label()
|
|
||||||
MainController.set_crumbs(crumbs)
|
|
||||||
case _:
|
|
||||||
AppNav.grid.hide_connect_panel()
|
|
||||||
AppNav.grid.hide_filter_panel()
|
|
||||||
|
|
||||||
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()
|
enum = self.get_page_by_enum()
|
||||||
is_mods = True if enum is NotebookPage.MODS else False
|
if enum is not None:
|
||||||
MainController.toggle_mod_panel(is_mods)
|
crumbs = enum.dict["crumbs"]
|
||||||
|
MainController.set_crumbs(crumbs)
|
||||||
|
|
||||||
# TODO:
|
is_mods = True if enum is NotebookPage.MODS else False
|
||||||
crumbs = enum.dict["crumbs"]
|
is_servers = True if enum is NotebookPage.SERVERS else False
|
||||||
MainController.set_crumbs(crumbs)
|
|
||||||
|
MainController.toggle_mod_panel(is_mods)
|
||||||
|
MainController.toggle_server_panels(is_servers)
|
||||||
|
|
||||||
|
match enum:
|
||||||
|
case NotebookPage.KEYS | NotebookPage.OPTIONS:
|
||||||
|
MainController.set_statusbar("")
|
||||||
|
case NotebookPage.SERVERS:
|
||||||
|
MainController.present_servers()
|
||||||
|
case _:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class Grid(Gtk.Grid):
|
class Grid(Gtk.Grid):
|
||||||
@@ -489,22 +449,17 @@ class Grid(Gtk.Grid):
|
|||||||
SINGLE_ROW = 1
|
SINGLE_ROW = 1
|
||||||
SINGLE_COL = 1
|
SINGLE_COL = 1
|
||||||
|
|
||||||
|
MainController.register_widget("grid", self)
|
||||||
|
|
||||||
self.statusbar = Statusbar(MainController)
|
self.statusbar = Statusbar(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)
|
||||||
|
|
||||||
AppNav.statusbar = self.statusbar
|
|
||||||
AppNav.grid = self
|
|
||||||
|
|
||||||
# FIXME: do not pass AppNav to right panel
|
|
||||||
self.right_panel = RightPanel(AppNav, MainController)
|
|
||||||
# TODO: move into right panel
|
|
||||||
self.sel_panel = ModSelectionPanel(MainController)
|
|
||||||
self.right_panel.pack_start(self.sel_panel, NO_EXPAND, NO_FILL, NO_PADDING)
|
|
||||||
|
|
||||||
self.notebook = Notebook()
|
self.notebook = Notebook()
|
||||||
self.conpan = ConnectPanel()
|
self.conpan = ConnectPanel()
|
||||||
|
|
||||||
|
|
||||||
self.attach(self.notebook, 0, 0, MAX_COLS, 1)
|
self.attach(self.notebook, 0, 0, MAX_COLS, 1)
|
||||||
|
|
||||||
els = (
|
els = (
|
||||||
@@ -518,17 +473,11 @@ class Grid(Gtk.Grid):
|
|||||||
|
|
||||||
self.show_all()
|
self.show_all()
|
||||||
|
|
||||||
def hide_filter_panel(self) -> None:
|
def toggle_filter_panel(self, state: bool) -> None:
|
||||||
self.right_panel.filters_vbox.set_visible(False)
|
self.right_panel.filters_vbox.set_visible(state)
|
||||||
|
|
||||||
def show_filter_panel(self) -> None:
|
def toggle_connect_panel(self, state: bool) -> None:
|
||||||
self.right_panel.filters_vbox.set_visible(True)
|
self.conpan.set_visible(state)
|
||||||
|
|
||||||
def hide_connect_panel(self) -> None:
|
|
||||||
self.conpan.set_visible(False)
|
|
||||||
|
|
||||||
def show_connect_panel(self) -> None:
|
|
||||||
self.conpan.set_visible(True)
|
|
||||||
|
|
||||||
def get_breadcrumbs(self) -> str:
|
def get_breadcrumbs(self) -> str:
|
||||||
return self.breadcrumbs.get_text()
|
return self.breadcrumbs.get_text()
|
||||||
@@ -572,23 +521,4 @@ class App(Gtk.Application):
|
|||||||
) -> None:
|
) -> None:
|
||||||
self.win.halt_proc_and_quit()
|
self.win.halt_proc_and_quit()
|
||||||
|
|
||||||
|
|
||||||
class AppNavigation:
|
|
||||||
grid: Grid
|
|
||||||
window: OuterWindow
|
|
||||||
notebook: Notebook
|
|
||||||
right_panel: RightPanel
|
|
||||||
statusbar: Statusbar
|
|
||||||
menu: MenuTreeView
|
|
||||||
servers: Gtk.ScrolledWindow
|
|
||||||
browser: ServerTreeView
|
|
||||||
saved: ServerTreeView
|
|
||||||
recent: ServerTreeView
|
|
||||||
lan: ServerTreeView
|
|
||||||
modtreeview: ModTreeView
|
|
||||||
logtreeview: LogTreeView
|
|
||||||
# TODO: add tree_log and tree_server views here
|
|
||||||
# or obtain via get_treeview()
|
|
||||||
|
|
||||||
AppNav = AppNavigation()
|
|
||||||
MainController = Controller()
|
MainController = Controller()
|
||||||
@@ -13,7 +13,7 @@ from dzgui.const.constants import NO_EXPAND, NO_FILL, NO_PADDING
|
|||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
class FilterPanel(Gtk.Box):
|
class FilterPanel(Gtk.Box):
|
||||||
def __init__(self, appnav, controller):
|
def __init__(self, controller):
|
||||||
super().__init__(spacing=6, vexpand=False)
|
super().__init__(spacing=6, vexpand=False)
|
||||||
|
|
||||||
# TODO: set strings in constants
|
# TODO: set strings in constants
|
||||||
@@ -32,7 +32,6 @@ class FilterPanel(Gtk.Box):
|
|||||||
strings.filter_modded: True,
|
strings.filter_modded: True,
|
||||||
}
|
}
|
||||||
|
|
||||||
self.AppNav = appnav
|
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
|
|
||||||
map_store = self.controller.get_map_store()
|
map_store = self.controller.get_map_store()
|
||||||
@@ -140,7 +139,8 @@ class FilterPanel(Gtk.Box):
|
|||||||
self.keyword_filter = ""
|
self.keyword_filter = ""
|
||||||
self.reinit_filters()
|
self.reinit_filters()
|
||||||
self.set_visible(False)
|
self.set_visible(False)
|
||||||
sel_panel = self.AppNav.grid.sel_panel
|
# TODO:
|
||||||
|
sel_panel = self.controller.mediator.grid.sel_panel
|
||||||
if sel_panel.is_visible():
|
if sel_panel.is_visible():
|
||||||
sel_panel.set_visible(False)
|
sel_panel.set_visible(False)
|
||||||
|
|
||||||
@@ -194,7 +194,8 @@ class FilterPanel(Gtk.Box):
|
|||||||
completion.set_model(map_store)
|
completion.set_model(map_store)
|
||||||
|
|
||||||
def restore_focus_to_treeview(self) -> Literal[False]:
|
def restore_focus_to_treeview(self) -> Literal[False]:
|
||||||
self.AppNav.treeview.grab_focus()
|
view = self.controller.get_active_treeview()
|
||||||
|
view.grab_focus()
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _on_keyword_keypress(
|
def _on_keyword_keypress(
|
||||||
@@ -233,7 +234,8 @@ class FilterPanel(Gtk.Box):
|
|||||||
return self.keyword_filter
|
return self.keyword_filter
|
||||||
|
|
||||||
def _on_keyword_enter(self, entry: Gtk.Entry) -> None:
|
def _on_keyword_enter(self, entry: Gtk.Entry) -> None:
|
||||||
self.AppNav.window.set_keep_below(False)
|
# TODO:
|
||||||
|
self.controller.mediator.window.set_keep_below(False)
|
||||||
keyword = entry.get_text().lower()
|
keyword = entry.get_text().lower()
|
||||||
if keyword == self.keyword_filter:
|
if keyword == self.keyword_filter:
|
||||||
return
|
return
|
||||||
@@ -241,7 +243,8 @@ class FilterPanel(Gtk.Box):
|
|||||||
return
|
return
|
||||||
logger.info(f"User filtered by keyword '{keyword}'")
|
logger.info(f"User filtered by keyword '{keyword}'")
|
||||||
self.keyword_filter = keyword
|
self.keyword_filter = keyword
|
||||||
self.AppNav.treeview.filter(FilterMode.KEYWORD, keyword)
|
treeview = self.controller.get_active_treeview()
|
||||||
|
treeview.filter(FilterMode.KEYWORD, keyword)
|
||||||
|
|
||||||
def _on_button_release(self, window, button) -> Literal[True]:
|
def _on_button_release(self, window, button) -> Literal[True]:
|
||||||
return True
|
return True
|
||||||
@@ -258,7 +261,9 @@ class FilterPanel(Gtk.Box):
|
|||||||
check.set_active(not state)
|
check.set_active(not state)
|
||||||
|
|
||||||
def _on_check_toggled(self, button: Gtk.CheckButton) -> None:
|
def _on_check_toggled(self, button: Gtk.CheckButton) -> None:
|
||||||
if not self.AppNav.treeview.is_server_context(self.AppNav.treeview.view):
|
treeview = self.controller.get_active_treeview()
|
||||||
|
# TODO: drop
|
||||||
|
if not treeview.is_server_context(self.AppNav.treeview.view):
|
||||||
return
|
return
|
||||||
label = button.get_label()
|
label = button.get_label()
|
||||||
state = button.get_active()
|
state = button.get_active()
|
||||||
@@ -269,9 +274,10 @@ class FilterPanel(Gtk.Box):
|
|||||||
mode = FilterMode.TOGGLE_OFF
|
mode = FilterMode.TOGGLE_OFF
|
||||||
|
|
||||||
self.enabled_filters[label] = state
|
self.enabled_filters[label] = state
|
||||||
self.AppNav.treeview.filter(mode, label)
|
treeview.filter(mode, label)
|
||||||
|
|
||||||
def _on_map_changed(self, combo: Gtk.ComboBox) -> None:
|
def _on_map_changed(self, combo: Gtk.ComboBox) -> None:
|
||||||
|
treeview = self.controller.get_active_treeview()
|
||||||
old_sel = self.selected_map
|
old_sel = self.selected_map
|
||||||
model = combo.get_model()
|
model = combo.get_model()
|
||||||
tree_iter = combo.get_active_iter()
|
tree_iter = combo.get_active_iter()
|
||||||
@@ -286,4 +292,4 @@ class FilterPanel(Gtk.Box):
|
|||||||
self.prior_map = self.selected_map
|
self.prior_map = self.selected_map
|
||||||
self.selected_map = selection
|
self.selected_map = selection
|
||||||
self.maps_entry.set_text(selection)
|
self.maps_entry.set_text(selection)
|
||||||
self.AppNav.treeview.filter(FilterMode.MAP)
|
treeview.filter(FilterMode.MAP)
|
||||||
@@ -5,6 +5,7 @@ from gi.repository import Gtk, Gdk
|
|||||||
from dzgui.const.enum import Preferences
|
from dzgui.const.enum import Preferences
|
||||||
from dzgui.views.components.buttonbox import ButtonBox
|
from dzgui.views.components.buttonbox import ButtonBox
|
||||||
from dzgui.views.components.filter_panel import FilterPanel
|
from dzgui.views.components.filter_panel import FilterPanel
|
||||||
|
from dzgui.views.components.mod_panel import ModSelectionPanel
|
||||||
from dzgui.views.components.icon import Icon
|
from dzgui.views.components.icon import Icon
|
||||||
from dzgui.views.components.web_button import RefreshButton
|
from dzgui.views.components.web_button import RefreshButton
|
||||||
# TODO: rename web_button
|
# TODO: rename web_button
|
||||||
@@ -13,15 +14,20 @@ from dzgui.util import strings
|
|||||||
|
|
||||||
# TODO: refactor depends on ServerTreeView
|
# TODO: refactor depends on ServerTreeView
|
||||||
class RightPanel(Gtk.Box):
|
class RightPanel(Gtk.Box):
|
||||||
def __init__(self, appnav, controller):
|
def __init__(self, controller):
|
||||||
super().__init__(spacing=6, orientation=Gtk.Orientation.VERTICAL)
|
super().__init__(spacing=6, orientation=Gtk.Orientation.VERTICAL)
|
||||||
|
|
||||||
self.AppNav = appnav
|
|
||||||
self.AppNav.right_panel = self
|
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
|
|
||||||
self.button_vbox = ButtonBox(controller)
|
self.button_vbox = ButtonBox(controller)
|
||||||
self.filters_vbox = FilterPanel(appnav, controller)
|
|
||||||
|
|
||||||
|
self.filters_vbox = FilterPanel(controller)
|
||||||
|
self.sel_panel = ModSelectionPanel(controller)
|
||||||
|
|
||||||
|
self.controller.register_widget("right_panel", self)
|
||||||
|
|
||||||
|
self.sel_panel.set_visible(False)
|
||||||
|
self.filters_vbox.set_visible(False)
|
||||||
|
|
||||||
# TODO: more custom button classes
|
# TODO: more custom button classes
|
||||||
self.ping = Gtk.Button(
|
self.ping = Gtk.Button(
|
||||||
@@ -49,26 +55,30 @@ class RightPanel(Gtk.Box):
|
|||||||
self.refresh_button.set_margin_end(80)
|
self.refresh_button.set_margin_end(80)
|
||||||
self.refresh_button.connect("clicked", self._on_refresh_clicked)
|
self.refresh_button.connect("clicked", self._on_refresh_clicked)
|
||||||
|
|
||||||
if controller.query_config(Preferences.DEBUG) == True:
|
#if controller.query_config(Preferences.DEBUG) == True:
|
||||||
self.debug_toggle.set_active(True)
|
# self.debug_toggle.set_active(True)
|
||||||
self.debug_toggle.connect("toggled", self._on_debug_toggled)
|
#self.debug_toggle.connect("toggled", self._on_debug_toggled)
|
||||||
|
|
||||||
# TODO: make button class
|
# TODO: make button class
|
||||||
i = Icon(INPUT_KEYBOARD)
|
i = Icon(INPUT_KEYBOARD)
|
||||||
i.set_margin_start(5)
|
i.set_margin_start(5)
|
||||||
self.question = Gtk.Button(
|
self.keys = Gtk.Button(
|
||||||
label=strings.keys_button,
|
label=strings.keys_button,
|
||||||
margin_start=80,
|
margin_start=80,
|
||||||
margin_end=80,
|
margin_end=80,
|
||||||
tooltip_text=strings.keys_tooltip,
|
tooltip_text=strings.keys_tooltip,
|
||||||
image = i,
|
image = i,
|
||||||
)
|
)
|
||||||
self.question.set_image_position(Gtk.PositionType.RIGHT)
|
self.keys.set_image_position(Gtk.PositionType.RIGHT)
|
||||||
self.question.connect("clicked", self._on_question_clicked)
|
self.keys.connect("clicked", self._on_question_clicked)
|
||||||
|
|
||||||
for el in self.button_vbox, self.question, self.filters_vbox, self.refresh_button:
|
for el in self.button_vbox, self.filters_vbox, self.refresh_button:
|
||||||
self.pack_start(el, NO_EXPAND, FILL, NO_PADDING)
|
self.pack_start(el, NO_EXPAND, FILL, NO_PADDING)
|
||||||
|
|
||||||
|
self.pack_start(self.sel_panel, NO_EXPAND, NO_FILL, NO_PADDING)
|
||||||
|
self.pack_start(self.keys, NO_EXPAND, FILL, NO_PADDING)
|
||||||
|
|
||||||
|
|
||||||
def enable_ping_button(self, state: bool) -> None:
|
def enable_ping_button(self, state: bool) -> None:
|
||||||
self.ping.set_visible(state)
|
self.ping.set_visible(state)
|
||||||
|
|
||||||
@@ -80,17 +90,6 @@ class RightPanel(Gtk.Box):
|
|||||||
self.selected = "All maps"
|
self.selected = "All maps"
|
||||||
self.filters_vbox.set_unique_maps(rows)
|
self.filters_vbox.set_unique_maps(rows)
|
||||||
|
|
||||||
def toggle_debug(self) -> None:
|
|
||||||
if type(self.AppNav.window.get_focus()) is Gtk.Entry:
|
|
||||||
return
|
|
||||||
state = self.debug_toggle.get_active()
|
|
||||||
self.debug_toggle.set_active(not state)
|
|
||||||
|
|
||||||
def _on_debug_toggled(self, button: Gtk.Button) -> None:
|
|
||||||
state = button.get_active()
|
|
||||||
grid = self.AppNav.grid
|
|
||||||
self.controller.toggle_debug_mode()
|
|
||||||
|
|
||||||
def _on_refresh_clicked(self, button: RefreshButton) -> None:
|
def _on_refresh_clicked(self, button: RefreshButton) -> None:
|
||||||
self.controller.refresh_tree()
|
self.controller.refresh_tree()
|
||||||
|
|
||||||
@@ -112,11 +111,10 @@ class RightPanel(Gtk.Box):
|
|||||||
path = Gtk.TreePath.new_from_indices([res.iteration])
|
path = Gtk.TreePath.new_from_indices([res.iteration])
|
||||||
temp_model[path][9] = res.ping
|
temp_model[path][9] = res.ping
|
||||||
ModelManager.ping_cache[res.addr] = res.ping
|
ModelManager.ping_cache[res.addr] = res.ping
|
||||||
|
# TODO: drop/rewrite
|
||||||
self.AppNav.treeview.set_model(temp_model)
|
self.AppNav.treeview.set_model(temp_model)
|
||||||
self.AppNav.treeview.wait_dialog.destroy()
|
self.AppNav.treeview.wait_dialog.destroy()
|
||||||
self.AppNav.treeview.enable_ping_column(True)
|
|
||||||
self.AppNav.treeview.grab_focus()
|
self.AppNav.treeview.grab_focus()
|
||||||
self.AppNav.right_panel.ping.set_sensitive(False)
|
|
||||||
|
|
||||||
# TODO:
|
# TODO:
|
||||||
unblock_signals()
|
unblock_signals()
|
||||||
@@ -129,7 +127,7 @@ class RightPanel(Gtk.Box):
|
|||||||
thread.start()
|
thread.start()
|
||||||
|
|
||||||
def _on_question_clicked(self, button: Gtk.Button) -> None:
|
def _on_question_clicked(self, button: Gtk.Button) -> None:
|
||||||
self.AppNav.grid.notebook.toggle_keybindings()
|
self.controller.open_keybindings()
|
||||||
|
|
||||||
def focus_button_box(self) -> None:
|
def focus_button_box(self) -> None:
|
||||||
self.button_vbox.buttons[0].grab_focus()
|
self.button_vbox.buttons[0].grab_focus()
|
||||||
@@ -21,6 +21,7 @@ class LogTreeView(ContextMixin, TreeView):
|
|||||||
super().__init__(controller, menu=ContextMenuGroup.LOG)
|
super().__init__(controller, menu=ContextMenuGroup.LOG)
|
||||||
|
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
|
self.controller.register_widget("logtreeview", self)
|
||||||
|
|
||||||
# TODO: maybe put this in init
|
# TODO: maybe put this in init
|
||||||
self.set_fixed_height_mode(True)
|
self.set_fixed_height_mode(True)
|
||||||
|
|||||||
@@ -43,6 +43,8 @@ class ServerTreeView(TreeView):
|
|||||||
def __init__(self, controller: "Controller") -> None:
|
def __init__(self, controller: "Controller") -> None:
|
||||||
super().__init__(controller)
|
super().__init__(controller)
|
||||||
|
|
||||||
|
QUEUE_CHECK_DELAY = 200
|
||||||
|
|
||||||
self.loaded = False
|
self.loaded = False
|
||||||
self.query_func: Callable = None
|
self.query_func: Callable = None
|
||||||
|
|
||||||
@@ -50,8 +52,6 @@ class ServerTreeView(TreeView):
|
|||||||
self.menu.connect("key-press-event", self._on_key)
|
self.menu.connect("key-press-event", self._on_key)
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
|
|
||||||
self.resizable_cols: list[Gtk.TreeViewColumn] = []
|
|
||||||
|
|
||||||
self.set_fixed_height_mode(True)
|
self.set_fixed_height_mode(True)
|
||||||
self.set_headers_visible(True)
|
self.set_headers_visible(True)
|
||||||
|
|
||||||
@@ -89,8 +89,6 @@ class ServerTreeView(TreeView):
|
|||||||
if column_title == "Map":
|
if column_title == "Map":
|
||||||
column.set_fixed_width(300)
|
column.set_fixed_width(300)
|
||||||
|
|
||||||
|
|
||||||
self.resizable_cols.append(column)
|
|
||||||
column.connect("notify::fixed-width", self._on_col_width_changed)
|
column.connect("notify::fixed-width", self._on_col_width_changed)
|
||||||
self.append_column(column)
|
self.append_column(column)
|
||||||
|
|
||||||
@@ -100,7 +98,7 @@ class ServerTreeView(TreeView):
|
|||||||
self.connect("generic_row_activated", self._parent_row_activated)
|
self.connect("generic_row_activated", self._parent_row_activated)
|
||||||
self.connect("generic_treesel_changed", self._parent_selection_changed)
|
self.connect("generic_treesel_changed", self._parent_selection_changed)
|
||||||
|
|
||||||
GLib.timeout_add(200, self._check_result_queue)
|
GLib.timeout_add(QUEUE_CHECK_DELAY, self._check_result_queue)
|
||||||
|
|
||||||
def _on_key(self, menu: Gtk.Menu, event: Gdk.EventKey) -> bool | None:
|
def _on_key(self, menu: Gtk.Menu, event: Gdk.EventKey) -> bool | None:
|
||||||
if not is_navkey(event.keyval):
|
if not is_navkey(event.keyval):
|
||||||
@@ -173,6 +171,7 @@ class ServerTreeView(TreeView):
|
|||||||
def _on_server_keypress(
|
def _on_server_keypress(
|
||||||
self, treeview: Gtk.TreeView, event: Gdk.EventKey
|
self, treeview: Gtk.TreeView, event: Gdk.EventKey
|
||||||
) -> bool | None:
|
) -> bool | None:
|
||||||
|
# TODO: rewrite AppNav
|
||||||
# TODO: use mixins
|
# TODO: use mixins
|
||||||
# CONTROL_MASK + KEY_l
|
# CONTROL_MASK + KEY_l
|
||||||
if event.state is Gdk.ModifierType.CONTROL_MASK:
|
if event.state is Gdk.ModifierType.CONTROL_MASK:
|
||||||
@@ -182,8 +181,6 @@ class ServerTreeView(TreeView):
|
|||||||
case Gdk.KEY_r:
|
case Gdk.KEY_r:
|
||||||
self.refresh_player_count()
|
self.refresh_player_count()
|
||||||
case Gdk.KEY_f:
|
case Gdk.KEY_f:
|
||||||
if not AppNav.treeview.is_server_context(AppNav.treeview.view):
|
|
||||||
return True
|
|
||||||
AppNav.right_panel.filters_vbox.keyword_entry.grab_focus()
|
AppNav.right_panel.filters_vbox.keyword_entry.grab_focus()
|
||||||
case Gdk.KEY_m:
|
case Gdk.KEY_m:
|
||||||
AppNav.right_panel.filters_vbox.maps_entry.grab_focus()
|
AppNav.right_panel.filters_vbox.maps_entry.grab_focus()
|
||||||
@@ -216,7 +213,6 @@ class ServerTreeView(TreeView):
|
|||||||
self.menu.show_all()
|
self.menu.show_all()
|
||||||
|
|
||||||
def _on_menu_click(self, item) -> None:
|
def _on_menu_click(self, item) -> None:
|
||||||
print(item.enum)
|
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def _on_server_button_release(
|
def _on_server_button_release(
|
||||||
@@ -278,8 +274,9 @@ class ServerTreeView(TreeView):
|
|||||||
|
|
||||||
self.terminate_process()
|
self.terminate_process()
|
||||||
record = self.get_record()
|
record = self.get_record()
|
||||||
#TODO
|
|
||||||
return
|
if record is None:
|
||||||
|
return
|
||||||
|
|
||||||
#model = self.get_model()
|
#model = self.get_model()
|
||||||
#if record is None:
|
#if record is None:
|
||||||
@@ -287,7 +284,6 @@ class ServerTreeView(TreeView):
|
|||||||
# return
|
# return
|
||||||
|
|
||||||
ip = record.ip
|
ip = record.ip
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
#self.emit("on_distcalc_started")
|
#self.emit("on_distcalc_started")
|
||||||
#self.current_proc = CalcDist(self, record.ip, self.queue, cache)
|
#self.current_proc = CalcDist(self, record.ip, self.queue, cache)
|
||||||
@@ -299,6 +295,7 @@ class ServerTreeView(TreeView):
|
|||||||
return f"{addr}:{qport}"
|
return f"{addr}:{qport}"
|
||||||
|
|
||||||
def get_record(self) -> dict | None:
|
def get_record(self) -> dict | None:
|
||||||
|
# TODO: delegate to controller
|
||||||
select = self.get_selection()
|
select = self.get_selection()
|
||||||
sels = select.get_selected_rows()
|
sels = select.get_selected_rows()
|
||||||
(model, pathlist) = sels
|
(model, pathlist) = sels
|
||||||
@@ -319,4 +316,3 @@ class ServerTreeView(TreeView):
|
|||||||
|
|
||||||
def set_loaded(self, status: bool) -> None:
|
def set_loaded(self, status: bool) -> None:
|
||||||
self.loaded = status
|
self.loaded = status
|
||||||
|
|
||||||
Reference in new issue
Block a user