[gtk/wip/otte/listview: 4/11] listitemwidget: Add single-click-activate



commit d824a301da4b0f4f93e23091fb58c3f9425e0f58
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Dec 13 20:56:32 2019 -0500

    listitemwidget: Add single-click-activate
    
    Add a mode to GtkListItemWidget that activates on
    single click and selects on hover. Make
    GtkListItemManager set this on its items
    when its own 'property' of the same name is set.

 gtk/gtklistitemmanager.c        | 30 +++++++++++++++++++++++
 gtk/gtklistitemmanagerprivate.h |  5 ++++
 gtk/gtklistitemwidget.c         | 54 ++++++++++++++++++++++++++++++++++++++++-
 gtk/gtklistitemwidgetprivate.h  |  3 +++
 4 files changed, 91 insertions(+), 1 deletion(-)
---
diff --git a/gtk/gtklistitemmanager.c b/gtk/gtklistitemmanager.c
index 92221235b6..ef0570d45a 100644
--- a/gtk/gtklistitemmanager.c
+++ b/gtk/gtklistitemmanager.c
@@ -33,6 +33,7 @@ struct _GtkListItemManager
   GtkWidget *widget;
   GtkSelectionModel *model;
   GtkListItemFactory *factory;
+  gboolean single_click_activate;
   const char *item_css_name;
 
   GtkRbTree *items;
@@ -932,6 +933,8 @@ gtk_list_item_manager_acquire_list_item (GtkListItemManager *self,
   result = gtk_list_item_widget_new (self->factory,
                                      self->item_css_name);
 
+  gtk_list_item_widget_set_single_click_activate (GTK_LIST_ITEM_WIDGET (result), 
self->single_click_activate);
+
   item = g_list_model_get_item (G_LIST_MODEL (self->model), position);
   selected = gtk_selection_model_is_selected (self->model, position);
   gtk_list_item_widget_update (GTK_LIST_ITEM_WIDGET (result), position, item, selected);
@@ -1079,6 +1082,33 @@ gtk_list_item_manager_release_list_item (GtkListItemManager *self,
   gtk_widget_unparent (item);
 }
 
+void
+gtk_list_item_manager_set_single_click_activate (GtkListItemManager *self,
+                                                 gboolean            single_click_activate)
+{
+  GtkListItemManagerItem *item;
+
+  g_return_if_fail (GTK_IS_LIST_ITEM_MANAGER (self));
+
+  self->single_click_activate = single_click_activate;
+
+  for (item = gtk_rb_tree_get_first (self->items);
+       item != NULL;
+       item = gtk_rb_tree_node_get_next (item))
+    {
+      if (item->widget)
+        gtk_list_item_widget_set_single_click_activate (GTK_LIST_ITEM_WIDGET (item->widget), 
single_click_activate);
+    }
+}
+
+gboolean
+gtk_list_item_manager_get_single_click_activate (GtkListItemManager   *self)
+{
+  g_return_val_if_fail (GTK_IS_LIST_ITEM_MANAGER (self), FALSE);
+
+  return self->single_click_activate;
+}
+
 GtkListItemTracker *
 gtk_list_item_tracker_new (GtkListItemManager *self)
 {
diff --git a/gtk/gtklistitemmanagerprivate.h b/gtk/gtklistitemmanagerprivate.h
index 18cdc6d9ff..ccb0570c20 100644
--- a/gtk/gtklistitemmanagerprivate.h
+++ b/gtk/gtklistitemmanagerprivate.h
@@ -87,6 +87,11 @@ void                    gtk_list_item_manager_set_model         (GtkListItemMana
 GtkSelectionModel *     gtk_list_item_manager_get_model         (GtkListItemManager     *self);
 
 guint                   gtk_list_item_manager_get_size          (GtkListItemManager     *self);
+void                    gtk_list_item_manager_set_single_click_activate
+                                                                (GtkListItemManager   *self,
+                                                                 gboolean              
single_click_activate);
+gboolean                gtk_list_item_manager_get_single_click_activate
+                                                                (GtkListItemManager   *self);
 
 GtkListItemTracker *    gtk_list_item_tracker_new               (GtkListItemManager     *self);
 void                    gtk_list_item_tracker_free              (GtkListItemManager     *self,
diff --git a/gtk/gtklistitemwidget.c b/gtk/gtklistitemwidget.c
index 60360288e2..a35e132d14 100644
--- a/gtk/gtklistitemwidget.c
+++ b/gtk/gtklistitemwidget.c
@@ -25,6 +25,7 @@
 #include "gtkbinlayout.h"
 #include "gtkcssnodeprivate.h"
 #include "gtkeventcontrollerkey.h"
+#include "gtkeventcontrollermotion.h"
 #include "gtkgestureclick.h"
 #include "gtkintl.h"
 #include "gtklistitemfactoryprivate.h"
@@ -43,11 +44,13 @@ struct _GtkListItemWidgetPrivate
   GObject *item;
   guint position;
   gboolean selected;
+  gboolean single_click_activate;
 };
 
 enum {
   PROP_0,
   PROP_FACTORY,
+  PROP_SINGLE_CLICK_ACTIVATE,
 
   N_PROPS
 };
@@ -162,6 +165,10 @@ gtk_list_item_widget_set_property (GObject      *object,
       gtk_list_item_widget_set_factory (self, g_value_get_object (value));
       break;
 
+    case PROP_SINGLE_CLICK_ACTIVATE:
+      gtk_list_item_widget_set_single_click_activate (self, g_value_get_boolean (value));
+      break;
+
     default:
       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
       break;
@@ -226,6 +233,13 @@ gtk_list_item_widget_class_init (GtkListItemWidgetClass *klass)
                          GTK_TYPE_LIST_ITEM_FACTORY,
                          G_PARAM_WRITABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
 
+  properties[PROP_SINGLE_CLICK_ACTIVATE] =
+    g_param_spec_boolean ("single-click-activate",
+                          "Single click activate",
+                          "Activate on single click",
+                          FALSE,
+                          G_PARAM_WRITABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
+
   g_object_class_install_properties (gobject_class, N_PROPS, properties);
 
   signals[ACTIVATE_SIGNAL] =
@@ -330,7 +344,7 @@ gtk_list_item_widget_click_gesture_pressed (GtkGestureClick   *gesture,
 
   if (!priv->list_item || priv->list_item->activatable)
     {
-      if (n_press == 2)
+      if (n_press == 2 || priv->single_click_activate)
         {
           gtk_widget_activate_action (GTK_WIDGET (self),
                                       "list.activate-item",
@@ -362,6 +376,26 @@ gtk_list_item_widget_focus_changed_cb (GtkEventControllerKey *controller,
     }
 }
 
+static void
+gtk_list_item_widget_hover_changed_cb (GtkEventControllerMotion *controller,
+                                       GParamSpec               *psepc,
+                                       GtkListItemWidget        *self)
+{
+  GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
+
+  if (!priv->single_click_activate ||
+      !gtk_event_controller_motion_contains_pointer (controller))
+    return;
+
+  if (!priv->list_item || priv->list_item->selectable)
+    {
+      gtk_widget_activate_action (GTK_WIDGET (self),
+                                  "list.select-item",
+                                  "(ubb)",
+                                  priv->position, FALSE, FALSE);
+    }
+}
+
 static void
 gtk_list_item_widget_click_gesture_released (GtkGestureClick   *gesture,
                                              int                n_press,
@@ -406,6 +440,10 @@ gtk_list_item_widget_init (GtkListItemWidget *self)
   controller = gtk_event_controller_key_new ();
   g_signal_connect (controller, "notify::contains-focus", G_CALLBACK 
(gtk_list_item_widget_focus_changed_cb), self);
   gtk_widget_add_controller (GTK_WIDGET (self), controller);
+
+  controller = gtk_event_controller_motion_new ();
+  g_signal_connect (controller, "notify::contains-pointer", G_CALLBACK 
(gtk_list_item_widget_hover_changed_cb), self);
+  gtk_widget_add_controller (GTK_WIDGET (self), controller);
 }
 
 GtkWidget *
@@ -540,6 +578,20 @@ gtk_list_item_widget_set_factory (GtkListItemWidget  *self,
   g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FACTORY]);
 }
 
+void
+gtk_list_item_widget_set_single_click_activate (GtkListItemWidget *self,
+                                                gboolean           single_click_activate)
+{
+  GtkListItemWidgetPrivate *priv = gtk_list_item_widget_get_instance_private (self);
+
+  if (priv->single_click_activate == single_click_activate)
+    return;
+
+  priv->single_click_activate = single_click_activate;
+
+  g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SINGLE_CLICK_ACTIVATE]);
+}
+
 void
 gtk_list_item_widget_add_child (GtkListItemWidget *self,
                                 GtkWidget         *child)
diff --git a/gtk/gtklistitemwidgetprivate.h b/gtk/gtklistitemwidgetprivate.h
index b5f2ec7393..f3c7fdbdc9 100644
--- a/gtk/gtklistitemwidgetprivate.h
+++ b/gtk/gtklistitemwidgetprivate.h
@@ -70,6 +70,9 @@ void                    gtk_list_item_widget_default_update     (GtkListItemWidg
 
 void                    gtk_list_item_widget_set_factory        (GtkListItemWidget      *self,
                                                                  GtkListItemFactory     *factory);
+void                    gtk_list_item_widget_set_single_click_activate
+                                                                (GtkListItemWidget     *self,
+                                                                 gboolean               
single_click_activate);
 void                    gtk_list_item_widget_add_child          (GtkListItemWidget      *self,
                                                                  GtkWidget              *child);
 void                    gtk_list_item_widget_remove_child       (GtkListItemWidget      *self,


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]