Files
dzgui/dzgui/views/trees/tree_mods.py
T

151 lines
5.0 KiB
Python

import logging
from typing import Any, TYPE_CHECKING
from dzgui.const.constants import APP_NAME, HEX_RED
from dzgui.const.enum import ContextMenuGroup
from dzgui.managers.mods import ModManager
from dzgui.util import strings, localize
from dzgui.views.mixins.context_mixin import ContextMixin
from dzgui.views.mixins.mods_mixin import ModsMixin
from dzgui.views.trees.tree_base import TreeView
import gi
gi.require_version("Gtk", "3.0")
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(APP_NAME)
class ModTreeView(ModsMixin, ContextMixin, TreeView): # type: ignore
def __init__(
self, controller: "Controller", menu: ContextMenuGroup = ContextMenuGroup.MOD
) -> None:
super().__init__(controller, menu=menu)
self.controller = controller
self.mod_man = ModManager(self, controller)
emitter = self.controller.get_emitter()
emitter.connect("mods_updated", self._on_mods_updated)
emitter.connect("mods_highlighted", self._on_mods_highlighted)
self.set_fixed_height_mode(True)
self.set_model(None)
for i, column_title in enumerate(strings.mod_cols):
renderer = Gtk.CellRendererText()
column = Gtk.TreeViewColumn(column_title, renderer, text=i)
column.set_cell_data_func(renderer, self._format_color, func_data=None)
if i == 3:
column.set_cell_data_func(renderer, self._format_float, func_data=None)
if column_title == "Mod":
column.set_fixed_width(500)
else:
column.set_fixed_width(150)
column.set_sizing(Gtk.TreeViewColumnSizing.FIXED)
column.set_sort_column_id(i)
if i != 4:
self.append_column(column)
self.selected_row = self.get_selection()
self.selected_row.set_mode(Gtk.SelectionMode.MULTIPLE)
self.connect("generic_row_activated", self._on_mod_row_activated)
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("button-press-event", self.on_row_click)
def on_row_click(self, widget: Gtk.TreeView, event: Gdk.EventButton) -> bool:
if event.state is Gdk.ModifierType.CONTROL_MASK and event.button == 1:
path_info = widget.get_path_at_pos(int(event.x), int(event.y))
if path_info is None:
return False
path, column, cellx, celly = path_info
model = self.get_model()
if model is None:
return False
if path is None:
return False
_iter = model.get_iter(path)
if self.get_selection().iter_is_selected(_iter):
self.get_selection().unselect_iter(_iter)
else:
self.get_selection().select_iter(_iter)
return True
return False
def get_mod_man(self) -> ModManager:
return self.mod_man
def load_mods(self) -> None:
self.mod_man.load_mods()
def _on_mods_highlighted(self, emitter: "Emitter") -> None:
self.get_selection().unselect_all()
def _on_mods_updated(self, emitter: "Emitter", msg: str, mods: int) -> None:
if mods < 1:
return
self.set_headers_visible(True)
path = Gtk.TreePath.new_from_indices([0])
self.set_cursor(path)
def get_selected_mod(self) -> str:
path = self.get_focused_row_path()
model = self.get_model()
if model is None:
raise AttributeError("Trying to call a method on a non-existent model")
tree_iter = model.get_iter(path)
mod = model.get_value(tree_iter, 2)
return str(mod)
def _parent_selection_changed(
self, base_class: TreeView, sel: Gtk.TreeSelection
) -> None:
pass
def _format_color(
self,
column: Gtk.TreeViewColumn,
cell: Gtk.CellRendererText,
model: Gtk.TreeModel,
it: Gtk.TreeIter,
data: Any,
) -> None:
state = model[it][4]
if state is True:
cell.set_property("foreground", HEX_RED)
else:
cell.set_property("foreground", None)
def _format_float(
self,
column: Gtk.TreeViewColumn,
cell: Gtk.CellRendererText,
model: Gtk.TreeModel,
it: Gtk.TreeIter,
data: Any,
) -> None:
val = model[it][3]
formatted = localize.number(val)
cell.set_property("text", formatted)
# NOTE: reapply color property after float conversion
self._format_color(column, cell, model, it, data)
def set_menu(self, context: ContextMenuGroup) -> None:
self.menu = context
class OfflineModTreeView(ModTreeView):
def __init__(self, controller: "Controller") -> None:
super().__init__(controller)