mirror of https://github.com/GNOME/gimp.git
modules: port GimpColorWheel to GTK+ 3.x
This commit is contained in:
parent
345ef9f0a9
commit
fc12d5bf7f
|
@ -95,33 +95,38 @@ enum
|
|||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static void gimp_color_wheel_dispose (GObject *object);
|
||||
|
||||
static void gimp_color_wheel_map (GtkWidget *widget);
|
||||
static void gimp_color_wheel_unmap (GtkWidget *widget);
|
||||
static void gimp_color_wheel_realize (GtkWidget *widget);
|
||||
static void gimp_color_wheel_unrealize (GtkWidget *widget);
|
||||
static void gimp_color_wheel_size_request (GtkWidget *widget,
|
||||
GtkRequisition *requisition);
|
||||
static void gimp_color_wheel_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
static gboolean gimp_color_wheel_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event);
|
||||
static gboolean gimp_color_wheel_button_release (GtkWidget *widget,
|
||||
GdkEventButton *event);
|
||||
static gboolean gimp_color_wheel_motion (GtkWidget *widget,
|
||||
GdkEventMotion *event);
|
||||
static gboolean gimp_color_wheel_expose (GtkWidget *widget,
|
||||
GdkEventExpose *event);
|
||||
static gboolean gimp_color_wheel_grab_broken (GtkWidget *widget,
|
||||
GdkEventGrabBroken *event);
|
||||
static gboolean gimp_color_wheel_focus (GtkWidget *widget,
|
||||
GtkDirectionType direction);
|
||||
static void gimp_color_wheel_move (GimpColorWheel *wheel,
|
||||
GtkDirectionType dir);
|
||||
static void gimp_color_wheel_dispose (GObject *object);
|
||||
|
||||
static void gimp_color_wheel_create_transform (GimpColorWheel *wheel);
|
||||
static void gimp_color_wheel_destroy_transform (GimpColorWheel *wheel);
|
||||
static void gimp_color_wheel_map (GtkWidget *widget);
|
||||
static void gimp_color_wheel_unmap (GtkWidget *widget);
|
||||
static void gimp_color_wheel_realize (GtkWidget *widget);
|
||||
static void gimp_color_wheel_unrealize (GtkWidget *widget);
|
||||
static void gimp_color_wheel_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void gimp_color_wheel_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural);
|
||||
static void gimp_color_wheel_size_allocate (GtkWidget *widget,
|
||||
GtkAllocation *allocation);
|
||||
static gboolean gimp_color_wheel_button_press (GtkWidget *widget,
|
||||
GdkEventButton *event);
|
||||
static gboolean gimp_color_wheel_button_release (GtkWidget *widget,
|
||||
GdkEventButton *event);
|
||||
static gboolean gimp_color_wheel_motion (GtkWidget *widget,
|
||||
GdkEventMotion *event);
|
||||
static gboolean gimp_color_wheel_draw (GtkWidget *widget,
|
||||
cairo_t *cr);
|
||||
static gboolean gimp_color_wheel_grab_broken (GtkWidget *widget,
|
||||
GdkEventGrabBroken *event);
|
||||
static gboolean gimp_color_wheel_focus (GtkWidget *widget,
|
||||
GtkDirectionType direction);
|
||||
static void gimp_color_wheel_move (GimpColorWheel *wheel,
|
||||
GtkDirectionType dir);
|
||||
|
||||
static void gimp_color_wheel_create_transform (GimpColorWheel *wheel);
|
||||
static void gimp_color_wheel_destroy_transform (GimpColorWheel *wheel);
|
||||
|
||||
|
||||
static guint wheel_signals[LAST_SIGNAL];
|
||||
|
@ -151,12 +156,13 @@ gimp_color_wheel_class_init (GimpColorWheelClass *class)
|
|||
widget_class->unmap = gimp_color_wheel_unmap;
|
||||
widget_class->realize = gimp_color_wheel_realize;
|
||||
widget_class->unrealize = gimp_color_wheel_unrealize;
|
||||
widget_class->size_request = gimp_color_wheel_size_request;
|
||||
widget_class->get_preferred_width = gimp_color_wheel_get_preferred_width;
|
||||
widget_class->get_preferred_height = gimp_color_wheel_get_preferred_height;
|
||||
widget_class->size_allocate = gimp_color_wheel_size_allocate;
|
||||
widget_class->button_press_event = gimp_color_wheel_button_press;
|
||||
widget_class->button_release_event = gimp_color_wheel_button_release;
|
||||
widget_class->motion_notify_event = gimp_color_wheel_motion;
|
||||
widget_class->expose_event = gimp_color_wheel_expose;
|
||||
widget_class->draw = gimp_color_wheel_draw;
|
||||
widget_class->focus = gimp_color_wheel_focus;
|
||||
widget_class->grab_broken_event = gimp_color_wheel_grab_broken;
|
||||
|
||||
|
@ -183,32 +189,32 @@ gimp_color_wheel_class_init (GimpColorWheelClass *class)
|
|||
|
||||
binding_set = gtk_binding_set_by_class (class);
|
||||
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_Up, 0,
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Up, 0,
|
||||
"move", 1,
|
||||
G_TYPE_ENUM, GTK_DIR_UP);
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KP_Up, 0,
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Up, 0,
|
||||
"move", 1,
|
||||
G_TYPE_ENUM, GTK_DIR_UP);
|
||||
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_Down, 0,
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Down, 0,
|
||||
"move", 1,
|
||||
G_TYPE_ENUM, GTK_DIR_DOWN);
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KP_Down, 0,
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Down, 0,
|
||||
"move", 1,
|
||||
G_TYPE_ENUM, GTK_DIR_DOWN);
|
||||
|
||||
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_Right, 0,
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Right, 0,
|
||||
"move", 1,
|
||||
G_TYPE_ENUM, GTK_DIR_RIGHT);
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KP_Right, 0,
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Right, 0,
|
||||
"move", 1,
|
||||
G_TYPE_ENUM, GTK_DIR_RIGHT);
|
||||
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_Left, 0,
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KEY_Left, 0,
|
||||
"move", 1,
|
||||
G_TYPE_ENUM, GTK_DIR_LEFT);
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KP_Left, 0,
|
||||
gtk_binding_entry_add_signal (binding_set, GDK_KEY_KP_Left, 0,
|
||||
"move", 1,
|
||||
G_TYPE_ENUM, GTK_DIR_LEFT);
|
||||
|
||||
|
@ -311,8 +317,6 @@ gimp_color_wheel_realize (GtkWidget *widget)
|
|||
|
||||
priv->window = gdk_window_new (parent_window, &attr, attr_mask);
|
||||
gdk_window_set_user_data (priv->window, wheel);
|
||||
|
||||
gtk_widget_style_attach (widget);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -329,8 +333,9 @@ gimp_color_wheel_unrealize (GtkWidget *widget)
|
|||
}
|
||||
|
||||
static void
|
||||
gimp_color_wheel_size_request (GtkWidget *widget,
|
||||
GtkRequisition *requisition)
|
||||
gimp_color_wheel_get_preferred_width (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
|
@ -340,8 +345,23 @@ gimp_color_wheel_size_request (GtkWidget *widget,
|
|||
"focus-padding", &focus_pad,
|
||||
NULL);
|
||||
|
||||
requisition->width = DEFAULT_SIZE + 2 * (focus_width + focus_pad);
|
||||
requisition->height = DEFAULT_SIZE + 2 * (focus_width + focus_pad);
|
||||
*minimum = *natural = DEFAULT_SIZE + 2 * (focus_width + focus_pad);
|
||||
}
|
||||
|
||||
static void
|
||||
gimp_color_wheel_get_preferred_height (GtkWidget *widget,
|
||||
gint *minimum,
|
||||
gint *natural)
|
||||
{
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
|
||||
gtk_widget_style_get (widget,
|
||||
"focus-line-width", &focus_width,
|
||||
"focus-padding", &focus_pad,
|
||||
NULL);
|
||||
|
||||
*minimum = *natural = DEFAULT_SIZE + 2 * (focus_width + focus_pad);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -664,7 +684,7 @@ set_cross_grab (GimpColorWheel *wheel,
|
|||
GDK_POINTER_MOTION_HINT_MASK |
|
||||
GDK_BUTTON_RELEASE_MASK,
|
||||
NULL, cursor, time);
|
||||
gdk_cursor_unref (cursor);
|
||||
g_object_unref (cursor);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -812,15 +832,11 @@ gimp_color_wheel_motion (GtkWidget *widget,
|
|||
/* Paints the hue ring */
|
||||
static void
|
||||
paint_ring (GimpColorWheel *wheel,
|
||||
cairo_t *cr,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
cairo_t *cr)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (wheel);
|
||||
GimpColorWheelPrivate *priv = wheel->priv;
|
||||
GtkAllocation allocation;
|
||||
gint width, height;
|
||||
gint xx, yy;
|
||||
gdouble dx, dy, dist;
|
||||
gdouble center_x;
|
||||
|
@ -833,18 +849,12 @@ paint_ring (GimpColorWheel *wheel,
|
|||
cairo_surface_t *source;
|
||||
cairo_t *source_cr;
|
||||
gint stride;
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
|
||||
gtk_widget_get_allocation (GTK_WIDGET (wheel), &allocation);
|
||||
width = gtk_widget_get_allocated_width (widget);
|
||||
height = gtk_widget_get_allocated_height (widget);
|
||||
|
||||
gtk_widget_style_get (widget,
|
||||
"focus-line-width", &focus_width,
|
||||
"focus-padding", &focus_pad,
|
||||
NULL);
|
||||
|
||||
center_x = allocation.width / 2.0;
|
||||
center_y = allocation.height / 2.0;
|
||||
center_x = width / 2.0;
|
||||
center_y = height / 2.0;
|
||||
|
||||
outer = priv->size / 2.0;
|
||||
inner = outer - priv->ring_width;
|
||||
|
@ -858,11 +868,11 @@ paint_ring (GimpColorWheel *wheel,
|
|||
{
|
||||
p = buf + yy * width;
|
||||
|
||||
dy = -(yy + y - center_y);
|
||||
dy = -(yy - center_y);
|
||||
|
||||
for (xx = 0; xx < width; xx++)
|
||||
{
|
||||
dx = xx + x - center_x;
|
||||
dx = xx - center_x;
|
||||
|
||||
dist = dx * dx + dy * dy;
|
||||
if (dist < ((inner-1) * (inner-1)) || dist > ((outer+1) * (outer+1)))
|
||||
|
@ -920,14 +930,14 @@ paint_ring (GimpColorWheel *wheel,
|
|||
hsv_to_rgb (&r, &g, &b);
|
||||
|
||||
if (GIMP_RGB_LUMINANCE (r, g, b) > 0.5)
|
||||
cairo_set_source_rgb (source_cr, 0., 0., 0.);
|
||||
cairo_set_source_rgb (source_cr, 0.0, 0.0, 0.0);
|
||||
else
|
||||
cairo_set_source_rgb (source_cr, 1., 1., 1.);
|
||||
cairo_set_source_rgb (source_cr, 1.0, 1.0, 1.0);
|
||||
|
||||
cairo_move_to (source_cr, -x + center_x, - y + center_y);
|
||||
cairo_move_to (source_cr, center_x, center_y);
|
||||
cairo_line_to (source_cr,
|
||||
-x + center_x + cos (priv->h * 2.0 * G_PI) * priv->size / 2,
|
||||
-y + center_y - sin (priv->h * 2.0 * G_PI) * priv->size / 2);
|
||||
center_x + cos (priv->h * 2.0 * G_PI) * priv->size / 2,
|
||||
center_y - sin (priv->h * 2.0 * G_PI) * priv->size / 2);
|
||||
cairo_stroke (source_cr);
|
||||
cairo_destroy (source_cr);
|
||||
|
||||
|
@ -935,14 +945,14 @@ paint_ring (GimpColorWheel *wheel,
|
|||
|
||||
cairo_save (cr);
|
||||
|
||||
cairo_set_source_surface (cr, source, x, y);
|
||||
cairo_set_source_surface (cr, source, 0, 0);
|
||||
cairo_surface_destroy (source);
|
||||
|
||||
cairo_set_line_width (cr, priv->ring_width);
|
||||
cairo_new_path (cr);
|
||||
cairo_arc (cr,
|
||||
center_x, center_y,
|
||||
priv->size / 2. - priv->ring_width / 2.,
|
||||
priv->size / 2.0 - priv->ring_width / 2.0,
|
||||
0, 2 * G_PI);
|
||||
cairo_stroke (cr);
|
||||
|
||||
|
@ -982,10 +992,7 @@ get_color (gdouble h,
|
|||
static void
|
||||
paint_triangle (GimpColorWheel *wheel,
|
||||
cairo_t *cr,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
gboolean draw_focus)
|
||||
{
|
||||
GtkWidget *widget = GTK_WIDGET (wheel);
|
||||
GimpColorWheelPrivate *priv = wheel->priv;
|
||||
|
@ -1001,8 +1008,12 @@ paint_triangle (GimpColorWheel *wheel,
|
|||
gint x_start, x_end;
|
||||
cairo_surface_t *source;
|
||||
gdouble r, g, b;
|
||||
gchar *detail;
|
||||
gint stride;
|
||||
gint width, height;
|
||||
GtkStyleContext *context;
|
||||
|
||||
width = gtk_widget_get_allocated_width (widget);
|
||||
height = gtk_widget_get_allocated_height (widget);
|
||||
|
||||
/* Compute triangle's vertices */
|
||||
|
||||
|
@ -1056,9 +1067,9 @@ paint_triangle (GimpColorWheel *wheel,
|
|||
{
|
||||
p = buf + yy * width;
|
||||
|
||||
if (yy + y >= y1 - PAD && yy + y < y3 + PAD)
|
||||
if (yy >= y1 - PAD && yy < y3 + PAD)
|
||||
{
|
||||
y_interp = CLAMP (yy + y, y1, y3);
|
||||
y_interp = CLAMP (yy, y1, y3);
|
||||
|
||||
if (y_interp < y2)
|
||||
{
|
||||
|
@ -1091,13 +1102,13 @@ paint_triangle (GimpColorWheel *wheel,
|
|||
SWAP (bl, br, t);
|
||||
}
|
||||
|
||||
x_start = MAX (xl - PAD, x);
|
||||
x_end = MIN (xr + PAD, x + width);
|
||||
x_start = MAX (xl - PAD, 0);
|
||||
x_end = MIN (xr + PAD, width);
|
||||
x_start = MIN (x_start, x_end);
|
||||
|
||||
c = (rl << 16) | (gl << 8) | bl;
|
||||
|
||||
for (xx = x; xx < x_start; xx++)
|
||||
for (xx = 0; xx < x_start; xx++)
|
||||
*p++ = c;
|
||||
|
||||
for (; xx < x_end; xx++)
|
||||
|
@ -1111,7 +1122,7 @@ paint_triangle (GimpColorWheel *wheel,
|
|||
|
||||
c = (rr << 16) | (gr << 8) | br;
|
||||
|
||||
for (; xx < x + width; xx++)
|
||||
for (; xx < width; xx++)
|
||||
*p++ = c;
|
||||
}
|
||||
}
|
||||
|
@ -1139,7 +1150,7 @@ paint_triangle (GimpColorWheel *wheel,
|
|||
|
||||
/* Draw a triangle with the image as a source */
|
||||
|
||||
cairo_set_source_surface (cr, source, x, y);
|
||||
cairo_set_source_surface (cr, source, 0, 0);
|
||||
cairo_surface_destroy (source);
|
||||
|
||||
cairo_move_to (cr, x1, y1);
|
||||
|
@ -1160,15 +1171,19 @@ paint_triangle (GimpColorWheel *wheel,
|
|||
b = priv->v;
|
||||
hsv_to_rgb (&r, &g, &b);
|
||||
|
||||
context = gtk_widget_get_style_context (widget);
|
||||
|
||||
gtk_style_context_save (context);
|
||||
|
||||
if (GIMP_RGB_LUMINANCE (r, g, b) > 0.5)
|
||||
{
|
||||
detail = "colorwheel_light";
|
||||
cairo_set_source_rgb (cr, 0., 0., 0.);
|
||||
gtk_style_context_add_class (context, "light-area-focus");
|
||||
cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
detail = "colorwheel_dark";
|
||||
cairo_set_source_rgb (cr, 1., 1., 1.);
|
||||
gtk_style_context_add_class (context, "dark-area-focus");
|
||||
cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
|
||||
}
|
||||
|
||||
#define RADIUS 4
|
||||
|
@ -1180,86 +1195,50 @@ paint_triangle (GimpColorWheel *wheel,
|
|||
|
||||
/* Draw focus outline */
|
||||
|
||||
if (gtk_widget_has_focus (widget) &&
|
||||
! priv->focus_on_ring)
|
||||
if (draw_focus && ! priv->focus_on_ring)
|
||||
{
|
||||
GtkAllocation allocation;
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
gint focus_width;
|
||||
gint focus_pad;
|
||||
|
||||
gtk_widget_style_get (widget,
|
||||
"focus-line-width", &focus_width,
|
||||
"focus-padding", &focus_pad,
|
||||
"focus-padding", &focus_pad,
|
||||
NULL);
|
||||
|
||||
gtk_paint_focus (gtk_widget_get_style (widget),
|
||||
gtk_widget_get_window (widget),
|
||||
gtk_widget_get_state (widget),
|
||||
NULL, widget, detail,
|
||||
allocation.x + xx - FOCUS_RADIUS - focus_width - focus_pad,
|
||||
allocation.y + yy - FOCUS_RADIUS - focus_width - focus_pad,
|
||||
2 * (FOCUS_RADIUS + focus_width + focus_pad),
|
||||
2 * (FOCUS_RADIUS + focus_width + focus_pad));
|
||||
gtk_render_focus (context, cr,
|
||||
xx - FOCUS_RADIUS - focus_width - focus_pad,
|
||||
yy - FOCUS_RADIUS - focus_width - focus_pad,
|
||||
2 * (FOCUS_RADIUS + focus_width + focus_pad),
|
||||
2 * (FOCUS_RADIUS + focus_width + focus_pad));
|
||||
}
|
||||
|
||||
gtk_style_context_restore (context);
|
||||
}
|
||||
|
||||
/* Paints the contents of the HSV color selector */
|
||||
static void
|
||||
paint (GimpColorWheel *hsv,
|
||||
cairo_t *cr,
|
||||
gint x,
|
||||
gint y,
|
||||
gint width,
|
||||
gint height)
|
||||
{
|
||||
GimpColorWheelPrivate *priv = hsv->priv;
|
||||
|
||||
if (! priv->transform)
|
||||
gimp_color_wheel_create_transform (hsv);
|
||||
|
||||
paint_ring (hsv, cr, x, y, width, height);
|
||||
paint_triangle (hsv, cr, x, y, width, height);
|
||||
}
|
||||
|
||||
static gint
|
||||
gimp_color_wheel_expose (GtkWidget *widget,
|
||||
GdkEventExpose *event)
|
||||
static gboolean
|
||||
gimp_color_wheel_draw (GtkWidget *widget,
|
||||
cairo_t *cr)
|
||||
{
|
||||
GimpColorWheel *wheel = GIMP_COLOR_WHEEL (widget);
|
||||
GimpColorWheelPrivate *priv = wheel->priv;
|
||||
GtkAllocation allocation;
|
||||
GdkRectangle dest;
|
||||
cairo_t *cr;
|
||||
gboolean draw_focus;
|
||||
|
||||
if (! (event->window == gtk_widget_get_window (widget) &&
|
||||
gtk_widget_is_drawable (widget)))
|
||||
return FALSE;
|
||||
draw_focus = gtk_widget_has_visible_focus (widget);
|
||||
|
||||
gtk_widget_get_allocation (widget, &allocation);
|
||||
if (! priv->transform)
|
||||
gimp_color_wheel_create_transform (wheel);
|
||||
|
||||
if (!gdk_rectangle_intersect (&event->area, &allocation, &dest))
|
||||
return FALSE;
|
||||
paint_ring (wheel, cr);
|
||||
paint_triangle (wheel, cr, draw_focus);
|
||||
|
||||
cr = gdk_cairo_create (gtk_widget_get_window (widget));
|
||||
if (draw_focus && priv->focus_on_ring)
|
||||
{
|
||||
GtkStyleContext *context = gtk_widget_get_style_context (widget);
|
||||
|
||||
cairo_translate (cr, allocation.x, allocation.y);
|
||||
paint (wheel, cr,
|
||||
dest.x - allocation.x,
|
||||
dest.y - allocation.y,
|
||||
dest.width, dest.height);
|
||||
cairo_destroy (cr);
|
||||
|
||||
if (gtk_widget_has_focus (widget) && priv->focus_on_ring)
|
||||
gtk_paint_focus (gtk_widget_get_style (widget),
|
||||
gtk_widget_get_window (widget),
|
||||
gtk_widget_get_state (widget),
|
||||
&event->area, widget, NULL,
|
||||
allocation.x,
|
||||
allocation.y,
|
||||
allocation.width,
|
||||
allocation.height);
|
||||
gtk_render_focus (context, cr, 0, 0,
|
||||
gtk_widget_get_allocated_width (widget),
|
||||
gtk_widget_get_allocated_height (widget));
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue