From 8aa5f291e8941c81cb9bfabf3bbad009b96527f9 Mon Sep 17 00:00:00 2001 From: Julian Sparber Date: Mon, 23 Nov 2020 17:48:19 +0100 Subject: [PATCH] folder-list: mordernize sidebar This makes each row a better click target and improves spacing in general. This move the expander arrow to the left and removes the indentation for folders which makes it possible to define a much smaller width for the sidebar. Fixes: https://gitlab.gnome.org/GNOME/geary/-/issues/880, https://gitlab.gnome.org/GNOME/geary/-/issues/1029 --- src/client/meson.build | 1 + .../sidebar/sidebar-expander-renderer.vala | 38 ++++++++++++++++ src/client/sidebar/sidebar-tree.vala | 45 ++++++++++++------- ui/application-main-window.ui | 1 - ui/geary.css | 10 ++++- 5 files changed, 76 insertions(+), 19 deletions(-) create mode 100644 src/client/sidebar/sidebar-expander-renderer.vala diff --git a/src/client/meson.build b/src/client/meson.build index 4efadc6d..f536a86c 100644 --- a/src/client/meson.build +++ b/src/client/meson.build @@ -137,6 +137,7 @@ client_vala_sources = files( 'sidebar/sidebar-common.vala', 'sidebar/sidebar-count-cell-renderer.vala', 'sidebar/sidebar-entry.vala', + 'sidebar/sidebar-expander-renderer.vala', 'sidebar/sidebar-tree.vala', 'util/util-avatar.vala', diff --git a/src/client/sidebar/sidebar-expander-renderer.vala b/src/client/sidebar/sidebar-expander-renderer.vala new file mode 100644 index 00000000..a13beb48 --- /dev/null +++ b/src/client/sidebar/sidebar-expander-renderer.vala @@ -0,0 +1,38 @@ +/* Copyright © 2020 Purism SPC + * + * This software is licensed under the GNU Lesser General Public License + * (version 2.1 or later). See the COPYING file in this distribution. + */ + +/** + * Cell renderer for the expander in the sidebar. + */ +public class SidebarExpanderRenderer : Gtk.CellRendererPixbuf { + public signal void toggle(Gtk.TreePath path); + public weak Gtk.Widget widget { get; set; } + public SidebarExpanderRenderer(Gtk.Widget widget) { + this.widget = widget; + xalign = 1; + mode = Gtk.CellRendererMode.ACTIVATABLE; + notify["is-expanded"].connect (update_arrow); + update_arrow(); + } + + private void update_arrow() { + if (is_expanded) + this.icon_name = "go-down-symbolic"; + else + this.icon_name = "go-next-symbolic"; + } + + public override bool activate (Gdk.Event event, + Gtk.Widget widget, + string path, + Gdk.Rectangle background_area, + Gdk.Rectangle cell_area, + Gtk.CellRendererState flags) { + toggle(new Gtk.TreePath.from_string (path)); + return true; + } +} + diff --git a/src/client/sidebar/sidebar-tree.vala b/src/client/sidebar/sidebar-tree.vala index 5434aa34..90db9bbd 100644 --- a/src/client/sidebar/sidebar-tree.vala +++ b/src/client/sidebar/sidebar-tree.vala @@ -62,6 +62,7 @@ public class Sidebar.Tree : Gtk.TreeView { ); private Gtk.IconTheme? icon_theme; + private Gtk.TreeViewColumn text_column; private Gtk.CellRendererText text_renderer; private unowned ExternalDropHandler drop_handler; private Gtk.Entry? text_entry = null; @@ -94,7 +95,7 @@ public class Sidebar.Tree : Gtk.TreeView { icon_theme = theme; get_style_context().add_class("sidebar"); - Gtk.TreeViewColumn text_column = new Gtk.TreeViewColumn(); + text_column = new Gtk.TreeViewColumn(); text_column.set_expand(true); Gtk.CellRendererPixbuf icon_renderer = new Gtk.CellRendererPixbuf(); text_column.pack_start(icon_renderer, false); @@ -109,16 +110,23 @@ public class Sidebar.Tree : Gtk.TreeView { append_column(text_column); // Count column. - Gtk.TreeViewColumn count_column = new Gtk.TreeViewColumn(); + Gtk.TreeViewColumn end_column = new Gtk.TreeViewColumn(); SidebarCountCellRenderer unread_renderer = new SidebarCountCellRenderer(); - count_column.pack_start(unread_renderer, false); - count_column.add_attribute(unread_renderer, "counter", Columns.COUNTER); - append_column(count_column); + end_column.set_cell_data_func(unread_renderer, counter_renderer_function); + end_column.pack_start(unread_renderer, false); + end_column.add_attribute(unread_renderer, "counter", Columns.COUNTER); + + // Expander arrows. + SidebarExpanderRenderer expander_renderer = new SidebarExpanderRenderer(this); + expander_renderer.toggle.connect(toggle_branch_expansion); + end_column.set_cell_data_func(expander_renderer, expander_renderer_function); + end_column.pack_start(expander_renderer, false); + append_column(end_column); set_headers_visible(false); set_enable_search(false); set_search_column(-1); - set_show_expanders(true); + set_show_expanders(false); set_reorderable(false); set_enable_tree_lines(false); set_grid_lines(Gtk.TreeViewGridLines.NONE); @@ -163,12 +171,17 @@ public class Sidebar.Tree : Gtk.TreeView { renderer.visible = !(wrapper.entry is Sidebar.Header); } + public void expander_renderer_function(Gtk.CellLayout layout, Gtk.CellRenderer renderer, Gtk.TreeModel model, Gtk.TreeIter iter) { + renderer.visible = renderer.is_expander; + } + public void counter_renderer_function(Gtk.CellLayout layout, Gtk.CellRenderer renderer, Gtk.TreeModel model, Gtk.TreeIter iter) { EntryWrapper? wrapper = get_wrapper_at_iter(iter); if (wrapper == null) { return; } - renderer.visible = !(wrapper.entry is Sidebar.Header); + var counter_renderer = renderer as SidebarCountCellRenderer; + renderer.visible = counter_renderer != null && counter_renderer.counter > 0; } private void on_drag_begin(Gdk.DragContext ctx) { @@ -296,11 +309,16 @@ public class Sidebar.Tree : Gtk.TreeView { } public override void row_activated(Gtk.TreePath path, Gtk.TreeViewColumn column) { + if (column != text_column) + return; + EntryWrapper? wrapper = get_wrapper_at_path(path); if (wrapper != null) { Sidebar.SelectableEntry? selectable = wrapper.entry as Sidebar.SelectableEntry; if (selectable != null) entry_activated(selectable); + else + toggle_branch_expansion (path); } } @@ -352,11 +370,11 @@ public class Sidebar.Tree : Gtk.TreeView { } } - public void toggle_branch_expansion(Gtk.TreePath path, bool expand_all) { + private void toggle_branch_expansion(Gtk.TreePath path) { if (is_row_expanded(path)) collapse_row(path); else - expand_row(path, expand_all); + expand_row(path, false); } public bool expand_to_entry(Sidebar.Entry entry) { @@ -823,13 +841,6 @@ public class Sidebar.Tree : Gtk.TreeView { return base.button_press_event(event); } - // Enable single click to toggle tree entries (bug 4985) - if (wrapper.entry is Sidebar.ExpandableEntry - || wrapper.entry is Sidebar.InternalDropTargetEntry) { - // all labels are InternalDropTargetEntries - toggle_branch_expansion(path, false); - } - // Is this a click on an already-highlighted tree item? if ((old_path_ref != null) && (old_path_ref.get_path() != null) && (old_path_ref.get_path().compare(path) == 0)) { @@ -872,7 +883,7 @@ public class Sidebar.Tree : Gtk.TreeView { case "KP_Enter": Gtk.TreePath? path = get_current_path(); if (path != null) - toggle_branch_expansion(path, false); + toggle_branch_expansion(path); return true; diff --git a/ui/application-main-window.ui b/ui/application-main-window.ui index 547b063f..a62ad616 100644 --- a/ui/application-main-window.ui +++ b/ui/application-main-window.ui @@ -52,7 +52,6 @@ in - 100 True True never diff --git a/ui/geary.css b/ui/geary.css index 2d1d48c3..66925c47 100644 --- a/ui/geary.css +++ b/ui/geary.css @@ -12,8 +12,16 @@ border-left-width: 0; border-top-width: 0; border-right-width: 0; - min-width: 300px; } + +.geary-folder-frame { + min-width: 250px; +} + +.geary-folder-frame .sidebar .cell { + padding: 9px 6px; +} + .geary-conversation-frame > border { border-left-width: 0; border-top-width: 0;