Merge pull request #29 from aclist/feat/model-manager

feat: delegate to model manager
This commit is contained in:
aclist authored and GitHub committed 2025-12-20 22:15:47 +09:00
commit 89de9aa48a
3 files changed
+65 -57

No files matched your search

+26 -38
View File
@@ -27,9 +27,6 @@ from dzgui.api.mods import (
from dzgui.const.enum import ( from dzgui.const.enum import (
Preferences, Preferences,
Popup, Popup,
MAIN_MENU_ROWS,
HELP_MENU_ROWS,
RowType,
NotebookPage, NotebookPage,
ButtonType, ButtonType,
ContextMenu, ContextMenu,
@@ -57,60 +54,48 @@ logger = logging.getLogger(__name__)
if TYPE_CHECKING: if TYPE_CHECKING:
from dzgui.views.components.buttonbox import ContextualButton from dzgui.views.components.buttonbox import ContextualButton
from dzgui.views.base import AppNavigation from dzgui.views.base import AppNavigation
from dzgui.const.enum import ContextMenu from dzgui.const.enum import ContextMenu, RowType
from dzgui.views.base import OuterWindow from dzgui.views.base import OuterWindow
class Controller: class Controller:
def __init__(self) -> None: def __init__(self) -> None:
# TODO: main controller delegates to model manager
self.map_store = Gtk.ListStore(str)
self.row_store = Gtk.ListStore(str, GObject.TYPE_PYOBJECT)
self.help_store = Gtk.ListStore(str, GObject.TYPE_PYOBJECT)
# NOTE: long timestamp numbers
self.modlist_store = Gtk.ListStore(str, GObject.TYPE_INT64, str)
self.log_store = Gtk.ListStore(str, str, str, str)
self.notes_cache: dict[str, str] = {}
self.is_developer: bool self.is_developer: bool
self.mediator: AppNavigation self.mediator: AppNavigation
self.prefs: UserPrefs self.prefs: UserPrefs
self.cooldown = 0 self.cooldown = 0
for row in MAIN_MENU_ROWS:
label = row.dict["label"]
self.row_store.append([label, row])
for row in HELP_MENU_ROWS:
label = row.dict["label"]
self.help_store.append([label, row])
self.model_manager = ModelManager() self.model_manager = ModelManager()
def set_help_menu_crumbs(self) -> None:
# TODO: going to be deprecated after server notebook is added
tip = self.mediator.treeview.get_model()[0][0]
store = self.model_manager.get_help_store()[0][0]
if tip == store:
self.set_crumbs("Help")
def set_crumbs(self, crumbs: str) -> None: def set_crumbs(self, crumbs: str) -> None:
self.mediator.grid.set_breadcrumbs(crumbs) self.mediator.grid.set_breadcrumbs(crumbs)
def get_crumbs(self) -> str: def get_crumbs(self) -> str:
return self.mediator.grid.get_breadcrumbs() return self.mediator.grid.get_breadcrumbs()
def get_row_store(self) -> Gtk.ListStore:
return self.model_manager.get_row_store()
def get_help_store(self) -> Gtk.ListStore: def get_help_store(self) -> Gtk.ListStore:
return self.help_store return self.model_manager.get_help_store()
def get_map_store(self) -> Gtk.ListStore: def get_map_store(self) -> Gtk.ListStore:
return self.map_store return self.model_manager.get_map_store()
def get_row_store(self) -> Gtk.ListStore:
return self.row_store
def get_modlist_store(self) -> Gtk.ListStore: def get_modlist_store(self) -> Gtk.ListStore:
return self.modlist_store return self.model_manager.get_modlist_store()
def get_mod_store(self) -> Gtk.ListStore: def get_mod_store(self) -> Gtk.ListStore:
return self.model_manager.get_mod_store() return self.model_manager.get_mod_store()
def get_log_store(self) -> Gtk.ListStore: def get_log_store(self) -> Gtk.ListStore:
return self.log_store return self.model_manager.get_log_store()
def terminate_process(self) -> None: def terminate_process(self) -> None:
# TODO: only used by server table multiprocessing queue # TODO: only used by server table multiprocessing queue
@@ -130,11 +115,10 @@ class Controller:
return self.query_config(Preferences.INSTALL) return self.query_config(Preferences.INSTALL)
def reinit_map_store(self) -> None: def reinit_map_store(self) -> None:
self.map_store.clear() self.model_manager.set_all_maps()
self.map_store.append(["All maps"])
def append_map(self, map_row: list) -> None: def append_map(self, map_row: list) -> None:
self.map_store.append(map_row) self.model_manager.append_map(map_row)
def set_mediator(self, mediator: "AppNavigation") -> None: def set_mediator(self, mediator: "AppNavigation") -> None:
self.mediator = mediator self.mediator = mediator
@@ -280,7 +264,7 @@ class Controller:
return True return True
return False return False
def set_statusbar_by_row(self, row: RowType) -> None: def set_statusbar_by_row(self, row: "RowType") -> None:
self.mediator.grid.statusbar.refresh(row) self.mediator.grid.statusbar.refresh(row)
def toggle_mod_panel(self, state: bool) -> None: def toggle_mod_panel(self, state: bool) -> None:
@@ -303,9 +287,12 @@ class Controller:
case ButtonType.MODS: case ButtonType.MODS:
self.load_mods() self.load_mods()
case ButtonType.HELP: case ButtonType.HELP:
self.mediator.treeview.set_model(self.help_store) help_store = self.model_manager.get_help_store()
self.mediator.treeview.set_model(help_store)
case ButtonType.MAIN_MENU: case ButtonType.MAIN_MENU:
self.mediator.treeview.set_model(self.row_store) # TODO: going to be deprecated after server notebook is added
row_store = self.model_manager.get_row_store()
self.mediator.treeview.set_model(row_store)
self.mediator.grid.notebook.set_page_by_enum(button.opens) self.mediator.grid.notebook.set_page_by_enum(button.opens)
self.set_crumbs(button.get_label()) self.set_crumbs(button.get_label())
@@ -360,6 +347,7 @@ class Controller:
shutil.rmtree(mods_path / mod) shutil.rmtree(mods_path / mod)
# NOTE: second pass to unlink DAYZ_EXP mods # NOTE: second pass to unlink DAYZ_EXP mods
# TODO: test this with working APPID_DAYZ_EXP installation
try: try:
app_path_exp = PeFile.get_nested_app_path(steam_path, APPID_DAYZ_EXP) app_path_exp = PeFile.get_nested_app_path(steam_path, APPID_DAYZ_EXP)
symlink = app_path_exp / md5 symlink = app_path_exp / md5
@@ -367,7 +355,6 @@ class Controller:
except PeFile.AppNotInstalledError: except PeFile.AppNotInstalledError:
pass pass
# TODO: belongs in model manager
model = self.model_manager.get_mod_store() model = self.model_manager.get_mod_store()
model.remove(it) model.remove(it)
@@ -433,8 +420,9 @@ class Controller:
def populate_log(self) -> None: def populate_log(self) -> None:
log = self.prefs.paths.debug log = self.prefs.paths.debug
store = self.log_store store = self.model_manager.get_log_store()
store.clear() store.clear()
# TODO: pop dialog if log is missing # TODO: pop dialog if log is missing
with open(log, "r") as f: with open(log, "r") as f:
lines = [line.split(strings.delimiter) for line in f.read().splitlines()] lines = [line.split(strings.delimiter) for line in f.read().splitlines()]
+37 -8
View File
@@ -1,10 +1,11 @@
from typing import Self
import gi import gi
gi.require_version("Gtk", "3.0") gi.require_version("Gtk", "3.0")
from gi.repository.Gtk import ListStore from gi.repository.Gtk import ListStore
from gi.repository import GObject from gi.repository import GObject
from dzgui.const.enum import FilterMode from dzgui.const.enum import FilterMode, MAIN_MENU_ROWS, HELP_MENU_ROWS
from dataclasses import dataclass, fields from dataclasses import dataclass, fields
@dataclass @dataclass
@@ -61,10 +62,9 @@ class ModelManager:
Methods are not thread-safe in themselves. Methods are not thread-safe in themselves.
""" """
def __init__(self) -> None:
def __init__(self): self.filter_cache: tuple
self.filter_cache = {} self.ping_cache: dict[str, int] = {}
self.ping_cache = {}
self.map_store = ListStore(str) self.map_store = ListStore(str)
self.row_store = self.new_model_from_class(MenuCols) self.row_store = self.new_model_from_class(MenuCols)
@@ -74,12 +74,19 @@ class ModelManager:
self.log_store = self.new_model_from_class(LogCols) self.log_store = self.new_model_from_class(LogCols)
self.modlist_store = self.new_model_from_class(ServerModCols) self.modlist_store = self.new_model_from_class(ServerModCols)
#self.mod_store = ListStore(str, str, str, float, str) for row in MAIN_MENU_ROWS:
label = row.dict["label"]
self.row_store.append([label, row])
for row in HELP_MENU_ROWS:
label = row.dict["label"]
self.help_store.append([label, row])
self.control_model = None self.control_model = None
self.filtered = None self.filtered = None
self.success = True self.success = True
def __new__(cls): def __new__(cls) -> Self:
if not hasattr(cls, "instance"): if not hasattr(cls, "instance"):
cls.instance = super(ModelManager, cls).__new__(cls) cls.instance = super(ModelManager, cls).__new__(cls)
return cls.instance return cls.instance
@@ -88,9 +95,24 @@ class ModelManager:
store = ListStore(*[ftype for field, ftype in cls.__annotations__.items()]) store = ListStore(*[ftype for field, ftype in cls.__annotations__.items()])
return store return store
def get_map_store(self) -> ListStore:
return self.map_store
def get_row_store(self) -> ListStore:
return self.row_store
def get_help_store(self) -> ListStore:
return self.help_store
def get_mod_store(self) -> ListStore: def get_mod_store(self) -> ListStore:
return self.mod_store return self.mod_store
def get_modlist_store(self) -> ListStore:
return self.modlist_store
def get_log_store(self) -> ListStore:
return self.log_store
def filter(self, mode: FilterMode, *args, **kwargs) -> None: def filter(self, mode: FilterMode, *args, **kwargs) -> None:
""" """
Native Gtk.TreeView.refilter() method was not performant enough Native Gtk.TreeView.refilter() method was not performant enough
@@ -312,3 +334,10 @@ class ModelManager:
self.ping_cache = {} self.ping_cache = {}
if full: if full:
self.control_model = None self.control_model = None
def set_all_maps(self) -> None:
self.map_store.clear()
self.map_store.append(["All maps"])
def append_map(self, row: list) -> None:
self.map_store.append(row)
+2 -11
View File
@@ -508,20 +508,11 @@ class Notebook(ScrollableMixin, Gtk.Notebook):
crumbs = enum.dict["crumbs"] crumbs = enum.dict["crumbs"]
MainController.set_crumbs(crumbs) MainController.set_crumbs(crumbs)
if enum is NotebookPage.MODS: # TODO: going to be deprecated after server notebook is added
return
# NOTE: Main Menu and Help page are of the same type
if enum is not NotebookPage.MAIN: if enum is not NotebookPage.MAIN:
return return
# FIXME: brittle MainController.set_help_menu_crumbs()
if crumbs == "Main menu":
if AppNav.treeview.get_model()[0][0] == MainController.help_store[0][0]:
MainController.set_crumbs("Help")
row = MAIN_MENU_ROWS[0]
AppNav.grid.statusbar.refresh(row)
class Statusbar(Gtk.Statusbar): class Statusbar(Gtk.Statusbar):