fix: connect signals to new notebook tabs

This commit is contained in:
aclist 2025-12-21 03:01:55 +09:00
parent e281345323
commit 8b3d8c94fd
10 changed files with 137 additions and 197 deletions

View File

@ -361,20 +361,6 @@ class ContextMenuGroup(Enum):
)
MAIN_MENU_ROWS = (
RowType.SERVER_BROWSER,
RowType.SAVED_SERVERS,
RowType.RECENT_SERVERS,
RowType.SCAN_LAN,
RowType.SEPARATOR,
RowType.QUICK_CONNECT,
RowType.CONN_BY_IP,
RowType.CONN_BY_ID,
RowType.SEPARATOR,
RowType.ADD_BY_IP,
RowType.ADD_BY_ID,
RowType.CHNG_FAV,
)
HELP_MENU_ROWS = (
RowType.CHANGELOG,
RowType.SHOW_LOG,
@ -389,87 +375,6 @@ HELP_MENU_ROWS = (
RowType.THANKS,
)
#class WindowContext(EnumWithAttrs):
# # TODO: deprecated
# @classmethod
# def row2con(cls, row: RowType) -> "WindowContext":
# m = WindowContext.MAIN_MENU
# for member in cls:
# if row in member.dict["rows"]:
# m = member
# elif row in member.dict["called_by"]:
# m = member
# else:
# continue
# return m
#
# # outer menu pages
# # TODO: some deprecated keys in here
# #MAIN_MENU = {
# # RowType.SERVER_BROWSER,
# # RowType.SAVED_SERVERS,
# # RowType.RECENT_SERVERS,
# # RowType.SCAN_LAN,
# # RowType.SEPARATOR,
# # RowType.QUICK_CONNECT,
# # RowType.CONN_BY_IP,
# # RowType.CONN_BY_ID,
# # RowType.SEPARATOR,
# # RowType.ADD_BY_IP,
# # RowType.ADD_BY_ID,
# # RowType.CHNG_FAV,
# # }
# #MODS = {
# # "label": "Mods",
# # "rows": [],
# # "called_by": [],
# #}
# HELP = {
# "label": "Help",
# "rows": [
# RowType.CHANGELOG,
# RowType.SHOW_LOG,
# RowType.DUMP_LOG,
# RowType.SEPARATOR,
# RowType.DOCS,
# RowType.DOCS_FALLBACK,
# RowType.BUGS,
# RowType.FORUM,
# RowType.SPONSOR,
# RowType.SEPARATOR,
# RowType.THANKS,
# ],
# "called_by": [],
# }
#
# ## inner server contexts
# #TABLE_API = {
# # "label": "",
# # "rows": [],
# # "called_by": [RowType.SERVER_BROWSER],
# #}
# #TABLE_SERVER = {
# # "label": "",
# # "rows": [],
# # "called_by": [
# # RowType.SAVED_SERVERS,
# # RowType.RECENT_SERVERS,
# # RowType.SCAN_LAN,
# # ],
# #}
# #TABLE_MODS = {
# # "label": "",
# # "rows": [],
# # "called_by": [
# # RowType.LIST_MODS,
# # ],
# #}
# #TABLE_LOG = {
# # "label": "",
# # "rows": [],
# # "called_by": [RowType.SHOW_LOG],
# #}
class ModButton(EnumWithAttrs):
SELECT_ALL = {
@ -499,10 +404,10 @@ class ModButton(EnumWithAttrs):
class ButtonType(EnumWithAttrs):
MAIN_MENU = {
"label": strings.buttons.main_label,
"tooltip": strings.buttons.main_tooltip,
"opens": NotebookPage.MAIN,
SERVERS = {
"label": strings.buttons.servers_label,
"tooltip": strings.buttons.servers_tooltip,
"opens": NotebookPage.SERVERS,
}
MODS = {
"label": strings.buttons.mods_label,
@ -517,7 +422,7 @@ class ButtonType(EnumWithAttrs):
HELP = {
"label": strings.buttons.help_label,
"tooltip": strings.buttons.help_tooltip,
"opens": NotebookPage.MAIN,
"opens": NotebookPage.HELP,
}
EXIT = {
"label": strings.buttons.exit_label,

View File

@ -79,8 +79,8 @@ class Controller:
def get_crumbs(self) -> str:
return self.mediator.grid.get_breadcrumbs()
def get_row_store(self) -> Gtk.ListStore:
return self.model_manager.get_row_store()
#def get_row_store(self) -> Gtk.ListStore:
# return self.model_manager.get_row_store()
def get_help_store(self) -> Gtk.ListStore:
return self.model_manager.get_help_store()
@ -160,7 +160,8 @@ class Controller:
widget.handler_block_by_func(func)
else:
widget.handler_unblock_by_func(func)
self.mediator.treeview.sel_blocked = state
# TODO
#self.mediator.treeview.sel_blocked = state
def toggle_debug_mode(self) -> None:
self.toggle_config(Preferences.DEBUG)
@ -277,6 +278,7 @@ class Controller:
self.mediator.grid.notebook.set_page_by_enum(page)
def open_page_by_button(self, button: "ContextualButton") -> None:
print(button.context)
match button.context:
case ButtonType.EXIT:
logger.info("Normal user exit")
@ -288,13 +290,16 @@ class Controller:
self.load_mods()
case ButtonType.HELP:
help_store = self.model_manager.get_help_store()
# TODO: simply set this model once and open the page
self.mediator.treeview.set_model(help_store)
case ButtonType.MAIN_MENU:
# TODO: going to be deprecated after server notebook is added
row_store = self.model_manager.get_row_store()
self.mediator.treeview.set_model(row_store)
case ButtonType.SERVERS:
self.mediator.notebook.set_page_by_enum(button.opens)
# TODO: shorten this
treeview = self.mediator.notebook.servers.get_active_treeview()
treeview.grab_focus()
return
self.mediator.grid.notebook.set_page_by_enum(button.opens)
self.mediator.notebook.set_page_by_enum(button.opens)
self.set_crumbs(button.get_label())
# TODO: deprecated?
@ -544,3 +549,29 @@ class Controller:
def get_developer_mode(self) -> bool:
return self.is_developer
def set_server_statusbar(self) -> None:
# TODO: different models
model = self.model_manager.get_server_store()
model = AppNav.treeview.get_model()
if model is None:
players = 0
hits = 0
else:
hits = len(model)
players = 0
for row in model:
players += row[4]
# TODO: move to util.format
players_pretty = pluralize("players", players)
hits_pretty = pluralize("matches", hits)
formatted = (
f"Found {hits:n} {hits_pretty} with {players:n} {players_pretty}"
)
suffix = "| Distance: calculating..."
if players == 0:
suffix = ""
self.set_text(formatted + suffix)
self.players = formatted

View File

@ -2,7 +2,7 @@ import re
from dataclasses import dataclass
from typing import Self
from dzgui.const.enum import FilterMode, MAIN_MENU_ROWS, HELP_MENU_ROWS
from dzgui.const.enum import FilterMode, HELP_MENU_ROWS
from dzgui.util import strings
import gi
@ -69,16 +69,16 @@ class ModelManager:
self.ping_cache: dict[str, int] = {}
self.map_store = ListStore(str)
self.row_store = self.new_model_from_class(MenuCols)
#self.row_store = self.new_model_from_class(MenuCols)
self.help_store = self.new_model_from_class(MenuCols)
self.mod_store = self.new_model_from_class(ModCols)
self.log_store = self.new_model_from_class(LogCols)
self.modlist_store = self.new_model_from_class(ServerModCols)
for row in MAIN_MENU_ROWS:
label = row.dict["label"]
self.row_store.append([label, row])
#for row in MAIN_MENU_ROWS:
# label = row.dict["label"]
# self.row_store.append([label, row])
for row in HELP_MENU_ROWS:
label = row.dict["label"]
@ -100,8 +100,8 @@ class ModelManager:
def get_map_store(self) -> ListStore:
return self.map_store
def get_row_store(self) -> ListStore:
return self.row_store
#def get_row_store(self) -> ListStore:
# return self.row_store
def get_help_store(self) -> ListStore:
return self.help_store

View File

@ -240,8 +240,8 @@ class Init:
@dataclass(slots=True, frozen=True)
class Button:
main_label: str
main_tooltip: str
servers_label: str
servers_tooltip: str
mods_label: str
mods_tooltip: str
options_label: str
@ -426,8 +426,8 @@ dialog = Dialog(
)
buttons = Button(
main_label="Main menu",
main_tooltip="Search for and connect to servers",
servers_label="Servers",
servers_tooltip="Search for and connect to servers",
mods_label="Mods",
mods_tooltip="Manage local mods",
options_label="Options",
@ -448,7 +448,7 @@ crumbs = Crumbs(
mods="Mods",
my_servers="Main menu > Saved servers",
options="Options",
servers="Main menu > Server browser",
servers="Servers",
thanks="Help > Special thanks",
developers="Options > Developers",
)

View File

@ -11,13 +11,12 @@ import threading
import typing # noqa
import warnings
from collections.abc import Callable
from concurrent.futures import wait
from concurrent.futures import ThreadPoolExecutor
#from concurrent.futures import wait
#from concurrent.futures import ThreadPoolExecutor
from dataclasses import dataclass
from enum import Enum
from pathlib import Path
from typing import Literal, Any
# TODO: most likely very little of this will be retained
from dzgui.const.enum import (
@ -26,7 +25,6 @@ from dzgui.const.enum import (
RowType,
NotebookPage,
VAdjustment,
MAIN_MENU_ROWS,
)
from dzgui.const.constants import NO_EXPAND, NO_FILL, EXPAND, FILL
from dzgui.const.constants import APP_NAME, APP_NAME_LOWER, WINDOW_DEFAULT_X, WINDOW_DEFAULT_Y
@ -34,26 +32,25 @@ from dzgui.controllers.mc import Controller
from dzgui.util import css, dist, localize, strings, ip, deck, open_links
from dzgui.util.format import pluralize
# GRID ITEMS
# NOTEBOOK ITEMS
# TODO: import notebook only and add components there?
from dzgui.views.pages.changelog import Changelog
from dzgui.views.pages.keys import Keybindings
from dzgui.views.pages.thanks import Thanks
from dzgui.views.pages.options import Options
from dzgui.views.pages.servers import ServerNotebook
from dzgui.views.pages.thanks import Thanks
from dzgui.views.components.mod_panel import ModSelectionPanel
from dzgui.views.components.right_panel import RightPanel
from dzgui.views.components.toast import Toast
from dzgui.views.dialogs.generic import GenericDialog
from dzgui.views.mixins.scrollable_mixin import ScrollableMixin
# TREES
from dzgui.views.trees.tree_log import LogTreeView
from dzgui.views.trees.tree_menu import MenuTreeView
from dzgui.views.trees.tree_mods import ModTreeView
from dzgui.views.trees.tree_servers import ServerTreeView
from dzgui.views.dialogs.generic import GenericDialog
# TODO: not going to be in base anymore
import dzgui.util._json as JSON # noqa
@ -233,6 +230,7 @@ class OuterWindow(Gtk.Window):
self.toast = Toast()
self.overlay = Gtk.Overlay()
self.overlay.add_overlay(self.grid)
# TODO: toast is deprecated
self.overlay.add_overlay(self.toast)
self.add(self.overlay)
@ -244,7 +242,7 @@ class OuterWindow(Gtk.Window):
self.grid.sel_panel.set_visible(False)
# TODO: register from treeview or notebook
AppNav.treeview = self.grid.notebook.scrollable_treelist.treeview
#AppNav.treeview = self.grid.notebook.scrollable_treelist.treeview
css.load_css()
AppNav.grid.notebook.set_page_by_enum(NotebookPage.SERVERS)
@ -268,27 +266,15 @@ class OuterWindow(Gtk.Window):
MainController.save_res_and_quit()
# TODO: consolidate
# wrap base tree class in this
class ScrollableTree(Gtk.ScrolledWindow):
def __init__(self):
super().__init__()
self.treeview = MenuTreeView(MainController)
self.add(self.treeview)
def _set_adjustment(self, adjustment: VAdjustment) -> None:
pass
class AppHeaderBar(Gtk.HeaderBar):
def __init__(self):
def __init__(self) -> None:
super().__init__()
self.props.title = APP_NAME
self.set_decoration_layout(":minimize,maximize,close")
self.set_show_close_button(True)
# TODO: deprecated
class ScrollableNote(ScrollableMixin, Gtk.Box):
def __init__(self, content_box: Gtk.Box, back_button=False):
super().__init__(orientation=Gtk.Orientation.VERTICAL)
@ -322,11 +308,11 @@ class Notebook(ScrollableMixin, Gtk.Notebook):
AppNav.notebook = self
self.prior_page: int
# TODO: set internally
self.scrollable_treelist = ScrollableTree()
self.scrollable_treelist.set_hexpand(False)
self.scrollable_treelist.set_vexpand(True)
self.scrollable_treelist.type = None
# TODO: set static help page
#self.scrollable_treelist = ScrollableTree()
#self.scrollable_treelist.set_hexpand(False)
#self.scrollable_treelist.set_vexpand(True)
#self.scrollable_treelist.type = None
self.change = Changelog(MainController)
self.clog = ScrollableNote(self.change, back_button=False)
@ -344,11 +330,8 @@ class Notebook(ScrollableMixin, Gtk.Notebook):
# 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
from dzgui.views.pages.servers import ServerNotebook
self.servers = ServerNotebook(MainController)
#self.ssu = Gtk.ScrolledWindow()
#self.servers = ServerTreeView(MainController)
#self.ssu.add(self.servers)
AppNav.servers = self.servers
self.quad = Gtk.ScrolledWindow()
@ -369,9 +352,9 @@ class Notebook(ScrollableMixin, Gtk.Notebook):
from dzgui.views.pages.devs import Developers
developers = Developers(MainController)
self.developers = ScrollableNote(developers)
self.pages = {
self.scrollable_treelist: NotebookPage.MAIN,
#self.scrollable_treelist: NotebookPage.MAIN,
self.clog: NotebookPage.CHANGELOG,
self.keys: NotebookPage.KEYS,
self.settings: NotebookPage.OPTIONS,
@ -491,6 +474,7 @@ class Notebook(ScrollableMixin, Gtk.Notebook):
self.focus_current()
# TODO: should be an internal property of those pages
blank = [
NotebookPage.SERVERS,
NotebookPage.OPTIONS,
NotebookPage.THANKS,
NotebookPage.CHANGELOG,
@ -510,13 +494,11 @@ class Notebook(ScrollableMixin, Gtk.Notebook):
crumbs = enum.dict["crumbs"]
MainController.set_crumbs(crumbs)
# TODO: going to be deprecated after server notebook is added
if enum is not NotebookPage.MAIN:
return
MainController.set_help_menu_crumbs()
# TODO:
# MainController.set_help_menu_crumbs()
# TODO: move to components
class Statusbar(Gtk.Statusbar):
def __init__(self) -> None:
super().__init__()
@ -603,6 +585,14 @@ class Grid(Gtk.Grid):
self.attach_next_to(
self.breadcrumbs, self.notebook, Gtk.PositionType.TOP, 3, 1
)
#from dzgui.views.components.connect_panel import ConnectPanel
#self.conpan = ConnectPanel()
#self.attach_next_to(
# self.conpan, self.notebook, Gtk.PositionType.BOTTOM, 3, 1
#)
self.attach_next_to(
self.statusbar, self.notebook, Gtk.PositionType.BOTTOM, 3, 1
)
@ -615,6 +605,7 @@ class Grid(Gtk.Grid):
return self.breadcrumbs.get_text()
def set_breadcrumbs(self, text: str) -> None:
# TODO: embolden func
self.breadcrumbs.set_markup(f"<b>{text}</b>")
@ -658,7 +649,12 @@ class AppNavigation:
window: OuterWindow
notebook: Notebook
right_panel: RightPanel
treeview: MenuTreeView
#treeview: 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

View File

@ -29,7 +29,6 @@ class ButtonBox(Gtk.Box):
orientation=Gtk.Orientation.VERTICAL,
)
self.prior_button = ButtonType.MAIN_MENU
self.controller = controller
self.buttons = list()
self.connect("key-press-event", self._on_keypress)
@ -56,6 +55,10 @@ class ButtonBox(Gtk.Box):
def _on_selection_button_clicked(self, button: Gtk.Button) -> None:
self.controller.open_page_by_button(button)
button.set_sensitive(False)
for b in self.buttons:
if b != button:
b.set_sensitive(True)
def _walk_buttons(self, increment: int) -> None:
for i, button in enumerate(self.buttons):

View File

@ -2,16 +2,31 @@ import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
from dzgui.views.components.web_button import WebButton
class ConnectPanel(Gtk.Grid):
def __init__(self) -> None:
super().__init__()
super().__init__(vexpand=False, margin=20)
self.label = Gtk.Label(label="Connect by IP/ID")
self.label2 = Gtk.Label(label="Save server by IP/ID")
self.entry1 = Gtk.Entry()
self.label2 = Gtk.Label(label="Favorite server")
# TODO: embold function
self.label2.set_markup("<b>Favorite server</b>")
sep = Gtk.Separator()
self.entry1 = Gtk.Entry(placeholder_text="Enter IP or Battlemetrics ID", hexpand=False)
self.entry2 = Gtk.Entry()
self.fav = Gtk.Label("MY favorite server")
self.favedit = Gtk.Button("Edit")
self.edit = WebButton(label="EDIT")
self.favbutton = Gtk.Button(label="Connect")
self.attach(self.label, 0, 0, 3, 1)
button = Gtk.Button(label="Connect")
self.attach_next_to(self.entry1, self.label, Gtk.PositionType.BOTTOM, 3, 1)
self.attach_next_to(self.label2, self.entry1, Gtk.PositionType.BOTTOM, 3, 1)
self.attach_next_to(self.entry2, self.label2, Gtk.PositionType.BOTTOM, 3, 1)
self.attach_next_to(button, self.entry1, Gtk.PositionType.RIGHT, 3, 1)
self.attach_next_to(sep, self.entry1, Gtk.PositionType.BOTTOM, 3, 1)
self.attach_next_to(self.label2, sep, Gtk.PositionType.BOTTOM, 3, 1)
self.attach_next_to(self.fav, self.label2, Gtk.PositionType.BOTTOM, 3, 1)
self.attach_next_to(self.edit, self.fav, Gtk.PositionType.RIGHT, 3, 1)
self.attach_next_to(self.favbutton, self.edit, Gtk.PositionType.RIGHT, 3, 1)

View File

@ -5,7 +5,7 @@ import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402
# TODO: abstract to support other icons
class WebButton(Gtk.Button):
def __init__(self, label: str):
super().__init__(label=label)

View File

@ -84,10 +84,15 @@ class TreeView(CursorMixin, Gtk.TreeView):
if is_navkey(event.keyval):
# TODO: investigate this
# TODO: get active tree if server view is open
servers = self.controller.mediator.notebook.servers
tv = servers.get_active_treeview()
if self.sel_blocked is False:
self.controller.suppress_signal(
self.controller.mediator.treeview,
self.controller.mediator.treeview.selected_row,
tv,
tv.selected_row,
#self.controller.mediator.treeview,
#self.controller.mediator.treeview.selected_row,
"_on_tree_selection_changed",
True,
)

View File

@ -80,14 +80,6 @@ class ServerTreeView(TreeView):
self.append_column(column)
# TODO: do not load model on initial init
# TODO: test values: see below
#r = Gtk.ListStore(
# str, str, str, str, int, int, int, str, int, int, str, bool
#)
#r.append(["TEST", "a", "a", "a", 0, 0, 0, "a", 0, 0, "a", False])
#self.set_model(r)
self.connect("on_distcalc_started", self._on_calclat_started)
@ -117,7 +109,7 @@ class ServerTreeView(TreeView):
addr = latest_result[0]
km = latest_result[1]
cache[addr] = km
# TODO: fixme
# FIXME
self.statusbar.append_distance(km)
return True
@ -137,9 +129,6 @@ class ServerTreeView(TreeView):
return True
AppNav.right_panel.filters_vbox.keyword_entry.grab_focus()
case Gdk.KEY_m:
# FIXME: should no longer be relevant
if AppNav.treeview.view == WindowContext.TABLE_MODS:
return True
AppNav.right_panel.filters_vbox.maps_entry.grab_focus()
else:
keyname = Gdk.keyval_name(event.keyval)
@ -164,6 +153,7 @@ class ServerTreeView(TreeView):
def _on_server_button_release(
self, widget: Gtk.Widget, event: Gdk.EventButton
) -> None:
# TODO: use ContextMixin
if event.type is Gdk.EventType.BUTTON_RELEASE and event.button != 3:
return
@ -181,6 +171,7 @@ class ServerTreeView(TreeView):
self.menu = Gtk.Menu()
mod_context_items = [ContextMenu.OPEN_WORKSHOP, ContextMenu.DELETE_MOD]
# TODO: reimplement server context enums
# TODO: inherit from tree_servers.py
server_context_items = {
RowType.SERVER_BROWSER: [
ContextMenu.ADD_SERVER,
@ -221,12 +212,7 @@ class ServerTreeView(TreeView):
}
# TODO: how to get current server context
if self.view == WindowContext.TABLE_MODS:
items = mod_context_items
elif self.subpage in server_context_items:
items = server_context_items[self.subpage]
else:
return
items = server_context_items[self.subpage]
for row in items:
if row == ContextMenu.ADD_SERVER:
@ -265,22 +251,21 @@ class ServerTreeView(TreeView):
print(self.get_value_at_index(0))
def _parent_selection_changed(self, base_class: TreeView, sel: Gtk.TreeSelection):
print(self.get_value_at_index(0))
self.terminate_process()
record = self.get_record()
print(record)
# TODO: ?
if not record:
grid.statusbar.update_server_meta()
if record is None:
# TODO: move to controller
#grid.statusbar.update_server_meta()
return
ip = record.ip
self.emit("on_distcalc_started")
self.current_proc = CalcDist(self, record.ip, self.queue, cache)
self.current_proc.start()
# TODO
#self.emit("on_distcalc_started")
#self.current_proc = CalcDist(self, record.ip, self.queue, cache)
#self.current_proc.start()
def get_record_string(self) -> str:
addr = self.get_value_at_index(7)