[gtk/wip/otte/listview: 50/76] listview: Add list.scroll_to_item action
- From: Benjamin Otte <otte src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/otte/listview: 50/76] listview: Add list.scroll_to_item action
- Date: Wed, 16 Oct 2019 19:50:18 +0000 (UTC)
commit 4277931bc3af6be146ff53a9b13d6381660534b0
Author: Benjamin Otte <otte redhat com>
Date: Fri Oct 4 06:50:47 2019 +0200
listview: Add list.scroll_to_item action
The action scrolls the given item into view.
Listitems activate this action when they gain focus.
gtk/gtklistitem.c | 22 ++++++++++++++++++++++
gtk/gtklistview.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 76 insertions(+)
---
diff --git a/gtk/gtklistitem.c b/gtk/gtklistitem.c
index b7a58d944d..e4a373ab82 100644
--- a/gtk/gtklistitem.c
+++ b/gtk/gtklistitem.c
@@ -22,6 +22,7 @@
#include "gtklistitemprivate.h"
#include "gtkcssnodeprivate.h"
+#include "gtkeventcontrollerkey.h"
#include "gtkgestureclick.h"
#include "gtkintl.h"
#include "gtkmain.h"
@@ -242,6 +243,22 @@ gtk_list_item_click_gesture_pressed (GtkGestureClick *gesture,
gtk_widget_grab_focus (widget);
}
+static void
+gtk_list_item_focus_changed_cb (GtkEventControllerKey *controller,
+ GParamSpec *psepc,
+ GtkListItem *self)
+{
+ GtkWidget *widget = GTK_WIDGET (self);
+
+ if (gtk_event_controller_key_contains_focus (controller))
+ {
+ gtk_widget_activate_action (widget,
+ "list.scroll-to-item",
+ "u",
+ self->position);
+ }
+}
+
static void
gtk_list_item_click_gesture_released (GtkGestureClick *gesture,
int n_press,
@@ -263,6 +280,7 @@ gtk_list_item_click_gesture_canceled (GtkGestureClick *gesture,
static void
gtk_list_item_init (GtkListItem *self)
{
+ GtkEventController *controller;
GtkGesture *gesture;
self->selectable = TRUE;
@@ -282,6 +300,10 @@ gtk_list_item_init (GtkListItem *self)
g_signal_connect (gesture, "cancel",
G_CALLBACK (gtk_list_item_click_gesture_canceled), self);
gtk_widget_add_controller (GTK_WIDGET (self), GTK_EVENT_CONTROLLER (gesture));
+
+ controller = gtk_event_controller_key_new ();
+ g_signal_connect (controller, "notify::contains-focus", G_CALLBACK (gtk_list_item_focus_changed_cb), self);
+ gtk_widget_add_controller (GTK_WIDGET (self), controller);
}
GtkListItem *
diff --git a/gtk/gtklistview.c b/gtk/gtklistview.c
index edfe6d047e..29cc7ef372 100644
--- a/gtk/gtklistview.c
+++ b/gtk/gtklistview.c
@@ -730,6 +730,48 @@ gtk_list_view_select_item (GtkWidget *widget,
}
}
+static void
+gtk_list_view_scroll_to_item (GtkWidget *widget,
+ const char *action_name,
+ GVariant *parameter)
+{
+ GtkListView *self = GTK_LIST_VIEW (widget);
+ ListRow *row;
+ guint pos;
+
+ if (!g_variant_check_format_string (parameter, "u", FALSE))
+ return;
+
+ g_variant_get (parameter, "u", &pos);
+ row = gtk_list_item_manager_get_nth (self->item_manager, pos, NULL);
+ if (row == NULL)
+ return;
+
+ if (row->parent.widget)
+ {
+ int y = list_row_get_y (self, row);
+ int start = gtk_adjustment_get_value (self->adjustment[GTK_ORIENTATION_VERTICAL]);
+ int height = gtk_widget_get_height (GTK_WIDGET (self));
+ double align;
+
+ if (y < start)
+ align = 0.0;
+ else if (y + row->height > start + height)
+ align = 1.0;
+ else
+ align = (double) (y - start) / (height - row->height);
+
+ gtk_list_view_set_anchor (self, pos, align);
+ }
+ else
+ {
+ if (pos < gtk_list_item_tracker_get_position (self->item_manager, self->anchor))
+ gtk_list_view_set_anchor (self, pos, 0.0);
+ else
+ gtk_list_view_set_anchor (self, pos, 1.0);
+ }
+}
+
static void
gtk_list_view_class_init (GtkListViewClass *klass)
{
@@ -809,6 +851,18 @@ gtk_list_view_class_init (GtkListViewClass *klass)
"(ubb)",
gtk_list_view_select_item);
+ /**
+ * GtkListView|list.scroll-to-item:
+ * @position: position of item to scroll to
+ *
+ * Scrolls to the item given in @position with the minimum amount
+ * of scrolling required. If the item is already visible, nothing happens.
+ */
+ gtk_widget_class_install_action (widget_class,
+ "list.scroll-to-item",
+ "u",
+ gtk_list_view_scroll_to_item);
+
gtk_widget_class_set_css_name (widget_class, I_("list"));
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]