diff --git a/dzgui/const/constants.py b/dzgui/const/constants.py index b98c8c9..c2c5956 100644 --- a/dzgui/const/constants.py +++ b/dzgui/const/constants.py @@ -30,6 +30,9 @@ APP_NAME_ABBR = "dzg" HEX_RED = "#FF0000" HEX_ORANGE = "#FFAC1C" +CLIPBOARD = "edit-copy-symbolic" +LIST_ADD = "list-add-symbolic" +STEAM_ICON = "steam_tray_mono" VIEW_CONCEAL = "view-conceal-symbolic" VIEW_REVEAL = "view-reveal-symbolic" INPUT_KEYBOARD = "input-keyboard-symbolic" diff --git a/dzgui/controllers/mc.py b/dzgui/controllers/mc.py index 9813734..15d5bdf 100644 --- a/dzgui/controllers/mc.py +++ b/dzgui/controllers/mc.py @@ -696,12 +696,13 @@ class Controller: case _: 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)) if len(fav) < 1: - return None - return fav - + return None, None + ip = str(self.query_config(Preferences.FAV_SRV)) + return fav, ip + def get_dist_cache(self) -> dict[str, "Haversine"]: return self.dist_cache diff --git a/dzgui/util/strings.py b/dzgui/util/strings.py index 037b8e6..d4da3c4 100644 --- a/dzgui/util/strings.py +++ b/dzgui/util/strings.py @@ -140,7 +140,7 @@ vim = { "k": "Move up a row/scroll down", "l": "Jump to main area from sidebar", "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", } key_contexts = ["Servers", "Navigation", "Vim-style keys"] diff --git a/dzgui/views/components/buttons.py b/dzgui/views/components/buttons.py index 2bcbe7e..b6edada 100644 --- a/dzgui/views/components/buttons.py +++ b/dzgui/views/components/buttons.py @@ -1,25 +1,61 @@ -from dzgui.util.strings import refresh -from dzgui.views.components.icon import Icon -from dzgui.const.constants import REFRESH_ICON, WEB_BROWSER, INPUT_KEYBOARD +from dzgui.util.strings import refresh, connect_panel +from dzgui.const.constants import ( + CLIPBOARD, + INPUT_KEYBOARD, + LIST_ADD, + REFRESH_ICON, + STEAM_ICON, + WEB_BROWSER, +) import gi gi.require_version("Gtk", "3.0") 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): def __init__(self, icon: str, margin: int = 0) -> None: super().__init__() - i = Icon(icon, l_margin=margin) - self.set_image(i) + self.icon = Icon(icon, l_margin=margin) + self.set_image(self.icon) self.set_image_position(Gtk.PositionType.RIGHT) + class IconTextButton(IconButton): def __init__(self, icon: str, label: str) -> None: super().__init__(icon, margin=5) 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): def __init__(self, label: str) -> None: super().__init__(icon=WEB_BROWSER, label=label) @@ -33,9 +69,28 @@ class RefreshButton(IconTextButton): self.set_margin_start(80) self.set_margin_end(80) + class KeysButton(IconTextButton): def __init__(self, label: str) -> None: super().__init__(icon=INPUT_KEYBOARD, label=label) self.set_margin_top(10) self.set_margin_start(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) diff --git a/dzgui/views/components/connect_panel.py b/dzgui/views/components/connect_panel.py index d69b498..4e96ab2 100644 --- a/dzgui/views/components/connect_panel.py +++ b/dzgui/views/components/connect_panel.py @@ -4,7 +4,7 @@ from dzgui.api.servers import validate_ip from dzgui.const.constants import NO_EXPAND, NO_FILL, NO_PADDING from dzgui.util.css import add_class, remove_class 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 import gi @@ -23,13 +23,14 @@ class LanPanel(Gtk.Frame): hbox = Gtk.Box(margin=10, spacing=5, halign=Gtk.Align.START) # TODO: strings label = BoldLabel("LAN query port") + self.set_label_widget(label) radio1 = Gtk.RadioButton.new_with_label(None, "Default port (27016)") radio2 = Gtk.RadioButton.new_from_widget(radio1) radio2.set_label("Custom port") self.entry = Gtk.Entry(placeholder_text="Query port") self.button = Gtk.Button(label="Scan") 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(radio2, 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("changed", self._on_text_changed) - # TODO: get ip as well? - user_fav = self.controller.get_favorite_label() + user_fav, user_ip = self.controller.get_favorite() - server_name = user_fav if user_fav is not None else connect_panel.no_fav - self.fav_label = Gtk.Label(label=server_name, halign=Gtk.Align.START) + 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, track_visited_links=False, halign=Gtk.Align.START, hexpand=True) scrollable_label = Gtk.ScrolledWindow() scrollable_label.add(self.fav_label) - self.fav_button = Gtk.Button(label=connect_panel.connect, - tooltip_text=connect_panel.connect_tooltip - ) + self.fav_button = SteamConnectButton() 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.add_server = AddButton() + self.conn_server = SteamConnectButton() self.conn_server.set_sensitive(False) self.add_server.set_sensitive(False) @@ -89,14 +82,15 @@ class ConnectPanel(Gtk.Box): conn_label = BoldLabel(connect_panel.favorite) 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 = ( - (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), + #(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.entry, 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.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) self.add(frame) 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: self.conn_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: # TODO: called by controller when changing fav + # TODO: href logic self.fav_label.set_text(text) def _on_entry_keypress(self, entry: Gtk.Entry, event: Gdk.EventKey) -> None: diff --git a/dzgui/views/components/right_panel.py b/dzgui/views/components/right_panel.py index 4f81e7e..4874901 100644 --- a/dzgui/views/components/right_panel.py +++ b/dzgui/views/components/right_panel.py @@ -8,7 +8,6 @@ from dzgui.const.enum import Preferences 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.buttons import RefreshButton, KeysButton 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 @@ -35,8 +34,9 @@ class RightPanel(Gtk.Box): self.refresh_button.connect("clicked", self._on_refresh_clicked) self.keys = KeysButton(keys_button) + self.keys.set_focus_on_click(False) 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: 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.start() - def _on_question_clicked(self, button: Gtk.Button) -> None: + def _on_keys_clicked(self, button: Gtk.Button) -> None: self.controller.open_keybindings() def focus_button_box(self) -> None: diff --git a/dzgui/views/dialogs/link_dialog.py b/dzgui/views/dialogs/link_dialog.py index b5db94f..ba7cded 100644 --- a/dzgui/views/dialogs/link_dialog.py +++ b/dzgui/views/dialogs/link_dialog.py @@ -5,7 +5,7 @@ from dzgui.const.enum import Popup, Preferences from dzgui.const.constants import NO_EXPAND, NO_FILL from dzgui.util.open_links import open_user_workshop from dzgui.views.dialogs.generic import GenericDialog -from dzgui.views.components.buttons import WebButton +from dzgui.views.components.buttons import SteamTextButton, WebButton import gi gi.require_version("Gtk", "3.0") @@ -30,7 +30,7 @@ class WorkshopLinkDialog(GenericDialog): a clickable link to their workshop subscriptions is added """ if uid is not None: - button = WebButton(label=button_label) + button = SteamTextButton(label=button_label) button.set_margin_start(60) button.set_margin_end(60) button.connect("clicked", self._on_button_clicked, uid) diff --git a/dzgui/views/pages/options.py b/dzgui/views/pages/options.py index 8d6fe55..8cf053c 100644 --- a/dzgui/views/pages/options.py +++ b/dzgui/views/pages/options.py @@ -416,9 +416,9 @@ class Options(Gtk.Box): frame = Gtk.Frame(hexpand=True) frame.add(widget) + frame.set_label_widget(label) box = Gtk.Box(orientation=Gtk.Orientation.VERTICAL) - box.add(label) box.add(frame) return box diff --git a/dzgui/views/trees/tree_servers.py b/dzgui/views/trees/tree_servers.py index d70aba8..4975cac 100644 --- a/dzgui/views/trees/tree_servers.py +++ b/dzgui/views/trees/tree_servers.py @@ -28,8 +28,6 @@ if TYPE_CHECKING: from dzgui.controllers.mc import Controller # TODO: restore missing methods -# TODO: add multiprocessing queue -# TODO: fix cache class EnumeratedMenuItem(Gtk.MenuItem): def __init__(self, enum: ContextMenu): @@ -190,7 +188,8 @@ class ServerTreeView(TreeView): if latest_result: addr = latest_result[0] haversine = latest_result[1] - cache[addr] = haversine + if addr not in cache: + cache[addr] = haversine # FIXME self.controller.set_statusbar_dist(haversine) return True