Minimize scrolling in gtkut_ctree_node_move_if_on_the_edge().
authorAndrej Kacian <ticho@claws-mail.org>
Sat, 5 Nov 2016 11:18:53 +0000 (12:18 +0100)
committerAndrej Kacian <ticho@claws-mail.org>
Sat, 5 Nov 2016 11:18:53 +0000 (12:18 +0100)
Instead of scrolling to get the target row to the middle of
the viewport (offset 0.5), scroll to offsets 0.2 or 0.8 if
the target row is above or below current viewport,
respectively. This makes it consistent with scrolling when
the target row is only partially visible.

src/gtk/gtkcmclist.c
src/gtk/gtkcmclist.h
src/gtk/gtkutils.c

index e58f8c565c7b7269c97ffc3c286f06898c4b8e01..853f5ce8b4a431703b9043562689bc5bdf1b83ba 100644 (file)
@@ -3310,6 +3310,42 @@ gtk_cmclist_row_is_visible (GtkCMCList *clist,
   return GTK_VISIBILITY_FULL;
 }
 
+gboolean
+gtk_cmclist_row_is_above_viewport (GtkCMCList *clist,
+                               gint row)
+{
+       cm_return_val_if_fail(GTK_IS_CMCLIST (clist), 0);
+
+       if (row < 0 || row >= clist->rows)
+               return FALSE;
+
+       if (clist->row_height == 0)
+               return FALSE;
+
+       if (row < ROW_FROM_YPIXEL (clist, 0))
+               return TRUE;
+
+       return FALSE;
+}
+
+gboolean
+gtk_cmclist_row_is_below_viewport (GtkCMCList *clist,
+                               gint row)
+{
+       cm_return_val_if_fail(GTK_IS_CMCLIST (clist), 0);
+
+       if (row < 0 || row >= clist->rows)
+               return FALSE;
+
+       if (clist->row_height == 0)
+               return FALSE;
+
+       if (row > ROW_FROM_YPIXEL (clist, clist->clist_window_height))
+               return TRUE;
+
+       return FALSE;
+}
+
 void
 gtk_cmclist_set_foreground (GtkCMCList       *clist,
                          gint            row,
index 4d2bc5a1ffdd8df3830b85b7cf8777e8e52abc3f..e3c1f09ddf35cfc3513391c6b2c9dbe0aff15618 100644 (file)
@@ -567,6 +567,12 @@ void gtk_cmclist_moveto (GtkCMCList *clist,
 GtkVisibility gtk_cmclist_row_is_visible (GtkCMCList *clist,
                                        gint      row);
 
+/* returns whether the row is above or below current viewport */
+gboolean gtk_cmclist_row_is_above_viewport (GtkCMCList *clist,
+                                       gint row);
+gboolean gtk_cmclist_row_is_below_viewport (GtkCMCList *clist,
+                                       gint row);
+
 /* returns the cell type */
 GtkCMCellType gtk_cmclist_get_cell_type (GtkCMCList *clist,
                                     gint      row,
index 15503f89ad003d05329412456b869f2a57da254d..4500e0a732f18580d4bc3f2cc29291079c358e50 100644 (file)
@@ -232,6 +232,7 @@ void gtkut_ctree_node_move_if_on_the_edge(GtkCMCTree *ctree, GtkCMCTreeNode *nod
        GtkCMCList *clist = GTK_CMCLIST(ctree);
        gint row;
        GtkVisibility row_visibility, prev_row_visibility, next_row_visibility;
+       gfloat row_align;
 
        cm_return_if_fail(ctree != NULL);
        cm_return_if_fail(node != NULL);
@@ -244,7 +245,12 @@ void gtkut_ctree_node_move_if_on_the_edge(GtkCMCTree *ctree, GtkCMCTreeNode *nod
        next_row_visibility = gtk_cmclist_row_is_visible(clist, row + 1);
 
        if (row_visibility == GTK_VISIBILITY_NONE) {
-               gtk_cmclist_moveto(clist, row, -1, 0.5, 0);
+               row_align = 0.5;
+               if (gtk_cmclist_row_is_above_viewport(clist, row))
+                       row_align = 0.2;
+               else if (gtk_cmclist_row_is_below_viewport(clist, row))
+                       row_align = 0.8;
+               gtk_cmclist_moveto(clist, row, -1, row_align, 0);
                return;
        }
        if (row_visibility == GTK_VISIBILITY_FULL &&