app: move lots of state handling from sunclasses to GimpCircle

This commit is contained in:
Michael Natterer 2014-05-30 03:25:02 +02:00
parent 7438d5bd04
commit 0df36e9dcf
4 changed files with 157 additions and 190 deletions

View File

@ -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_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_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_background_hsv (gdouble angle,
gdouble distance,
guchar *rgb);
static void gimp_circle_real_reset_target (GimpCircle *circle);
static void gimp_circle_draw_background (GimpCircle *circle,
cairo_t *cr,
gint size,
GimpCircleBackground background);
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,

View File

@ -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,

View File

@ -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,
@ -341,24 +310,6 @@ gimp_dial_button_press_event (GtkWidget *widget,
return FALSE;
}
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)
static void
gimp_dial_reset_target (GimpCircle *circle)
{
GimpDial *dial = GIMP_DIAL (widget);
dial->priv->in_widget = TRUE;
return FALSE;
}
static gboolean
gimp_dial_leave_notify_event (GtkWidget *widget,
GdkEventCrossing *event)
{
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);
}

View File

@ -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,
@ -290,24 +256,6 @@ gimp_polar_button_press_event (GtkWidget *widget,
return FALSE;
}
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)
static void
gimp_polar_reset_target (GimpCircle *circle)
{
GimpPolar *polar = GIMP_POLAR (widget);
polar->priv->in_widget = TRUE;
return FALSE;
}
static gboolean
gimp_polar_leave_notify_event (GtkWidget *widget,
GdkEventCrossing *event)
{
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);
}