feat: connect panel WIP

This commit is contained in:
aclist 2026-01-11 01:52:29 +09:00
parent e2ec093f67
commit 59ef15073f
9 changed files with 111 additions and 42 deletions

View File

@ -30,6 +30,9 @@ APP_NAME_ABBR = "dzg"
HEX_RED = "#FF0000" HEX_RED = "#FF0000"
HEX_ORANGE = "#FFAC1C" HEX_ORANGE = "#FFAC1C"
CLIPBOARD = "edit-copy-symbolic"
LIST_ADD = "list-add-symbolic"
STEAM_ICON = "steam_tray_mono"
VIEW_CONCEAL = "view-conceal-symbolic" VIEW_CONCEAL = "view-conceal-symbolic"
VIEW_REVEAL = "view-reveal-symbolic" VIEW_REVEAL = "view-reveal-symbolic"
INPUT_KEYBOARD = "input-keyboard-symbolic" INPUT_KEYBOARD = "input-keyboard-symbolic"

View File

@ -696,12 +696,13 @@ class Controller:
case _: case _:
return False return False
def get_favorite_label(self) -> str | None: def get_favorite(self) -> tuple[str, str] | tuple[None, None]:
fav = str(self.query_config(Preferences.FAV_LBL)) fav = str(self.query_config(Preferences.FAV_LBL))
if len(fav) < 1: if len(fav) < 1:
return None return None, None
return fav ip = str(self.query_config(Preferences.FAV_SRV))
return fav, ip
def get_dist_cache(self) -> dict[str, "Haversine"]: def get_dist_cache(self) -> dict[str, "Haversine"]:
return self.dist_cache return self.dist_cache

View File

@ -140,7 +140,7 @@ vim = {
"k": "Move up a row/scroll down", "k": "Move up a row/scroll down",
"l": "Jump to main area from sidebar", "l": "Jump to main area from sidebar",
"h": "Jump to sidebar from main area", "h": "Jump to sidebar from main area",
"gg": "Jump to first row/top of page", "g": "Jump to first row/top of page",
"G": "Jump to last row/bottom of page", "G": "Jump to last row/bottom of page",
} }
key_contexts = ["Servers", "Navigation", "Vim-style keys"] key_contexts = ["Servers", "Navigation", "Vim-style keys"]

View File

@ -1,25 +1,61 @@
from dzgui.util.strings import refresh from dzgui.util.strings import refresh, connect_panel
from dzgui.views.components.icon import Icon from dzgui.const.constants import (
from dzgui.const.constants import REFRESH_ICON, WEB_BROWSER, INPUT_KEYBOARD CLIPBOARD,
INPUT_KEYBOARD,
LIST_ADD,
REFRESH_ICON,
STEAM_ICON,
WEB_BROWSER,
)
import gi import gi
gi.require_version("Gtk", "3.0") gi.require_version("Gtk", "3.0")
from gi.repository import Gtk # noqa E402 from gi.repository import Gtk # noqa E402
class Icon(Gtk.Image):
def __init__(self, name: str, l_margin=0) -> None:
super().__init__(icon_name=name,
icon_size=Gtk.IconSize.BUTTON,
margin_start=l_margin,
ypad=2,
)
class LargeIcon(Gtk.Image):
def __init__(self, name: str, l_margin=5) -> None:
super().__init__(icon_name=name,
icon_size=Gtk.IconSize.LARGE_TOOLBAR,
margin_start=l_margin
)
class IconButton(Gtk.Button): class IconButton(Gtk.Button):
def __init__(self, icon: str, margin: int = 0) -> None: def __init__(self, icon: str, margin: int = 0) -> None:
super().__init__() super().__init__()
i = Icon(icon, l_margin=margin) self.icon = Icon(icon, l_margin=margin)
self.set_image(i) self.set_image(self.icon)
self.set_image_position(Gtk.PositionType.RIGHT) self.set_image_position(Gtk.PositionType.RIGHT)
class IconTextButton(IconButton): class IconTextButton(IconButton):
def __init__(self, icon: str, label: str) -> None: def __init__(self, icon: str, label: str) -> None:
super().__init__(icon, margin=5) super().__init__(icon, margin=5)
self.set_label(label) self.set_label(label)
class LargeIconTextButton(IconButton):
def __init__(self, icon: str, label: str) -> None:
super().__init__(icon)
self.set_label(label)
self.set_image(LargeIcon(icon))
class ClipboardButton(IconButton):
def __init__(self) -> None:
super().__init__(CLIPBOARD)
class WebButton(IconTextButton): class WebButton(IconTextButton):
def __init__(self, label: str) -> None: def __init__(self, label: str) -> None:
super().__init__(icon=WEB_BROWSER, label=label) super().__init__(icon=WEB_BROWSER, label=label)
@ -33,9 +69,28 @@ class RefreshButton(IconTextButton):
self.set_margin_start(80) self.set_margin_start(80)
self.set_margin_end(80) self.set_margin_end(80)
class KeysButton(IconTextButton): class KeysButton(IconTextButton):
def __init__(self, label: str) -> None: def __init__(self, label: str) -> None:
super().__init__(icon=INPUT_KEYBOARD, label=label) super().__init__(icon=INPUT_KEYBOARD, label=label)
self.set_margin_top(10) self.set_margin_top(10)
self.set_margin_start(80) self.set_margin_start(80)
self.set_margin_end(80) self.set_margin_end(80)
class SteamConnectButton(LargeIconTextButton):
def __init__(self) -> None:
super().__init__(icon=STEAM_ICON, label=connect_panel.connect)
self.set_tooltip_text(connect_panel.connect_tooltip)
class SteamTextButton(SteamConnectButton):
def __init__(self, label: str) -> None:
super().__init__()
self.set_label(label)
class AddButton(IconTextButton):
def __init__(self) -> None:
super().__init__(icon=LIST_ADD, label=connect_panel.add)
self.set_tooltip_text(connect_panel.add_tooltip)

View File

@ -4,7 +4,7 @@ from dzgui.api.servers import validate_ip
from dzgui.const.constants import NO_EXPAND, NO_FILL, NO_PADDING from dzgui.const.constants import NO_EXPAND, NO_FILL, NO_PADDING
from dzgui.util.css import add_class, remove_class from dzgui.util.css import add_class, remove_class
from dzgui.util.strings import connect_panel from dzgui.util.strings import connect_panel
from dzgui.views.components.buttons import WebButton from dzgui.views.components.buttons import AddButton, ClipboardButton, IconTextButton, SteamConnectButton, WebButton
from dzgui.views.components.labels import BoldLabel from dzgui.views.components.labels import BoldLabel
import gi import gi
@ -23,13 +23,14 @@ class LanPanel(Gtk.Frame):
hbox = Gtk.Box(margin=10, spacing=5, halign=Gtk.Align.START) hbox = Gtk.Box(margin=10, spacing=5, halign=Gtk.Align.START)
# TODO: strings # TODO: strings
label = BoldLabel("LAN query port") label = BoldLabel("LAN query port")
self.set_label_widget(label)
radio1 = Gtk.RadioButton.new_with_label(None, "Default port (27016)") radio1 = Gtk.RadioButton.new_with_label(None, "Default port (27016)")
radio2 = Gtk.RadioButton.new_from_widget(radio1) radio2 = Gtk.RadioButton.new_from_widget(radio1)
radio2.set_label("Custom port") radio2.set_label("Custom port")
self.entry = Gtk.Entry(placeholder_text="Query port") self.entry = Gtk.Entry(placeholder_text="Query port")
self.button = Gtk.Button(label="Scan") self.button = Gtk.Button(label="Scan")
radio1.connect("toggled", self._on_radio_toggled) radio1.connect("toggled", self._on_radio_toggled)
hbox.pack_start(label, NO_EXPAND, NO_FILL, NO_PADDING) #hbox.pack_start(label, NO_EXPAND, NO_FILL, NO_PADDING)
hbox.pack_start(radio1, NO_EXPAND, NO_FILL, NO_PADDING) hbox.pack_start(radio1, NO_EXPAND, NO_FILL, NO_PADDING)
hbox.pack_start(radio2, NO_EXPAND, NO_FILL, NO_PADDING) hbox.pack_start(radio2, NO_EXPAND, NO_FILL, NO_PADDING)
hbox.pack_start(self.entry, NO_EXPAND, NO_FILL, NO_PADDING) hbox.pack_start(self.entry, NO_EXPAND, NO_FILL, NO_PADDING)
@ -59,26 +60,18 @@ class ConnectPanel(Gtk.Box):
self.entry.connect("key-press-event", self._on_entry_keypress) self.entry.connect("key-press-event", self._on_entry_keypress)
self.entry.connect("changed", self._on_text_changed) self.entry.connect("changed", self._on_text_changed)
# TODO: get ip as well? user_fav, user_ip = self.controller.get_favorite()
user_fav = self.controller.get_favorite_label()
server_name = user_fav if user_fav is not None else connect_panel.no_fav server_name = f"{user_fav} ({user_ip})" if user_fav is not None else connect_panel.no_fav
self.fav_label = Gtk.Label(label=server_name, halign=Gtk.Align.START) self.fav_label = Gtk.Label(label=server_name, track_visited_links=False, halign=Gtk.Align.START, hexpand=True)
scrollable_label = Gtk.ScrolledWindow() scrollable_label = Gtk.ScrolledWindow()
scrollable_label.add(self.fav_label) scrollable_label.add(self.fav_label)
self.fav_button = Gtk.Button(label=connect_panel.connect, self.fav_button = SteamConnectButton()
tooltip_text=connect_panel.connect_tooltip
)
self.fav_edit = Gtk.Button(label=connect_panel.edit) self.fav_edit = Gtk.Button(label=connect_panel.edit)
self.edit_server = WebButton(label="EDIT")
self.conn_server= Gtk.Button(label=connect_panel.connect, self.add_server = AddButton()
tooltip_text=connect_panel.connect_tooltip self.conn_server = SteamConnectButton()
)
self.add_server = Gtk.Button(label=connect_panel.add,
tooltip_text=connect_panel.add_tooltip
)
self.conn_server.set_sensitive(False) self.conn_server.set_sensitive(False)
self.add_server.set_sensitive(False) self.add_server.set_sensitive(False)
@ -89,14 +82,15 @@ class ConnectPanel(Gtk.Box):
conn_label = BoldLabel(connect_panel.favorite) conn_label = BoldLabel(connect_panel.favorite)
self.grid = Gtk.Grid(margin=10, vexpand=False, column_spacing=15, row_spacing=5) self.grid = Gtk.Grid(margin=10, vexpand=False, column_spacing=15, row_spacing=5)
self.grid.attach(conn_label, 0, 0, COLS, ROWS) #self.grid.attach(conn_label, 0, 0, COLS, ROWS)
self.grid.attach(self.entry, 0, 0, COLS, ROWS)
els = ( els = (
(scrollable_label, conn_label, Gtk.PositionType.RIGHT, 3, ROWS), #(scrollable_label, conn_label, Gtk.PositionType.RIGHT, 3, ROWS),
(self.fav_button, scrollable_label, Gtk.PositionType.RIGHT, COLS, ROWS), #(self.fav_button, scrollable_label, Gtk.PositionType.RIGHT, COLS, ROWS),
(add_label, conn_label, Gtk.PositionType.BOTTOM, COLS, ROWS), #(add_label, conn_label, Gtk.PositionType.BOTTOM, COLS, ROWS),
(self.entry, scrollable_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.add_server, self.entry, Gtk.PositionType.RIGHT, COLS, ROWS),
(self.conn_server, self.add_server, Gtk.PositionType.RIGHT, COLS, ROWS), (self.conn_server, self.add_server, Gtk.PositionType.RIGHT, COLS, ROWS),
) )
@ -106,12 +100,28 @@ class ConnectPanel(Gtk.Box):
self.lan = LanPanel(self.controller) self.lan = LanPanel(self.controller)
self.add(self.lan) self.add(self.lan)
frame = Gtk.Frame(margin_top=10, margin_bottom=5) label = BoldLabel("Favorite server")
frame = Gtk.Frame(margin_top=10, margin_bottom=5, label_widget=label)
b = ClipboardButton()
b.set_tooltip_text("Copy IP to clipboard")
b.connect("clicked", self._on_ip_clicked, user_ip)
grid = Gtk.Grid(margin=10, vexpand=False, column_spacing=15, row_spacing=5)
grid.attach(scrollable_label, 0, 0, 3, ROWS)
grid.attach_next_to(b, scrollable_label, Gtk.PositionType.RIGHT, COLS, ROWS)
grid.attach_next_to(self.fav_button, b, Gtk.PositionType.RIGHT, COLS, ROWS)
frame.add(grid)
self.add(frame)
label = BoldLabel("Connect")
frame = Gtk.Frame(margin_top=10, margin_bottom=5, label_widget=label)
frame.add(self.grid) frame.add(self.grid)
self.add(frame) self.add(frame)
self.lan.set_visible(False) self.lan.set_visible(False)
def _on_ip_clicked(self, button: Gtk.Button, ip: str) -> None:
self.controller.copy_clipboard(ip)
def mark_valid(self) -> None: def mark_valid(self) -> None:
self.conn_server.set_sensitive(True) self.conn_server.set_sensitive(True)
self.add_server.set_sensitive(True) self.add_server.set_sensitive(True)
@ -141,6 +151,7 @@ class ConnectPanel(Gtk.Box):
def set_fav_label(self, text: str) -> None: def set_fav_label(self, text: str) -> None:
# TODO: called by controller when changing fav # TODO: called by controller when changing fav
# TODO: href logic
self.fav_label.set_text(text) self.fav_label.set_text(text)
def _on_entry_keypress(self, entry: Gtk.Entry, event: Gdk.EventKey) -> None: def _on_entry_keypress(self, entry: Gtk.Entry, event: Gdk.EventKey) -> None:

View File

@ -8,7 +8,6 @@ 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.mod_panel import ModSelectionPanel
from dzgui.views.components.icon import Icon
from dzgui.views.components.buttons import RefreshButton, KeysButton 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.const.constants import NO_EXPAND, NO_FILL, EXPAND, FILL, INPUT_KEYBOARD, NO_PADDING
from dzgui.util.strings import refresh_tooltip, refresh, keys_button, keys_tooltip from dzgui.util.strings import refresh_tooltip, refresh, keys_button, keys_tooltip
@ -35,8 +34,9 @@ class RightPanel(Gtk.Box):
self.refresh_button.connect("clicked", self._on_refresh_clicked) self.refresh_button.connect("clicked", self._on_refresh_clicked)
self.keys = KeysButton(keys_button) self.keys = KeysButton(keys_button)
self.keys.set_focus_on_click(False)
self.keys.set_tooltip_text(keys_tooltip) self.keys.set_tooltip_text(keys_tooltip)
self.keys.connect("clicked", self._on_question_clicked) self.keys.connect("clicked", self._on_keys_clicked)
for el in self.button_vbox, self.keys, 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(el, NO_EXPAND, FILL, NO_PADDING)
@ -100,7 +100,7 @@ class RightPanel(Gtk.Box):
# thread = threading.Thread(target=_update_pings, args=()) # thread = threading.Thread(target=_update_pings, args=())
# thread.start() # thread.start()
def _on_question_clicked(self, button: Gtk.Button) -> None: def _on_keys_clicked(self, button: Gtk.Button) -> None:
self.controller.open_keybindings() self.controller.open_keybindings()
def focus_button_box(self) -> None: def focus_button_box(self) -> None:

View File

@ -5,7 +5,7 @@ from dzgui.const.enum import Popup, Preferences
from dzgui.const.constants import NO_EXPAND, NO_FILL from dzgui.const.constants import NO_EXPAND, NO_FILL
from dzgui.util.open_links import open_user_workshop from dzgui.util.open_links import open_user_workshop
from dzgui.views.dialogs.generic import GenericDialog from dzgui.views.dialogs.generic import GenericDialog
from dzgui.views.components.buttons import WebButton from dzgui.views.components.buttons import SteamTextButton, WebButton
import gi import gi
gi.require_version("Gtk", "3.0") gi.require_version("Gtk", "3.0")
@ -30,7 +30,7 @@ class WorkshopLinkDialog(GenericDialog):
a clickable link to their workshop subscriptions is added a clickable link to their workshop subscriptions is added
""" """
if uid is not None: if uid is not None:
button = WebButton(label=button_label) button = SteamTextButton(label=button_label)
button.set_margin_start(60) button.set_margin_start(60)
button.set_margin_end(60) button.set_margin_end(60)
button.connect("clicked", self._on_button_clicked, uid) button.connect("clicked", self._on_button_clicked, uid)

View File

@ -416,9 +416,9 @@ class Options(Gtk.Box):
frame = Gtk.Frame(hexpand=True) frame = Gtk.Frame(hexpand=True)
frame.add(widget) frame.add(widget)
frame.set_label_widget(label)
box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL)
box.add(label)
box.add(frame) box.add(frame)
return box return box

View File

@ -28,8 +28,6 @@ if TYPE_CHECKING:
from dzgui.controllers.mc import Controller from dzgui.controllers.mc import Controller
# TODO: restore missing methods # TODO: restore missing methods
# TODO: add multiprocessing queue
# TODO: fix cache
class EnumeratedMenuItem(Gtk.MenuItem): class EnumeratedMenuItem(Gtk.MenuItem):
def __init__(self, enum: ContextMenu): def __init__(self, enum: ContextMenu):
@ -190,7 +188,8 @@ class ServerTreeView(TreeView):
if latest_result: if latest_result:
addr = latest_result[0] addr = latest_result[0]
haversine = latest_result[1] haversine = latest_result[1]
cache[addr] = haversine if addr not in cache:
cache[addr] = haversine
# FIXME # FIXME
self.controller.set_statusbar_dist(haversine) self.controller.set_statusbar_dist(haversine)
return True return True