[libhandy/wip/haecker-felix/flap-widget] Click to close



commit b4a4af31a21819e03ada6bbdae73de9115ed34c9
Author: Alexander Mikhaylenko <alexm gnome org>
Date:   Mon Nov 23 15:43:53 2020 +0500

    Click to close

 debian/libhandy-1-0.symbols |   2 +
 src/hdy-flap.c              | 124 +++++++++++++++++++++++++++++++++++++++++---
 src/hdy-flap.h              |   6 +++
 3 files changed, 126 insertions(+), 6 deletions(-)
---
diff --git a/debian/libhandy-1-0.symbols b/debian/libhandy-1-0.symbols
index bea9e16a..501b3016 100644
--- a/debian/libhandy-1-0.symbols
+++ b/debian/libhandy-1-0.symbols
@@ -121,6 +121,7 @@ libhandy-1.so.0 libhandy-1-0 #MINVER#
  hdy_expander_row_set_subtitle@LIBHANDY_1_0 0.80.0
  hdy_expander_row_set_use_underline@LIBHANDY_1_0 0.80.0
  hdy_flap_fold_policy_get_type@LIBHANDY_1_0 1.1.0
+ hdy_flap_get_click_to_close@LIBHANDY_1_0 1.1.0
  hdy_flap_get_flap@LIBHANDY_1_0 1.1.0
  hdy_flap_get_flap_position@LIBHANDY_1_0 1.1.0
  hdy_flap_get_fold_duration@LIBHANDY_1_0 1.1.0
@@ -133,6 +134,7 @@ libhandy-1.so.0 libhandy-1-0 #MINVER#
  hdy_flap_get_transition_type@LIBHANDY_1_0 1.1.0
  hdy_flap_get_type@LIBHANDY_1_0 1.1.0
  hdy_flap_new@LIBHANDY_1_0 1.1.0
+ hdy_flap_set_click_to_close@LIBHANDY_1_0 1.1.0
  hdy_flap_set_flap@LIBHANDY_1_0 1.1.0
  hdy_flap_set_flap_position@LIBHANDY_1_0 1.1.0
  hdy_flap_set_fold_duration@LIBHANDY_1_0 1.1.0
diff --git a/src/hdy-flap.c b/src/hdy-flap.c
index f6a8545d..440f628a 100644
--- a/src/hdy-flap.c
+++ b/src/hdy-flap.c
@@ -86,6 +86,9 @@ struct _HdyFlap
 
   HdySwipeTracker *tracker;
   gboolean swipe_active;
+
+  gboolean click_to_close;
+  GtkGesture *click_gesture;
 };
 
 static void hdy_flap_buildable_init (GtkBuildableIface *iface);
@@ -108,6 +111,7 @@ enum {
   PROP_FOLD_DURATION,
   PROP_REVEAL_DURATION,
   PROP_TRANSITION_TYPE,
+  PROP_CLICK_TO_CLOSE,
 
   /* Overridden properties */
   PROP_ORIENTATION,
@@ -253,6 +257,9 @@ set_reveal_flap (HdyFlap  *self,
       hdy_swipeable_emit_child_switched (HDY_SWIPEABLE (self), reveal_flap ? 1 : 0, duration);
   }
 
+  if (self->click_to_close)
+    gtk_event_controller_reset (GTK_EVENT_CONTROLLER (self->click_gesture));
+
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_REVEAL_FLAP]);
 }
 
@@ -281,6 +288,9 @@ set_folded (HdyFlap  *self,
   if (!self->locked)
     set_reveal_flap (self, !self->folded, self->fold_duration, TRUE);
 
+  if (self->click_to_close)
+    gtk_event_controller_reset (GTK_EVENT_CONTROLLER (self->click_gesture));
+
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_FOLDED]);
 }
 
@@ -318,6 +328,31 @@ end_swipe_cb (HdySwipeTracker *tracker,
     set_reveal_flap (self, to > 0, duration, FALSE);
 }
 
+static void
+pressed_cb (GtkGestureMultiPress *gesture,
+            gint                  n_press,
+            gdouble               x,
+            gdouble               y,
+            HdyFlap              *self)
+{
+  if (self->reveal_progress <= 0 || self->fold_progress <= 0) {
+    gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
+
+    return;
+  }
+
+  if (x >= self->flap_allocation.x &&
+      x <= self->flap_allocation.x + self->flap_allocation.width &&
+      y >= self->flap_allocation.y &&
+      y <= self->flap_allocation.y + self->flap_allocation.height) {
+    gtk_gesture_set_state (GTK_GESTURE (gesture), GTK_EVENT_SEQUENCE_DENIED);
+
+    return;
+  }
+
+  hdy_flap_set_reveal_flap (self, FALSE);
+}
+
 static void
 register_window (HdyFlap        *self,
                  GtkWidget      *widget,
@@ -1149,6 +1184,9 @@ hdy_flap_get_property (GObject    *object,
   case PROP_TRANSITION_TYPE:
     g_value_set_enum (value, hdy_flap_get_transition_type (self));
     break;
+  case PROP_CLICK_TO_CLOSE:
+    g_value_set_boolean (value, hdy_flap_get_click_to_close (self));
+    break;
   case PROP_ORIENTATION:
     g_value_set_enum (value, self->orientation);
     break;
@@ -1193,6 +1231,9 @@ hdy_flap_set_property (GObject      *object,
   case PROP_TRANSITION_TYPE:
     hdy_flap_set_transition_type (self, g_value_get_enum (value));
     break;
+  case PROP_CLICK_TO_CLOSE:
+    hdy_flap_set_click_to_close (self, g_value_get_boolean (value));
+    break;
   case PROP_ORIENTATION:
     set_orientation (self, g_value_get_enum (value));
     break;
@@ -1202,14 +1243,15 @@ hdy_flap_set_property (GObject      *object,
 }
 
 static void
-hdy_flap_finalize (GObject *object)
+hdy_flap_dispose (GObject *object)
 {
   HdyFlap *self = HDY_FLAP (object);
 
   g_clear_object (&self->shadow_helper);
   g_clear_object (&self->tracker);
+  g_clear_object (&self->click_gesture);
 
-  G_OBJECT_CLASS (hdy_flap_parent_class)->finalize (object);
+  G_OBJECT_CLASS (hdy_flap_parent_class)->dispose (object);
 }
 
 static void
@@ -1221,7 +1263,7 @@ hdy_flap_class_init (HdyFlapClass *klass)
 
   object_class->get_property = hdy_flap_get_property;
   object_class->set_property = hdy_flap_set_property;
-  object_class->finalize = hdy_flap_finalize;
+  object_class->dispose = hdy_flap_dispose;
 
   widget_class->get_preferred_width = hdy_flap_get_preferred_width;
   widget_class->get_preferred_width_for_height = hdy_flap_get_preferred_width_for_height;
@@ -1321,7 +1363,7 @@ hdy_flap_class_init (HdyFlapClass *klass)
                           _("Folded"),
                           _("Folded"),
                           FALSE,
-                          G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY);
+                          G_PARAM_READABLE);
 
   /**
    * HdyFlap:fold-duration:
@@ -1362,6 +1404,18 @@ hdy_flap_class_init (HdyFlapClass *klass)
                        HDY_FLAP_TRANSITION_TYPE_OVER,
                        G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
 
+  /**
+   * HdyFlap:click-to-close:
+   *
+   * Since: 1.1
+   */
+  props[PROP_CLICK_TO_CLOSE] =
+    g_param_spec_boolean ("click-to-close",
+                          _("Click to Close"),
+                          _("Click to Close"),
+                          TRUE,
+                          G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY);
+
   g_object_class_install_properties (object_class, LAST_PROP, props);
 
   g_object_class_override_property (object_class,
@@ -1385,6 +1439,7 @@ hdy_flap_init (HdyFlap *self)
   self->fold_progress = 0;
   self->fold_duration = 250;
   self->reveal_duration = 250;
+  self->click_to_close = TRUE;
 
   self->shadow_helper = hdy_shadow_helper_new (GTK_WIDGET (self));
   self->tracker = hdy_swipe_tracker_new (HDY_SWIPEABLE (self));
@@ -1395,6 +1450,13 @@ hdy_flap_init (HdyFlap *self)
   g_signal_connect_object (self->tracker, "end-swipe", G_CALLBACK (end_swipe_cb), self, 0);
 
   update_swipe_tracker (self);
+
+  self->click_gesture = gtk_gesture_multi_press_new (GTK_WIDGET (self));
+  gtk_gesture_single_set_exclusive (GTK_GESTURE_SINGLE (self->click_gesture), TRUE);
+  gtk_gesture_single_set_button (GTK_GESTURE_SINGLE (self->click_gesture), GDK_BUTTON_PRIMARY);
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (self->click_gesture),
+                                              GTK_PHASE_CAPTURE);
+  g_signal_connect_object (self->click_gesture, "pressed", G_CALLBACK (pressed_cb), self, 0);
 }
 
 static void
@@ -1641,7 +1703,8 @@ hdy_flap_set_flap (HdyFlap   *self,
     gtk_widget_set_parent (self->flap, GTK_WIDGET (self));
   }
 
-  hdy_swipe_tracker_set_enabled (self->tracker, self->flap != NULL);
+  if (self->tracker)
+    hdy_swipe_tracker_set_enabled (self->tracker, self->flap != NULL);
 
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_FLAP]);
 }
@@ -1697,7 +1760,8 @@ hdy_flap_set_separator (HdyFlap   *self,
     gtk_widget_set_parent (self->separator, GTK_WIDGET (self));
   }
 
-  hdy_swipe_tracker_set_enabled (self->tracker, self->separator != NULL);
+  if (self->tracker)
+    hdy_swipe_tracker_set_enabled (self->tracker, self->separator != NULL);
 
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_SEPARATOR]);
 }
@@ -1988,3 +2052,51 @@ hdy_flap_set_transition_type (HdyFlap               *self,
 
   g_object_notify_by_pspec (G_OBJECT (self), props[PROP_TRANSITION_TYPE]);
 }
+
+/**
+ * hdy_flap_get_click_to_close:
+ * @self: a #HdyFlap
+ *
+ * Returns: %TRUE if flap widget is click to close.
+ *
+ * Since: 1.1
+ */
+gboolean
+hdy_flap_get_click_to_close (HdyFlap *self)
+{
+  g_return_val_if_fail (HDY_IS_FLAP (self), FALSE);
+
+  return self->click_to_close;
+}
+
+/**
+ * hdy_flap_set_click_to_close:
+ * @self: a #HdyFlap
+ * @click_to_close: Reveal flap
+ *
+ * Since: 1.1
+ */
+void
+hdy_flap_set_click_to_close (HdyFlap  *self,
+                             gboolean  click_to_close)
+{
+  GtkPropagationPhase phase = GTK_PHASE_NONE;
+
+  g_return_if_fail (HDY_IS_FLAP (self));
+
+  click_to_close = !!click_to_close;
+
+  if (self->click_to_close == click_to_close)
+    return;
+
+  self->click_to_close = click_to_close;
+
+  if (click_to_close)
+    phase = GTK_PHASE_CAPTURE;
+
+  gtk_event_controller_reset (GTK_EVENT_CONTROLLER (self->click_gesture));
+  gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (self->click_gesture),
+                                              phase);
+
+  g_object_notify_by_pspec (G_OBJECT (self), props[PROP_CLICK_TO_CLOSE]);
+}
diff --git a/src/hdy-flap.h b/src/hdy-flap.h
index ca9a078b..7d1d776d 100644
--- a/src/hdy-flap.h
+++ b/src/hdy-flap.h
@@ -94,4 +94,10 @@ HDY_AVAILABLE_IN_1_1
 void                  hdy_flap_set_transition_type (HdyFlap               *self,
                                                     HdyFlapTransitionType  transition_type);
 
+HDY_AVAILABLE_IN_1_1
+gboolean hdy_flap_get_click_to_close (HdyFlap  *self);
+HDY_AVAILABLE_IN_1_1
+void     hdy_flap_set_click_to_close (HdyFlap  *self,
+                                      gboolean  click_to_close);
+
 G_END_DECLS


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