* Boston, MA 02111-1307, USA.
*/
-#include <config.h>
-#include <math.h>
-#include <string.h>
-#include "gtkhsv.h"
-#include "gdk/gdkkeysyms.h"
-#include "gtkbindings.h"
-#include "gtkcontainer.h"
-#include "gtkmarshalers.h"
-#include "gtkalias.h"
-
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
+#include "config.h"
+
+#include <math.h>
+#include <string.h>
+
+#include "gdk/gdkkeysyms.h"
+
+#include "gtkhsv.h"
+#include "gtkbindings.h"
+#include "gtkmarshalers.h"
+#include "gtkintl.h"
+#include "gtkalias.h"
+
/* Default width/height */
#define DEFAULT_SIZE 100
LAST_SIGNAL
};
-static void gtk_hsv_class_init (GtkHSVClass *class);
-static void gtk_hsv_init (GtkHSV *hsv);
static void gtk_hsv_destroy (GtkObject *object);
static void gtk_hsv_map (GtkWidget *widget);
static void gtk_hsv_unmap (GtkWidget *widget);
GdkEventMotion *event);
static gint gtk_hsv_expose (GtkWidget *widget,
GdkEventExpose *event);
+static gboolean gtk_hsv_grab_broken (GtkWidget *widget,
+ GdkEventGrabBroken *event);
static gboolean gtk_hsv_focus (GtkWidget *widget,
GtkDirectionType direction);
static void gtk_hsv_move (GtkHSV *hsv,
GtkDirectionType dir);
static guint hsv_signals[LAST_SIGNAL];
-static GtkWidgetClass *parent_class;
-
-/**
- * gtk_hsv_get_type:
- * @void:
- *
- * Registers the &GtkHSV class if necessary, and returns the type ID associated
- * to it.
- *
- * Return value: The type ID of the &GtkHSV class.
- **/
-GType
-gtk_hsv_get_type (void)
-{
- static GType hsv_type = 0;
-
- if (!hsv_type) {
- static const GTypeInfo hsv_info = {
- sizeof (GtkHSVClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) gtk_hsv_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (GtkHSV),
- 0, /* n_preallocs */
- (GInstanceInitFunc) gtk_hsv_init,
- };
-
- hsv_type = g_type_register_static (GTK_TYPE_WIDGET, "GtkHSV",
- &hsv_info, 0);
- }
-
- return hsv_type;
-}
+G_DEFINE_TYPE (GtkHSV, gtk_hsv, GTK_TYPE_WIDGET)
/* Class initialization function for the HSV color selector */
static void
gtk_hsv_class_init (GtkHSVClass *class)
{
+ GObjectClass *gobject_class;
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
GtkHSVClass *hsv_class;
GtkBindingSet *binding_set;
+ gobject_class = (GObjectClass *) class;
object_class = (GtkObjectClass *) class;
widget_class = (GtkWidgetClass *) class;
hsv_class = GTK_HSV_CLASS (class);
- parent_class = g_type_class_peek_parent (class);
-
object_class->destroy = gtk_hsv_destroy;
widget_class->map = gtk_hsv_map;
widget_class->motion_notify_event = gtk_hsv_motion;
widget_class->expose_event = gtk_hsv_expose;
widget_class->focus = gtk_hsv_focus;
+ widget_class->grab_broken_event = gtk_hsv_grab_broken;
hsv_class->move = gtk_hsv_move;
hsv_signals[CHANGED] =
- g_signal_new ("changed",
+ g_signal_new (I_("changed"),
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GtkHSVClass, changed),
G_TYPE_NONE, 0);
hsv_signals[MOVE] =
- g_signal_new ("move",
+ g_signal_new (I_("move"),
G_OBJECT_CLASS_TYPE (object_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (GtkHSVClass, move),
gtk_binding_entry_add_signal (binding_set, GDK_KP_Left, 0,
"move", 1,
G_TYPE_ENUM, GTK_DIR_LEFT);
+
+ g_type_class_add_private (gobject_class, sizeof (HSVPrivate));
}
/* Object initialization function for the HSV color selector */
gtk_hsv_init (GtkHSV *hsv)
{
HSVPrivate *priv;
+
+ priv = G_TYPE_INSTANCE_GET_PRIVATE (hsv, GTK_TYPE_HSV, HSVPrivate);
- priv = g_new0 (HSVPrivate, 1);
hsv->priv = priv;
-
+
GTK_WIDGET_SET_FLAGS (hsv, GTK_NO_WINDOW);
GTK_WIDGET_SET_FLAGS (hsv, GTK_CAN_FOCUS);
static void
gtk_hsv_destroy (GtkObject *object)
{
- GtkHSV *hsv;
-
- g_return_if_fail (GTK_IS_HSV (object));
-
- hsv = GTK_HSV (object);
-
- if (hsv->priv)
- {
- g_free (hsv->priv);
- hsv->priv = NULL;
- }
-
- GTK_OBJECT_CLASS (parent_class)->destroy (object);
+ GTK_OBJECT_CLASS (gtk_hsv_parent_class)->destroy (object);
}
/* Default signal handlers */
hsv = GTK_HSV (widget);
priv = hsv->priv;
- GTK_WIDGET_CLASS (parent_class)->map (widget);
+ GTK_WIDGET_CLASS (gtk_hsv_parent_class)->map (widget);
gdk_window_show (priv->window);
}
gdk_window_hide (priv->window);
- GTK_WIDGET_CLASS (parent_class)->unmap (widget);
+ GTK_WIDGET_CLASS (gtk_hsv_parent_class)->unmap (widget);
}
/* Realize handler for the HSV color selector */
g_object_unref (priv->gc);
priv->gc = NULL;
-
- if (GTK_WIDGET_CLASS (parent_class)->unrealize)
- GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
+
+ GTK_WIDGET_CLASS (gtk_hsv_parent_class)->unrealize (widget);
}
/* Size_request handler for the HSV color selector */
gint *vy)
{
HSVPrivate *priv;
- gdouble center;
+ gdouble center_x;
+ gdouble center_y;
gdouble inner, outer;
gdouble angle;
-
+
priv = hsv->priv;
-
- center = GTK_WIDGET (hsv)->requisition.width / 2.0;
+
+ center_x = GTK_WIDGET (hsv)->allocation.width / 2.0;
+ center_y = GTK_WIDGET (hsv)->allocation.height / 2.0;
outer = priv->size / 2.0;
inner = outer - priv->ring_width;
angle = priv->h * 2.0 * G_PI;
-
- *hx = floor (center + cos (angle) * inner + 0.5);
- *hy = floor (center - sin (angle) * inner + 0.5);
- *sx = floor (center + cos (angle + 2.0 * G_PI / 3.0) * inner + 0.5);
- *sy = floor (center - sin (angle + 2.0 * G_PI / 3.0) * inner + 0.5);
- *vx = floor (center + cos (angle + 4.0 * G_PI / 3.0) * inner + 0.5);
- *vy = floor (center - sin (angle + 4.0 * G_PI / 3.0) * inner + 0.5);
+
+ *hx = floor (center_x + cos (angle) * inner + 0.5);
+ *hy = floor (center_y - sin (angle) * inner + 0.5);
+ *sx = floor (center_x + cos (angle + 2.0 * G_PI / 3.0) * inner + 0.5);
+ *sy = floor (center_y - sin (angle + 2.0 * G_PI / 3.0) * inner + 0.5);
+ *vx = floor (center_x + cos (angle + 4.0 * G_PI / 3.0) * inner + 0.5);
+ *vy = floor (center_y - sin (angle + 4.0 * G_PI / 3.0) * inner + 0.5);
}
/* Computes whether a point is inside the hue ring */
{
HSVPrivate *priv;
gdouble dx, dy, dist;
- gdouble center, inner, outer;
-
+ gdouble center_x;
+ gdouble center_y;
+ gdouble inner, outer;
+
priv = hsv->priv;
-
- center = priv->size / 2.0;
+
+ center_x = GTK_WIDGET (hsv)->allocation.width / 2.0;
+ center_y = GTK_WIDGET (hsv)->allocation.height / 2.0;
outer = priv->size / 2.0;
inner = outer - priv->ring_width;
-
- dx = x - center;
- dy = center - y;
+
+ dx = x - center_x;
+ dy = center_y - y;
dist = dx * dx + dy * dy;
-
+
return (dist >= inner * inner && dist <= outer * outer);
}
gdouble *s,
gdouble *v)
{
- HSVPrivate *priv;
int ihx, ihy, isx, isy, ivx, ivy;
double hx, hy, sx, sy, vx, vy;
- double center;
-
- priv = hsv->priv;
-
+ double center_x;
+ double center_y;
+
compute_triangle (hsv, &ihx, &ihy, &isx, &isy, &ivx, &ivy);
- center = GTK_WIDGET (hsv)->requisition.width / 2.0;
- hx = ihx - center;
- hy = center - ihy;
- sx = isx - center;
- sy = center - isy;
- vx = ivx - center;
- vy = center - ivy;
- x -= center;
- y = center - y;
+ center_x = GTK_WIDGET (hsv)->allocation.width / 2.0;
+ center_y = GTK_WIDGET (hsv)->allocation.height / 2.0;
+ hx = ihx - center_x;
+ hy = center_y - ihy;
+ sx = isx - center_x;
+ sy = center_y - isy;
+ vx = ivx - center_x;
+ vy = center_y - ivy;
+ x -= center_x;
+ y = center_y - y;
if (vx * (x - sx) + vy * (y - sy) < 0.0)
{
gdouble x,
gdouble y)
{
- HSVPrivate *priv;
- double center;
+ double center_x;
+ double center_y;
double dx, dy;
double angle;
-
- priv = hsv->priv;
-
- center = GTK_WIDGET (hsv)->requisition.width / 2.0;
- dx = x - center;
- dy = center - y;
-
+
+ center_x = GTK_WIDGET (hsv)->allocation.width / 2.0;
+ center_y = GTK_WIDGET (hsv)->allocation.height / 2.0;
+ dx = x - center_x;
+ dy = center_y - y;
+
angle = atan2 (dy, dx);
if (angle < 0.0)
angle += 2.0 * G_PI;
-
+
return angle / (2.0 * G_PI);
}
gdk_cursor_unref (cursor);
}
+static gboolean
+gtk_hsv_grab_broken (GtkWidget *widget,
+ GdkEventGrabBroken *event)
+{
+ GtkHSV *hsv = GTK_HSV (widget);
+ HSVPrivate *priv;
+
+ priv = hsv->priv;
+
+ priv->mode = DRAG_NONE;
+
+ return TRUE;
+}
+
/* Button_press_event handler for the HSV color selector */
static gint
gtk_hsv_button_press (GtkWidget *widget,
GtkHSV *hsv;
HSVPrivate *priv;
double x, y;
- gint ix, iy;
GdkModifierType mods;
hsv = GTK_HSV (widget);
if (priv->mode == DRAG_NONE)
return FALSE;
- if (event->is_hint)
- {
- gdk_window_get_pointer (priv->window, &ix, &iy, &mods);
- x = ix;
- y = iy;
- }
- else
- {
- x = event->x;
- y = event->y;
- }
-
+ gdk_event_request_motions (event);
+ x = event->x;
+ y = event->y;
+ mods = event->state;
+
if (priv->mode == DRAG_H)
{
gtk_hsv_set_color (hsv, compute_v (hsv, x, y), priv->s, priv->v);
HSVPrivate *priv;
int xx, yy;
gdouble dx, dy, dist;
- gdouble center;
+ gdouble center_x;
+ gdouble center_y;
gdouble inner, outer;
guint32 *buf, *p;
gdouble angle;
gdouble r, g, b;
cairo_surface_t *source;
cairo_t *source_cr;
+ gint stride;
gint focus_width;
gint focus_pad;
NULL);
priv = hsv->priv;
-
- center = widget->requisition.width / 2.0;
-
+
+ center_x = widget->allocation.width / 2.0;
+ center_y = widget->allocation.height / 2.0;
+
outer = priv->size / 2.0;
inner = outer - priv->ring_width;
/* Create an image initialized with the ring colors */
- buf = g_new (guint32, width * height);
+ stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, width);
+ buf = g_new (guint32, height * stride / 4);
for (yy = 0; yy < height; yy++)
{
p = buf + yy * width;
- dy = -(yy + y - center);
+ dy = -(yy + y - center_y);
for (xx = 0; xx < width; xx++)
{
- dx = xx + x - center;
+ dx = xx + x - center_x;
dist = dx * dx + dy * dy;
if (dist < ((inner-1) * (inner-1)) || dist > ((outer+1) * (outer+1)))
}
}
- source = cairo_image_surface_create_for_data ((char *)buf,
+ source = cairo_image_surface_create_for_data ((unsigned char *)buf,
CAIRO_FORMAT_RGB24,
- width, height, 4 * width);
+ width, height, stride);
/* Now draw the value marker onto the source image, so that it
* will get properly clipped at the edges of the ring
else
cairo_set_source_rgb (source_cr, 1., 1., 1.);
- cairo_move_to (source_cr, -x + center, - y + center);
+ cairo_move_to (source_cr, -x + center_x, - y + center_y);
cairo_line_to (source_cr,
- -x + center + cos (priv->h * 2.0 * G_PI) * center,
- -y + center - sin (priv->h * 2.0 * G_PI) * center);
+ -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);
cairo_stroke (source_cr);
cairo_destroy (source_cr);
cairo_set_line_width (cr, priv->ring_width);
cairo_new_path (cr);
cairo_arc (cr,
- center, center,
+ center_x, center_y,
priv->size / 2. - priv->ring_width / 2.,
0, 2 * G_PI);
cairo_stroke (cr);
gint x2, y2, r2, g2, b2; /* Second vertex */
gint x3, y3, r3, g3, b3; /* Third vertex */
gint t;
- guint32 *buf, *p;
+ guint32 *buf, *p, c;
gint xl, xr, rl, rr, gl, gr, bl, br; /* Scanline data */
gint xx, yy;
gint x_interp, y_interp;
cairo_surface_t *source;
gdouble r, g, b;
gchar *detail;
+ gint stride;
priv = hsv->priv;
}
/* Shade the triangle */
-
- buf = g_new (guint32, width * height);
+
+ stride = cairo_format_stride_for_width (CAIRO_FORMAT_RGB24, width);
+ buf = g_new (guint32, height * stride / 4);
for (yy = 0; yy < height; yy++)
{
x_start = MAX (xl - PAD, x);
x_end = MIN (xr + PAD, x + width);
+ x_start = MIN (x_start, x_end);
- p += (x_start - x);
+ c = (rl << 16) | (gl << 8) | bl;
- for (xx = x_start; xx < x_end; xx++)
+ for (xx = x; xx < x_start; xx++)
+ *p++ = c;
+
+ for (; xx < x_end; xx++)
{
x_interp = CLAMP (xx, xl, xr);
(LERP (gl, gr, xl, xr, x_interp) << 8) |
LERP (bl, br, xl, xr, x_interp));
}
+
+ c = (rr << 16) | (gr << 8) | br;
+
+ for (; xx < x + width; xx++)
+ *p++ = c;
}
}
- source = cairo_image_surface_create_for_data ((char *)buf,
+ source = cairo_image_surface_create_for_data ((unsigned char *)buf,
CAIRO_FORMAT_RGB24,
- width, height, 4 * width);
+ width, height, stride);
/* Draw a triangle with the image as a source */
dest.x - widget->allocation.x,
dest.y - widget->allocation.y,
dest.width, dest.height);
-
+ cairo_destroy (cr);
+
if (GTK_WIDGET_HAS_FOCUS (hsv) && priv->focus_on_ring)
gtk_paint_focus (widget->style, widget->window,
GTK_WIDGET_STATE (widget),
/**
* gtk_hsv_new:
- * @void:
*
* Creates a new HSV color selector.
*
* Return value: A newly-created HSV color selector.
- **/
+ *
+ * Since: 2.14
+ */
GtkWidget*
gtk_hsv_new (void)
{
/**
* gtk_hsv_set_color:
- * @hsv: An HSV color selector.
- * @h: Hue.
- * @s: Saturation.
- * @v: Value.
+ * @hsv: An HSV color selector
+ * @h: Hue
+ * @s: Saturation
+ * @v: Value
+ *
+ * Sets the current color in an HSV color selector.
+ * Color component values must be in the [0.0, 1.0] range.
*
- * Sets the current color in an HSV color selector. Color component values must
- * be in the [0.0, 1.0] range.
- **/
+ * Since: 2.14
+ */
void
gtk_hsv_set_color (GtkHSV *hsv,
gdouble h,
{
HSVPrivate *priv;
- g_return_if_fail (hsv != NULL);
g_return_if_fail (GTK_IS_HSV (hsv));
g_return_if_fail (h >= 0.0 && h <= 1.0);
g_return_if_fail (s >= 0.0 && s <= 1.0);
/**
* gtk_hsv_get_color:
- * @hsv: An HSV color selector.
- * @h: Return value for the hue.
- * @s: Return value for the saturation.
- * @v: Return value for the value.
+ * @hsv: An HSV color selector
+ * @h: Return value for the hue
+ * @s: Return value for the saturation
+ * @v: Return value for the value
*
- * Queries the current color in an HSV color selector. Returned values will be
- * in the [0.0, 1.0] range.
- **/
+ * Queries the current color in an HSV color selector.
+ * Returned values will be in the [0.0, 1.0] range.
+ *
+ * Since: 2.14
+ */
void
-gtk_hsv_get_color (GtkHSV *hsv, double *h, double *s, double *v)
+gtk_hsv_get_color (GtkHSV *hsv,
+ double *h,
+ double *s,
+ double *v)
{
HSVPrivate *priv;
/**
* gtk_hsv_set_metrics:
- * @hsv: An HSV color selector.
- * @size: Diameter for the hue ring.
- * @ring_width: Width of the hue ring.
+ * @hsv: An HSV color selector
+ * @size: Diameter for the hue ring
+ * @ring_width: Width of the hue ring
*
* Sets the size and ring width of an HSV color selector.
- **/
+ *
+ * Since: 2.14
+ */
void
gtk_hsv_set_metrics (GtkHSV *hsv,
gint size,
/**
* gtk_hsv_get_metrics:
- * @hsv: An HSV color selector.
- * @size: Return value for the diameter of the hue ring.
- * @ring_width: Return value for the width of the hue ring.
+ * @hsv: An HSV color selector
+ * @size: Return value for the diameter of the hue ring
+ * @ring_width: Return value for the width of the hue ring
*
* Queries the size and ring width of an HSV color selector.
- **/
+ *
+ * Since: 2.14
+ */
void
gtk_hsv_get_metrics (GtkHSV *hsv,
gint *size,
/**
* gtk_hsv_is_adjusting:
- * @hsv:
+ * @hsv: A #GtkHSV
*
- * An HSV color selector can be said to be adjusting if multiple rapid changes
- * are being made to its value, for example, when the user is adjusting the
- * value with the mouse. This function queries whether the HSV color selector
- * is being adjusted or not.
+ * An HSV color selector can be said to be adjusting if multiple rapid
+ * changes are being made to its value, for example, when the user is
+ * adjusting the value with the mouse. This function queries whether
+ * the HSV color selector is being adjusted or not.
*
- * Return value: TRUE if clients can ignore changes to the color value, since
- * they may be transitory, or FALSE if they should consider the color value
- * status to be final.
- **/
+ * Return value: %TRUE if clients can ignore changes to the color value,
+ * since they may be transitory, or %FALSE if they should consider
+ * the color value status to be final.
+ *
+ * Since: 2.14
+ */
gboolean
gtk_hsv_is_adjusting (GtkHSV *hsv)
{
/**
* gtk_hsv_to_rgb:
- * @h: Hue.
- * @s: Saturation.
- * @v: Value.
- * @r: Return value for the red component.
- * @g: Return value for the green component.
- * @b: Return value for the blue component.
- *
- * Converts a color from HSV space to RGB. Input values must be in the
- * [0.0, 1.0] range; output values will be in the same range.
- **/
+ * @h: Hue
+ * @s: Saturation
+ * @v: Value
+ * @r: Return value for the red component
+ * @g: Return value for the green component
+ * @b: Return value for the blue component
+ *
+ * Converts a color from HSV space to RGB.
+ * Input values must be in the [0.0, 1.0] range;
+ * output values will be in the same range.
+ *
+ * Since: 2.14
+ */
void
gtk_hsv_to_rgb (gdouble h,
gdouble s,
}
/**
- * gtk_hsv_to_rgb:
- * @r: Red.
- * @g: Green.
- * @b: Blue.
- * @h: Return value for the hue component.
- * @s: Return value for the saturation component.
- * @v: Return value for the value component.
- *
- * Converts a color from RGB space to HSV. Input values must be in the
- * [0.0, 1.0] range; output values will be in the same range.
- **/
+ * gtk_rgb_to_hsv:
+ * @r: Red
+ * @g: Green
+ * @b: Blue
+ * @h: Return value for the hue component
+ * @s: Return value for the saturation component
+ * @v: Return value for the value component
+ *
+ * Converts a color from RGB space to HSV.
+ * Input values must be in the [0.0, 1.0] range;
+ * output values will be in the same range.
+ *
+ * Since: 2.14
+ */
void
gtk_rgb_to_hsv (gdouble r,
gdouble g,