[gimp] app: move lots of state handling from sunclasses to GimpCircle



commit 0df36e9dcfbc9d0fd02631df434746c1dc4cd7a5
Author: Michael Natterer <mitch gimp org>
Date:   Fri May 30 03:25:02 2014 +0200

    app: move lots of state handling from sunclasses to GimpCircle

 app/widgets/gimpcircle.c |  161 +++++++++++++++++++++++++++++++++++++--------
 app/widgets/gimpcircle.h |    5 +-
 app/widgets/gimpdial.c   |   92 ++++-----------------------
 app/widgets/gimppolar.c  |   95 ++++------------------------
 4 files changed, 160 insertions(+), 193 deletions(-)
---
diff --git a/app/widgets/gimpcircle.c b/app/widgets/gimpcircle.c
index 95d9a03..2f146c3 100644
--- a/app/widgets/gimpcircle.c
+++ b/app/widgets/gimpcircle.c
@@ -53,38 +53,50 @@ struct _GimpCirclePrivate
 
   GdkWindow            *event_window;
   cairo_surface_t      *surface;
+  gboolean              has_grab;
+  gboolean              in_widget;
 };
 
 
-static void        gimp_circle_dispose         (GObject              *object);
-static void        gimp_circle_set_property    (GObject              *object,
-                                                guint                 property_id,
-                                                const GValue         *value,
-                                                GParamSpec           *pspec);
-static void        gimp_circle_get_property    (GObject              *object,
-                                                guint                 property_id,
-                                                GValue               *value,
-                                                GParamSpec           *pspec);
-
-static void        gimp_circle_realize         (GtkWidget            *widget);
-static void        gimp_circle_unrealize       (GtkWidget            *widget);
-static void        gimp_circle_map             (GtkWidget            *widget);
-static void        gimp_circle_unmap           (GtkWidget            *widget);
-static void        gimp_circle_size_request    (GtkWidget            *widget,
-                                                GtkRequisition       *requisition);
-static void        gimp_circle_size_allocate   (GtkWidget            *widget,
-                                                GtkAllocation        *allocation);
-static gboolean    gimp_circle_expose_event    (GtkWidget            *widget,
-                                                GdkEventExpose       *event);
-
-static void        gimp_circle_background_hsv  (gdouble               angle,
-                                                gdouble               distance,
-                                                guchar               *rgb);
-
-static void        gimp_circle_draw_background (GimpCircle           *circle,
-                                                cairo_t              *cr,
-                                                gint                  size,
-                                                GimpCircleBackground  background);
+static void        gimp_circle_dispose              (GObject              *object);
+static void        gimp_circle_set_property         (GObject              *object,
+                                                     guint                 property_id,
+                                                     const GValue         *value,
+                                                     GParamSpec           *pspec);
+static void        gimp_circle_get_property         (GObject              *object,
+                                                     guint                 property_id,
+                                                     GValue               *value,
+                                                     GParamSpec           *pspec);
+
+static void        gimp_circle_realize              (GtkWidget            *widget);
+static void        gimp_circle_unrealize            (GtkWidget            *widget);
+static void        gimp_circle_map                  (GtkWidget            *widget);
+static void        gimp_circle_unmap                (GtkWidget            *widget);
+static void        gimp_circle_size_request         (GtkWidget            *widget,
+                                                     GtkRequisition       *requisition);
+static void        gimp_circle_size_allocate        (GtkWidget            *widget,
+                                                     GtkAllocation        *allocation);
+static gboolean    gimp_circle_expose_event         (GtkWidget            *widget,
+                                                     GdkEventExpose       *event);
+static gboolean    gimp_circle_button_press_event   (GtkWidget            *widget,
+                                                     GdkEventButton       *bevent);
+static gboolean    gimp_circle_button_release_event (GtkWidget            *widget,
+                                                     GdkEventButton       *bevent);
+static gboolean    gimp_circle_enter_notify_event   (GtkWidget            *widget,
+                                                     GdkEventCrossing     *event);
+static gboolean    gimp_circle_leave_notify_event   (GtkWidget            *widget,
+                                                     GdkEventCrossing     *event);
+
+static void        gimp_circle_real_reset_target    (GimpCircle           *circle);
+
+static void        gimp_circle_background_hsv       (gdouble               angle,
+                                                     gdouble               distance,
+                                                     guchar               *rgb);
+
+static void        gimp_circle_draw_background      (GimpCircle           *circle,
+                                                     cairo_t              *cr,
+                                                     gint                  size,
+                                                     GimpCircleBackground  background);
 
 
 G_DEFINE_TYPE (GimpCircle, gimp_circle, GTK_TYPE_WIDGET)
@@ -109,6 +121,12 @@ gimp_circle_class_init (GimpCircleClass *klass)
   widget_class->size_request         = gimp_circle_size_request;
   widget_class->size_allocate        = gimp_circle_size_allocate;
   widget_class->expose_event         = gimp_circle_expose_event;
+  widget_class->button_press_event   = gimp_circle_button_press_event;
+  widget_class->button_release_event = gimp_circle_button_release_event;
+  widget_class->enter_notify_event   = gimp_circle_enter_notify_event;
+  widget_class->leave_notify_event   = gimp_circle_leave_notify_event;
+
+  klass->reset_target                = gimp_circle_real_reset_target;
 
   g_object_class_install_property (object_class, PROP_SIZE,
                                    g_param_spec_int ("size",
@@ -143,6 +161,13 @@ gimp_circle_init (GimpCircle *circle)
                                               GimpCirclePrivate);
 
   gtk_widget_set_has_window (GTK_WIDGET (circle), FALSE);
+  gtk_widget_add_events (GTK_WIDGET (circle),
+                         GDK_POINTER_MOTION_MASK |
+                         GDK_BUTTON_PRESS_MASK   |
+                         GDK_BUTTON_RELEASE_MASK |
+                         GDK_BUTTON1_MOTION_MASK |
+                         GDK_ENTER_NOTIFY_MASK   |
+                         GDK_LEAVE_NOTIFY_MASK);
 }
 
 static void
@@ -281,6 +306,12 @@ gimp_circle_unmap (GtkWidget *widget)
 {
   GimpCircle *circle = GIMP_CIRCLE (widget);
 
+  if (circle->priv->has_grab)
+    {
+      gtk_grab_remove (widget);
+      circle->priv->has_grab = FALSE;
+    }
+
   if (circle->priv->event_window)
     gdk_window_hide (circle->priv->event_window);
 
@@ -349,6 +380,70 @@ gimp_circle_expose_event (GtkWidget      *widget,
   return FALSE;
 }
 
+static gboolean
+gimp_circle_button_press_event (GtkWidget      *widget,
+                                GdkEventButton *bevent)
+{
+  GimpCircle *circle = GIMP_CIRCLE (widget);
+
+  if (bevent->type == GDK_BUTTON_PRESS &&
+      bevent->button == 1)
+    {
+      gtk_grab_add (widget);
+      circle->priv->has_grab = TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+gimp_circle_button_release_event (GtkWidget      *widget,
+                                  GdkEventButton *bevent)
+{
+  GimpCircle *circle = GIMP_CIRCLE (widget);
+
+  if (bevent->button == 1)
+    {
+      gtk_grab_remove (widget);
+      circle->priv->has_grab = FALSE;
+
+      if (! circle->priv->in_widget)
+        GIMP_CIRCLE_GET_CLASS (circle)->reset_target (circle);
+    }
+
+  return FALSE;
+}
+
+static gboolean
+gimp_circle_enter_notify_event (GtkWidget        *widget,
+                                GdkEventCrossing *event)
+{
+  GimpCircle *circle = GIMP_CIRCLE (widget);
+
+  circle->priv->in_widget = TRUE;
+
+  return FALSE;
+}
+
+static gboolean
+gimp_circle_leave_notify_event (GtkWidget        *widget,
+                                GdkEventCrossing *event)
+{
+  GimpCircle *circle = GIMP_CIRCLE (widget);
+
+  circle->priv->in_widget = FALSE;
+
+  if (! circle->priv->has_grab)
+    GIMP_CIRCLE_GET_CLASS (circle)->reset_target (circle);
+
+  return FALSE;
+}
+
+static void
+gimp_circle_real_reset_target (GimpCircle *circle)
+{
+}
+
 
 /*  public functions  */
 
@@ -382,6 +477,14 @@ get_angle_and_distance (gdouble  center_x,
   return angle;
 }
 
+gboolean
+_gimp_circle_has_grab (GimpCircle *circle)
+{
+  g_return_val_if_fail (GIMP_IS_CIRCLE (circle), FALSE);
+
+  return circle->priv->has_grab;
+}
+
 gdouble
 _gimp_circle_get_angle_and_distance (GimpCircle *circle,
                                      gdouble     event_x,
diff --git a/app/widgets/gimpcircle.h b/app/widgets/gimpcircle.h
index 9c10ff3..d751e2f 100644
--- a/app/widgets/gimpcircle.h
+++ b/app/widgets/gimpcircle.h
@@ -39,7 +39,7 @@ typedef struct _GimpCircleClass   GimpCircleClass;
 
 struct _GimpCircle
 {
-  GtkWidget        parent_instance;
+  GtkWidget          parent_instance;
 
   GimpCirclePrivate *priv;
 };
@@ -47,6 +47,8 @@ struct _GimpCircle
 struct _GimpCircleClass
 {
   GtkWidgetClass  parent_class;
+
+  void (* reset_target) (GimpCircle *circle);
 };
 
 
@@ -54,6 +56,7 @@ GType          gimp_circle_get_type                (void) G_GNUC_CONST;
 
 GtkWidget    * gimp_circle_new                     (void);
 
+gboolean       _gimp_circle_has_grab               (GimpCircle *circle);
 gdouble        _gimp_circle_get_angle_and_distance (GimpCircle *circle,
                                                     gdouble     event_x,
                                                     gdouble     event_y,
diff --git a/app/widgets/gimpdial.c b/app/widgets/gimpdial.c
index 02342aa..690e960 100644
--- a/app/widgets/gimpdial.c
+++ b/app/widgets/gimpdial.c
@@ -68,8 +68,6 @@ struct _GimpDialPrivate
 
   DialTarget  target;
   gdouble     last_angle;
-  gboolean    has_grab;
-  gboolean    in_widget;
 };
 
 
@@ -82,19 +80,14 @@ static void        gimp_dial_get_property         (GObject            *object,
                                                    GValue             *value,
                                                    GParamSpec         *pspec);
 
-static void        gimp_dial_unmap                (GtkWidget          *widget);
 static gboolean    gimp_dial_expose_event         (GtkWidget          *widget,
                                                    GdkEventExpose     *event);
 static gboolean    gimp_dial_button_press_event   (GtkWidget          *widget,
                                                    GdkEventButton     *bevent);
-static gboolean    gimp_dial_button_release_event (GtkWidget          *widget,
-                                                   GdkEventButton     *bevent);
 static gboolean    gimp_dial_motion_notify_event  (GtkWidget          *widget,
                                                    GdkEventMotion     *mevent);
-static gboolean    gimp_dial_enter_notify_event   (GtkWidget          *widget,
-                                                   GdkEventCrossing   *event);
-static gboolean    gimp_dial_leave_notify_event   (GtkWidget          *widget,
-                                                   GdkEventCrossing   *event);
+
+static void        gimp_dial_reset_target         (GimpCircle         *circle);
 
 static void        gimp_dial_set_target           (GimpDial           *dial,
                                                    DialTarget          target);
@@ -120,19 +113,18 @@ G_DEFINE_TYPE (GimpDial, gimp_dial, GIMP_TYPE_CIRCLE)
 static void
 gimp_dial_class_init (GimpDialClass *klass)
 {
-  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
-  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+  GObjectClass    *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass  *widget_class = GTK_WIDGET_CLASS (klass);
+  GimpCircleClass *circle_class = GIMP_CIRCLE_CLASS (klass);
 
   object_class->get_property         = gimp_dial_get_property;
   object_class->set_property         = gimp_dial_set_property;
 
-  widget_class->unmap                = gimp_dial_unmap;
   widget_class->expose_event         = gimp_dial_expose_event;
   widget_class->button_press_event   = gimp_dial_button_press_event;
-  widget_class->button_release_event = gimp_dial_button_release_event;
   widget_class->motion_notify_event  = gimp_dial_motion_notify_event;
-  widget_class->enter_notify_event   = gimp_dial_enter_notify_event;
-  widget_class->leave_notify_event   = gimp_dial_leave_notify_event;
+
+  circle_class->reset_target         = gimp_dial_reset_target;
 
   g_object_class_install_property (object_class, PROP_ALPHA,
                                    g_param_spec_double ("alpha",
@@ -171,14 +163,6 @@ gimp_dial_init (GimpDial *dial)
   dial->priv = G_TYPE_INSTANCE_GET_PRIVATE (dial,
                                             GIMP_TYPE_DIAL,
                                             GimpDialPrivate);
-
-  gtk_widget_add_events (GTK_WIDGET (dial),
-                         GDK_POINTER_MOTION_MASK |
-                         GDK_BUTTON_PRESS_MASK   |
-                         GDK_BUTTON_RELEASE_MASK |
-                         GDK_BUTTON1_MOTION_MASK |
-                         GDK_ENTER_NOTIFY_MASK   |
-                         GDK_LEAVE_NOTIFY_MASK);
 }
 
 static void
@@ -249,20 +233,6 @@ gimp_dial_get_property (GObject    *object,
     }
 }
 
-static void
-gimp_dial_unmap (GtkWidget *widget)
-{
-  GimpDial *dial = GIMP_DIAL (widget);
-
-  if (dial->priv->has_grab)
-    {
-      gtk_grab_remove (widget);
-      dial->priv->has_grab = FALSE;
-    }
-
-  GTK_WIDGET_CLASS (parent_class)->unmap (widget);
-}
-
 static gboolean
 gimp_dial_expose_event (GtkWidget      *widget,
                         GdkEventExpose *event)
@@ -315,8 +285,7 @@ gimp_dial_button_press_event (GtkWidget      *widget,
     {
       gdouble angle;
 
-      gtk_grab_add (widget);
-      dial->priv->has_grab = TRUE;
+      GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, bevent);
 
       angle = _gimp_circle_get_angle_and_distance (GIMP_CIRCLE (dial),
                                                    bevent->x, bevent->y,
@@ -342,24 +311,6 @@ gimp_dial_button_press_event (GtkWidget      *widget,
 }
 
 static gboolean
-gimp_dial_button_release_event (GtkWidget      *widget,
-                                GdkEventButton *bevent)
-{
-  GimpDial *dial = GIMP_DIAL (widget);
-
-  if (bevent->button == 1)
-    {
-      gtk_grab_remove (widget);
-      dial->priv->has_grab = FALSE;
-
-      if (! dial->priv->in_widget)
-        gimp_dial_set_target (dial, DIAL_TARGET_NONE);
-    }
-
-  return FALSE;
-}
-
-static gboolean
 gimp_dial_motion_notify_event (GtkWidget      *widget,
                                GdkEventMotion *mevent)
 {
@@ -371,7 +322,7 @@ gimp_dial_motion_notify_event (GtkWidget      *widget,
                                                mevent->x, mevent->y,
                                                &distance);
 
-  if (dial->priv->has_grab)
+  if (_gimp_circle_has_grab (GIMP_CIRCLE (dial)))
     {
       gdouble delta;
 
@@ -437,29 +388,10 @@ gimp_dial_motion_notify_event (GtkWidget      *widget,
   return FALSE;
 }
 
-static gboolean
-gimp_dial_enter_notify_event (GtkWidget        *widget,
-                              GdkEventCrossing *event)
-{
-  GimpDial *dial = GIMP_DIAL (widget);
-
-  dial->priv->in_widget = TRUE;
-
-  return FALSE;
-}
-
-static gboolean
-gimp_dial_leave_notify_event (GtkWidget        *widget,
-                              GdkEventCrossing *event)
+static void
+gimp_dial_reset_target (GimpCircle *circle)
 {
-  GimpDial *dial = GIMP_DIAL (widget);
-
-  dial->priv->in_widget = FALSE;
-
-  if (! dial->priv->has_grab)
-    gimp_dial_set_target (dial, DIAL_TARGET_NONE);
-
-  return FALSE;
+  gimp_dial_set_target (GIMP_DIAL (circle), DIAL_TARGET_NONE);
 }
 
 
diff --git a/app/widgets/gimppolar.c b/app/widgets/gimppolar.c
index acd544f..839c65a 100644
--- a/app/widgets/gimppolar.c
+++ b/app/widgets/gimppolar.c
@@ -38,9 +38,6 @@
 #include "gimppolar.h"
 
 
-#define SEGMENT_FRACTION 0.3
-
-
 enum
 {
   PROP_0,
@@ -61,8 +58,6 @@ struct _GimpPolarPrivate
   gdouble      radius;
 
   PolarTarget  target;
-  gboolean     has_grab;
-  gboolean     in_widget;
 };
 
 
@@ -75,19 +70,14 @@ static void        gimp_polar_get_property         (GObject            *object,
                                                     GValue             *value,
                                                     GParamSpec         *pspec);
 
-static void        gimp_polar_unmap                (GtkWidget          *widget);
 static gboolean    gimp_polar_expose_event         (GtkWidget          *widget,
                                                     GdkEventExpose     *event);
 static gboolean    gimp_polar_button_press_event   (GtkWidget          *widget,
                                                     GdkEventButton     *bevent);
-static gboolean    gimp_polar_button_release_event (GtkWidget          *widget,
-                                                    GdkEventButton     *bevent);
 static gboolean    gimp_polar_motion_notify_event  (GtkWidget          *widget,
                                                     GdkEventMotion     *mevent);
-static gboolean    gimp_polar_enter_notify_event   (GtkWidget          *widget,
-                                                    GdkEventCrossing   *event);
-static gboolean    gimp_polar_leave_notify_event   (GtkWidget          *widget,
-                                                    GdkEventCrossing   *event);
+
+static void        gimp_polar_reset_target         (GimpCircle         *circle);
 
 static void        gimp_polar_set_target           (GimpPolar           *polar,
                                                     PolarTarget          target);
@@ -111,19 +101,18 @@ G_DEFINE_TYPE (GimpPolar, gimp_polar, GIMP_TYPE_CIRCLE)
 static void
 gimp_polar_class_init (GimpPolarClass *klass)
 {
-  GObjectClass   *object_class = G_OBJECT_CLASS (klass);
-  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+  GObjectClass    *object_class = G_OBJECT_CLASS (klass);
+  GtkWidgetClass  *widget_class = GTK_WIDGET_CLASS (klass);
+  GimpCircleClass *circle_class = GIMP_CIRCLE_CLASS (klass);
 
   object_class->get_property         = gimp_polar_get_property;
   object_class->set_property         = gimp_polar_set_property;
 
-  widget_class->unmap                = gimp_polar_unmap;
   widget_class->expose_event         = gimp_polar_expose_event;
   widget_class->button_press_event   = gimp_polar_button_press_event;
-  widget_class->button_release_event = gimp_polar_button_release_event;
   widget_class->motion_notify_event  = gimp_polar_motion_notify_event;
-  widget_class->enter_notify_event   = gimp_polar_enter_notify_event;
-  widget_class->leave_notify_event   = gimp_polar_leave_notify_event;
+
+  circle_class->reset_target         = gimp_polar_reset_target;
 
   g_object_class_install_property (object_class, PROP_ANGLE,
                                    g_param_spec_double ("angle",
@@ -148,14 +137,6 @@ gimp_polar_init (GimpPolar *polar)
   polar->priv = G_TYPE_INSTANCE_GET_PRIVATE (polar,
                                              GIMP_TYPE_POLAR,
                                              GimpPolarPrivate);
-
-  gtk_widget_add_events (GTK_WIDGET (polar),
-                         GDK_POINTER_MOTION_MASK |
-                         GDK_BUTTON_PRESS_MASK   |
-                         GDK_BUTTON_RELEASE_MASK |
-                         GDK_BUTTON1_MOTION_MASK |
-                         GDK_ENTER_NOTIFY_MASK   |
-                         GDK_LEAVE_NOTIFY_MASK);
 }
 
 static void
@@ -208,20 +189,6 @@ gimp_polar_get_property (GObject    *object,
     }
 }
 
-static void
-gimp_polar_unmap (GtkWidget *widget)
-{
-  GimpPolar *polar = GIMP_POLAR (widget);
-
-  if (polar->priv->has_grab)
-    {
-      gtk_grab_remove (widget);
-      polar->priv->has_grab = FALSE;
-    }
-
-  GTK_WIDGET_CLASS (parent_class)->unmap (widget);
-}
-
 static gboolean
 gimp_polar_expose_event (GtkWidget      *widget,
                          GdkEventExpose *event)
@@ -273,8 +240,7 @@ gimp_polar_button_press_event (GtkWidget      *widget,
       gdouble angle;
       gdouble radius;
 
-      gtk_grab_add (widget);
-      polar->priv->has_grab = TRUE;
+      GTK_WIDGET_CLASS (parent_class)->button_press_event (widget, bevent);
 
       angle = _gimp_circle_get_angle_and_distance (GIMP_CIRCLE (polar),
                                                    bevent->x, bevent->y,
@@ -291,24 +257,6 @@ gimp_polar_button_press_event (GtkWidget      *widget,
 }
 
 static gboolean
-gimp_polar_button_release_event (GtkWidget      *widget,
-                                 GdkEventButton *bevent)
-{
-  GimpPolar *polar = GIMP_POLAR (widget);
-
-  if (bevent->button == 1)
-    {
-      gtk_grab_remove (widget);
-      polar->priv->has_grab = FALSE;
-
-      if (! polar->priv->in_widget)
-        gimp_polar_set_target (polar, POLAR_TARGET_NONE);
-    }
-
-  return FALSE;
-}
-
-static gboolean
 gimp_polar_motion_notify_event (GtkWidget      *widget,
                                 GdkEventMotion *mevent)
 {
@@ -320,7 +268,7 @@ gimp_polar_motion_notify_event (GtkWidget      *widget,
                                                mevent->x, mevent->y,
                                                &radius);
 
-  if (polar->priv->has_grab)
+  if (_gimp_circle_has_grab (GIMP_CIRCLE (polar)))
     {
       radius = MIN (radius, 1.0);
 
@@ -356,29 +304,10 @@ gimp_polar_motion_notify_event (GtkWidget      *widget,
   return FALSE;
 }
 
-static gboolean
-gimp_polar_enter_notify_event (GtkWidget        *widget,
-                               GdkEventCrossing *event)
-{
-  GimpPolar *polar = GIMP_POLAR (widget);
-
-  polar->priv->in_widget = TRUE;
-
-  return FALSE;
-}
-
-static gboolean
-gimp_polar_leave_notify_event (GtkWidget        *widget,
-                               GdkEventCrossing *event)
+static void
+gimp_polar_reset_target (GimpCircle *circle)
 {
-  GimpPolar *polar = GIMP_POLAR (widget);
-
-  polar->priv->in_widget = FALSE;
-
-  if (! polar->priv->has_grab)
-    gimp_polar_set_target (polar, POLAR_TARGET_NONE);
-
-  return FALSE;
+  gimp_polar_set_target (GIMP_POLAR (circle), POLAR_TARGET_NONE);
 }
 
 


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