From 23a986847a61f4744a1e9a323a4f5b353358d2e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Csaba=20Gy=C3=B6rgyi?= Date: Tue, 16 Apr 2024 18:00:28 +0200 Subject: [PATCH] Fix alignment in hierarchical views Leverage GtkTreeExpander's ability to handle indentation both for tags in the sidebar and tasks in the task list. Create a children_count property for the Tag class so that the expander can bind to it. This fixes GitHub issue #1042 --- GTG/core/tags.py | 10 ++++++++++ GTG/gtk/browser/sidebar.py | 22 ++++------------------ GTG/gtk/browser/task_pane.py | 27 +++------------------------ GTG/gtk/data/style.css | 6 +----- 4 files changed, 18 insertions(+), 47 deletions(-) diff --git a/GTG/core/tags.py b/GTG/core/tags.py index 71f0afb68d..b19db37c8b 100644 --- a/GTG/core/tags.py +++ b/GTG/core/tags.py @@ -80,6 +80,13 @@ def __eq__(self, other) -> bool: return self.id == other.id + @GObject.Property(type=int) + def children_count(self) -> str: + """Read only property.""" + + return len(self.children) + + @GObject.Property(type=str) def name(self) -> str: """Read only property.""" @@ -362,6 +369,7 @@ def add(self, item: Any, parent_id: UUID = None) -> None: self.model.append(item) self.emit('added', item) + if parent_id: self.lookup[parent_id].notify('children_count') def parent(self, item_id: UUID, parent_id: UUID) -> None: @@ -370,6 +378,7 @@ def parent(self, item_id: UUID, parent_id: UUID) -> None: item = self.lookup[item_id] pos = self.model.find(item) self.model.remove(pos[1]) + if parent_id: self.lookup[parent_id].notify('children_count') @@ -378,3 +387,4 @@ def unparent(self, item_id: UUID, parent_id: UUID) -> None: super().unparent(item_id, parent_id) item = self.lookup[item_id] self.model.append(item) + if parent_id: self.lookup[parent_id].notify('children_count') diff --git a/GTG/gtk/browser/sidebar.py b/GTG/gtk/browser/sidebar.py index 78c166a2cd..9c8c20770f 100644 --- a/GTG/gtk/browser/sidebar.py +++ b/GTG/gtk/browser/sidebar.py @@ -282,6 +282,8 @@ def tags_setup_cb(self, factory, listitem, user_data=None) -> None: expander.set_margin_end(6) expander.add_css_class('arrow-only-expander') + expander.set_indent_for_icon(True) + expander.set_indent_for_depth(True) icon.set_margin_end(6) color.set_margin_end(6) color.set_size_request(16, 16) @@ -375,6 +377,8 @@ def tags_bind_cb(self, signallistitem, listitem, user_data=None) -> None: item.bind_property('task_count_open', open_count_label, 'label', BIND_FLAGS), item.bind_property('task_count_actionable', actionable_count_label, 'label', BIND_FLAGS), item.bind_property('task_count_closed', closed_count_label, 'label', BIND_FLAGS), + + item.bind_property('children_count',expander,'hide-expander',BIND_FLAGS, lambda _,x: x==0), ] self.browser.bind_property('is_pane_open', open_count_label, 'visible', BIND_FLAGS) @@ -382,24 +386,6 @@ def tags_bind_cb(self, signallistitem, listitem, user_data=None) -> None: self.browser.bind_property('is_pane_closed', closed_count_label, 'visible', BIND_FLAGS) - if item.parent: - parent = item - depth = 0 - - while parent.parent: - depth += 1 - parent = parent.parent - - box.set_margin_start((18 * depth) + 16) - else: - box.set_margin_start(18) - - if not item.children: - expander.set_visible(False) - else: - expander.set_visible(True) - - def tags_unbind_cb(self, signallistitem, listitem, user_data=None) -> None: """Clean up bindings made in tags_bind_cb""" for binding in listitem.bindings: diff --git a/GTG/gtk/browser/task_pane.py b/GTG/gtk/browser/task_pane.py index 25d436b09d..46a29f395d 100644 --- a/GTG/gtk/browser/task_pane.py +++ b/GTG/gtk/browser/task_pane.py @@ -40,6 +40,8 @@ def __init__(self, config, is_actionable=False): self.expander = Gtk.TreeExpander() self.expander.set_margin_end(6) self.expander.add_css_class('arrow-only-expander') + self.expander.set_indent_for_icon(True) + self.expander.set_indent_for_depth(True) self.check = Gtk.CheckButton() self.check.set_margin_end(6) @@ -60,30 +62,6 @@ def set_has_children(self, value) -> bool: if self.is_actionable: value = False - - self.expander.set_visible(value) - - if value: - widget = self.expander - else: - widget = self.check - - check_width = 21 - margin = 6 - - indent = margin if value else (check_width + margin) - - if self.task.parent and not self.is_actionable: - parent = self.task - depth = 0 - - while parent.parent: - depth += 1 - parent = parent.parent - - widget.set_margin_start(indent + (21 * depth)) - else: - widget.set_margin_start(indent) @GObject.Property(type=bool, default=True) @@ -533,6 +511,7 @@ def show_start(binding, value, user_data=None): listitem.bindings = [ item.bind_property('has_children', box, 'has_children', BIND_FLAGS), + item.bind_property('has_children', expander, 'hide-expander', BIND_FLAGS,lambda _,x: not x), item.bind_property('title', label, 'label', BIND_FLAGS), item.bind_property('excerpt', box, 'tooltip-text', BIND_FLAGS), diff --git a/GTG/gtk/data/style.css b/GTG/gtk/data/style.css index 951c688ba3..68549cf24e 100644 --- a/GTG/gtk/data/style.css +++ b/GTG/gtk/data/style.css @@ -98,10 +98,6 @@ textview check { border-spacing: 0; } -.arrow-only-expander indent { - -gtk-icon-size: 0px; -} - .closed-task { opacity: 0.5; -} \ No newline at end of file +}