From b9c7f4fe1ee4d68e287c3cceb955d850fba26eeb Mon Sep 17 00:00:00 2001 From: Michael Natterer Date: Sun, 25 May 2014 18:22:44 +0200 Subject: [PATCH] app: make GimpDial's backgrond configurable and add a plain version which does not show any background color wheel. --- app/widgets/gimpdial.c | 220 +++++++++++++++++++++--------------- app/widgets/widgets-enums.c | 29 +++++ app/widgets/widgets-enums.h | 11 ++ 3 files changed, 169 insertions(+), 91 deletions(-) diff --git a/app/widgets/gimpdial.c b/app/widgets/gimpdial.c index 957ba8eabd..5d0901cc67 100644 --- a/app/widgets/gimpdial.c +++ b/app/widgets/gimpdial.c @@ -38,14 +38,12 @@ #define SEGMENT_FRACTION 0.3 -typedef void (* GimpDialBGFunc) (gdouble angle, - gdouble distance, - guchar *rgb); enum { PROP_0, PROP_BORDER_WIDTH, + PROP_BACKGROUND, PROP_ALPHA, PROP_BETA, PROP_CLOCKWISE @@ -61,59 +59,59 @@ typedef enum struct _GimpDialPrivate { - gdouble alpha; - gdouble beta; - gboolean clockwise; + gint border_width; + GimpDialBackground background; + + gdouble alpha; + gdouble beta; + gboolean clockwise; GdkWindow *event_window; - DialTarget target; gdouble last_angle; - - gint border_width; guint has_grab : 1; }; -static void gimp_dial_dispose (GObject *object); -static void gimp_dial_set_property (GObject *object, - guint property_id, - const GValue *value, - GParamSpec *pspec); -static void gimp_dial_get_property (GObject *object, - guint property_id, - GValue *value, - GParamSpec *pspec); +static void gimp_dial_dispose (GObject *object); +static void gimp_dial_set_property (GObject *object, + guint property_id, + const GValue *value, + GParamSpec *pspec); +static void gimp_dial_get_property (GObject *object, + guint property_id, + GValue *value, + GParamSpec *pspec); -static void gimp_dial_realize (GtkWidget *widget); -static void gimp_dial_unrealize (GtkWidget *widget); -static void gimp_dial_map (GtkWidget *widget); -static void gimp_dial_unmap (GtkWidget *widget); -static void gimp_dial_size_request (GtkWidget *widget, - GtkRequisition *requisition); -static void gimp_dial_size_allocate (GtkWidget *widget, - GtkAllocation *allocation); -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 void gimp_dial_realize (GtkWidget *widget); +static void gimp_dial_unrealize (GtkWidget *widget); +static void gimp_dial_map (GtkWidget *widget); +static void gimp_dial_unmap (GtkWidget *widget); +static void gimp_dial_size_request (GtkWidget *widget, + GtkRequisition *requisition); +static void gimp_dial_size_allocate (GtkWidget *widget, + GtkAllocation *allocation); +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 void gimp_dial_background_func_hsv (gdouble angle, - gdouble distance, - guchar *rgb); +static void gimp_dial_background_hsv (gdouble angle, + gdouble distance, + guchar *rgb); -static void gimp_dial_draw_background (cairo_t *cr, - gint size, - GimpDialBGFunc bg_func); -static void gimp_dial_draw_arrows (cairo_t *cr, - gint size, - gdouble alpha, - gdouble beta, - gboolean clockwise); +static void gimp_dial_draw_background (cairo_t *cr, + gint size, + GimpDialBackground background); +static void gimp_dial_draw_arrows (cairo_t *cr, + gint size, + gdouble alpha, + gdouble beta, + gboolean clockwise); G_DEFINE_TYPE (GimpDial, gimp_dial, GTK_TYPE_WIDGET) @@ -149,6 +147,14 @@ gimp_dial_class_init (GimpDialClass *klass) GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, PROP_BACKGROUND, + g_param_spec_enum ("background", + NULL, NULL, + GIMP_TYPE_DIAL_BACKGROUND, + GIMP_DIAL_BACKGROUND_HSV, + GIMP_PARAM_READWRITE | + G_PARAM_CONSTRUCT)); + g_object_class_install_property (object_class, PROP_ALPHA, g_param_spec_double ("alpha", NULL, NULL, @@ -208,6 +214,11 @@ gimp_dial_set_property (GObject *object, gtk_widget_queue_resize (GTK_WIDGET (dial)); break; + case PROP_BACKGROUND: + dial->priv->background = g_value_get_enum (value); + gtk_widget_queue_draw (GTK_WIDGET (dial)); + break; + case PROP_ALPHA: dial->priv->alpha = g_value_get_double (value); gtk_widget_queue_draw (GTK_WIDGET (dial)); @@ -243,6 +254,10 @@ gimp_dial_get_property (GObject *object, g_value_set_int (value, dial->priv->border_width); break; + case PROP_BACKGROUND: + g_value_set_enum (value, dial->priv->background); + break; + case PROP_ALPHA: g_value_set_double (value, dial->priv->alpha); break; @@ -386,7 +401,7 @@ gimp_dial_expose_event (GtkWidget *widget, allocation.x + border_width + x, allocation.y + border_width + y); - gimp_dial_draw_background (cr, size, gimp_dial_background_func_hsv); + gimp_dial_draw_background (cr, size, dial->priv->background); gimp_dial_draw_arrows (cr, size, dial->priv->alpha, dial->priv->beta, dial->priv->clockwise); @@ -575,9 +590,9 @@ gimp_dial_new (void) /* private functions */ static void -gimp_dial_background_func_hsv (gdouble angle, - gdouble distance, - guchar *rgb) +gimp_dial_background_hsv (gdouble angle, + gdouble distance, + guchar *rgb) { gdouble v = 1 - sqrt (distance) / 4; /* it just looks nicer this way */ @@ -585,53 +600,74 @@ gimp_dial_background_func_hsv (gdouble angle, } static void -gimp_dial_draw_background (cairo_t *cr, - gint size, - GimpDialBGFunc bg_func) +gimp_dial_draw_background (cairo_t *cr, + gint size, + GimpDialBackground background) { - cairo_surface_t *surface; - guchar *data; - gint stride; - gint x, y; - - surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, size, size); - - data = cairo_image_surface_get_data (surface); - stride = cairo_image_surface_get_stride (surface); - - for (y = 0; y < size; y++) - { - for (x = 0; x < size; x++) - { - gdouble angle; - gdouble distance; - guchar rgb[3]; - - angle = get_angle_and_distance (size / 2.0, size / 2.0, size / 2.0, - x, y, - &distance); - - bg_func (angle, MIN (1.0, distance), rgb); - - GIMP_CAIRO_ARGB32_SET_PIXEL (data + y * stride + x * 4, - rgb[0], rgb[1], rgb[2], 255); - } - } - - cairo_surface_mark_dirty (surface); - cairo_save (cr); - cairo_set_source_surface (cr, surface, 0.0, 0.0); + if (background == GIMP_DIAL_BACKGROUND_PLAIN) + { + cairo_arc (cr, size / 2.0, size / 2.0, size / 2.0 - 1.5, 0.0, 2 * G_PI); - cairo_arc (cr, size / 2.0, size / 2.0, size / 2.0, 0.0, 2 * G_PI); - cairo_clip (cr); + cairo_set_line_width (cr, 3.0); + cairo_set_source_rgba (cr, 1.0, 1.0, 1.0, 0.6); + cairo_stroke_preserve (cr); - cairo_paint (cr); + cairo_set_line_width (cr, 1.0); + cairo_set_source_rgba (cr, 0.0, 0.0, 0.0, 0.8); + cairo_stroke (cr); + } + else + { + cairo_surface_t *surface; + guchar *data; + gint stride; + gint x, y; + + surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, size, size); + + data = cairo_image_surface_get_data (surface); + stride = cairo_image_surface_get_stride (surface); + + for (y = 0; y < size; y++) + { + for (x = 0; x < size; x++) + { + gdouble angle; + gdouble distance; + guchar rgb[3] = { 0, }; + + angle = get_angle_and_distance (size / 2.0, size / 2.0, size / 2.0, + x, y, + &distance); + + switch (background) + { + case GIMP_DIAL_BACKGROUND_HSV: + gimp_dial_background_hsv (angle, distance, rgb); + break; + + default: + break; + } + + GIMP_CAIRO_ARGB32_SET_PIXEL (data + y * stride + x * 4, + rgb[0], rgb[1], rgb[2], 255); + } + } + + cairo_surface_mark_dirty (surface); + cairo_set_source_surface (cr, surface, 0.0, 0.0); + cairo_surface_destroy (surface); + + cairo_arc (cr, size / 2.0, size / 2.0, size / 2.0, 0.0, 2 * G_PI); + cairo_clip (cr); + + cairo_paint (cr); + } cairo_restore (cr); - - cairo_surface_destroy (surface); } static void @@ -641,7 +677,7 @@ gimp_dial_draw_arrows (cairo_t *cr, gdouble beta, gboolean clockwise) { - gint radius = size / 2.0; + gint radius = size / 2.0 - 1.5; gint dist; gint direction = clockwise ? -1 : 1; @@ -651,6 +687,8 @@ gimp_dial_draw_arrows (cairo_t *cr, cairo_save (cr); + cairo_translate (cr, 1.5, 1.5); /* half the broad line width */ + cairo_move_to (cr, radius, radius); cairo_line_to (cr, ROUND (radius + radius * cos (alpha)), @@ -697,7 +735,7 @@ gimp_dial_draw_arrows (cairo_t *cr, radius + dist * cos (beta), radius - dist * sin (beta)); cairo_line_to (cr, - ROUND (radius + dist * cos(beta) + + ROUND (radius + dist * cos (beta) + direction * TICK * sin (beta)), ROUND (radius - dist * sin(beta) + direction * TICK * cos (beta))); diff --git a/app/widgets/widgets-enums.c b/app/widgets/widgets-enums.c index 9f6d07bf72..368da01de8 100644 --- a/app/widgets/widgets-enums.c +++ b/app/widgets/widgets-enums.c @@ -163,6 +163,35 @@ gimp_color_pick_state_get_type (void) return type; } +GType +gimp_dial_background_get_type (void) +{ + static const GEnumValue values[] = + { + { GIMP_DIAL_BACKGROUND_PLAIN, "GIMP_DIAL_BACKGROUND_PLAIN", "plain" }, + { GIMP_DIAL_BACKGROUND_HSV, "GIMP_DIAL_BACKGROUND_HSV", "hsv" }, + { 0, NULL, NULL } + }; + + static const GimpEnumDesc descs[] = + { + { GIMP_DIAL_BACKGROUND_PLAIN, NC_("dial-background", "Plain"), NULL }, + { GIMP_DIAL_BACKGROUND_HSV, NC_("dial-background", "HSV"), NULL }, + { 0, NULL, NULL } + }; + + static GType type = 0; + + if (G_UNLIKELY (! type)) + { + type = g_enum_register_static ("GimpDialBackground", values); + gimp_type_set_translation_context (type, "dial-background"); + gimp_enum_set_value_descriptions (type, descs); + } + + return type; +} + GType gimp_histogram_scale_get_type (void) { diff --git a/app/widgets/widgets-enums.h b/app/widgets/widgets-enums.h index 0c846eea24..3286b39545 100644 --- a/app/widgets/widgets-enums.h +++ b/app/widgets/widgets-enums.h @@ -83,6 +83,17 @@ typedef enum } GimpColorPickState; +#define GIMP_TYPE_DIAL_BACKGROUND (gimp_dial_background_get_type ()) + +GType gimp_dial_background_get_type (void) G_GNUC_CONST; + +typedef enum +{ + GIMP_DIAL_BACKGROUND_PLAIN, /*< desc="Plain" >*/ + GIMP_DIAL_BACKGROUND_HSV /*< desc="HSV" >*/ +} GimpDialBackground; + + #define GIMP_TYPE_HISTOGRAM_SCALE (gimp_histogram_scale_get_type ()) GType gimp_histogram_scale_get_type (void) G_GNUC_CONST;