[libdazzle/dzl-suggestion-entry-touch-selection] suggestion-entry: Add touch based single press selection



commit 9d00621106af8d59a2932dd82f4c1d7052f566e5
Author: Jan-Michael Brummer <jan brummer tabos org>
Date:   Sat Sep 28 14:15:31 2019 +0200

    suggestion-entry: Add touch based single press selection
    
    Analog to common mobile systems select whole text on first press into the entry. Every following
    press will just set the text marker position.

 src/suggestions/dzl-suggestion-entry.c | 69 ++++++++++++++++++++++------------
 1 file changed, 46 insertions(+), 23 deletions(-)
---
diff --git a/src/suggestions/dzl-suggestion-entry.c b/src/suggestions/dzl-suggestion-entry.c
index 896e5bb..0694951 100644
--- a/src/suggestions/dzl-suggestion-entry.c
+++ b/src/suggestions/dzl-suggestion-entry.c
@@ -37,6 +37,7 @@ typedef struct
   DzlSuggestionPopover      *popover;
   DzlSuggestionEntryBuffer  *buffer;
   GListModel                *model;
+  GtkGesture                *press_gesture;
 
   gulong                     changed_handler;
 
@@ -46,6 +47,7 @@ typedef struct
 
   guint                      activate_on_single_click : 1;
   guint                      compact : 1;
+  guint                      allow_touch_selection : 1;
 
   gint                       in_key_press;
   gint                       in_move_by;
@@ -173,6 +175,7 @@ dzl_suggestion_entry_focus_out_event (GtkWidget     *widget,
     _dzl_suggestion_popover_set_focused (priv->popover, FALSE);
 
   g_signal_emit (self, signals [HIDE_SUGGESTIONS], 0);
+  priv->allow_touch_selection = TRUE;
 
   return GTK_WIDGET_CLASS (dzl_suggestion_entry_parent_class)->focus_out_event (widget, event);
 }
@@ -435,6 +438,7 @@ dzl_suggestion_entry_destroy (GtkWidget *widget)
     gtk_widget_destroy (GTK_WIDGET (priv->popover));
 
   g_clear_object (&priv->model);
+  g_clear_object (&priv->press_gesture);
 
   g_assert (priv->popover == NULL);
 
@@ -688,6 +692,44 @@ dzl_suggestion_entry_class_init (DzlSuggestionEntryClass *klass)
   changed_signal_id = g_signal_lookup ("changed", GTK_TYPE_ENTRY);
 }
 
+static void
+dzl_suggestion_entry_set_selection_bounds (GtkEditable *editable,
+                                           gint         start_pos,
+                                           gint         end_pos)
+{
+  DzlSuggestionEntry *self = (DzlSuggestionEntry *)editable;
+  DzlSuggestionEntryPrivate *priv = dzl_suggestion_entry_get_instance_private (self);
+
+  g_assert (DZL_IS_SUGGESTION_ENTRY (self));
+
+  g_signal_handler_block (self, priv->changed_handler);
+
+  if (end_pos < 0)
+    end_pos = gtk_entry_buffer_get_length (GTK_ENTRY_BUFFER (priv->buffer));
+
+  if (end_pos > (gint)dzl_suggestion_entry_buffer_get_typed_length (priv->buffer))
+    dzl_suggestion_entry_buffer_commit (priv->buffer);
+
+  editable_parent_iface->set_selection_bounds (editable, start_pos, end_pos);
+
+  g_signal_handler_unblock (self, priv->changed_handler);
+}
+
+static
+void gesture_released (GtkGestureMultiPress *gesture,
+                       gint                  n_press,
+                       gdouble               x,
+                       gdouble               y,
+                       DzlSuggestionEntry   *self)
+{
+  DzlSuggestionEntryPrivate *priv = dzl_suggestion_entry_get_instance_private (self);
+
+  if (n_press == 1 && priv->allow_touch_selection) {
+    dzl_suggestion_entry_set_selection_bounds (GTK_EDITABLE (self), 0, -1);
+    priv->allow_touch_selection = FALSE;
+  }
+}
+
 static void
 dzl_suggestion_entry_init (DzlSuggestionEntry *self)
 {
@@ -727,6 +769,10 @@ dzl_suggestion_entry_init (DzlSuggestionEntry *self)
                                "suggestion");
 
   priv->buffer = dzl_suggestion_entry_buffer_new ();
+
+  priv->press_gesture = gtk_gesture_multi_press_new (GTK_WIDGET (self));
+  gtk_gesture_single_set_touch_only (GTK_GESTURE_SINGLE (priv->press_gesture), TRUE);
+  g_signal_connect (priv->press_gesture, "released", G_CALLBACK (gesture_released), self);
 }
 
 GtkWidget *
@@ -755,29 +801,6 @@ buildable_iface_init (GtkBuildableIface *iface)
   iface->get_internal_child = dzl_suggestion_entry_get_internal_child;
 }
 
-static void
-dzl_suggestion_entry_set_selection_bounds (GtkEditable *editable,
-                                           gint         start_pos,
-                                           gint         end_pos)
-{
-  DzlSuggestionEntry *self = (DzlSuggestionEntry *)editable;
-  DzlSuggestionEntryPrivate *priv = dzl_suggestion_entry_get_instance_private (self);
-
-  g_assert (DZL_IS_SUGGESTION_ENTRY (self));
-
-  g_signal_handler_block (self, priv->changed_handler);
-
-  if (end_pos < 0)
-    end_pos = gtk_entry_buffer_get_length (GTK_ENTRY_BUFFER (priv->buffer));
-
-  if (end_pos > (gint)dzl_suggestion_entry_buffer_get_typed_length (priv->buffer))
-    dzl_suggestion_entry_buffer_commit (priv->buffer);
-
-  editable_parent_iface->set_selection_bounds (editable, start_pos, end_pos);
-
-  g_signal_handler_unblock (self, priv->changed_handler);
-}
-
 static void
 editable_iface_init (GtkEditableInterface *iface)
 {


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