mirror of
https://github.com/aclist/dztui.git
synced 2026-08-26 17:57:06 +02:00
feat: dedicated emitter
This commit is contained in:
parent
ea841395fc
commit
ac7700ec23
@ -254,7 +254,6 @@ class Record:
|
||||
qport: int
|
||||
|
||||
|
||||
# TODO: refactor this
|
||||
def get_prereqs(ip: str, qport: int) -> Prereqs:
|
||||
try:
|
||||
info = a2s.info((ip, qport))
|
||||
|
||||
@ -58,3 +58,4 @@ LEGACY_IPS_PATH = ".local/share/dzgui/helpers/ips.csv"
|
||||
|
||||
DEBUG_LOG = f"{APP_NAME}_DEBUG.LOG"
|
||||
SYSTEM_LOG = f"{APP_NAME}_SYSTEM.LOG"
|
||||
CHANGELOG_PATH = "data/CHANGELOG.md"
|
||||
|
||||
@ -110,14 +110,14 @@ class Preferences(EnumWithAttrs):
|
||||
|
||||
|
||||
class NotebookPage(EnumWithAttrs):
|
||||
CHANGELOG = {"crumbs": strings.crumbs.changelog, "statusbar": False}
|
||||
KEYS = {"crumbs": strings.crumbs.keys, "statusbar": False}
|
||||
LOG = {"crumbs": strings.crumbs.log, "statusbar": False}
|
||||
CHANGELOG = {"crumbs": strings.crumbs.changelog, "statusbar": True}
|
||||
KEYS = {"crumbs": strings.crumbs.keys, "statusbar": True}
|
||||
LOG = {"crumbs": strings.crumbs.log, "statusbar": True}
|
||||
HELP = {"crumbs": strings.crumbs._help, "statusbar": True}
|
||||
MODS = {"crumbs": strings.crumbs.mods, "statusbar": True}
|
||||
OPTIONS = {"crumbs": strings.crumbs.options, "statusbar": False}
|
||||
SERVERS = {"crumbs": strings.crumbs.servers, "statusbar": True}
|
||||
THANKS = {"crumbs": strings.crumbs.thanks, "statusbar": False}
|
||||
THANKS = {"crumbs": strings.crumbs.thanks, "statusbar": True}
|
||||
DEVELOPERS = {"crumbs": strings.crumbs.developers, "statusbar": False}
|
||||
|
||||
|
||||
|
||||
61
dzgui/controllers/emitter.py
Normal file
61
dzgui/controllers/emitter.py
Normal file
@ -0,0 +1,61 @@
|
||||
from typing import Union, TYPE_CHECKING
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gdk, GObject # noqa E402
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.const.enum import NotebookPage, ServerTab
|
||||
|
||||
# TODO: rename signals to e.g. maps_keybinding_pressed
|
||||
|
||||
class Emitter(GObject.GObject):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def request_keyword_focus(self) -> None:
|
||||
"""User invoked Ctrl-f keybinding from ServerTreeView"""
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def request_maps_focus(self) -> None:
|
||||
"""User invoked Ctrl-m keybinding from ServerTreeView"""
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def request_ip_entry_focus(self) -> None:
|
||||
"""User invoked Ctrl-i keybinding from ServerTreeView"""
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def request_lan_entry_focus(self) -> None:
|
||||
"""User invoked Ctrl-p keybinding from ServerTreeView"""
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def request_button_box_focus(self) -> None:
|
||||
"""User invoked right movement keybinding from ServerTreeView"""
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=(int,))
|
||||
def check_button_pressed(self, keyval: int) -> None:
|
||||
"""User toggled filter panel check button via keyboard"""
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def distcalc_started(self) -> 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
|
||||
@ -12,7 +12,6 @@ from typing import Any, Callable, Literal, Union, TYPE_CHECKING
|
||||
import dzgui.api.pefile as PeFile
|
||||
import dzgui.api.servers as Servers
|
||||
import dzgui.util._json as JSON # noqa
|
||||
from dzgui.views.dialogs.generic import ExceptionDialog, WaitDialog
|
||||
|
||||
from dzgui.api.probe import test_steam_api, test_bm_api
|
||||
from dzgui.api.mods import (
|
||||
@ -35,6 +34,7 @@ from dzgui.const.constants import (
|
||||
from dzgui.config import update
|
||||
from dzgui.config.query import lookup
|
||||
from dzgui.config.userprefs import UserPrefs
|
||||
from dzgui.controllers.emitter import Emitter
|
||||
from dzgui.model.misc_model import ModelManager
|
||||
from dzgui.util import strings
|
||||
from dzgui.util.diag import write_diagnostic
|
||||
@ -43,7 +43,7 @@ from dzgui.util.localize import number
|
||||
from dzgui.util.open_links import open_workshop_page, open_user_workshop
|
||||
from dzgui.util.format import format_mods, format_player_count
|
||||
from dzgui.util.redact import redact_log
|
||||
|
||||
from dzgui.views.dialogs.generic import ExceptionDialog, WaitDialog
|
||||
from dzgui.views.dialogs.filepicker import FilePicker
|
||||
|
||||
import gi
|
||||
@ -83,43 +83,6 @@ class AppNavigation:
|
||||
logtreeview: "LogTreeView"
|
||||
filters: "FilterPanel"
|
||||
|
||||
class Emitter(GObject.GObject):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def request_keyword_focus(self) -> None:
|
||||
"""User invoked Ctrl-f keybinding from ServerTreeView"""
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def request_maps_focus(self) -> None:
|
||||
"""User invoked Ctrl-m keybinding from ServerTreeView"""
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def request_ip_entry_focus(self) -> None:
|
||||
"""User invoked Ctrl-i keybinding from ServerTreeView"""
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def request_lan_entry_focus(self) -> None:
|
||||
"""User invoked Ctrl-p keybinding from ServerTreeView"""
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def request_button_box_focus(self) -> None:
|
||||
"""User invoked right movement keybinding from ServerTreeView"""
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def distcalc_started(self) -> 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
|
||||
|
||||
|
||||
class Controller(GObject.GObject):
|
||||
def __init__(self) -> None:
|
||||
@ -128,11 +91,11 @@ class Controller(GObject.GObject):
|
||||
self.prefs: UserPrefs
|
||||
|
||||
self.model_man = ModelManager()
|
||||
self.emitter = Emitter()
|
||||
|
||||
# NOTE: suppress requests until entire UI is loaded
|
||||
self.loaded = False
|
||||
|
||||
self.emitter = Emitter()
|
||||
|
||||
def get_emitter(self) -> Emitter:
|
||||
return self.emitter
|
||||
@ -169,8 +132,7 @@ class Controller(GObject.GObject):
|
||||
|
||||
def terminate_process(self) -> None:
|
||||
# TODO: only used by server table multiprocessing queue
|
||||
tv = self.get_active_treeview()
|
||||
tv.terminate_process()
|
||||
self.get_active_treeview().terminate_process()
|
||||
|
||||
def get_prefs(self) -> UserPrefs:
|
||||
return self.prefs
|
||||
@ -626,16 +588,6 @@ class Controller(GObject.GObject):
|
||||
def unselect_all_mods(self) -> None:
|
||||
self.mediator.modtreeview.get_selection().unselect_all()
|
||||
|
||||
def dump_test_1(self) -> None:
|
||||
import time
|
||||
|
||||
time.sleep(1)
|
||||
data = (
|
||||
["BAR", "a", "a", "a", 1, 1, 1, "185.207.214.16:2302", 0, 0, "a", False],
|
||||
["BAR", "a", "a", "a", 1, 1, 1, "172.111.51.156:2302", 0, 0, "a", False],
|
||||
)
|
||||
self.push_data(data)
|
||||
|
||||
def dump_test_2(self) -> None:
|
||||
import time
|
||||
time.sleep(1)
|
||||
@ -741,6 +693,7 @@ class Controller(GObject.GObject):
|
||||
dialog.run()
|
||||
|
||||
@call_on_thread
|
||||
# FIXME: entire process is behind thread, including destroy_on_idle()
|
||||
def update_api_key(self, text: str, key: Preferences) -> None:
|
||||
self.test_api_response(text, key)
|
||||
|
||||
@ -825,26 +778,6 @@ class Controller(GObject.GObject):
|
||||
def focus_button_box(self) -> None:
|
||||
self.mediator.right_panel.focus_button_box()
|
||||
|
||||
def toggle_check(self, event: Gdk.EventKey) -> None | Literal[False]:
|
||||
mappings = {
|
||||
Gdk.KEY_1: 0,
|
||||
Gdk.KEY_2: 1,
|
||||
Gdk.KEY_3: 2,
|
||||
Gdk.KEY_4: 3,
|
||||
Gdk.KEY_5: 4,
|
||||
Gdk.KEY_6: 5,
|
||||
Gdk.KEY_7: 6,
|
||||
Gdk.KEY_8: 7,
|
||||
Gdk.KEY_9: 8,
|
||||
Gdk.KEY_0: 9,
|
||||
Gdk.KEY_minus: 10,
|
||||
Gdk.KEY_backslash: 11,
|
||||
}
|
||||
if event.keyval not in mappings:
|
||||
return False
|
||||
index = mappings[event.keyval]
|
||||
self.mediator.filters.toggle_check(index)
|
||||
|
||||
def get_favorite(self) -> tuple[str, str] | tuple[None, None]:
|
||||
fav = str(self.query_config(Preferences.FAV_LBL))
|
||||
if len(fav) < 1:
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
from dataclasses import dataclass
|
||||
|
||||
from dzgui.const.constants import SYSTEM_LOG
|
||||
|
||||
|
||||
@ -605,3 +604,7 @@ atomic_buttons = AtomicButton(
|
||||
)
|
||||
|
||||
steam_icon_missing="Steam icon not found in IconTheme"
|
||||
|
||||
missing_changelog = "Error: failed to read changelog"
|
||||
esc_to_return = "Press ESC to return"
|
||||
question_to_return = "Press ? to return"
|
||||
|
||||
@ -191,13 +191,13 @@ class Notebook(ScrollableMixin, Gtk.Notebook): # type: ignore
|
||||
self.help = Help(MainController)
|
||||
self.clog = Changelog(MainController)
|
||||
|
||||
self.keys = Keybindings()
|
||||
self.keys = Keybindings(MainController)
|
||||
self.settings = Options(MainController)
|
||||
|
||||
self.servers = ServerNotebook(MainController)
|
||||
self.mods = Mods(MainController)
|
||||
|
||||
self.thanks = Thanks()
|
||||
self.thanks = Thanks(MainController)
|
||||
self.log = Log(MainController)
|
||||
self.developers = Developers(MainController)
|
||||
|
||||
@ -272,12 +272,7 @@ class Notebook(ScrollableMixin, Gtk.Notebook): # type: ignore
|
||||
if widget is None:
|
||||
return
|
||||
|
||||
if widget is self.servers:
|
||||
MainController.grab_active_treeview()
|
||||
return
|
||||
|
||||
w = widget.get_children()[0]
|
||||
w.grab_focus()
|
||||
widget.grab_content_area()
|
||||
|
||||
def get_page(self) -> Gtk.Widget | None:
|
||||
ind = self.get_current_page()
|
||||
|
||||
@ -4,11 +4,13 @@ from dzgui.const.enum import ButtonType
|
||||
from dzgui.const.constants import NO_EXPAND, NO_FILL, NO_PADDING
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk # noqa E402
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class ContextualButton(Gtk.Button):
|
||||
def __init__(self, label, opens, tooltip, context):
|
||||
super().__init__(
|
||||
@ -20,6 +22,7 @@ class ContextualButton(Gtk.Button):
|
||||
self.context = context
|
||||
self.opens = opens
|
||||
|
||||
|
||||
class ButtonBox(Gtk.Box):
|
||||
def __init__(self, controller) -> None:
|
||||
super().__init__(
|
||||
@ -41,7 +44,7 @@ class ButtonBox(Gtk.Box):
|
||||
opens=side_button.dict["opens"],
|
||||
tooltip=side_button.dict["tooltip"],
|
||||
context=side_button,
|
||||
)
|
||||
)
|
||||
|
||||
# FIXME: if debug log fails to load, still opens table
|
||||
size = (10, 10) if prefs.is_steam_deck else (50, 50)
|
||||
@ -52,7 +55,6 @@ class ButtonBox(Gtk.Box):
|
||||
button.connect("clicked", self._on_selection_button_clicked)
|
||||
self.pack_start(button, NO_EXPAND, NO_FILL, NO_PADDING)
|
||||
|
||||
|
||||
def _on_selection_button_clicked(self, button: Gtk.Button) -> None:
|
||||
self.controller.open_page_by_button(button)
|
||||
|
||||
|
||||
@ -16,6 +16,7 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.controllers.mc import Controller
|
||||
from dzgui.controllers.emitter import Emitter
|
||||
|
||||
|
||||
class FilterPanel(Gtk.Box):
|
||||
@ -94,6 +95,7 @@ class FilterPanel(Gtk.Box):
|
||||
self.emitter.connect(
|
||||
"request_maps_focus", lambda _: self.maps_entry.grab_focus()
|
||||
)
|
||||
self.emitter.connect("check_button_pressed", self.toggle_check_by_key)
|
||||
|
||||
completion = Gtk.EntryCompletion(inline_completion=True)
|
||||
completion.set_text_column(0)
|
||||
@ -251,6 +253,26 @@ class FilterPanel(Gtk.Box):
|
||||
def set_active_combo(self, row: int) -> None:
|
||||
self.maps_combo.set_active(row)
|
||||
|
||||
def toggle_check_by_key(self, emitter: "Emitter", keyval: int) -> None | Literal[False]:
|
||||
mappings = {
|
||||
Gdk.KEY_1: 0,
|
||||
Gdk.KEY_2: 1,
|
||||
Gdk.KEY_3: 2,
|
||||
Gdk.KEY_4: 3,
|
||||
Gdk.KEY_5: 4,
|
||||
Gdk.KEY_6: 5,
|
||||
Gdk.KEY_7: 6,
|
||||
Gdk.KEY_8: 7,
|
||||
Gdk.KEY_9: 8,
|
||||
Gdk.KEY_0: 9,
|
||||
Gdk.KEY_minus: 10,
|
||||
Gdk.KEY_backslash: 11,
|
||||
}
|
||||
if keyval not in mappings:
|
||||
return False
|
||||
index = mappings[keyval]
|
||||
self.toggle_check(index)
|
||||
|
||||
def toggle_check(self, digit: int) -> None:
|
||||
check = self.checks[digit]
|
||||
state = check.get_active()
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
from typing import TYPE_CHECKING
|
||||
from typing import Optional, TYPE_CHECKING
|
||||
|
||||
from dzgui.views.components.buttonbox import ButtonBox
|
||||
from dzgui.views.components.filter_panel import FilterPanel
|
||||
@ -13,6 +13,7 @@ from gi.repository import Gtk, GLib # noqa E402
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.controllers.mc import Controller
|
||||
from dzgui.controllers.emitter import Emitter
|
||||
|
||||
|
||||
class RightPanel(Gtk.Box):
|
||||
@ -78,5 +79,5 @@ class RightPanel(Gtk.Box):
|
||||
# thread = threading.Thread(target=_update_pings, args=())
|
||||
# thread.start()
|
||||
|
||||
def focus_button_box(self) -> None:
|
||||
def focus_button_box(self, emitter: Optional["Emitter"] = None) -> None:
|
||||
self.button_vbox.buttons[0].grab_focus()
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
from typing import Self, Union, TYPE_CHECKING
|
||||
|
||||
from dzgui.const.enum import NotebookPage, ServerTab
|
||||
from dzgui.util.strings import esc_to_return, question_to_return
|
||||
|
||||
import gi
|
||||
|
||||
@ -46,8 +47,8 @@ class Statusbar(Gtk.Grid):
|
||||
controller.mediator.notebook.connect_after(
|
||||
"switch-page", self._on_notebook_page_changed
|
||||
)
|
||||
self.emitter.connect("distcalc_started", self._on_distcalc_started)
|
||||
# TODO:
|
||||
self.emitter.connect("distcalc_started", lambda _: self.spinner.start())
|
||||
self.connect("distcalc_ended", self._on_distcalc_ended)
|
||||
|
||||
self.connect("server_page_changed", self._on_server_page_changed)
|
||||
@ -77,10 +78,19 @@ class Statusbar(Gtk.Grid):
|
||||
|
||||
enum = notebook.get_page_by_enum()
|
||||
show_statusbar = enum.dict["statusbar"]
|
||||
|
||||
if show_statusbar is False:
|
||||
self.set_by_context(enum, "")
|
||||
return
|
||||
|
||||
if enum in (
|
||||
NotebookPage.THANKS,
|
||||
NotebookPage.CHANGELOG,
|
||||
NotebookPage.LOG,
|
||||
):
|
||||
self.set_by_context(enum, esc_to_return)
|
||||
return
|
||||
|
||||
match enum:
|
||||
case NotebookPage.MODS:
|
||||
bar = self.controller.format_mod_statusbar()
|
||||
@ -89,6 +99,8 @@ class Statusbar(Gtk.Grid):
|
||||
case NotebookPage.SERVERS:
|
||||
self.emit("server_page_changed", ServerTab.BROWSER)
|
||||
return
|
||||
case NotebookPage.KEYS:
|
||||
bar = question_to_return
|
||||
|
||||
self.set_by_context(enum, bar)
|
||||
|
||||
@ -122,7 +134,7 @@ class Statusbar(Gtk.Grid):
|
||||
|
||||
self.set_by_context(context, count)
|
||||
tree = self.controller.get_active_treeview()
|
||||
# TODO: emit page change signal on emitter, treeview catches signal and calls distcalc
|
||||
# TODO: emit page change signal on emitter, treeview catches signal and calls distcalc directly
|
||||
tree.emit("distcalc_started")
|
||||
|
||||
def pop(self, context: Union["ServerTab", "NotebookPage"]) -> None:
|
||||
|
||||
@ -2,6 +2,7 @@ from dzgui.const.enum import CursorPosition
|
||||
from dzgui.const.constants import SEPARATOR
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa E402
|
||||
|
||||
@ -20,7 +21,7 @@ class CursorMixin:
|
||||
case Gdk.KEY_l | Gdk.KEY_Right:
|
||||
if event.state is Gdk.ModifierType.CONTROL_MASK:
|
||||
return
|
||||
self.controller.mediator.right_panel.focus_button_box()
|
||||
self.emitter.emit("request_button_box_focus")
|
||||
case _:
|
||||
return False
|
||||
|
||||
|
||||
13
dzgui/views/mixins/help_menu_mixin.py
Normal file
13
dzgui/views/mixins/help_menu_mixin.py
Normal file
@ -0,0 +1,13 @@
|
||||
from typing import Literal
|
||||
|
||||
from dzgui.const.enum import NotebookPage
|
||||
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk # noqa
|
||||
|
||||
class HelpMenuMixin:
|
||||
def _on_esc_keypress(self, widget: Gtk.Widget, event: Gdk.EventKey) -> Literal[True]:
|
||||
if event.keyval == Gdk.KEY_Escape:
|
||||
self.controller.open_page(NotebookPage.HELP)
|
||||
return True
|
||||
@ -2,9 +2,11 @@ from dzgui.const.enum import VAdjustment
|
||||
from dzgui.const.constants import SCROLL_INCREMENT
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk # noqa
|
||||
|
||||
|
||||
class ScrollableMixin:
|
||||
def _on_keypress(self, widget: Gtk.Widget, event: Gdk.EventKey) -> None:
|
||||
match event.keyval:
|
||||
@ -16,6 +18,8 @@ class ScrollableMixin:
|
||||
self._set_adjustment(VAdjustment.TOP)
|
||||
case Gdk.KEY_G:
|
||||
self._set_adjustment(VAdjustment.BOTTOM)
|
||||
case Gdk.KEY_l | Gdk.KEY_Right:
|
||||
self.controller.get_emitter().emit("request_button_box_focus")
|
||||
|
||||
def _set_adjustment(self, adjustment: VAdjustment) -> None:
|
||||
vadj = self.get_vadjustment()
|
||||
@ -29,4 +33,3 @@ class ScrollableMixin:
|
||||
case VAdjustment.DOWN:
|
||||
adj = vadj.get_value() + SCROLL_INCREMENT
|
||||
vadj.set_value(adj)
|
||||
|
||||
|
||||
@ -3,31 +3,35 @@ import logging
|
||||
from typing import TYPE_CHECKING
|
||||
from importlib import resources
|
||||
|
||||
from dzgui.const.constants import APP_NAME_LOWER
|
||||
from dzgui.const.constants import APP_NAME_LOWER, CHANGELOG_PATH
|
||||
from dzgui.util.strings import missing_changelog
|
||||
from dzgui.util.format import format_pango
|
||||
from dzgui.views.mixins.help_menu_mixin import HelpMenuMixin
|
||||
from dzgui.views.mixins.scrollable_mixin import ScrollableMixin
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk # noqa E402
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.controllers.mc import Controller
|
||||
|
||||
class Changelog(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
|
||||
|
||||
class Changelog(HelpMenuMixin, ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
|
||||
def __init__(self, controller: "Controller"):
|
||||
super().__init__(propagate_natural_width=False)
|
||||
|
||||
try:
|
||||
changelog = resources.read_text(APP_NAME_LOWER, "data/CHANGELOG.md")
|
||||
changelog = resources.read_text(APP_NAME_LOWER, CHANGELOG_PATH)
|
||||
except OSError as e:
|
||||
logger.critical(e)
|
||||
changelog = "Error: Failed to read changelog"
|
||||
changelog = missing_changelog
|
||||
|
||||
# TODO: should long text be wrapped?
|
||||
self.controller = controller
|
||||
formatted = format_pango(changelog)
|
||||
self.changelog_label = Gtk.Label(valign=Gtk.Align.START, margin=15)
|
||||
self.changelog_label.set_markup(formatted)
|
||||
@ -36,3 +40,7 @@ class Changelog(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
|
||||
self.add(self.box)
|
||||
|
||||
self.connect("key-press-event", self._on_keypress)
|
||||
self.connect("key-press-event", self._on_esc_keypress)
|
||||
|
||||
def grab_content_area(self) -> None:
|
||||
self.grab_focus()
|
||||
|
||||
@ -18,7 +18,11 @@ class Help(Gtk.ScrolledWindow):
|
||||
|
||||
self.controller = controller
|
||||
|
||||
self.treeview.focus_first_row()
|
||||
# FIXME: remember focused row
|
||||
#self.treeview.focus_first_row()
|
||||
|
||||
def get_treeview(self) -> MenuTreeView:
|
||||
return self.treeview
|
||||
|
||||
def grab_content_area(self) -> None:
|
||||
self.treeview.grab_focus()
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from dzgui.views.mixins.scrollable_mixin import ScrollableMixin
|
||||
from dzgui.util.strings import navigation, servers, vim, key_header, key_contexts
|
||||
from dzgui.util.css import add_class
|
||||
@ -6,15 +8,18 @@ import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk # noqa E402
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.controllers.mc import Controller
|
||||
|
||||
class Keybindings(ScrollableMixin, Gtk.ScrolledWindow):
|
||||
"""
|
||||
Notebook page holding a prearranged grid
|
||||
of keybindings and their descriptions
|
||||
"""
|
||||
def __init__(self) -> None:
|
||||
def __init__(self, controller: "Controller") -> None:
|
||||
super().__init__()
|
||||
|
||||
self.controller = controller
|
||||
self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
|
||||
|
||||
label = Gtk.Label(label=key_header)
|
||||
@ -101,3 +106,6 @@ class Keybindings(ScrollableMixin, Gtk.ScrolledWindow):
|
||||
grid.attach_next_to(separator, sidebar, Gtk.PositionType.RIGHT, w, h)
|
||||
grid.attach_next_to(keys_box, separator, Gtk.PositionType.RIGHT, w, h)
|
||||
return grid
|
||||
|
||||
def grab_content_area(self) -> None:
|
||||
self.box.grab_focus()
|
||||
|
||||
@ -1,14 +1,19 @@
|
||||
from typing import TYPE_CHECKING
|
||||
from dzgui.views.mixins.cursor_mixin import CursorMixin
|
||||
from dzgui.views.mixins.help_menu_mixin import HelpMenuMixin
|
||||
from dzgui.views.trees.tree_log import LogTreeView
|
||||
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk # noqa E402
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.controllers.mc import Controller
|
||||
|
||||
class Log(Gtk.ScrolledWindow):
|
||||
|
||||
class Log(CursorMixin, HelpMenuMixin, Gtk.ScrolledWindow):
|
||||
def __init__(self, controller: "Controller") -> None:
|
||||
super().__init__()
|
||||
self.treeview = LogTreeView(controller)
|
||||
@ -17,5 +22,10 @@ class Log(Gtk.ScrolledWindow):
|
||||
self.controller = controller
|
||||
self.controller.register_widget("logtreeview", self.treeview)
|
||||
|
||||
self.connect("key-press-event", self._on_esc_keypress)
|
||||
|
||||
def get_treeview(self) -> LogTreeView:
|
||||
return self.treeview
|
||||
|
||||
def grab_content_area(self) -> None:
|
||||
self.treeview.grab_focus()
|
||||
|
||||
@ -28,3 +28,6 @@ class Mods(Gtk.ScrolledWindow):
|
||||
|
||||
def _on_map(self, widget: Self) -> None:
|
||||
self.controller.toggle_mod_panel(True)
|
||||
|
||||
def grab_content_area(self) -> None:
|
||||
self.tree.grab_focus()
|
||||
|
||||
@ -524,3 +524,6 @@ class Options(Gtk.Box):
|
||||
icon, state = VIEW_CONCEAL, True
|
||||
widget.set_icon_from_icon_name(Gtk.EntryIconPosition.SECONDARY, icon)
|
||||
widget.set_visibility(state)
|
||||
|
||||
def grab_content_area(self) -> None:
|
||||
return
|
||||
|
||||
@ -71,6 +71,9 @@ class ServerNotebook(Gtk.ScrolledWindow):
|
||||
self.notebook.prev_page()
|
||||
case _:
|
||||
return
|
||||
self.grab_content_area()
|
||||
|
||||
def grab_content_area(self) -> None:
|
||||
self.get_active_treeview().grab_focus()
|
||||
|
||||
def get_current_tab_text(self) -> None:
|
||||
|
||||
@ -1,26 +1,37 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from dzgui.util.format import format_pango
|
||||
from dzgui.util.strings import thanks
|
||||
from dzgui.views.mixins.help_menu_mixin import HelpMenuMixin
|
||||
from dzgui.views.mixins.scrollable_mixin import ScrollableMixin
|
||||
|
||||
import gi
|
||||
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk # noqa E402
|
||||
|
||||
# TODO: wrap and center long values
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.controllers.mc import Controller
|
||||
|
||||
class Thanks(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
|
||||
|
||||
class Thanks(HelpMenuMixin, ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
|
||||
"""
|
||||
Special thanks page recognizing contributors to the project in alpha-order
|
||||
"""
|
||||
def __init__(self) -> None:
|
||||
|
||||
def __init__(self, controller: "Controller") -> None:
|
||||
super().__init__()
|
||||
|
||||
self.controller = controller
|
||||
self.box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=10)
|
||||
label = format_pango(thanks.header)
|
||||
header = Gtk.Label()
|
||||
header.set_markup(label)
|
||||
|
||||
description = Gtk.Label(label=thanks.description, justify=Gtk.Justification.CENTER)
|
||||
description = Gtk.Label(
|
||||
label=thanks.description, justify=Gtk.Justification.CENTER
|
||||
)
|
||||
|
||||
users = [f"- {user}" for user in sorted(thanks.users, key=str.lower)]
|
||||
pretty_users = "\n".join(users)
|
||||
@ -32,3 +43,7 @@ class Thanks(ScrollableMixin, Gtk.ScrolledWindow): # type: ignore
|
||||
self.add(self.box)
|
||||
|
||||
self.connect("key-press-event", self._on_keypress)
|
||||
self.connect("key-press-event", self._on_esc_keypress)
|
||||
|
||||
def grab_content_area(self) -> None:
|
||||
self.grab_focus()
|
||||
|
||||
@ -32,6 +32,7 @@ class TreeView(CursorMixin, Gtk.TreeView): # type: ignore
|
||||
self.controller = controller
|
||||
self.sel_blocked = False
|
||||
self.set_row_separator_func(self._separate)
|
||||
self.emitter = self.controller.get_emitter()
|
||||
|
||||
self.selected_row = self.get_selection()
|
||||
self.selected_row.set_mode(Gtk.SelectionMode.SINGLE)
|
||||
|
||||
@ -203,14 +203,11 @@ class ServerTreeView(TreeView):
|
||||
self.current_proc.terminate()
|
||||
|
||||
def _on_distcalc_started(self, treeview: Self):
|
||||
# bar = self.controller.get_statusbar()
|
||||
|
||||
record = self.get_record()
|
||||
if record is None:
|
||||
return
|
||||
|
||||
self.emitter.emit("distcalc_started")
|
||||
# bar.emit("server_row_changed")
|
||||
cache = self.controller.get_dist_cache()
|
||||
|
||||
if record.ip in cache:
|
||||
@ -242,8 +239,6 @@ class ServerTreeView(TreeView):
|
||||
def _on_server_keypress(
|
||||
self, treeview: Gtk.TreeView, event: Gdk.EventKey
|
||||
) -> bool | None:
|
||||
# TODO: use mixins
|
||||
# CONTROL_MASK + KEY_l
|
||||
if event.state is Gdk.ModifierType.CONTROL_MASK:
|
||||
match event.keyval:
|
||||
case Gdk.KEY_l:
|
||||
@ -266,7 +261,7 @@ class ServerTreeView(TreeView):
|
||||
case Gdk.KEY_l | Gdk.KEY_Right:
|
||||
self.emitter.emit("request_button_box_focus")
|
||||
case _:
|
||||
self.controller.toggle_check(event)
|
||||
self.emitter.emit("check_button_pressed", event.keyval)
|
||||
|
||||
def set_context_menu(self, items: ContextMenuGroup) -> None:
|
||||
# TODO: if debug is on, add raw command copy to context menu
|
||||
@ -286,7 +281,6 @@ class ServerTreeView(TreeView):
|
||||
# TODO: use ContextMixin
|
||||
if event.type is Gdk.EventType.BUTTON_RELEASE and event.button != 3:
|
||||
return
|
||||
|
||||
try:
|
||||
pathinfo = self.get_path_at_pos(int(event.x), int(event.y))
|
||||
if pathinfo is None:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user