mirror of
https://github.com/aclist/dztui.git
synced 2026-11-07 10:30:40 +01:00
feat: dzgui 7 alpha
This commit is contained in:
1 parent
1acdbd58c5
commit
2e5b771137
150 files changed
+10359
No files matched your search
@@ -0,0 +1,86 @@
|
||||
import logging
|
||||
import functools
|
||||
|
||||
import gi # noqa E402
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
from dzgui.const.enum import ButtonType
|
||||
from dzgui.const.enum import NotebookPage
|
||||
from dzgui.const.enum import RowType
|
||||
from dzgui.const.constants import NO_EXPAND, NO_FILL, EXPAND, FILL
|
||||
|
||||
from typing import Callable
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class ContextualButton(Gtk.Button):
|
||||
def __init__(self, label, opens, tooltip, context):
|
||||
super().__init__(
|
||||
label=label,
|
||||
tooltip_text=tooltip
|
||||
)
|
||||
|
||||
self.context = context
|
||||
self.opens = opens
|
||||
|
||||
class ButtonBox(Gtk.Box):
|
||||
def __init__(self, controller):
|
||||
super().__init__(
|
||||
spacing=6,
|
||||
margin_top=0,
|
||||
margin_start=10,
|
||||
margin_end=10,
|
||||
orientation=Gtk.Orientation.VERTICAL,
|
||||
)
|
||||
|
||||
self.prior_button = ButtonType.MAIN_MENU
|
||||
self.controller = controller
|
||||
self.buttons = list()
|
||||
self.connect("key-press-event", self._on_keypress)
|
||||
prefs = controller.get_prefs()
|
||||
|
||||
for side_button in ButtonType:
|
||||
button = ContextualButton(
|
||||
label=side_button.dict["label"],
|
||||
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)
|
||||
x, y = size
|
||||
button.set_size_request(x, y)
|
||||
|
||||
self.buttons.append(button)
|
||||
button.connect("clicked", self._on_selection_button_clicked)
|
||||
self.pack_start(button, NO_EXPAND, NO_FILL, 0)
|
||||
|
||||
|
||||
def _on_selection_button_clicked(self, button: Gtk.Button) -> None:
|
||||
self.controller.open_page_by_button(button)
|
||||
|
||||
def _walk_buttons(self, increment: int) -> None:
|
||||
for i, button in enumerate(self.buttons):
|
||||
if button.is_focus():
|
||||
n = i + increment
|
||||
if n == len(self.buttons):
|
||||
return
|
||||
if n == -1:
|
||||
return
|
||||
n = self.buttons[n]
|
||||
n.grab_focus()
|
||||
return
|
||||
|
||||
def _on_keypress(self, widget: Gtk.Widget, event: Gdk.EventKey) -> None:
|
||||
match event.keyval:
|
||||
case Gdk.KEY_h:
|
||||
self.controller.focus_notebook()
|
||||
case Gdk.KEY_j:
|
||||
self._walk_buttons(1)
|
||||
case Gdk.KEY_k:
|
||||
self._walk_buttons(-1)
|
||||
case Gdk.KEY_question:
|
||||
self.controller.open_keybindings()
|
||||
@@ -0,0 +1,17 @@
|
||||
import gi # noqa E402
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
class ConnectPanel(Gtk.Grid):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
self.label = Gtk.Label(label="Connect by IP/ID")
|
||||
self.label2 = Gtk.Label(label="Save server by IP/ID")
|
||||
self.entry1 = Gtk.Entry()
|
||||
self.entry2 = Gtk.Entry()
|
||||
|
||||
self.attach(self.label, 0, 0, 3, 1)
|
||||
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)
|
||||
@@ -0,0 +1,38 @@
|
||||
import gi # noqa E402
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
from dzgui.const.constants import HELP_BUBBLE
|
||||
|
||||
class InfoEventBox(Gtk.EventBox):
|
||||
def __init__(self, text: str, parent: Gtk.Widget):
|
||||
super().__init__(margin_start=10)
|
||||
|
||||
self.parent = parent
|
||||
self.text = text
|
||||
|
||||
self.icon = Gtk.Image.new_from_icon_name(
|
||||
HELP_BUBBLE, Gtk.IconSize.LARGE_TOOLBAR
|
||||
)
|
||||
self.icon.set_opacity(0.8)
|
||||
box = Gtk.Box()
|
||||
box.add(self.icon)
|
||||
|
||||
self.connect("enter-notify-event", self._on_enter_tooltip)
|
||||
self.connect("leave-notify-event", self._on_leave_tooltip)
|
||||
self.add(box)
|
||||
|
||||
def _on_enter_tooltip(
|
||||
self, eventbox: Gtk.EventBox, eventcrossing: Gdk.EventCrossing
|
||||
) -> None:
|
||||
self.icon.set_opacity(1)
|
||||
self.parent.controller.set_statusbar(self.text)
|
||||
|
||||
def _on_leave_tooltip(
|
||||
self, eventbox: Gtk.EventBox, eventcrossing: Gdk.EventCrossing
|
||||
) -> None:
|
||||
self.icon.set_opacity(0.8)
|
||||
self.parent.controller.set_statusbar("")
|
||||
|
||||
def set_text(self, text: str) -> None:
|
||||
self.text = text
|
||||
@@ -0,0 +1,286 @@
|
||||
import logging
|
||||
|
||||
import gi # noqa E402
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, Pango
|
||||
|
||||
from typing import Literal
|
||||
from dzgui.util import strings
|
||||
from dzgui.util.margins import set_surrounding_margins
|
||||
from dzgui.const.enum import FilterMode
|
||||
from dzgui.const.constants import NO_EXPAND, NO_FILL
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
class FilterPanel(Gtk.Box):
|
||||
def __init__(self, appnav, controller):
|
||||
super().__init__(spacing=6)
|
||||
|
||||
# TODO: set strings in constants
|
||||
self.default_filters = {
|
||||
strings.filter_1pp: True,
|
||||
strings.filter_day: True,
|
||||
strings.filter_empty: False,
|
||||
strings.filter_3pp: True,
|
||||
strings.filter_night: True,
|
||||
strings.filter_full: False,
|
||||
strings.filter_lowpop: True,
|
||||
strings.filter_nonascii: False,
|
||||
strings.filter_duplicate: False,
|
||||
strings.filter_official: True,
|
||||
strings.filter_unofficial: True,
|
||||
strings.filter_modded: True,
|
||||
}
|
||||
|
||||
self.AppNav = appnav
|
||||
self.controller = controller
|
||||
|
||||
map_store = self.controller.get_map_store()
|
||||
|
||||
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
|
||||
|
||||
button_grid = Gtk.Grid(
|
||||
halign=Gtk.Align.CENTER, column_spacing=5, column_homogeneous=True
|
||||
)
|
||||
row = 1
|
||||
col = 0
|
||||
for check in self.default_filters.keys():
|
||||
checkbox = Gtk.CheckButton(label=check)
|
||||
label = checkbox.get_children()
|
||||
label[0].set_ellipsize(Pango.EllipsizeMode.END)
|
||||
|
||||
if self.default_filters[check]:
|
||||
checkbox.set_active(True)
|
||||
|
||||
col = col + 1
|
||||
if col > 3:
|
||||
row += 1
|
||||
col = 1
|
||||
button_grid.attach(checkbox, col, row, 1, 1)
|
||||
|
||||
checkbox.connect("toggled", self._on_check_toggled)
|
||||
self.checks.append(checkbox)
|
||||
|
||||
self.connect("button-release-event", self._on_button_release)
|
||||
self.set_orientation(Gtk.Orientation.VERTICAL)
|
||||
set_surrounding_margins(self, 10)
|
||||
self.set_margin_top(1)
|
||||
|
||||
self.filters_label = Gtk.Label(label="Filters")
|
||||
|
||||
self.keyword_entry = Gtk.Entry()
|
||||
self.keyword_entry.set_placeholder_text("Filter by keyword")
|
||||
self.keyword_entry.connect("activate", self._on_keyword_enter)
|
||||
self.keyword_entry.connect(
|
||||
"key-press-event", self._on_keyword_keypress
|
||||
)
|
||||
|
||||
completion = Gtk.EntryCompletion(inline_completion=True)
|
||||
completion.set_text_column(0)
|
||||
completion.set_minimum_key_length(1)
|
||||
completion.connect("match_selected", self._on_completer_match)
|
||||
|
||||
renderer_text = Gtk.CellRendererText(ellipsize=Pango.EllipsizeMode.END)
|
||||
self.maps_combo = Gtk.ComboBox.new_with_model_and_entry(map_store)
|
||||
self.maps_combo.set_entry_text_column(0)
|
||||
|
||||
self.maps_entry = self.maps_combo.get_child()
|
||||
self.maps_entry.set_completion(completion)
|
||||
self.maps_entry.set_placeholder_text("Filter by map")
|
||||
self.maps_entry.connect("changed", self._on_map_completion, True)
|
||||
self.maps_entry.connect("key-press-event", self._on_map_entry_keypress)
|
||||
|
||||
# FIXME: only giving two params to pack_start
|
||||
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)
|
||||
|
||||
self.pack_start(self.filters_label, NO_EXPAND, NO_FILL, 0)
|
||||
self.pack_start(self.keyword_entry, NO_EXPAND, NO_FILL, 0)
|
||||
self.pack_start(self.maps_combo, NO_EXPAND, NO_FILL, 0)
|
||||
|
||||
self.pack_start(button_grid, NO_EXPAND, NO_FILL, 0)
|
||||
|
||||
def set_unique_maps(self, maps: list) -> None:
|
||||
if len(maps) < 1:
|
||||
return
|
||||
# FIXME: clear typehints
|
||||
u_maps = set([row[1] for row in maps]) # type: ignore
|
||||
u_maps = sorted(u_maps) # type: ignore
|
||||
for m in u_maps:
|
||||
self.controller.append_map([m])
|
||||
self.maps_hr.append(m)
|
||||
|
||||
def get_filters(self) -> tuple:
|
||||
filters = []
|
||||
filters.append(self.selected_map)
|
||||
filters.append(self.keyword_filter)
|
||||
for k in self.enabled_filters:
|
||||
if not self.enabled_filters[k]:
|
||||
filters.append(k)
|
||||
return tuple(filters)
|
||||
|
||||
# used on personal/local server lists
|
||||
def enable_all_filters(self) -> None:
|
||||
for check in self.checks:
|
||||
check.set_active(True)
|
||||
for k in self.enabled_filters:
|
||||
self.enabled_filters[k] = True
|
||||
|
||||
def reinit_panel(self) -> None:
|
||||
self.keyword_entry.set_text("")
|
||||
self.keyword_filter = ""
|
||||
self.reinit_filters()
|
||||
self.set_visible(False)
|
||||
sel_panel = self.AppNav.grid.sel_panel
|
||||
if sel_panel.is_visible():
|
||||
sel_panel.set_visible(False)
|
||||
|
||||
def reinit_filters(self) -> None:
|
||||
self.enabled_filters = dict(self.default_filters)
|
||||
for check in self.checks:
|
||||
label = check.get_label()
|
||||
state = self.default_filters[label]
|
||||
check.set_active(state)
|
||||
|
||||
def _on_map_entry_keypress(
|
||||
self, entry: Gtk.Entry, event: Gdk.EventKey
|
||||
) -> None:
|
||||
match event.keyval:
|
||||
case Gdk.KEY_Return:
|
||||
text = entry.get_text()
|
||||
if text is None:
|
||||
return
|
||||
"""
|
||||
If entry is exact match for value in liststore,
|
||||
trigger map change function
|
||||
"""
|
||||
for i in enumerate(map_store): # type: ignore
|
||||
if text == i[1][0]:
|
||||
self.maps_combo.set_active(i[0])
|
||||
self._on_map_changed(self.maps_combo)
|
||||
case Gdk.KEY_Escape:
|
||||
GLib.idle_add(self.restore_focus_to_treeview)
|
||||
"""
|
||||
This is a workaround for widget.grab_remove()
|
||||
Sets cursor position to SOL when unfocusing
|
||||
"""
|
||||
text = self.maps_entry.get_text()
|
||||
self.maps_entry.set_position(len(text))
|
||||
case _:
|
||||
return
|
||||
|
||||
def _on_completer_match(
|
||||
self,
|
||||
completion: Gtk.EntryCompletion,
|
||||
model: Gtk.ListStore,
|
||||
it: Gtk.TreeIter,
|
||||
) -> None:
|
||||
self.maps_combo.set_active_iter(it)
|
||||
|
||||
def _on_map_completion(self, entry, editable):
|
||||
text = entry.get_text()
|
||||
completion = entry.get_completion()
|
||||
map_store = self.controller.get_map_store()
|
||||
if len(text) >= completion.get_minimum_key_length():
|
||||
completion.set_model(map_store)
|
||||
|
||||
def restore_focus_to_treeview(self) -> Literal[False]:
|
||||
self.AppNav.treeview.grab_focus()
|
||||
return False
|
||||
|
||||
def _on_keyword_keypress(
|
||||
self, entry: Gtk.Entry, event: Gdk.EventKey
|
||||
) -> bool:
|
||||
match event.keyval:
|
||||
case Gdk.KEY_Up:
|
||||
return True
|
||||
case Gdk.KEY_Down:
|
||||
return True
|
||||
case Gdk.KEY_Escape:
|
||||
GLib.idle_add(self.restore_focus_to_treeview)
|
||||
return True
|
||||
return False
|
||||
|
||||
def _on_combo_keypress(
|
||||
self, combo: Gtk.ComboBox, event: Gdk.EventKey
|
||||
) -> bool:
|
||||
match event.keyval:
|
||||
case Gdk.KEY_Down:
|
||||
self.maps_combo.popup()
|
||||
return True
|
||||
case _:
|
||||
return False
|
||||
|
||||
def set_prior_map(self, mapname: str) -> None:
|
||||
self.prior_map = mapname
|
||||
|
||||
def get_prior_map(self) -> str:
|
||||
return self.prior_map
|
||||
|
||||
def get_selected_map(self) -> str:
|
||||
return self.selected_map
|
||||
|
||||
def get_keyword_filter(self) -> str:
|
||||
return self.keyword_filter
|
||||
|
||||
def _on_keyword_enter(self, entry: Gtk.Entry) -> None:
|
||||
self.AppNav.window.set_keep_below(False)
|
||||
keyword = entry.get_text().lower()
|
||||
if keyword == self.keyword_filter:
|
||||
return
|
||||
if keyword.isspace():
|
||||
return
|
||||
logger.info(f"User filtered by keyword '{keyword}'")
|
||||
self.keyword_filter = keyword
|
||||
self.AppNav.treeview.filter(FilterMode.KEYWORD, keyword)
|
||||
|
||||
def _on_button_release(self, window, button) -> Literal[True]:
|
||||
return True
|
||||
|
||||
def get_active_combo(self) -> int:
|
||||
return self.maps_combo.get_active()
|
||||
|
||||
def set_active_combo(self, row: int) -> None:
|
||||
self.maps_combo.set_active(row)
|
||||
|
||||
def toggle_check(self, digit: int) -> None:
|
||||
check = self.checks[digit]
|
||||
state = check.get_active()
|
||||
check.set_active(not state)
|
||||
|
||||
def _on_check_toggled(self, button: Gtk.CheckButton) -> None:
|
||||
if not self.AppNav.treeview.is_server_context(self.AppNav.treeview.view):
|
||||
return
|
||||
label = button.get_label()
|
||||
state = button.get_active()
|
||||
logger.info(f"User toggled button '{label}' to {state}")
|
||||
if state:
|
||||
mode = FilterMode.TOGGLE_ON
|
||||
else:
|
||||
mode = FilterMode.TOGGLE_OFF
|
||||
|
||||
self.enabled_filters[label] = state
|
||||
self.AppNav.treeview.filter(mode, label)
|
||||
|
||||
def _on_map_changed(self, combo: Gtk.ComboBox) -> None:
|
||||
old_sel = self.selected_map
|
||||
model = combo.get_model()
|
||||
tree_iter = combo.get_active_iter()
|
||||
if tree_iter is None:
|
||||
return
|
||||
selection = model[tree_iter][0]
|
||||
if selection == old_sel:
|
||||
return
|
||||
if not selection:
|
||||
return
|
||||
logger.info(f"User selected map '{selection}'")
|
||||
self.prior_map = self.selected_map
|
||||
self.selected_map = selection
|
||||
self.maps_entry.set_text(selection)
|
||||
self.AppNav.treeview.filter(FilterMode.MAP)
|
||||
@@ -0,0 +1,10 @@
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk
|
||||
|
||||
class Icon(Gtk.Image):
|
||||
def __init__(self, name: str, l_margin=0):
|
||||
super().__init__(icon_name=name,
|
||||
icon_size=Gtk.IconSize.BUTTON,
|
||||
margin_start=l_margin
|
||||
)
|
||||
@@ -0,0 +1,12 @@
|
||||
import gi # noqa E402
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk
|
||||
|
||||
class LeftLabel(Gtk.Label):
|
||||
def __init__(self, text: str, tooltip: str = ""):
|
||||
super().__init__(
|
||||
label=text,
|
||||
halign=Gtk.Align.START,
|
||||
)
|
||||
self.set_tooltip_text(tooltip)
|
||||
pass
|
||||
@@ -0,0 +1,88 @@
|
||||
import threading
|
||||
|
||||
import gi # noqa E402
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk, GLib
|
||||
|
||||
from dzgui.const.enum import ModButton, Popup
|
||||
from dzgui.const.constants import NO_EXPAND, FILL
|
||||
from dzgui.util import strings
|
||||
|
||||
from dzgui.views.dialogs.generic import GenericDialog
|
||||
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.controllers.mc import Controller
|
||||
|
||||
class EnumeratedModButton(Gtk.Button):
|
||||
def __init__(self, enum: ModButton) -> None:
|
||||
super().__init__(margin_start=10, margin_end=10)
|
||||
|
||||
self.enum = enum
|
||||
self.set_label(enum.dict["label"])
|
||||
self.set_tooltip_text(enum.dict["tooltip"])
|
||||
|
||||
|
||||
class ModSelectionPanel(Gtk.Box):
|
||||
def __init__(self, controller: "Controller") -> None:
|
||||
super().__init__(spacing=6, orientation=Gtk.Orientation.VERTICAL, margin_top=15)
|
||||
|
||||
self.controller = controller
|
||||
|
||||
buttons = (
|
||||
ModButton.SELECT_ALL,
|
||||
ModButton.UNSELECT_ALL,
|
||||
ModButton.HIGHLIGHT_STALE,
|
||||
ModButton.DELETE_SELECTED,
|
||||
)
|
||||
|
||||
self.header = Gtk.Label()
|
||||
self.header.set_markup(f"<b>{strings.mod_panel.header}</b>")
|
||||
|
||||
self.main_panel = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
|
||||
for button in buttons:
|
||||
b = EnumeratedModButton(button)
|
||||
b.connect("clicked", self._on_button_clicked)
|
||||
self.main_panel.pack_start(b, NO_EXPAND, FILL, 0)
|
||||
|
||||
self.extra_panel = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
|
||||
for button in (ModButton.SELECT_STALE, ModButton.UNHIGHLIGHT_STALE):
|
||||
b = EnumeratedModButton(button)
|
||||
b.connect("clicked", self._on_button_clicked)
|
||||
b.set_sensitive(False)
|
||||
self.extra_panel.pack_start(b, NO_EXPAND, FILL, 0)
|
||||
|
||||
self.pack_start(self.header, NO_EXPAND, FILL, 0)
|
||||
self.pack_start(self.main_panel, NO_EXPAND, FILL, 0)
|
||||
self.pack_start(self.extra_panel, NO_EXPAND, FILL, 0)
|
||||
|
||||
def after_colorize(self) -> None:
|
||||
self.controller.unselect_all_mods()
|
||||
self.swap_sensitive(True)
|
||||
|
||||
def swap_sensitive(self, state: bool) -> None:
|
||||
for child in self.extra_panel.get_children():
|
||||
child.set_sensitive(state)
|
||||
for child in self.main_panel.get_children():
|
||||
if child.enum == ModButton.HIGHLIGHT_STALE:
|
||||
child.set_sensitive(not state)
|
||||
|
||||
def _on_button_clicked(self, button: EnumeratedModButton) -> None:
|
||||
match button.enum:
|
||||
case ModButton.SELECT_ALL:
|
||||
self.controller.toggle_mod_selection(True)
|
||||
case ModButton.UNSELECT_ALL:
|
||||
self.controller.toggle_mod_selection(False)
|
||||
case ModButton.DELETE_SELECTED:
|
||||
self.controller.delete_multiple_mods()
|
||||
|
||||
case ModButton.HIGHLIGHT_STALE:
|
||||
self.controller.set_callback(self.after_colorize)
|
||||
self.controller.highlight_stale()
|
||||
case ModButton.UNHIGHLIGHT_STALE:
|
||||
self.controller.uncolorize_mods()
|
||||
self.swap_sensitive(False)
|
||||
case ModButton.SELECT_STALE:
|
||||
self.controller.select_colorized()
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
import gi # noqa E402
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, Gdk
|
||||
|
||||
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.icon import Icon
|
||||
from dzgui.const.constants import NO_EXPAND, NO_FILL, EXPAND, FILL, INPUT_KEYBOARD
|
||||
from dzgui.util import strings
|
||||
|
||||
# TODO: refactor depends on ServerTreeView
|
||||
class RightPanel(Gtk.Box):
|
||||
def __init__(self, appnav, controller):
|
||||
super().__init__(spacing=6, orientation=Gtk.Orientation.VERTICAL)
|
||||
|
||||
self.AppNav = appnav
|
||||
self.AppNav.right_panel = self
|
||||
self.controller = controller
|
||||
|
||||
self.button_vbox = ButtonBox(controller)
|
||||
self.filters_vbox = FilterPanel(appnav, controller)
|
||||
|
||||
for el in self.button_vbox, self.filters_vbox:
|
||||
padding = 0
|
||||
self.pack_start(el, NO_EXPAND, NO_FILL, padding)
|
||||
|
||||
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)
|
||||
|
||||
self.debug_toggle = Gtk.ToggleButton(
|
||||
label=strings.debug_mode,
|
||||
margin_top=10,
|
||||
margin_start=80,
|
||||
margin_end=80,
|
||||
tooltip_text=strings.debug_tooltip,
|
||||
)
|
||||
|
||||
if controller.query_config(Preferences.DEBUG) == True:
|
||||
self.debug_toggle.set_active(True)
|
||||
self.debug_toggle.connect("toggled", self._on_debug_toggled)
|
||||
|
||||
i = Icon(INPUT_KEYBOARD)
|
||||
i.set_margin_start(5)
|
||||
self.question = Gtk.Button(
|
||||
label=strings.keys_button,
|
||||
margin_start=80,
|
||||
margin_end=80,
|
||||
tooltip_text=strings.keys_tooltip,
|
||||
image = i,
|
||||
)
|
||||
self.question.set_image_position(Gtk.PositionType.RIGHT)
|
||||
self.question.connect("clicked", self._on_question_clicked)
|
||||
|
||||
for el in self.ping, self.debug_toggle, self.question:
|
||||
padding = 0
|
||||
self.pack_start(el, NO_EXPAND, FILL, padding)
|
||||
|
||||
def enable_ping_button(self, state: bool) -> None:
|
||||
self.ping.set_visible(state)
|
||||
|
||||
def reinit_maps(self, rows: list) -> None:
|
||||
self.controller.reinit_map_store()
|
||||
# TODO: communicate with controller
|
||||
#controller.clear_map_store()
|
||||
#map_store.append(["All maps"])
|
||||
self.selected = "All maps"
|
||||
self.filters_vbox.set_unique_maps(rows)
|
||||
|
||||
def toggle_debug(self) -> None:
|
||||
if type(self.AppNav.window.get_focus()) is Gtk.Entry:
|
||||
return
|
||||
state = self.debug_toggle.get_active()
|
||||
self.debug_toggle.set_active(not state)
|
||||
|
||||
def _on_debug_toggled(self, button: Gtk.Button) -> None:
|
||||
state = button.get_active()
|
||||
grid = self.AppNav.grid
|
||||
self.controller.toggle_debug_mode()
|
||||
|
||||
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
|
||||
self.AppNav.treeview.set_model(temp_model)
|
||||
self.AppNav.treeview.wait_dialog.destroy()
|
||||
self.AppNav.treeview.enable_ping_column(True)
|
||||
self.AppNav.treeview.grab_focus()
|
||||
self.AppNav.right_panel.ping.set_sensitive(False)
|
||||
|
||||
# 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()
|
||||
|
||||
def _on_question_clicked(self, button: Gtk.Button) -> None:
|
||||
self.AppNav.grid.notebook.toggle_keybindings()
|
||||
|
||||
def focus_button_box(self) -> None:
|
||||
self.button_vbox.buttons[0].grab_focus()
|
||||
@@ -0,0 +1,46 @@
|
||||
from typing import Literal
|
||||
from dzgui.util import css
|
||||
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk, GLib # noqa E402
|
||||
|
||||
|
||||
class Toast(Gtk.EventBox):
|
||||
def __init__(self) -> None:
|
||||
super().__init__()
|
||||
|
||||
self.label = Gtk.Label(hexpand=True)
|
||||
self.box = Gtk.Box(
|
||||
orientation=Gtk.Orientation.HORIZONTAL,
|
||||
halign=Gtk.Align.CENTER,
|
||||
valign=Gtk.Align.CENTER,
|
||||
)
|
||||
self.box.add(self.label)
|
||||
self.add(self.box)
|
||||
self.box.set_size_request(200, 100)
|
||||
|
||||
css.add_class(self.box, "toast-label")
|
||||
|
||||
def set_text(self, text: str) -> None:
|
||||
self.label.set_text(text)
|
||||
|
||||
def set_text_and_fade(self, text: str) -> None:
|
||||
self.set_text(text)
|
||||
self.pop()
|
||||
self._defer_fade()
|
||||
|
||||
def fade_out(self) -> bool:
|
||||
if self.get_opacity() == 0:
|
||||
self.set_visible(False)
|
||||
self.set_opacity(1)
|
||||
return False
|
||||
self.set_opacity(self.get_opacity() - 0.03)
|
||||
return True
|
||||
|
||||
def pop(self) -> None:
|
||||
self.set_visible(True)
|
||||
|
||||
def _defer_fade(self) -> Literal[False]:
|
||||
GLib.timeout_add(30, self.fade_out)
|
||||
return False
|
||||
@@ -0,0 +1,15 @@
|
||||
from dzgui.views.components.icon import Icon
|
||||
from dzgui.const.constants import WEB_BROWSER
|
||||
|
||||
import gi
|
||||
gi.require_version("Gtk", "3.0")
|
||||
from gi.repository import Gtk # noqa E402
|
||||
|
||||
|
||||
class WebButton(Gtk.Button):
|
||||
def __init__(self, label: str):
|
||||
super().__init__(label=label)
|
||||
|
||||
icon = Icon(WEB_BROWSER, l_margin=5)
|
||||
self.set_image(icon)
|
||||
self.set_image_position(Gtk.PositionType.RIGHT)
|
||||
Reference in new issue
Block a user