mirror of
https://github.com/aclist/dztui.git
synced 2026-08-28 10:47:15 +02:00
feat: wrap callback function
This commit is contained in:
parent
2c8e722d8a
commit
96244a4560
@ -83,7 +83,23 @@ class Emitter(GObject.GObject):
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=(str,bool,))
|
||||
@GObject.Signal(
|
||||
flags=GObject.SignalFlags.RUN_LAST,
|
||||
arg_types=(
|
||||
str,
|
||||
bool,
|
||||
),
|
||||
)
|
||||
def check_toggled(self, label: str, state: bool) -> None:
|
||||
pass
|
||||
|
||||
@GObject.Signal(
|
||||
flags=GObject.SignalFlags.RUN_LAST,
|
||||
arg_types=(
|
||||
str,
|
||||
bool,
|
||||
),
|
||||
)
|
||||
def check_toggled(self, label: str, state: bool) -> None:
|
||||
pass
|
||||
|
||||
@ -102,3 +118,15 @@ class Emitter(GObject.GObject):
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=(object,))
|
||||
def load_maps(self, store: ListStore) -> None:
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def mod_page_loaded(self) -> None:
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def mods_highlighted(self) -> None:
|
||||
pass
|
||||
|
||||
@GObject.Signal(flags=GObject.SignalFlags.RUN_LAST, arg_types=())
|
||||
def api_change_failed(self) -> None:
|
||||
pass
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import inspect
|
||||
import logging
|
||||
import shutil
|
||||
import threading
|
||||
@ -93,11 +94,22 @@ class AppNavigation:
|
||||
filters: "FilterPanel"
|
||||
|
||||
|
||||
class CleanupFunc:
|
||||
def __init__(self, func: Callable, *args, **kwargs) -> None:
|
||||
sig = inspect.signature(func)
|
||||
self.func = func
|
||||
self.bindings = sig.bind(*args, **kwargs)
|
||||
|
||||
def call(self) -> None:
|
||||
self.func(*self.bindings.args, *self.bindings.kwargs)
|
||||
|
||||
|
||||
class Controller(GObject.GObject):
|
||||
def __init__(self) -> None:
|
||||
self.dist_cache: dict[str, "Haversine", "ServerTab"] = {}
|
||||
self.mediator = AppNavigation()
|
||||
self.prefs: UserPrefs
|
||||
self.cleanup_func: CleanupFunc = None
|
||||
|
||||
self.model_man = ModelManager()
|
||||
self.emitter = Emitter()
|
||||
@ -114,10 +126,14 @@ class Controller(GObject.GObject):
|
||||
def decorator(func: Callable) -> Callable:
|
||||
@wraps(func)
|
||||
def wrapper(*args, **kwargs):
|
||||
def callback() -> None:
|
||||
func(*args, **kwargs)
|
||||
GLib.idle_add(self._destroy_on_idle)
|
||||
|
||||
self = args[0]
|
||||
self.wait_dialog = WaitDialog(self, dialog_str)
|
||||
self.wait_dialog.show_all()
|
||||
thread = threading.Thread(target=func, args=args)
|
||||
thread = threading.Thread(target=callback)
|
||||
thread.start()
|
||||
|
||||
return wrapper
|
||||
@ -156,6 +172,7 @@ class Controller(GObject.GObject):
|
||||
def unblock_signals(self) -> None:
|
||||
self.block_signals(False)
|
||||
|
||||
@deprecated("Currently unused")
|
||||
def block_signals(self, state: bool = True) -> None:
|
||||
self.suppress_signal(
|
||||
self.mediator.filters,
|
||||
@ -280,6 +297,7 @@ class Controller(GObject.GObject):
|
||||
|
||||
self.emitter.emit("distcalc_ended", dist, context)
|
||||
|
||||
# TODO: threading
|
||||
def delete_multiple_mods(self) -> None:
|
||||
sel = self.mediator.modtreeview.get_selection()
|
||||
model, pathlist = sel.get_selected_rows()
|
||||
@ -290,10 +308,13 @@ class Controller(GObject.GObject):
|
||||
total_mods, total_size = self.calc_mod_size()
|
||||
self.update_mod_statusbar()
|
||||
|
||||
def load_mods_cleanup(self, model: Gtk.ListStore) -> None:
|
||||
self.mediator.modtreeview.set_model(model)
|
||||
self.emitter.emit("mod_page_loaded")
|
||||
|
||||
@call_on_thread(strings.dialog.modlist)
|
||||
def load_mods(self) -> None:
|
||||
# TODO: threading; could get slow with 100s of mods
|
||||
model = self.model_man.get_mod_store()
|
||||
model.clear()
|
||||
model = self.model_man.new_mod_store()
|
||||
path = self.query_config(Preferences.DEFAULT)
|
||||
mods = get_delimited_mods(Path(path))
|
||||
|
||||
@ -302,6 +323,8 @@ class Controller(GObject.GObject):
|
||||
mod.append(None)
|
||||
model.append(mod)
|
||||
|
||||
self.cleanup_func = CleanupFunc(self.load_mods_cleanup, model)
|
||||
|
||||
def toggle_config(self, context: Preferences) -> None:
|
||||
config = self.prefs.paths.config
|
||||
try:
|
||||
@ -484,16 +507,21 @@ class Controller(GObject.GObject):
|
||||
except PeFile.AppNotInstalledError:
|
||||
pass
|
||||
|
||||
model = self.model_man.get_mod_store()
|
||||
model = self.get_mod_store()
|
||||
model.remove(it)
|
||||
|
||||
def get_mod_store(self) -> Gtk.ListStore:
|
||||
return self.mediator.modtreeview.get_model()
|
||||
|
||||
def format_mod_statusbar(self) -> None:
|
||||
total_mods, total_size = self.calc_mod_size()
|
||||
msg = format_mods(total_size, total_mods)
|
||||
return msg
|
||||
|
||||
def calc_mod_size(self) -> tuple[int, int]:
|
||||
model = self.model_man.get_mod_store()
|
||||
model = self.get_mod_store()
|
||||
if model is None:
|
||||
return 0, 0
|
||||
total_mods = len(model)
|
||||
total_size = 0
|
||||
for mod in model:
|
||||
@ -590,7 +618,7 @@ class Controller(GObject.GObject):
|
||||
self.open_page(NotebookPage.LOG)
|
||||
|
||||
def select_colorized(self) -> None:
|
||||
model = self.model_man.get_mod_store()
|
||||
model = self.get_mod_store()
|
||||
sel = self.mediator.modtreeview.get_selection()
|
||||
for mod in model:
|
||||
it = mod.iter
|
||||
@ -598,29 +626,14 @@ class Controller(GObject.GObject):
|
||||
if mod[4] == HEX_RED:
|
||||
sel.select_path(path)
|
||||
|
||||
# TODO: make as method of tree?
|
||||
def uncolorize_mods(self) -> None:
|
||||
model = self.model_man.get_mod_store()
|
||||
model = self.get_mod_store()
|
||||
for mod in model:
|
||||
it = mod.iter
|
||||
path = model.get_path(it)
|
||||
model[path][4] = None
|
||||
|
||||
def colorize_mods(self) -> None:
|
||||
model = self.model_man.get_mod_store()
|
||||
stale = find_stale_mods(self.prefs.paths.config)
|
||||
for mod in model:
|
||||
it = mod.iter
|
||||
path = model.get_path(it)
|
||||
# TODO: consider storing in ListStore as int
|
||||
# TODO: clone existing model and set outside of threai
|
||||
if int(mod[2]) in stale:
|
||||
model[path][4] = HEX_RED
|
||||
|
||||
self.destroy_on_idle()
|
||||
|
||||
def unselect_all_mods(self) -> None:
|
||||
self.mediator.modtreeview.get_selection().unselect_all()
|
||||
|
||||
def dump_test_2(self) -> None:
|
||||
import time
|
||||
|
||||
@ -810,7 +823,6 @@ class Controller(GObject.GObject):
|
||||
self.new_maps = None
|
||||
|
||||
treeview.grab_focus()
|
||||
self.destroy_on_idle()
|
||||
# if self.success is False:
|
||||
# # TODO: different dialogs for server tab contexts, e.g. lan timeout
|
||||
# # TODO: if history/favorites is empty, don't even trigger a call to dump data
|
||||
@ -818,10 +830,10 @@ class Controller(GObject.GObject):
|
||||
# dialog.run()
|
||||
|
||||
def cleanup_on_failure(self) -> None:
|
||||
# TODO: what if refresh action occurred, and the old model is valid?
|
||||
treeview = self.get_active_treeview()
|
||||
treeview.set_model(None)
|
||||
map_man = treeview.get_map_man()
|
||||
# TODO: what if refresh action occurred, and the old model is still valid?
|
||||
# TODO: disable map, keyword, and filter widgets if model is None?
|
||||
# -> signal driven (servers_empty)
|
||||
# would have to make those unsensitive when changing server tabs
|
||||
@ -832,7 +844,6 @@ class Controller(GObject.GObject):
|
||||
# TODO: distinguish signals, e.g. "servers_failed_to_load"
|
||||
self.emitter.emit("servers_loaded", context)
|
||||
treeview.grab_focus()
|
||||
self.destroy_on_idle()
|
||||
dialog = ExceptionDialog(self, "API TIMEOUT")
|
||||
dialog.run()
|
||||
|
||||
@ -841,7 +852,7 @@ class Controller(GObject.GObject):
|
||||
treeview.set_loaded(True)
|
||||
# TODO: wipe control model on failure or keep old results?
|
||||
# manager = treeview.get_filter_man()
|
||||
GLib.idle_add(self.cleanup_on_failure)
|
||||
self.cleanup_func = CleanupFunc(self.cleanup_on_failure)
|
||||
|
||||
def push_data(self, data: tuple, mode: Optional[FilterMode], success: bool) -> None:
|
||||
|
||||
@ -866,38 +877,31 @@ class Controller(GObject.GObject):
|
||||
self.new_maps = sorted(u_maps)
|
||||
|
||||
treeview.set_loaded(True)
|
||||
GLib.idle_add(self.cleanup)
|
||||
self.cleanup_func = CleanupFunc(self.cleanup)
|
||||
|
||||
@call_on_thread(strings.dialog.working)
|
||||
def highlight_stale(self) -> None:
|
||||
self.colorize_mods()
|
||||
model = self.get_mod_store()
|
||||
stale = find_stale_mods(self.prefs.paths.config)
|
||||
for mod in model:
|
||||
it = mod.iter
|
||||
path = model.get_path(it)
|
||||
# TODO: consider storing in ListStore as int
|
||||
# FIXME: deep copy existing model and set outside of thread
|
||||
if int(mod[2]) in stale:
|
||||
model[path][4] = HEX_RED
|
||||
self.cleanup_func = CleanupFunc(lambda: self.emitter.emit("mods_highlighted"))
|
||||
|
||||
def get_callback(self) -> Callable | None:
|
||||
return self.callback["func"]
|
||||
def get_cleanup_func(self) -> CleanupFunc:
|
||||
return self.cleanup_func
|
||||
|
||||
def get_callback_args(self) -> Any:
|
||||
return self.callback["args"]
|
||||
|
||||
def set_callback(self, callback: Callable | None, *args) -> None:
|
||||
"""
|
||||
Lets calling widgets register a callback function
|
||||
when spawning a threaded process
|
||||
"""
|
||||
self.callback = {"func": callback, "args": args}
|
||||
|
||||
def destroy_on_idle(self) -> None:
|
||||
"""
|
||||
TODO: chiefly responsible for removing spinner dialog
|
||||
"""
|
||||
def _destroy_on_idle(self) -> None:
|
||||
self.wait_dialog.destroy()
|
||||
func = self.get_callback()
|
||||
self.mediator.window.set_sensitive(True)
|
||||
# TODO: spawn error dialog if API crawl failed
|
||||
# most likely going to drop callback method
|
||||
func = self.get_cleanup_func()
|
||||
if func is not None:
|
||||
args = self.get_callback_args()
|
||||
GLib.idle_add(func, *args)
|
||||
self.set_callback(None, None)
|
||||
func.call()
|
||||
self.cleanup_func = None
|
||||
self.mediator.window.set_sensitive(True)
|
||||
|
||||
def dump_diagnostics(self) -> None:
|
||||
picker = FilePicker(self.mediator.window)
|
||||
@ -909,7 +913,8 @@ class Controller(GObject.GObject):
|
||||
dialog = ExceptionDialog(self, str(e))
|
||||
dialog.run()
|
||||
|
||||
def test_api_response(self, text: str, key: Preferences) -> None:
|
||||
@call_on_thread(strings.dialog.working)
|
||||
def update_api_key(self, text: str, key: Preferences) -> None:
|
||||
if key is Preferences.STEAM:
|
||||
res = test_steam_api(text)
|
||||
else:
|
||||
@ -917,17 +922,9 @@ class Controller(GObject.GObject):
|
||||
|
||||
if res is True:
|
||||
self.update_config(key, text)
|
||||
self.set_callback(None, None)
|
||||
self.destroy_on_idle()
|
||||
else:
|
||||
self.destroy_on_idle()
|
||||
dialog = ExceptionDialog(self, strings.api_error)
|
||||
dialog.run()
|
||||
|
||||
@call_on_thread(strings.dialog.working)
|
||||
# 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)
|
||||
# FIXME: dialog spawning in thread
|
||||
self.cleanup_func = CleanupFunc(self.emitter.emit("api_change_failed"))
|
||||
|
||||
def set_resolution(self, window: "OuterWindow") -> None:
|
||||
if self.prefs.is_game_mode:
|
||||
@ -985,14 +982,12 @@ class Controller(GObject.GObject):
|
||||
self.push_data("", mode, success=True)
|
||||
|
||||
# FIXME: optional label/map/keyword parameter
|
||||
# FIXME: drop set_callback
|
||||
# TODO: consolidate with method above
|
||||
def refilter_model(self, mode: FilterMode, label: Optional[str] = None) -> None:
|
||||
tv = self.get_active_treeview()
|
||||
filter_man = tv.get_filter_man()
|
||||
if filter_man.get_control() is None:
|
||||
return
|
||||
# TODO: deprecated in this context?
|
||||
self.set_callback(None, None)
|
||||
self.filter_threaded(mode, label)
|
||||
|
||||
def populate_model(self) -> None:
|
||||
@ -1001,18 +996,15 @@ class Controller(GObject.GObject):
|
||||
self.emitter.emit("servers_loaded", treeview.get_enum())
|
||||
return
|
||||
|
||||
# TODO: maybe set tree to none afterwards (swap models)
|
||||
# treeview.set_model(None)
|
||||
func = treeview.get_query_func()
|
||||
if func is None:
|
||||
self.emitter.emit("servers_loaded", treeview.get_enum())
|
||||
treeview.set_model(None)
|
||||
return
|
||||
# TODO:
|
||||
# TODO: clear ephemeral model if necessary
|
||||
# manager = treeview.get_filter_man()
|
||||
# manager.clear_model()
|
||||
self.first_iteration = True
|
||||
self.set_callback(None, None)
|
||||
self.run_query_func(func)
|
||||
|
||||
def get_favorite(self) -> tuple[str, str] | tuple[None, None]:
|
||||
@ -1034,9 +1026,6 @@ class Controller(GObject.GObject):
|
||||
def get_modlist_store(self) -> Gtk.ListStore:
|
||||
return self.model_man.get_modlist_store()
|
||||
|
||||
def get_mod_store(self) -> Gtk.ListStore:
|
||||
return self.model_man.get_mod_store()
|
||||
|
||||
def get_log_store(self) -> Gtk.ListStore:
|
||||
return self.model_man.get_log_store()
|
||||
|
||||
|
||||
@ -47,8 +47,8 @@ class ModelManager:
|
||||
|
||||
self.map_store = ListStore(str)
|
||||
self.help_store = self.new_model_from_class(MenuCols)
|
||||
self.mod_store = self.new_model_from_class(ModCols)
|
||||
self.log_store = self.new_model_from_class(LogCols)
|
||||
# FIXME: needs to be generated on demand
|
||||
self.modlist_store = self.new_model_from_class(ServerModCols)
|
||||
|
||||
for row in HELP_MENU_ROWS:
|
||||
@ -65,8 +65,8 @@ class ModelManager:
|
||||
def get_help_store(self) -> ListStore:
|
||||
return self.help_store
|
||||
|
||||
def get_mod_store(self) -> ListStore:
|
||||
return self.mod_store
|
||||
def new_mod_store(self) -> ListStore:
|
||||
return self.new_model_from_class(ModCols)
|
||||
|
||||
def get_log_store(self) -> ListStore:
|
||||
return self.log_store
|
||||
|
||||
@ -16,7 +16,7 @@ if TYPE_CHECKING:
|
||||
|
||||
class EnumeratedModButton(Gtk.Button):
|
||||
def __init__(self, enum: ModButton) -> None:
|
||||
super().__init__(margin_start=10, margin_end=10)
|
||||
super().__init__(margin_start=10, margin_end=10, focus_on_click=False)
|
||||
|
||||
self.enum = enum
|
||||
self.set_label(enum.dict["label"])
|
||||
@ -30,6 +30,7 @@ class ModSelectionPanel(Gtk.Box):
|
||||
self.controller = controller
|
||||
emitter = controller.get_emitter()
|
||||
emitter.connect("mod_page_toggled", self._on_mod_page_toggled)
|
||||
emitter.connect("mods_highlighted", self._on_mods_highlighted)
|
||||
|
||||
header = BoldLabel(mod_panel.header)
|
||||
|
||||
@ -60,14 +61,17 @@ class ModSelectionPanel(Gtk.Box):
|
||||
for el in header, self.main_panel, self.stale_panel:
|
||||
self.pack_start(el, NO_EXPAND, FILL, NO_PADDING)
|
||||
|
||||
def _on_mods_highlighted(self, emitter: "Emitter") -> None:
|
||||
self.swap_sensitive(True)
|
||||
|
||||
def _on_mod_page_toggled(self, emitter: "Emitter", state: bool) -> None:
|
||||
self.set_visible(state)
|
||||
|
||||
def after_colorize(self) -> None:
|
||||
# TODO: split into signal that touches two widgets,
|
||||
# modtreeview and this widget
|
||||
self.controller.unselect_all_mods()
|
||||
self.swap_sensitive(True)
|
||||
#def after_colorize(self) -> None:
|
||||
# # TODO: split into signal that touches two widgets,
|
||||
# # modtreeview and this widget
|
||||
# #self.controller.unselect_all_mods()
|
||||
# self.swap_sensitive(True)
|
||||
|
||||
def swap_sensitive(self, state: bool) -> None:
|
||||
for child in self.stale_panel.get_children():
|
||||
@ -79,15 +83,12 @@ class ModSelectionPanel(Gtk.Box):
|
||||
def _on_button_clicked(self, button: EnumeratedModButton) -> None:
|
||||
match button.enum:
|
||||
case ModButton.SELECT_ALL:
|
||||
# TODO: signals
|
||||
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()
|
||||
|
||||
@ -44,6 +44,7 @@ class RightPanel(Gtk.Box):
|
||||
state = self.controller.has_server_model()
|
||||
for widget in (self.refresh_button, self.filters_vbox):
|
||||
widget.set_sensitive(state)
|
||||
# FIXME: may wish to reload these in place to show new data
|
||||
if context in (ServerTab.RECENT, ServerTab.SAVED):
|
||||
self.refresh_button.set_sensitive(False)
|
||||
|
||||
|
||||
@ -51,6 +51,11 @@ class Statusbar(Gtk.Grid):
|
||||
self.emitter.connect("distcalc_started", self._on_distcalc_started)
|
||||
self.emitter.connect("distcalc_ended", self._on_distcalc_ended)
|
||||
self.emitter.connect("servers_loaded", self._on_servers_loaded)
|
||||
self.emitter.connect("mod_page_loaded", self._on_mod_page_loaded)
|
||||
|
||||
def _on_mod_page_loaded(self, emitter: "Emitter") -> None:
|
||||
msg = self.controller.format_mod_statusbar()
|
||||
self.set_by_context(NotebookPage.MODS, msg)
|
||||
|
||||
def _on_notebook_page_changed(
|
||||
self, notebook: "Notebook", child: Gtk.Widget, index: int
|
||||
@ -75,12 +80,15 @@ class Statusbar(Gtk.Grid):
|
||||
|
||||
match enum:
|
||||
case NotebookPage.MODS:
|
||||
bar = self.controller.format_mod_statusbar()
|
||||
return
|
||||
# FIXME: format on callback after mods load
|
||||
#bar = self.controller.format_mod_statusbar()
|
||||
case NotebookPage.HELP:
|
||||
bar = self.controller.get_help_row()
|
||||
case NotebookPage.SERVERS:
|
||||
context = self.controller.get_active_context()
|
||||
self.emitter.emit("servers_loaded", context)
|
||||
# FIXME: may be superfluous
|
||||
#self.emitter.emit("servers_loaded", context)
|
||||
return
|
||||
case NotebookPage.KEYS:
|
||||
bar = question_to_return
|
||||
|
||||
@ -37,6 +37,7 @@ from gi.repository import Gtk, Gdk # noqa
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.controllers.mc import Controller
|
||||
from dzgui.controllers.emitter import Emitter
|
||||
|
||||
|
||||
class Options(Gtk.Box):
|
||||
@ -48,6 +49,8 @@ class Options(Gtk.Box):
|
||||
)
|
||||
|
||||
self.controller = controller
|
||||
emitter = controller.get_emitter()
|
||||
emitter.connect("api_change_failed", self._on_api_change_failed)
|
||||
|
||||
self.DEFAULT_WIDTH = 1
|
||||
self.DEFAULT_HEIGHT = 1
|
||||
@ -270,6 +273,9 @@ class Options(Gtk.Box):
|
||||
self, button: Gtk.Button, entry: Gtk.Entry, enum: Preferences
|
||||
) -> None:
|
||||
old_text = self.controller.query_config(enum)
|
||||
self.old_text = old_text
|
||||
self.old_entry = entry
|
||||
|
||||
button.set_sensitive(False)
|
||||
match enum:
|
||||
case Preferences.NAME:
|
||||
@ -277,9 +283,14 @@ class Options(Gtk.Box):
|
||||
self.controller.update_config(enum, value)
|
||||
case Preferences.BM | Preferences.STEAM:
|
||||
text = "".join(entry.get_text().split())
|
||||
self.controller.set_callback(self.restore_api_text, old_text, entry)
|
||||
# self.controller.set_callback(self.restore_api_text, old_text, entry)
|
||||
self.controller.update_api_key(text, enum)
|
||||
|
||||
def _on_api_change_failed(self, emitter: "Emitter") -> None:
|
||||
self.old_entry.set_text(self.old_text)
|
||||
dialog = ExceptionDialog(self.controller, strings.api_error)
|
||||
dialog.run()
|
||||
|
||||
def restore_api_text(self, text: str, entry: Gtk.Entry) -> None:
|
||||
entry.set_text(text)
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from dzgui.controllers.mc import Controller
|
||||
from dzgui.controllers.emitter import Emitter
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
@ -23,12 +24,14 @@ class ModTreeView(ModsMixin, ContextMixin, TreeView):
|
||||
def __init__(self, controller: "Controller") -> None:
|
||||
super().__init__(controller, menu=ContextMenuGroup.MOD)
|
||||
self.controller = controller
|
||||
emitter = self.controller.get_emitter()
|
||||
emitter.connect("mod_page_loaded", self._on_mod_page_loaded)
|
||||
emitter.connect("mods_highlighted", self._on_mods_highlighted)
|
||||
|
||||
self.set_fixed_height_mode(True)
|
||||
self.set_headers_visible(True)
|
||||
|
||||
mod_store = self.controller.get_mod_store()
|
||||
self.set_model(mod_store)
|
||||
self.set_model(None)
|
||||
|
||||
for i, column_title in enumerate(strings.mod_cols):
|
||||
renderer = Gtk.CellRendererText()
|
||||
@ -52,26 +55,27 @@ class ModTreeView(ModsMixin, ContextMixin, TreeView):
|
||||
self.connect("generic_treesel_changed", self._parent_selection_changed)
|
||||
self.connect("button-press-event", self.present_menu)
|
||||
self.connect("key-press-event", self.present_menu)
|
||||
self.connect("map", self._on_map)
|
||||
|
||||
def _on_map(self, tree: Self) -> None:
|
||||
# FIXME: placeholder logic
|
||||
# identify root cause of row unfocus on init
|
||||
def _on_mods_highlighted(self, emitter: "Emitter") -> None:
|
||||
self.get_selection().unselect_all()
|
||||
|
||||
# TODO: test loading with no mods
|
||||
def _on_mod_page_loaded(self, emitter: "Emitter") -> None:
|
||||
self.set_cursor(0)
|
||||
|
||||
# def _on_mods_keypress(self, widget: Gtk.Widget, event: Gdk.EventKey) -> None:
|
||||
# # TODO: multiselect
|
||||
# # if event.keyval is Gdk.KEY_space:
|
||||
# # it = self.get_focused_row_iter()
|
||||
# # self.get_selection().select_iter(it)
|
||||
# # path = self.get_focused_row_path()
|
||||
# # self.set_cursor(path)
|
||||
# # return False
|
||||
# self.present_menu(widget, event)
|
||||
# def _on_mods_keypress(self, widget: Gtk.Widget, event: Gdk.EventKey) -> None:
|
||||
# # TODO: multiselect
|
||||
# # if event.keyval is Gdk.KEY_space:
|
||||
# # it = self.get_focused_row_iter()
|
||||
# # self.get_selection().select_iter(it)
|
||||
# # path = self.get_focused_row_path()
|
||||
# # self.set_cursor(path)
|
||||
# # return False
|
||||
# self.present_menu(widget, event)
|
||||
|
||||
# def _on_mods_button_press(self, widget: Gtk.Widget, event: Gdk.EventButton) -> None:
|
||||
# if event.button == 3:
|
||||
# self.present_menu(widget, event)
|
||||
# def _on_mods_button_press(self, widget: Gtk.Widget, event: Gdk.EventButton) -> None:
|
||||
# if event.button == 3:
|
||||
# self.present_menu(widget, event)
|
||||
|
||||
def _parent_selection_changed(self, base_class: TreeView, sel: Gtk.TreeSelection):
|
||||
pass
|
||||
|
||||
Loading…
Reference in New Issue
Block a user