* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
+#include <stdlib.h>
+#include <stdio.h>
#include <math.h>
+#include <gdk/gdk.h>
#include "gtkcolorsel.h"
+#include "gtkwindow.h"
#include "gtkhbbox.h"
+#include "gtkdnd.h"
+#include "gtkselection.h"
/*
* If you change the way the color values are stored,
static gint gtk_color_selection_wheel_timeout (GtkColorSelection *colorsel);
static void gtk_color_selection_sample_resize (GtkWidget *widget,
gpointer data);
-static void gtk_color_selection_drop_handle (GtkWidget *widget,
- GdkEvent *event,
- GtkWidget *theclorsel);
-static void gtk_color_selection_drag_handle (GtkWidget *widget,
- GdkEvent *event,
- GtkWidget *thecolorsel);
+static void gtk_color_selection_drag_begin (GtkWidget *widget,
+ GdkDragContext *context,
+ gpointer data);
+static void gtk_color_selection_drop_handle (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ gpointer data);
+static void gtk_color_selection_drag_handle (GtkWidget *widget,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ gpointer data);
static void gtk_color_selection_draw_wheel_marker (GtkColorSelection *colorsel);
static void gtk_color_selection_draw_wheel_frame (GtkColorSelection *colorsel);
static void gtk_color_selection_draw_value_marker (GtkColorSelection *colorsel);
#define SF GtkSignalFunc
-scale_val_type scale_vals[NUM_CHANNELS] =
+static const scale_val_type scale_vals[NUM_CHANNELS] =
{
{"Hue:", 0.0, 360.0, 1.00, 10.00, (SF) gtk_color_selection_hsv_updater},
{"Saturation:", 0.0, 1.0, 0.01, 0.01, (SF) gtk_color_selection_hsv_updater},
if (!color_selection_type)
{
- GtkTypeInfo colorsel_info =
+ static const GtkTypeInfo colorsel_info =
{
"GtkColorSelection",
sizeof (GtkColorSelection),
sizeof (GtkColorSelectionClass),
(GtkClassInitFunc) gtk_color_selection_class_init,
(GtkObjectInitFunc) gtk_color_selection_init,
- (GtkArgSetFunc) NULL,
- (GtkArgGetFunc) NULL,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
};
color_selection_type = gtk_type_unique (gtk_vbox_get_type (), &colorsel_info);
GTK_RUN_FIRST,
object_class->type,
GTK_SIGNAL_OFFSET (GtkColorSelectionClass, color_changed),
- gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
+ gtk_marshal_NONE__NONE, GTK_TYPE_NONE, 0);
gtk_object_class_add_signals (object_class, color_selection_signals, LAST_SIGNAL);
colorsel->policy = GTK_UPDATE_CONTINUOUS;
hbox = gtk_hbox_new (FALSE, 5);
- gtk_container_border_width (GTK_CONTAINER (hbox), 5);
+ gtk_container_set_border_width (GTK_CONTAINER (hbox), 5);
gtk_container_add (GTK_CONTAINER (colorsel), hbox);
vbox = gtk_vbox_new (FALSE, 5);
frame = gtk_frame_new (NULL);
gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
- gtk_container_border_width (GTK_CONTAINER (frame), 0);
+ gtk_container_set_border_width (GTK_CONTAINER (frame), 0);
gtk_box_pack_start (GTK_BOX (hbox2), frame, FALSE, TRUE, 0);
gtk_widget_show (frame);
gtk_signal_connect_object (GTK_OBJECT (adj), "value_changed",
scale_vals[n].updater, (gpointer) colorsel->scales[n]);
gtk_object_set_data (GTK_OBJECT (colorsel->scales[n]), "_GtkColorSelection", (gpointer) colorsel);
- gtk_object_set_data (GTK_OBJECT (colorsel->scales[n]), value_index_key, (gpointer) n);
+ gtk_object_set_data (GTK_OBJECT (colorsel->scales[n]), value_index_key, GINT_TO_POINTER (n));
gtk_signal_connect_object (GTK_OBJECT (colorsel->entries[n]), "changed",
scale_vals[n].updater, (gpointer) colorsel->entries[n]);
gtk_object_set_data (GTK_OBJECT (colorsel->entries[n]), "_GtkColorSelection", (gpointer) colorsel);
- gtk_object_set_data (GTK_OBJECT (colorsel->entries[n]), value_index_key, (gpointer) n);
+ gtk_object_set_data (GTK_OBJECT (colorsel->entries[n]), value_index_key, GINT_TO_POINTER (n));
}
colorsel->opacity_label = label;
colorsel->values[n] = color[i++];
}
- if (colorsel->use_opacity == TRUE)
+ if (colorsel->use_opacity)
{
colorsel->old_values[OPACITY] = colorsel->values[OPACITY];
colorsel->values[OPACITY] = color[i];
for (n = RED; n <= BLUE; n++)
color[i++] = colorsel->values[n];
- if (colorsel->use_opacity == TRUE)
+ if (colorsel->use_opacity)
color[i] = colorsel->values[OPACITY];
}
gtk_color_selection_realize (GtkWidget *widget)
{
GtkColorSelection *colorsel;
- gchar *type_accept_list[] = {"application/x-color"};
+
+ static const GtkTargetEntry targets[] = {
+ { "application/x-color", 0 }
+ };
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_COLOR_SELECTION (widget));
if (GTK_WIDGET_CLASS (color_selection_parent_class)->realize)
(*GTK_WIDGET_CLASS (color_selection_parent_class)->realize) (widget);
- gtk_widget_dnd_drag_set (colorsel->sample_area,
- 1, type_accept_list, 1);
- gtk_widget_dnd_drop_set (colorsel->sample_area,
- 1, type_accept_list, 1, 0);
- gtk_signal_connect_after (GTK_OBJECT (colorsel->sample_area),
- "drop_data_available_event",
- GTK_SIGNAL_FUNC (gtk_color_selection_drop_handle),
- colorsel);
- gtk_signal_connect_after (GTK_OBJECT (colorsel->sample_area),
- "drag_request_event",
- GTK_SIGNAL_FUNC (gtk_color_selection_drag_handle),
- colorsel);
+ gtk_drag_dest_set (colorsel->sample_area,
+ GTK_DEST_DEFAULT_HIGHLIGHT |
+ GTK_DEST_DEFAULT_MOTION |
+ GTK_DEST_DEFAULT_DROP,
+ targets, 1,
+ GDK_ACTION_COPY);
+
+ gtk_drag_source_set (colorsel->sample_area,
+ GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
+ targets, 1,
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
+
+ gtk_signal_connect (GTK_OBJECT (colorsel->sample_area),
+ "drag_begin",
+ GTK_SIGNAL_FUNC (gtk_color_selection_drag_begin),
+ colorsel);
+ gtk_signal_connect (GTK_OBJECT (colorsel->sample_area),
+ "drag_data_get",
+ GTK_SIGNAL_FUNC (gtk_color_selection_drag_handle),
+ colorsel);
+ gtk_signal_connect (GTK_OBJECT (colorsel->sample_area),
+ "drag_data_received",
+ GTK_SIGNAL_FUNC (gtk_color_selection_drop_handle),
+ colorsel);
}
static void
if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (widget)))
{
colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkColorSelection");
- i = (gint) gtk_object_get_data (GTK_OBJECT (widget), value_index_key);
+ i = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), value_index_key));
if (GTK_IS_SCALE (widget))
{
if (GTK_WIDGET_DRAWABLE (GTK_WIDGET (widget)))
{
colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (widget), "_GtkColorSelection");
- i = (gint) gtk_object_get_data (GTK_OBJECT (widget), value_index_key);
+ i = GPOINTER_TO_INT (gtk_object_get_data (GTK_OBJECT (widget), value_index_key));
if (GTK_IS_SCALE (widget))
{
colorsel->use_opacity = use_opacity;
- if (use_opacity == FALSE && GTK_WIDGET_VISIBLE (colorsel->scales[OPACITY]))
+ if (!use_opacity && GTK_WIDGET_VISIBLE (colorsel->scales[OPACITY]))
{
gtk_widget_hide (colorsel->opacity_label);
gtk_widget_hide (colorsel->scales[OPACITY]);
gtk_widget_hide (colorsel->entries[OPACITY]);
}
- else if (use_opacity == TRUE && !GTK_WIDGET_VISIBLE (colorsel->scales[OPACITY]))
+ else if (use_opacity && !GTK_WIDGET_VISIBLE (colorsel->scales[OPACITY]))
{
gtk_widget_show (colorsel->opacity_label);
gtk_widget_show (colorsel->scales[OPACITY]);
}
static void
-gtk_color_selection_drop_handle (GtkWidget *widget, GdkEvent *event,
- GtkWidget *thecolorsel)
+gtk_color_selection_drag_begin (GtkWidget *widget,
+ GdkDragContext *context,
+ gpointer data)
{
- /* This is currently a gdouble array of the format (I think):
- use_opacity
+ GtkColorSelection *colorsel = data;
+ GtkWidget *window;
+ gdouble colors[4];
+ GdkColor bg;
+
+ window = gtk_window_new(GTK_WINDOW_POPUP);
+ gtk_widget_set_app_paintable (GTK_WIDGET (window), TRUE);
+ gtk_widget_set_usize (window, 48, 32);
+ gtk_widget_realize (window);
+
+ gtk_color_selection_get_color (colorsel, colors);
+ bg.red = 0xffff * colors[0];
+ bg.green = 0xffff * colors[1];
+ bg.blue = 0xffff * colors[2];
+
+ gdk_color_alloc (gtk_widget_get_colormap (window), &bg);
+ gdk_window_set_background (window->window, &bg);
+
+ gtk_drag_set_icon_widget (context, window, -2, -2);
+}
+
+static void
+gtk_color_selection_drop_handle (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ gpointer data)
+{
+ GtkColorSelection *colorsel = data;
+ guint16 *vals;
+ gdouble colors[4];
+
+ /* This is currently a guint16 array of the format:
R
G
B
opacity
*/
- gdouble *v = event->dropdataavailable.data;
- gtk_color_selection_set_opacity(GTK_COLOR_SELECTION(thecolorsel),
- (v[0]==1.0)?TRUE:FALSE);
- gtk_color_selection_set_color(GTK_COLOR_SELECTION(thecolorsel),
- v + 1);
- g_free(event->dropdataavailable.data);
- g_free(event->dropdataavailable.data_type);
+
+ if (selection_data->length < 0)
+ return;
+
+ if ((selection_data->format != 16) ||
+ (selection_data->length != 8))
+ {
+ g_warning ("Received invalid color data\n");
+ return;
+ }
+
+ vals = (guint16 *)selection_data->data;
+
+ colors[0] = (gdouble)vals[0] / 0xffff;
+ colors[1] = (gdouble)vals[1] / 0xffff;
+ colors[2] = (gdouble)vals[2] / 0xffff;
+ colors[3] = (gdouble)vals[3] / 0xffff;
+
+ gtk_color_selection_set_color(colorsel, colors);
}
static void
-gtk_color_selection_drag_handle (GtkWidget *widget, GdkEvent *event,
- GtkWidget *thecolorsel)
+gtk_color_selection_drag_handle (GtkWidget *widget,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ gpointer data)
{
- gdouble sendvals[(BLUE - RED + 1) + 3];
+ GtkColorSelection *colorsel = data;
+ guint16 vals[4];
+ gdouble colors[4];
- sendvals[0] = (GTK_COLOR_SELECTION(thecolorsel)->use_opacity)?1.0:0.0;
- gtk_color_selection_get_color(GTK_COLOR_SELECTION(thecolorsel),
- sendvals + 1);
+ gtk_color_selection_get_color(colorsel, colors);
- gtk_widget_dnd_data_set(widget,
- event,
- (gpointer)sendvals,
- sizeof(sendvals));
+ vals[0] = colors[0] * 0xffff;
+ vals[1] = colors[1] * 0xffff;
+ vals[2] = colors[2] * 0xffff;
+ vals[3] = colorsel->use_opacity ? colors[3] * 0xffff : 0xffff;
+
+ g_print ("%x %x\n", vals[0], vals[4]);
+ g_print ("%g\n", colorsel->values[OPACITY]);
+ g_print ("%d\n", colorsel->use_opacity);
+
+ gtk_selection_data_set (selection_data,
+ gdk_atom_intern ("application/x-color", FALSE),
+ 16, (guchar *)vals, 8);
}
static void
gtk_color_selection_value_timeout (GtkColorSelection *colorsel)
{
gint x, y;
-
+
+ GDK_THREADS_ENTER ();
+
gdk_window_get_pointer (colorsel->value_area->window, &x, &y, NULL);
gtk_color_selection_update_value (colorsel, y);
gtk_color_selection_color_changed (colorsel);
+ GDK_THREADS_LEAVE ();
+
return (TRUE);
}
colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (area), "_GtkColorSelection");
+ if (colorsel->value_gc == NULL)
+ colorsel->value_gc = gdk_gc_new (colorsel->value_area->window);
+
switch (event->type)
{
case GDK_MAP:
gtk_color_selection_draw_value_marker (colorsel);
break;
case GDK_EXPOSE:
- if (colorsel->value_gc == NULL)
- colorsel->value_gc = gdk_gc_new (colorsel->value_area->window);
gtk_color_selection_draw_value_marker (colorsel);
break;
case GDK_BUTTON_PRESS:
break;
case GDK_BUTTON_RELEASE:
gtk_grab_remove (area);
- if (colorsel->timer_active == TRUE)
+ if (colorsel->timer_active)
gtk_timeout_remove (colorsel->timer_tag);
colorsel->timer_active = FALSE;
gtk_color_selection_color_changed (colorsel);
break;
case GDK_MOTION_NOTIFY:
+ /* Even though we select BUTTON_MOTION_MASK, we seem to need
+ * to occasionally get events without buttons pressed.
+ */
+ if (!(event->motion.state &
+ (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)))
+ return FALSE;
+
y = event->motion.y;
if (event->motion.is_hint || (event->motion.window != area->window))
gtk_color_selection_color_changed (colorsel);
break;
case GTK_UPDATE_DELAYED:
- if (colorsel->timer_active == TRUE)
+ if (colorsel->timer_active)
gtk_timeout_remove (colorsel->timer_tag);
colorsel->timer_tag = gtk_timeout_add (TIMER_DELAY,
gint x, y;
colorsel = (GtkColorSelection*) gtk_object_get_data (GTK_OBJECT (area), "_GtkColorSelection");
-
+
+ if (colorsel->wheel_gc == NULL)
+ colorsel->wheel_gc = gdk_gc_new (colorsel->wheel_area->window);
+ if (colorsel->sample_gc == NULL)
+ colorsel->sample_gc = gdk_gc_new (colorsel->sample_area->window);
+ if (colorsel->value_gc == NULL)
+ colorsel->value_gc = gdk_gc_new (colorsel->value_area->window);
+
switch (event->type)
{
case GDK_MAP:
gtk_color_selection_draw_sample (colorsel, TRUE);
break;
case GDK_EXPOSE:
- if (colorsel->wheel_gc == NULL)
- colorsel->wheel_gc = gdk_gc_new (colorsel->wheel_area->window);
- if (colorsel->sample_gc == NULL)
- colorsel->sample_gc = gdk_gc_new (colorsel->sample_area->window);
- if (colorsel->value_gc == NULL)
- colorsel->value_gc = gdk_gc_new (colorsel->value_area->window);
gtk_color_selection_draw_wheel_marker (colorsel);
gtk_color_selection_draw_wheel_frame (colorsel);
break;
break;
case GDK_BUTTON_RELEASE:
gtk_grab_remove (area);
- if (colorsel->timer_active == TRUE)
+ if (colorsel->timer_active)
gtk_timeout_remove (colorsel->timer_tag);
colorsel->timer_active = FALSE;
gtk_color_selection_color_changed (colorsel);
break;
case GDK_MOTION_NOTIFY:
+ /* Even though we select BUTTON_MOTION_MASK, we seem to need
+ * to occasionally get events without buttons pressed.
+ */
+ if (!(event->motion.state &
+ (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)))
+ return FALSE;
+
x = event->motion.x;
y = event->motion.y;
gtk_color_selection_color_changed (colorsel);
break;
case GTK_UPDATE_DELAYED:
- if (colorsel->timer_active == TRUE)
+ if (colorsel->timer_active)
gtk_timeout_remove (colorsel->timer_tag);
colorsel->timer_tag = gtk_timeout_add (TIMER_DELAY,
(GtkFunction) gtk_color_selection_wheel_timeout,
v -= sv;
}
- gtk_widget_draw (colorsel->value_area, NULL);
+ gtk_widget_queue_draw (colorsel->value_area);
}
static void
GtkStyle *style;
gint w, h;
- style = gtk_widget_get_style (GTK_WIDGET (colorsel));
+ style = gtk_widget_get_style (colorsel->wheel_area);
w = colorsel->wheel_area->allocation.width;
h = colorsel->wheel_area->allocation.height;
gint x, y, i, wid, heig, n;
gdouble cx, cy, h, s, c[3];
guchar bg[3];
- GtkStyle *style = gtk_widget_get_style (GTK_WIDGET (colorsel));
+ GtkStyle *style = gtk_widget_get_style (colorsel->wheel_area);
wid = colorsel->wheel_area->allocation.width;
heig = colorsel->wheel_area->allocation.height;
i = 0;
for (x = 0; x < wid; x++)
{
- if (gtk_color_selection_eval_wheel (x, y, cx, cy, &h, &s) == TRUE)
+ if (gtk_color_selection_eval_wheel (x, y, cx, cy, &h, &s))
{
for (n = 0; n < 3; n++)
colorsel->wheel_buf[i++] = bg[n];
gtk_preview_draw_row (GTK_PREVIEW (colorsel->wheel_area), colorsel->wheel_buf, 0, y, wid);
}
- gtk_widget_draw (colorsel->wheel_area, NULL);
+ if (colorsel->wheel_area->window)
+ {
+ GdkPixmap *pm = NULL;
+ GdkGC *pmgc = NULL;
+ GdkColor col;
+ gint w, h;
+
+ pm = gdk_pixmap_new (colorsel->wheel_area->window, wid, heig, 1);
+ pmgc = gdk_gc_new (pm);
+
+ col.pixel = 0;
+ gdk_gc_set_foreground(pmgc, &col);
+ gdk_draw_rectangle(pm, pmgc, TRUE, 0, 0, wid, heig);
+ col.pixel = 1;
+
+ gdk_gc_set_foreground(pmgc, &col);
+ gdk_draw_arc (pm, pmgc, TRUE, 0, 0, wid, heig, 0, 360*64);
+
+ w = colorsel->wheel_area->allocation.width;
+ h = colorsel->wheel_area->allocation.height;
+
+ gdk_draw_arc (pm, pmgc,
+ FALSE, 1, 1, w - 1, h - 1, 30 * 64, 180 * 64);
+ gdk_draw_arc (pm, pmgc,
+ FALSE, 0, 0, w, h, 30 * 64, 180 * 64);
+ gdk_draw_arc (pm, pmgc,
+ FALSE, 1, 1, w - 1, h - 1, 210 * 64, 180 * 64);
+ gdk_draw_arc (pm, pmgc,
+ FALSE, 0, 0, w, h, 210 * 64, 180 * 64);
+ gdk_window_shape_combine_mask(colorsel->wheel_area->window, pm, 0, 0);
+ gdk_pixmap_unref(pm);
+ gdk_gc_destroy(pmgc);
+ }
}
static void
c[n + 3] = (guchar) (255.0 * colorsel->values[i++]);
}
- if (colorsel->use_opacity == TRUE)
+ if (colorsel->use_opacity)
{
o = colorsel->values[OPACITY];
oldo = colorsel->old_values[OPACITY];
gtk_preview_draw_row (GTK_PREVIEW (colorsel->sample_area), colorsel->sample_buf, 0, y, wid);
}
- gtk_widget_draw (colorsel->sample_area, NULL);
+ gtk_widget_queue_draw (colorsel->sample_area);
}
static gint
gdouble cx, gdouble cy,
gdouble *h, gdouble *s)
{
- gdouble d, r, rx, ry, l;
+ gdouble r, rx, ry;
- rx = (gdouble) x - cx;
- ry = (gdouble) y - cy;
+ rx = ((gdouble) x - cx);
+ ry = ((gdouble) y - cy);
- d = (SQR (cy) * SQR (rx) + SQR (cx) * SQR (ry) - SQR (cx) * SQR (cy));
+ rx = rx/cx;
+ ry = ry/cy;
r = sqrt (SQR (rx) + SQR (ry));
else
*h = 0.0;
- l = sqrt (SQR ((cx * cos (*h + 0.5 * M_PI))) + SQR ((cy * sin (*h + 0.5 * M_PI))));
- *s = r / l;
+ *s = r;
*h = 360.0 * (*h) / (2.0 * M_PI) + 180;
if (*s == 0.0)
*s = 0.00001;
else if (*s > 1.0)
- *s = 1.0;
-
- return ((d > 0.0));
+ {
+ *s = 1.0;
+ return TRUE;
+ }
+ return FALSE;
}
static void
sizeof (GtkColorSelectionDialogClass),
(GtkClassInitFunc) gtk_color_selection_dialog_class_init,
(GtkObjectInitFunc) gtk_color_selection_dialog_init,
- (GtkArgSetFunc) NULL,
- (GtkArgGetFunc) NULL,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
};
color_selection_dialog_type = gtk_type_unique (gtk_window_get_type (), &colorsel_diag_info);
GtkWidget *action_area, *frame;
colorseldiag->main_vbox = gtk_vbox_new (FALSE, 10);
- gtk_container_border_width (GTK_CONTAINER (colorseldiag), 10);
+ gtk_container_set_border_width (GTK_CONTAINER (colorseldiag), 10);
gtk_container_add (GTK_CONTAINER (colorseldiag), colorseldiag->main_vbox);
gtk_widget_show (colorseldiag->main_vbox);