columnview: Implement gtk_column_view_scroll_to()
authorBenjamin Otte <otte@redhat.com>
Tue, 7 Mar 2023 23:53:14 +0000 (00:53 +0100)
committerBenjamin Otte <otte@redhat.com>
Sat, 5 Aug 2023 01:51:54 +0000 (03:51 +0200)
It's basically the listview version, but with an (optional) column to do
cell-based scrolling/focusing.

gtk/gtkcolumnview.c
gtk/gtkcolumnview.h
gtk/gtkcolumnviewprivate.h
gtk/gtkcolumnviewrowwidget.c

index 8a87f758dde893f94da78965cdefb01f8562eb69..c3db9d0e7fa50017a8362857a5a70c00c8663f3a 100644 (file)
@@ -35,6 +35,7 @@
 #include "gtkgesturedrag.h"
 #include "gtklistviewprivate.h"
 #include "gtkscrollable.h"
+#include "gtkscrollinfoprivate.h"
 #include "gtksizerequest.h"
 #include "gtktypebuiltins.h"
 #include "gtkwidgetprivate.h"
@@ -1722,7 +1723,7 @@ gtk_column_view_remove_column (GtkColumnView       *self,
       else
         item = NULL;
 
-      gtk_column_view_set_focus_column (self, item);
+      gtk_column_view_set_focus_column (self, item, TRUE);
     }
 }
 
@@ -1782,23 +1783,27 @@ gtk_column_view_insert_column (GtkColumnView       *self,
 
 static void
 gtk_column_view_scroll_to_column (GtkColumnView       *self,
-                                  GtkColumnViewColumn *column)
+                                  GtkColumnViewColumn *column,
+                                  GtkScrollInfo       *scroll_info)
 {
-  int col_x, col_width, adj_x, adj_width;
+  int col_x, col_width, new_value;
 
   gtk_column_view_column_get_header_allocation (column, &col_x, &col_width);
-  adj_x = gtk_adjustment_get_value (self->hadjustment);
-  adj_width = gtk_adjustment_get_page_size (self->hadjustment);
 
-  if (col_x < adj_x)
-    gtk_adjustment_set_value (self->hadjustment, col_x);
-  else if (col_x + col_width > adj_x + adj_width)
-    gtk_adjustment_set_value (self->hadjustment, adj_x + adj_width - col_width);
+  new_value = gtk_scroll_info_compute_for_orientation (scroll_info,
+                                                       GTK_ORIENTATION_HORIZONTAL,
+                                                       col_x,
+                                                       col_width,
+                                                       gtk_adjustment_get_value (self->hadjustment),
+                                                       gtk_adjustment_get_page_size (self->hadjustment));
+
+  gtk_adjustment_set_value (self->hadjustment, new_value);
 }
 
 void
 gtk_column_view_set_focus_column (GtkColumnView       *self,
-                                  GtkColumnViewColumn *column)
+                                  GtkColumnViewColumn *column,
+                                  gboolean             scroll)
 {
   g_assert (column == NULL || gtk_column_view_column_get_column_view (column) == self);
 
@@ -1807,8 +1812,8 @@ gtk_column_view_set_focus_column (GtkColumnView       *self,
 
   self->focus_column = column;
 
-  if (column)
-    gtk_column_view_scroll_to_column (self, column);
+  if (column && scroll)
+    gtk_column_view_scroll_to_column (self, column, NULL);
 }
 
 GtkColumnViewColumn *
@@ -2174,3 +2179,44 @@ gtk_column_view_set_header_factory (GtkColumnView      *self,
   g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HEADER_FACTORY]);
 }
 
+/**
+ * gtk_column_view_scroll_to:
+ * @self: The columnview to scroll in
+ * @pos: position of the item
+ * @column: (nullable) (transfer none): The column to scroll to
+ *   or %NULL to not scroll columns.
+ * @flags: actions to perform
+ * @scroll: (nullable) (transfer full): details of how to perform
+ *   the scroll operation or %NULL to scroll into view
+ *
+ * Scroll to the row at the given position - or cell if a column is
+ * given - and performs the actions specified in @flags.
+ *
+ * This function works no matter if the listview is shown or focused.
+ * If it isn't, then the changes will take effect once that happens.
+ *
+ * Since: 4.12
+ */
+void
+gtk_column_view_scroll_to (GtkColumnView       *self,
+                           guint                pos,
+                           GtkColumnViewColumn *column,
+                           GtkListScrollFlags   flags,
+                           GtkScrollInfo       *scroll)
+{
+  g_return_if_fail (GTK_IS_COLUMN_VIEW (self));
+  g_return_if_fail (column == NULL || GTK_IS_COLUMN_VIEW_COLUMN (column));
+  if (column)
+    {
+      g_return_if_fail (gtk_column_view_column_get_column_view (column) == self);
+    }
+
+  if (column && (flags & GTK_LIST_SCROLL_FOCUS))
+    gtk_column_view_set_focus_column (self, column, FALSE);
+
+  gtk_list_view_scroll_to (self->listview, pos, flags, scroll);
+
+  if (column)
+    gtk_column_view_scroll_to_column (self, column, scroll);
+}
+
index c80c1698960ea2eb4119e365189ec15f1e8d2b8e..d15c35d7fcdd67ffa301a1e67c35a91283e1cd2e 100644 (file)
@@ -122,7 +122,6 @@ GDK_AVAILABLE_IN_4_12
 GtkListItemFactory *
                 gtk_column_view_get_row_factory                 (GtkColumnView          *self);
 
-
 GDK_AVAILABLE_IN_4_12
 void            gtk_column_view_set_header_factory              (GtkColumnView          *self,
                                                                  GtkListItemFactory     *factory);
@@ -130,5 +129,12 @@ GDK_AVAILABLE_IN_4_12
 GtkListItemFactory *
                 gtk_column_view_get_header_factory              (GtkColumnView          *self);
 
+GDK_AVAILABLE_IN_4_12
+void            gtk_column_view_scroll_to                       (GtkColumnView          *self,
+                                                                 guint                   pos,
+                                                                 GtkColumnViewColumn    *column,
+                                                                 GtkListScrollFlags      flags,
+                                                                 GtkScrollInfo          *scroll);
+
 G_END_DECLS
 
index 1a3061e332833b2b00a9b458270e17572054fcba..f92b6da36a0aeb68b9e511e7ed15019ddaebe7ca 100644 (file)
@@ -40,6 +40,7 @@ void                    gtk_column_view_distribute_width        (GtkColumnView
                                                                  GtkRequestedSize       *sizes);
 
 void                    gtk_column_view_set_focus_column        (GtkColumnView          *self,
-                                                                 GtkColumnViewColumn    *focus_column);
+                                                                 GtkColumnViewColumn    *focus_column,
+                                                                 gboolean                scroll);
 GtkColumnViewColumn *   gtk_column_view_get_focus_column        (GtkColumnView          *self);
 
index de71a721f5ae7222ad5d4e279c25d45c4aa2d91d..3febbf813ce6414be4f89d8f869f9e9f51197ec4 100644 (file)
@@ -288,7 +288,7 @@ gtk_column_view_row_widget_focus (GtkWidget        *widget,
         {
           if (gtk_widget_grab_focus_self (widget))
             {
-              gtk_column_view_set_focus_column (view, NULL);
+              gtk_column_view_set_focus_column (view, NULL, FALSE);
               return TRUE;
             }
         }
@@ -323,7 +323,7 @@ gtk_column_view_row_widget_grab_focus (GtkWidget *widget)
 
   if (gtk_widget_grab_focus_self (widget))
     {
-      gtk_column_view_set_focus_column (view, NULL);
+      gtk_column_view_set_focus_column (view, NULL, FALSE);
       return TRUE;
     }
 
@@ -354,7 +354,8 @@ gtk_column_view_row_widget_set_focus_child (GtkWidget *widget,
   if (child)
     {
       gtk_column_view_set_focus_column (gtk_column_view_row_widget_get_column_view (self),
-                                        gtk_column_view_row_child_get_column (child));
+                                        gtk_column_view_row_child_get_column (child),
+                                        TRUE);
     }
 }