From 2120ef38d9e20041169c0e94410f73cd97685622 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Wed, 8 Mar 2023 00:53:14 +0100 Subject: [PATCH] columnview: Implement gtk_column_view_scroll_to() It's basically the listview version, but with an (optional) column to do cell-based scrolling/focusing. --- gtk/gtkcolumnview.c | 70 +++++++++++++++++++++++++++++------- gtk/gtkcolumnview.h | 8 ++++- gtk/gtkcolumnviewprivate.h | 3 +- gtk/gtkcolumnviewrowwidget.c | 7 ++-- 4 files changed, 71 insertions(+), 17 deletions(-) diff --git a/gtk/gtkcolumnview.c b/gtk/gtkcolumnview.c index 8a87f758dd..c3db9d0e7f 100644 --- a/gtk/gtkcolumnview.c +++ b/gtk/gtkcolumnview.c @@ -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); +} + diff --git a/gtk/gtkcolumnview.h b/gtk/gtkcolumnview.h index c80c169896..d15c35d7fc 100644 --- a/gtk/gtkcolumnview.h +++ b/gtk/gtkcolumnview.h @@ -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 diff --git a/gtk/gtkcolumnviewprivate.h b/gtk/gtkcolumnviewprivate.h index 1a3061e332..f92b6da36a 100644 --- a/gtk/gtkcolumnviewprivate.h +++ b/gtk/gtkcolumnviewprivate.h @@ -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); diff --git a/gtk/gtkcolumnviewrowwidget.c b/gtk/gtkcolumnviewrowwidget.c index de71a721f5..3febbf813c 100644 --- a/gtk/gtkcolumnviewrowwidget.c +++ b/gtk/gtkcolumnviewrowwidget.c @@ -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); } }