feat: dynamic connect panel (WIP)

This commit is contained in:
aclist committed 2026-01-02 05:25:00 +09:00
1 parent 5f0c8f7654
commit 06e6065236
14 files changed
+185 -180

No files matched your search

@@ -1,5 +1,5 @@
from dzgui.views.components.icon import Icon
from dzgui.const.constants import REFRESH_ICON, WEB_BROWSER
from dzgui.const.constants import REFRESH_ICON, WEB_BROWSER, INPUT_KEYBOARD
import gi
gi.require_version("Gtk", "3.0")
@@ -9,7 +9,6 @@ from gi.repository import Gtk # noqa E402
class IconButton(Gtk.Button):
def __init__(self, icon: str, margin: int = 0):
super().__init__()
i = Icon(icon, l_margin=margin)
self.set_image(i)
self.set_image_position(Gtk.PositionType.RIGHT)
@@ -18,7 +17,6 @@ class IconButton(Gtk.Button):
class IconTextButton(IconButton):
def __init__(self, icon: str, label: str):
super().__init__(icon, margin=5)
self.set_label(label)
@@ -31,4 +29,14 @@ class WebButton(IconTextButton):
class RefreshButton(IconTextButton):
def __init__(self, label: str):
super().__init__(icon=REFRESH_ICON, label=label)
pass
self.set_margin_top(10)
self.set_margin_start(80)
self.set_margin_end(80)
class KeysButton(IconTextButton):
def __init__(self, label: str):
super().__init__(icon=INPUT_KEYBOARD, label=label)
self.set_margin_top(10)
self.set_margin_start(80)
self.set_margin_end(80)
+55 -30
View File
@@ -1,47 +1,72 @@
from dzgui.util.format import embolden
from dzgui.views.components.web_button import WebButton
from typing import TYPE_CHECKING
from dzgui.util.strings import connect_panel
from dzgui.views.components.buttons import WebButton
from dzgui.views.components.labels import BoldLabel
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 ConnectPanel(Gtk.Frame):
def __init__(self) -> None:
def __init__(self, controller: "Controller") -> None:
super().__init__(margin_top=10, margin_bottom=5)
self.label = Gtk.Label(label="Add/connect")
self.label2 = Gtk.Label(label="Favorite server")
COLS = 1
ROWS = 1
self.controller = controller
# TODO: strings
text = embolden("Favorite server")
self.label2.set_markup(text)
self.entry1 = Gtk.Entry(placeholder_text="Enter IP or Battlemetrics ID", hexpand=False)
self.entry2 = Gtk.Entry()
self.fav = Gtk.Label(label="MY favorite server very long title")
self.favedit = Gtk.Button("Edit")
self.edit = WebButton(label="EDIT")
self.favbutton = Gtk.Button(label="Connect")
self.entry = Gtk.Entry(
placeholder_text=connect_panel.placeholder,
hexpand=True,
tooltip_text=connect_panel.entry_tooltip
)
# TODO: dedent
long = """IP: Format as IP:Query port, e.g.\n192.168.1.1:27016\n
Battlemetrics: numeric server ID
"""
# TODO: get ip as well?
user_fav = self.controller.get_favorite_label()
# TODO: add tooltips to all buttons
self.entry1.set_tooltip_text(long)
server_name = user_fav if user_fav is not None else connect_panel.no_fav
scrollable_label = Gtk.ScrolledWindow()
label = Gtk.Label(label=server_name, halign=Gtk.Align.START)
scrollable_label.add(label)
self.con = Gtk.Button(label="Connect")
self.addb = Gtk.Button(label="Add")
self.fav_button = Gtk.Button(label=connect_panel.connect,
tooltip_text=connect_panel.connect_tooltip
)
self.fav_edit = Gtk.Button(label=connect_panel.edit)
self.edit_server = WebButton(label="EDIT")
self.conn_server= Gtk.Button(label=connect_panel.connect,
tooltip_text=connect_panel.connect_tooltip
)
self.add_server = Gtk.Button(label=connect_panel.add,
tooltip_text=connect_panel.add_tooltip
)
self.conn_server.set_sensitive(False)
self.add_server.set_sensitive(False)
if server_name is None:
self.fav_button.set_sensitive(False)
add_label = BoldLabel(connect_panel.add_con)
conn_label = BoldLabel(connect_panel.favorite)
self.grid = Gtk.Grid(margin=10, vexpand=False, column_spacing=15, row_spacing=5)
self.grid.attach(self.label2, 0, 0, 3, 1)
button = Gtk.Button(label="Connect")
self.grid.attach_next_to(self.fav, self.label2, Gtk.PositionType.RIGHT, 3, 1)
self.grid.attach_next_to(self.favbutton, self.fav, Gtk.PositionType.RIGHT, 3, 1)
self.grid.attach_next_to(self.label, self.label2, Gtk.PositionType.BOTTOM, 3, 1)
self.grid.attach_next_to(self.entry1, self.label, Gtk.PositionType.RIGHT, 3, 1)
self.grid.attach_next_to(self.addb, self.entry1, Gtk.PositionType.RIGHT, 3, 1)
self.grid.attach_next_to(self.con, self.addb, Gtk.PositionType.RIGHT, 3, 1)
self.grid.attach(conn_label, 0, 0, COLS, ROWS)
els = (
(scrollable_label, conn_label, Gtk.PositionType.RIGHT, 3, ROWS),
(self.fav_button, scrollable_label, Gtk.PositionType.RIGHT, COLS, ROWS),
(add_label, conn_label, Gtk.PositionType.BOTTOM, COLS, ROWS),
(self.entry, scrollable_label, Gtk.PositionType.BOTTOM, COLS, ROWS),
(self.add_server, self.fav_button, Gtk.PositionType.BOTTOM, COLS, ROWS),
(self.conn_server, self.add_server, Gtk.PositionType.RIGHT, COLS, ROWS),
)
for el, sibling, pos, h_span, v_span in els:
self.grid.attach_next_to(el, sibling, pos, h_span, v_span)
self.add(self.grid)
+12 -17
View File
@@ -1,15 +1,15 @@
import logging
from typing import Literal
import gi # noqa E402
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk, Gdk, Pango, GLib
from typing import Literal
from dzgui.util import strings
from dzgui.util.format import embolden
from dzgui.util.margins import set_surrounding_margins
from dzgui.const.enum import FilterMode
from dzgui.const.constants import NO_EXPAND, NO_FILL, NO_PADDING
from dzgui.util import strings
from dzgui.util.margins import set_surrounding_margins
from dzgui.views.components.labels import BoldLabel
logger = logging.getLogger(__name__)
@@ -17,7 +17,6 @@ class FilterPanel(Gtk.Box):
def __init__(self, controller):
super().__init__(spacing=6, vexpand=False)
# TODO: set strings in constants
self.default_filters = {
strings.filter_1pp: True,
strings.filter_day: True,
@@ -39,10 +38,11 @@ class FilterPanel(Gtk.Box):
self.checks = []
self.maps_hr = []
self.enabled_filters = dict(self.default_filters)
self.keyword_filter = ""
self.selected_map = strings.all_maps
self.prior_map = strings.all_maps
self.keyword_filter: str
self.selected_map: str = strings.all_maps
self.prior_map: str = strings.all_maps
button_grid = Gtk.Grid(
halign=Gtk.Align.CENTER, column_spacing=5, column_homogeneous=True
@@ -72,9 +72,7 @@ class FilterPanel(Gtk.Box):
self.set_margin_top(1)
# TODO: strings
text = embolden("Filters")
self.filters_label = Gtk.Label()
self.filters_label.set_markup(text)
self.filters_label = BoldLabel("Filters")
self.keyword_entry = Gtk.Entry()
self.keyword_entry.set_placeholder_text("Filter by keyword")
@@ -99,16 +97,13 @@ class FilterPanel(Gtk.Box):
self.maps_entry.connect("key-press-event", self._on_map_entry_keypress)
# FIXME: only giving two params to pack_start
# cf. EXPAND
# cf. EXPAND, NO_EXPAND
self.maps_combo.pack_start(renderer_text, True)
self.maps_combo.connect("changed", self._on_map_changed)
self.maps_combo.connect("key-press-event", self._on_combo_keypress)
# TODO: consolidate
self.pack_start(self.filters_label, NO_EXPAND, NO_FILL, NO_PADDING)
self.pack_start(self.keyword_entry, NO_EXPAND, NO_FILL, NO_PADDING)
self.pack_start(self.maps_combo, NO_EXPAND, NO_FILL, NO_PADDING)
self.pack_start(button_grid, NO_EXPAND, NO_FILL, NO_PADDING)
for el in self.filters_label, self.keyword_entry, self.maps_combo, button_grid:
self.pack_start(el, NO_EXPAND, NO_FILL, NO_PADDING)
def set_unique_maps(self, maps: list) -> None:
if len(maps) < 1:
+2 -4
View File
@@ -3,7 +3,7 @@ from typing import TYPE_CHECKING
from dzgui.const.enum import ModButton
from dzgui.const.constants import NO_EXPAND, FILL, NO_PADDING
from dzgui.util.strings import mod_panel
from dzgui.util.format import embolden
from dzgui.views.components.labels import BoldLabel
import gi
gi.require_version("Gtk", "3.0")
@@ -27,9 +27,7 @@ class ModSelectionPanel(Gtk.Box):
self.controller = controller
header = Gtk.Label()
text = embolden(mod_panel.header)
header.set_markup(text)
header = BoldLabel(mod_panel.header)
self.main_panel = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
buttons = (
+41 -82
View File
@@ -7,8 +7,7 @@ from dzgui.views.components.buttonbox import ButtonBox
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.web_button import RefreshButton
# TODO: rename web_button
from dzgui.views.components.buttons import RefreshButton, KeysButton
from dzgui.const.constants import NO_EXPAND, NO_FILL, EXPAND, FILL, INPUT_KEYBOARD, NO_PADDING
from dzgui.util import strings
@@ -17,71 +16,31 @@ class RightPanel(Gtk.Box):
def __init__(self, controller):
super().__init__(spacing=6, orientation=Gtk.Orientation.VERTICAL)
self.controller = controller
self.controller.register_widget("right_panel", self)
self.button_vbox = ButtonBox(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
self.ping = Gtk.Button(
label=strings.ping_servers,
margin_top=10,
margin_start=80,
margin_end=80,
tooltip_text=strings.ping_tooltip,
)
self.ping.connect("clicked", self._on_ping_clicked)
# TODO: drop after adding context menu row
self.debug_toggle = Gtk.ToggleButton(
label=strings.debug_mode,
margin_top=10,
margin_start=80,
margin_end=80,
tooltip_text=strings.debug_tooltip,
)
# TODO: icon
# TODO: strings, move strings into buttons.py
self.refresh_button = RefreshButton("Refresh")
self.refresh_button.set_margin_top(10)
self.refresh_button.set_margin_start(80)
self.refresh_button.set_margin_end(80)
# TODO: tooltip, strings
# TODO: update refresh button sensitivity on cooldown
self.refresh_button.set_tooltip_text("Refresh server data")
self.refresh_button.connect("clicked", self._on_refresh_clicked)
#if controller.query_config(Preferences.DEBUG) == True:
# self.debug_toggle.set_active(True)
#self.debug_toggle.connect("toggled", self._on_debug_toggled)
# TODO: make button class
i = Icon(INPUT_KEYBOARD)
i.set_margin_start(5)
self.keys = Gtk.Button(
label=strings.keys_button,
margin_start=80,
margin_end=80,
tooltip_text=strings.keys_tooltip,
image = i,
)
self.keys.set_image_position(Gtk.PositionType.RIGHT)
self.keys = KeysButton(strings.keys_button)
self.keys.set_tooltip_text(strings.keys_tooltip)
self.keys.connect("clicked", self._on_question_clicked)
for el in self.button_vbox, self.filters_vbox, self.refresh_button:
for el in self.button_vbox, self.keys, self.filters_vbox, self.refresh_button:
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:
self.ping.set_visible(state)
# TODO: move to filter panel
def reinit_maps(self, rows: list) -> None:
self.controller.reinit_map_store()
# TODO: communicate with controller
@@ -93,38 +52,38 @@ class RightPanel(Gtk.Box):
def _on_refresh_clicked(self, button: RefreshButton) -> None:
self.controller.refresh_tree()
def _on_ping_clicked(self, button: Gtk.Button) -> None:
# TODO
block_signals()
#def _on_ping_clicked(self, button: Gtk.Button) -> None:
# # TODO
# block_signals()
def _update_pings():
# TODO
rows = ModelManager.get_filtered()
with ThreadPoolExecutor(100) as executor:
futures = [
executor.submit(Servers.ping, i, row)
for i, row in enumerate(rows)
]
wait(futures)
for future in futures:
res = future.result()
path = Gtk.TreePath.new_from_indices([res.iteration])
temp_model[path][9] = res.ping
ModelManager.ping_cache[res.addr] = res.ping
# TODO: drop/rewrite
self.AppNav.treeview.set_model(temp_model)
self.AppNav.treeview.wait_dialog.destroy()
self.AppNav.treeview.grab_focus()
# def _update_pings():
# # TODO
# rows = ModelManager.get_filtered()
# with ThreadPoolExecutor(100) as executor:
# futures = [
# executor.submit(Servers.ping, i, row)
# for i, row in enumerate(rows)
# ]
# wait(futures)
# for future in futures:
# res = future.result()
# path = Gtk.TreePath.new_from_indices([res.iteration])
# temp_model[path][9] = res.ping
# ModelManager.ping_cache[res.addr] = res.ping
# # TODO: drop/rewrite
# self.AppNav.treeview.set_model(temp_model)
# self.AppNav.treeview.wait_dialog.destroy()
# self.AppNav.treeview.grab_focus()
# TODO:
unblock_signals()
# # TODO:
# unblock_signals()
temp_model = self.AppNav.treeview.get_model()
self.AppNav.treeview.set_model(None)
self.AppNav.treeview.wait_dialog = GenericDialog("Pinging servers", Popup.WAIT)
self.AppNav.treeview.wait_dialog.show_all()
thread = threading.Thread(target=_update_pings, args=())
thread.start()
# temp_model = self.AppNav.treeview.get_model()
# self.AppNav.treeview.set_model(None)
# self.AppNav.treeview.wait_dialog = GenericDialog("Pinging servers", Popup.WAIT)
# self.AppNav.treeview.wait_dialog.show_all()
# thread = threading.Thread(target=_update_pings, args=())
# thread.start()
def _on_question_clicked(self, button: Gtk.Button) -> None:
self.controller.open_keybindings()