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
This commit is contained in:
Julian Sparber 2020-11-23 17:48:19 +01:00 committed by Julian Sparber
parent e070607f58
commit 8aa5f291e8
5 changed files with 76 additions and 19 deletions

View file

@ -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',

View file

@ -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;
}
}

View file

@ -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;

View file

@ -52,7 +52,6 @@
<property name="shadow_type">in</property>
<child>
<object class="GtkScrolledWindow" id="folder_list_scrolled">
<property name="width_request">100</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="hscrollbar_policy">never</property>

View file

@ -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;