gtk+ r20651 - in trunk: . gtk
- From: johan svn gnome org
- To: svn-commits-list gnome org
- Subject: gtk+ r20651 - in trunk: . gtk
- Date: Fri, 20 Jun 2008 15:01:31 +0000 (UTC)
Author: johan
Date: Fri Jun 20 15:01:31 2008
New Revision: 20651
URL: http://svn.gnome.org/viewvc/gtk+?rev=20651&view=rev
Log:
2008-06-20 Johan Dahlin <jdahlin async com br>
* gtk/gtkcolorsel.c: Modernize and order things as most
other objects. Defines at the top, class init before init
before gobject methods before object method before widget
methods. No changes to the logic done.
Modified:
trunk/ChangeLog
trunk/gtk/gtkcolorsel.c
Modified: trunk/gtk/gtkcolorsel.c
==============================================================================
--- trunk/gtk/gtkcolorsel.c (original)
+++ trunk/gtk/gtkcolorsel.c Fri Jun 20 15:01:31 2008
@@ -26,9 +26,10 @@
*/
#include <config.h>
-#include "gdkconfig.h"
#include <math.h>
+#include <string.h>
+#include "gdkconfig.h"
#include "gdk/gdkkeysyms.h"
#include "gtkcolorsel.h"
#include "gtkhsv.h"
@@ -60,18 +61,30 @@
#include "gtkintl.h"
#include "gtkalias.h"
-#include <string.h>
-
/* Number of elements in the custom palatte */
#define GTK_CUSTOM_PALETTE_WIDTH 10
#define GTK_CUSTOM_PALETTE_HEIGHT 2
+#define CUSTOM_PALETTE_ENTRY_WIDTH 20
+#define CUSTOM_PALETTE_ENTRY_HEIGHT 20
+
+/* The cursor for the dropper */
+#define DROPPER_WIDTH 17
+#define DROPPER_HEIGHT 17
+#define DROPPER_X_HOT 2
+#define DROPPER_Y_HOT 16
+
+#define SAMPLE_WIDTH 64
+#define SAMPLE_HEIGHT 28
+#define CHECK_SIZE 16
+#define BIG_STEP 20
+
/* Conversion between 0->1 double and and guint16. See
* scale_round() below for more general conversions
*/
#define SCALE(i) (i / 65535.)
#define UNSCALE(d) ((guint16)(d * 65535 + 0.5))
-
+#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
enum {
COLOR_CHANGED,
@@ -163,7 +176,7 @@
static void gtk_color_selection_set_palette_color (GtkColorSelection *colorsel,
gint index,
GdkColor *color);
-static void set_focus_line_attributes (GtkWidget *drawing_area,
+static void set_focus_line_attributes (GtkWidget *drawing_area,
cairo_t *cr,
gint *focus_width);
static void default_noscreen_change_palette_func (const GdkColor *colors,
@@ -176,6 +189,46 @@
static void make_all_relations (AtkObject *atk_obj,
ColorSelectionPrivate *priv);
+static void hsv_changed (GtkWidget *hsv,
+ gpointer data);
+static void get_screen_color (GtkWidget *button);
+static void adjustment_changed (GtkAdjustment *adjustment,
+ gpointer data);
+static void opacity_entry_changed (GtkWidget *opacity_entry,
+ gpointer data);
+static void hex_changed (GtkWidget *hex_entry,
+ gpointer data);
+static gboolean hex_focus_out (GtkWidget *hex_entry,
+ GdkEventFocus *event,
+ gpointer data);
+static void color_sample_new (GtkColorSelection *colorsel);
+static void make_label_spinbutton (GtkColorSelection *colorsel,
+ GtkWidget **spinbutton,
+ gchar *text,
+ GtkWidget *table,
+ gint i,
+ gint j,
+ gint channel_type,
+ const gchar *tooltip);
+static void make_palette_frame (GtkColorSelection *colorsel,
+ GtkWidget *table,
+ gint i,
+ gint j);
+static void set_selected_palette (GtkColorSelection *colorsel,
+ int x,
+ int y);
+static void set_focus_line_attributes (GtkWidget *drawing_area,
+ cairo_t *cr,
+ gint *focus_width);
+static gboolean mouse_press (GtkWidget *invisible,
+ GdkEventButton *event,
+ gpointer data);
+static void palette_change_notify_instance (GObject *object,
+ GParamSpec *pspec,
+ gpointer data);
+static void update_palette (GtkColorSelection *colorsel);
+static void shutdown_eyedropper (GtkWidget *widget);
+
static guint color_selection_signals[LAST_SIGNAL] = { 0 };
static const gchar default_colors[] = "black:white:gray50:red:purple:blue:light blue:green:yellow:orange:lavender:brown:goldenrod4:dodger blue:pink:light green:gray10:gray30:gray75:gray90";
@@ -183,13 +236,6 @@
static GtkColorSelectionChangePaletteFunc noscreen_change_palette_hook = default_noscreen_change_palette_func;
static GtkColorSelectionChangePaletteWithScreenFunc change_palette_hook = default_change_palette_func;
-/* The cursor for the dropper */
-#define DROPPER_WIDTH 17
-#define DROPPER_HEIGHT 17
-#define DROPPER_X_HOT 2
-#define DROPPER_Y_HOT 16
-
-
static const guchar dropper_bits[] = {
0xff, 0x8f, 0x01, 0xff, 0x77, 0x01, 0xff, 0xfb, 0x00, 0xff, 0xf8, 0x00,
0x7f, 0xff, 0x00, 0xff, 0x7e, 0x01, 0xff, 0x9d, 0x01, 0xff, 0xd8, 0x01,
@@ -204,1930 +250,1980 @@
0x7c, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x1e, 0x00, 0x00, 0x0d, 0x00, 0x00,
0x02, 0x00, 0x00, };
-
-/*
- *
- * The Sample Color
- *
- */
-#define SAMPLE_WIDTH 64
-#define SAMPLE_HEIGHT 28
-
-static void color_sample_draw_sample (GtkColorSelection *colorsel, int which);
-static void color_sample_update_samples (GtkColorSelection *colorsel);
+G_DEFINE_TYPE (GtkColorSelection, gtk_color_selection, GTK_TYPE_VBOX)
static void
-set_color_internal (GtkColorSelection *colorsel,
- gdouble *color)
+gtk_color_selection_class_init (GtkColorSelectionClass *klass)
{
- ColorSelectionPrivate *priv;
- gint i;
+ GObjectClass *gobject_class;
+ GtkObjectClass *object_class;
+ GtkWidgetClass *widget_class;
- priv = colorsel->private_data;
- priv->changing = TRUE;
- priv->color[COLORSEL_RED] = color[0];
- priv->color[COLORSEL_GREEN] = color[1];
- priv->color[COLORSEL_BLUE] = color[2];
- priv->color[COLORSEL_OPACITY] = color[3];
- gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
- priv->color[COLORSEL_GREEN],
- priv->color[COLORSEL_BLUE],
- &priv->color[COLORSEL_HUE],
- &priv->color[COLORSEL_SATURATION],
- &priv->color[COLORSEL_VALUE]);
- if (priv->default_set == FALSE)
- {
- for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
- priv->old_color[i] = priv->color[i];
- }
- priv->default_set = TRUE;
- priv->default_alpha_set = TRUE;
- update_color (colorsel);
-}
-
-static void
-set_color_icon (GdkDragContext *context,
- gdouble *colors)
-{
- GdkPixbuf *pixbuf;
- guint32 pixel;
-
- pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE,
- 8, 48, 32);
-
- pixel = (((UNSCALE (colors[COLORSEL_RED]) & 0xff00) << 16) |
- ((UNSCALE (colors[COLORSEL_GREEN]) & 0xff00) << 8) |
- ((UNSCALE (colors[COLORSEL_BLUE]) & 0xff00)));
+ gobject_class = G_OBJECT_CLASS (klass);
+ gobject_class->finalize = gtk_color_selection_finalize;
+ gobject_class->set_property = gtk_color_selection_set_property;
+ gobject_class->get_property = gtk_color_selection_get_property;
- gdk_pixbuf_fill (pixbuf, pixel);
+ object_class = GTK_OBJECT_CLASS (klass);
+ object_class->destroy = gtk_color_selection_destroy;
- gtk_drag_set_icon_pixbuf (context, pixbuf, -2, -2);
- g_object_unref (pixbuf);
-}
-
-static void
-color_sample_drag_begin (GtkWidget *widget,
- GdkDragContext *context,
- gpointer data)
-{
- GtkColorSelection *colorsel = data;
- ColorSelectionPrivate *priv;
- gdouble *colsrc;
+ widget_class = GTK_WIDGET_CLASS (klass);
+ widget_class->realize = gtk_color_selection_realize;
+ widget_class->unrealize = gtk_color_selection_unrealize;
+ widget_class->show_all = gtk_color_selection_show_all;
+ widget_class->grab_broken_event = gtk_color_selection_grab_broken;
- priv = colorsel->private_data;
+ g_object_class_install_property (gobject_class,
+ PROP_HAS_OPACITY_CONTROL,
+ g_param_spec_boolean ("has-opacity-control",
+ P_("Has Opacity Control"),
+ P_("Whether the color selector should allow setting opacity"),
+ FALSE,
+ GTK_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_HAS_PALETTE,
+ g_param_spec_boolean ("has-palette",
+ P_("Has palette"),
+ P_("Whether a palette should be used"),
+ FALSE,
+ GTK_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_CURRENT_COLOR,
+ g_param_spec_boxed ("current-color",
+ P_("Current Color"),
+ P_("The current color"),
+ GDK_TYPE_COLOR,
+ GTK_PARAM_READWRITE));
+ g_object_class_install_property (gobject_class,
+ PROP_CURRENT_ALPHA,
+ g_param_spec_uint ("current-alpha",
+ P_("Current Alpha"),
+ P_("The current opacity value (0 fully transparent, 65535 fully opaque)"),
+ 0, 65535, 65535,
+ GTK_PARAM_READWRITE));
- if (widget == priv->old_sample)
- colsrc = priv->old_color;
- else
- colsrc = priv->color;
+ color_selection_signals[COLOR_CHANGED] =
+ g_signal_new (I_("color_changed"),
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ G_STRUCT_OFFSET (GtkColorSelectionClass, color_changed),
+ NULL, NULL,
+ _gtk_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
- set_color_icon (context, colsrc);
-}
+ gtk_settings_install_property (g_param_spec_string ("gtk-color-palette",
+ P_("Custom palette"),
+ P_("Palette to use in the color selector"),
+ default_colors,
+ GTK_PARAM_READWRITE));
-static void
-color_sample_drag_end (GtkWidget *widget,
- GdkDragContext *context,
- gpointer data)
-{
- g_object_set_data (G_OBJECT (widget), I_("gtk-color-selection-drag-window"), NULL);
+ g_type_class_add_private (gobject_class, sizeof (ColorSelectionPrivate));
}
static void
-color_sample_drop_handle (GtkWidget *widget,
- GdkDragContext *context,
- gint x,
- gint y,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- gpointer data)
+gtk_color_selection_init (GtkColorSelection *colorsel)
{
- GtkColorSelection *colorsel = data;
+ GtkWidget *top_hbox;
+ GtkWidget *top_right_vbox;
+ GtkWidget *table, *label, *hbox, *frame, *vbox, *button;
+ GtkAdjustment *adjust;
+ GtkWidget *picker_image;
+ gint i, j;
ColorSelectionPrivate *priv;
- guint16 *vals;
- gdouble color[4];
- priv = colorsel->private_data;
-
- /* This is currently a guint16 array of the format:
- * R
- * G
- * B
- * opacity
- */
-
- if (selection_data->length < 0)
- return;
-
- /* We accept drops with the wrong format, since the KDE color
- * chooser incorrectly drops application/x-color with format 8.
- */
- if (selection_data->length != 8)
- {
- g_warning ("Received invalid color data\n");
- return;
- }
-
- vals = (guint16 *)selection_data->data;
+ AtkObject *atk_obj;
+ GList *focus_chain = NULL;
- if (widget == priv->cur_sample)
- {
- color[0] = (gdouble)vals[0] / 0xffff;
- color[1] = (gdouble)vals[1] / 0xffff;
- color[2] = (gdouble)vals[2] / 0xffff;
- color[3] = (gdouble)vals[3] / 0xffff;
-
- set_color_internal (colorsel, color);
- }
-}
+ gtk_widget_push_composite_child ();
-static void
-color_sample_drag_handle (GtkWidget *widget,
- GdkDragContext *context,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- gpointer data)
-{
- GtkColorSelection *colorsel = data;
- ColorSelectionPrivate *priv;
- guint16 vals[4];
- gdouble *colsrc;
+ priv = colorsel->private_data = G_TYPE_INSTANCE_GET_PRIVATE (colorsel, GTK_TYPE_COLOR_SELECTION, ColorSelectionPrivate);
+ priv->changing = FALSE;
+ priv->default_set = FALSE;
+ priv->default_alpha_set = FALSE;
- priv = colorsel->private_data;
+ top_hbox = gtk_hbox_new (FALSE, 12);
+ gtk_box_pack_start (GTK_BOX (colorsel), top_hbox, FALSE, FALSE, 0);
- if (widget == priv->old_sample)
- colsrc = priv->old_color;
- else
- colsrc = priv->color;
+ vbox = gtk_vbox_new (FALSE, 6);
+ priv->triangle_colorsel = gtk_hsv_new ();
+ g_signal_connect (priv->triangle_colorsel, "changed",
+ G_CALLBACK (hsv_changed), colorsel);
+ gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15);
+ gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0);
+ gtk_widget_set_tooltip_text (priv->triangle_colorsel,
+ _("Select the color you want from the outer ring. Select the darkness or lightness of that color using the inner triangle."));
- vals[0] = colsrc[COLORSEL_RED] * 0xffff;
- vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
- vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
- vals[3] = priv->has_opacity ? colsrc[COLORSEL_OPACITY] * 0xffff : 0xffff;
+ hbox = gtk_hbox_new (FALSE, 6);
+ gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
- gtk_selection_data_set (selection_data,
- gdk_atom_intern_static_string ("application/x-color"),
- 16, (guchar *)vals, 8);
-}
+ frame = gtk_frame_new (NULL);
+ gtk_widget_set_size_request (frame, -1, 30);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+ color_sample_new (colorsel);
+ gtk_container_add (GTK_CONTAINER (frame), priv->sample_area);
+ gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
+
+ button = gtk_button_new ();
-/* which = 0 means draw old sample, which = 1 means draw new */
-static void
-color_sample_draw_sample (GtkColorSelection *colorsel, int which)
-{
- GtkWidget *da;
- gint x, y, wid, heig, goff;
- ColorSelectionPrivate *priv;
- cairo_t *cr;
+ gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
+ g_object_set_data (G_OBJECT (button), I_("COLORSEL"), colorsel);
+ g_signal_connect (button, "clicked",
+ G_CALLBACK (get_screen_color), NULL);
+ picker_image = gtk_image_new_from_stock (GTK_STOCK_COLOR_PICKER, GTK_ICON_SIZE_BUTTON);
+ gtk_container_add (GTK_CONTAINER (button), picker_image);
+ gtk_widget_show (GTK_WIDGET (picker_image));
+ gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+
+ gtk_widget_set_tooltip_text (button,
+ _("Click the eyedropper, then click a color anywhere on your screen to select that color."));
- g_return_if_fail (colorsel != NULL);
- priv = colorsel->private_data;
+ top_right_vbox = gtk_vbox_new (FALSE, 6);
+ gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0);
+ table = gtk_table_new (8, 6, FALSE);
+ gtk_box_pack_start (GTK_BOX (top_right_vbox), table, FALSE, FALSE, 0);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 6);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 12);
- g_return_if_fail (priv->sample_area != NULL);
- if (!GTK_WIDGET_DRAWABLE (priv->sample_area))
- return;
+ make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("_Hue:"), table, 0, 0, COLORSEL_HUE,
+ _("Position on the color wheel."));
+ gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (priv->hue_spinbutton), TRUE);
+ make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("_Saturation:"), table, 0, 1, COLORSEL_SATURATION,
+ _("\"Deepness\" of the color."));
+ make_label_spinbutton (colorsel, &priv->val_spinbutton, _("_Value:"), table, 0, 2, COLORSEL_VALUE,
+ _("Brightness of the color."));
+ make_label_spinbutton (colorsel, &priv->red_spinbutton, _("_Red:"), table, 6, 0, COLORSEL_RED,
+ _("Amount of red light in the color."));
+ make_label_spinbutton (colorsel, &priv->green_spinbutton, _("_Green:"), table, 6, 1, COLORSEL_GREEN,
+ _("Amount of green light in the color."));
+ make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("_Blue:"), table, 6, 2, COLORSEL_BLUE,
+ _("Amount of blue light in the color."));
+ gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4);
- if (which == 0)
- {
- da = priv->old_sample;
- goff = 0;
- }
- else
- {
- da = priv->cur_sample;
- goff = priv->old_sample->allocation.width % 32;
- }
+ priv->opacity_label = gtk_label_new_with_mnemonic (_("Op_acity:"));
+ gtk_misc_set_alignment (GTK_MISC (priv->opacity_label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_label, 0, 1, 4, 5);
+ adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0));
+ g_object_set_data (G_OBJECT (adjust), I_("COLORSEL"), colorsel);
+ priv->opacity_slider = gtk_hscale_new (adjust);
+ gtk_widget_set_tooltip_text (priv->opacity_slider,
+ _("Transparency of the color."));
+ gtk_label_set_mnemonic_widget (GTK_LABEL (priv->opacity_label),
+ priv->opacity_slider);
+ gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE);
+ g_signal_connect (adjust, "value_changed",
+ G_CALLBACK (adjustment_changed),
+ GINT_TO_POINTER (COLORSEL_OPACITY));
+ gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5);
+ priv->opacity_entry = gtk_entry_new ();
+ gtk_widget_set_tooltip_text (priv->opacity_entry,
+ _("Transparency of the color."));
+ gtk_widget_set_size_request (priv->opacity_entry, 40, -1);
- cr = gdk_cairo_create (da->window);
+ g_signal_connect (priv->opacity_entry, "activate",
+ G_CALLBACK (opacity_entry_changed), colorsel);
+ gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5);
- wid = da->allocation.width;
- heig = da->allocation.height;
+ label = gtk_label_new_with_mnemonic (_("Color _name:"));
+ gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ priv->hex_entry = gtk_entry_new ();
- /* Below needs tweaking for non-power-of-two */
-#define CHECK_SIZE 16
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->hex_entry);
+
+ g_signal_connect (priv->hex_entry, "activate",
+ G_CALLBACK (hex_changed), colorsel);
+
+ g_signal_connect (priv->hex_entry, "focus_out_event",
+ G_CALLBACK (hex_focus_out), colorsel);
+
+ gtk_widget_set_tooltip_text (priv->hex_entry,
+ _("You can enter an HTML-style hexadecimal color value, or simply a color name such as 'orange' in this entry."));
- if (priv->has_opacity)
- {
- /* Draw checks in background */
+ gtk_entry_set_width_chars (GTK_ENTRY (priv->hex_entry), 7);
+ gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6);
- cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
- cairo_rectangle (cr, 0, 0, wid, heig);
- cairo_fill (cr);
+ focus_chain = g_list_append (focus_chain, priv->hue_spinbutton);
+ focus_chain = g_list_append (focus_chain, priv->sat_spinbutton);
+ focus_chain = g_list_append (focus_chain, priv->val_spinbutton);
+ focus_chain = g_list_append (focus_chain, priv->red_spinbutton);
+ focus_chain = g_list_append (focus_chain, priv->green_spinbutton);
+ focus_chain = g_list_append (focus_chain, priv->blue_spinbutton);
+ focus_chain = g_list_append (focus_chain, priv->opacity_slider);
+ focus_chain = g_list_append (focus_chain, priv->opacity_entry);
+ focus_chain = g_list_append (focus_chain, priv->hex_entry);
+ gtk_container_set_focus_chain (GTK_CONTAINER (table), focus_chain);
+ g_list_free (focus_chain);
- cairo_set_source_rgb (cr, 0.75, 0.75, 0.75);
- for (x = goff & -CHECK_SIZE; x < goff + wid; x += CHECK_SIZE)
- for (y = 0; y < heig; y += CHECK_SIZE)
- if ((x / CHECK_SIZE + y / CHECK_SIZE) % 2 == 0)
- cairo_rectangle (cr, x - goff, y, CHECK_SIZE, CHECK_SIZE);
- cairo_fill (cr);
+ /* Set up the palette */
+ table = gtk_table_new (GTK_CUSTOM_PALETTE_HEIGHT, GTK_CUSTOM_PALETTE_WIDTH, TRUE);
+ gtk_table_set_row_spacings (GTK_TABLE (table), 1);
+ gtk_table_set_col_spacings (GTK_TABLE (table), 1);
+ for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
+ {
+ for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
+ {
+ make_palette_frame (colorsel, table, i, j);
+ }
}
+ set_selected_palette (colorsel, 0, 0);
+ priv->palette_frame = gtk_vbox_new (FALSE, 6);
+ label = gtk_label_new_with_mnemonic (_("_Palette:"));
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_box_pack_start (GTK_BOX (priv->palette_frame), label, FALSE, FALSE, 0);
- if (which == 0)
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label),
+ priv->custom_palette[0][0]);
+
+ gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (priv->palette_frame), table, FALSE, FALSE, 0);
+
+ gtk_widget_show_all (top_hbox);
+
+ /* hide unused stuff */
+
+ if (priv->has_opacity == FALSE)
{
- cairo_set_source_rgba (cr,
- priv->old_color[COLORSEL_RED],
- priv->old_color[COLORSEL_GREEN],
- priv->old_color[COLORSEL_BLUE],
- priv->has_opacity ?
- priv->old_color[COLORSEL_OPACITY] : 1.0);
+ gtk_widget_hide (priv->opacity_label);
+ gtk_widget_hide (priv->opacity_slider);
+ gtk_widget_hide (priv->opacity_entry);
}
- else
+
+ if (priv->has_palette == FALSE)
{
- cairo_set_source_rgba (cr,
- priv->color[COLORSEL_RED],
- priv->color[COLORSEL_GREEN],
- priv->color[COLORSEL_BLUE],
- priv->has_opacity ?
- priv->color[COLORSEL_OPACITY] : 1.0);
+ gtk_widget_hide (priv->palette_frame);
}
- cairo_rectangle (cr, 0, 0, wid, heig);
- cairo_fill (cr);
+ atk_obj = gtk_widget_get_accessible (priv->triangle_colorsel);
+ if (GTK_IS_ACCESSIBLE (atk_obj))
+ {
+ atk_object_set_name (atk_obj, _("Color Wheel"));
+ atk_object_set_role (gtk_widget_get_accessible (GTK_WIDGET (colorsel)), ATK_ROLE_COLOR_CHOOSER);
+ make_all_relations (atk_obj, priv);
+ }
- cairo_destroy (cr);
+ gtk_widget_pop_composite_child ();
}
-
+/* GObject methods */
static void
-color_sample_update_samples (GtkColorSelection *colorsel)
-{
- ColorSelectionPrivate *priv = colorsel->private_data;
- gtk_widget_queue_draw (priv->old_sample);
- gtk_widget_queue_draw (priv->cur_sample);
-}
-
-static gboolean
-color_old_sample_expose (GtkWidget *da,
- GdkEventExpose *event,
- GtkColorSelection *colorsel)
+gtk_color_selection_finalize (GObject *object)
{
- color_sample_draw_sample (colorsel, 0);
- return FALSE;
+ G_OBJECT_CLASS (gtk_color_selection_parent_class)->finalize (object);
}
-
-static gboolean
-color_cur_sample_expose (GtkWidget *da,
- GdkEventExpose *event,
- GtkColorSelection *colorsel)
+static void
+gtk_color_selection_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
{
- color_sample_draw_sample (colorsel, 1);
- return FALSE;
+ GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
+
+ switch (prop_id)
+ {
+ case PROP_HAS_OPACITY_CONTROL:
+ gtk_color_selection_set_has_opacity_control (colorsel,
+ g_value_get_boolean (value));
+ break;
+ case PROP_HAS_PALETTE:
+ gtk_color_selection_set_has_palette (colorsel,
+ g_value_get_boolean (value));
+ break;
+ case PROP_CURRENT_COLOR:
+ gtk_color_selection_set_current_color (colorsel, g_value_get_boxed (value));
+ break;
+ case PROP_CURRENT_ALPHA:
+ gtk_color_selection_set_current_alpha (colorsel, g_value_get_uint (value));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+
}
static void
-color_sample_setup_dnd (GtkColorSelection *colorsel, GtkWidget *sample)
+gtk_color_selection_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
{
- static const GtkTargetEntry targets[] = {
- { "application/x-color", 0 }
- };
- ColorSelectionPrivate *priv;
- priv = colorsel->private_data;
-
- gtk_drag_source_set (sample,
- GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
- targets, 1,
- GDK_ACTION_COPY | GDK_ACTION_MOVE);
+ GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
+ GdkColor color;
- g_signal_connect (sample,
- "drag_begin",
- G_CALLBACK (color_sample_drag_begin),
- colorsel);
- if (sample == priv->cur_sample)
+ switch (prop_id)
{
-
- gtk_drag_dest_set (sample,
- GTK_DEST_DEFAULT_HIGHLIGHT |
- GTK_DEST_DEFAULT_MOTION |
- GTK_DEST_DEFAULT_DROP,
- targets, 1,
- GDK_ACTION_COPY);
-
- g_signal_connect (sample,
- "drag_end",
- G_CALLBACK (color_sample_drag_end),
- colorsel);
+ case PROP_HAS_OPACITY_CONTROL:
+ g_value_set_boolean (value, gtk_color_selection_get_has_opacity_control (colorsel));
+ break;
+ case PROP_HAS_PALETTE:
+ g_value_set_boolean (value, gtk_color_selection_get_has_palette (colorsel));
+ break;
+ case PROP_CURRENT_COLOR:
+ gtk_color_selection_get_current_color (colorsel, &color);
+ g_value_set_boxed (value, &color);
+ break;
+ case PROP_CURRENT_ALPHA:
+ g_value_set_uint (value, gtk_color_selection_get_current_alpha (colorsel));
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
}
-
- g_signal_connect (sample,
- "drag_data_get",
- G_CALLBACK (color_sample_drag_handle),
- colorsel);
- g_signal_connect (sample,
- "drag_data_received",
- G_CALLBACK (color_sample_drop_handle),
- colorsel);
-
}
+/* GtkObject methods */
static void
-color_sample_new (GtkColorSelection *colorsel)
+gtk_color_selection_destroy (GtkObject *object)
{
- ColorSelectionPrivate *priv;
-
- priv = colorsel->private_data;
-
- priv->sample_area = gtk_hbox_new (FALSE, 0);
- priv->old_sample = gtk_drawing_area_new ();
- priv->cur_sample = gtk_drawing_area_new ();
+ GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
+ ColorSelectionPrivate *priv = cselection->private_data;
- gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->old_sample,
- TRUE, TRUE, 0);
- gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->cur_sample,
- TRUE, TRUE, 0);
-
- g_signal_connect (priv->old_sample, "expose_event",
- G_CALLBACK (color_old_sample_expose),
- colorsel);
- g_signal_connect (priv->cur_sample, "expose_event",
- G_CALLBACK (color_cur_sample_expose),
- colorsel);
-
- color_sample_setup_dnd (colorsel, priv->old_sample);
- color_sample_setup_dnd (colorsel, priv->cur_sample);
+ if (priv->dropper_grab_widget)
+ {
+ gtk_widget_destroy (priv->dropper_grab_widget);
+ priv->dropper_grab_widget = NULL;
+ }
- gtk_widget_set_tooltip_text (priv->old_sample,
- _("The previously-selected color, for comparison to the color you're selecting now. You can drag this color to a palette entry, or select this color as current by dragging it to the other color swatch alongside."));
+ GTK_OBJECT_CLASS (gtk_color_selection_parent_class)->destroy (object);
+}
+/* GtkWidget methods */
- gtk_widget_set_tooltip_text (priv->cur_sample,
- _("The color you've chosen. You can drag this color to a palette entry to save it for use in the future."));
-
- gtk_widget_show_all (priv->sample_area);
+static void
+gtk_color_selection_realize (GtkWidget *widget)
+{
+ GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget);
+ ColorSelectionPrivate *priv = colorsel->private_data;
+ GtkSettings *settings = gtk_widget_get_settings (widget);
+
+ priv->settings_connection = g_signal_connect (settings,
+ "notify::gtk-color-palette",
+ G_CALLBACK (palette_change_notify_instance),
+ widget);
+ update_palette (colorsel);
+
+ GTK_WIDGET_CLASS (gtk_color_selection_parent_class)->realize (widget);
+}
+
+static void
+gtk_color_selection_unrealize (GtkWidget *widget)
+{
+ GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget);
+ ColorSelectionPrivate *priv = colorsel->private_data;
+ GtkSettings *settings = gtk_widget_get_settings (widget);
+
+ g_signal_handler_disconnect (settings, priv->settings_connection);
+
+ GTK_WIDGET_CLASS (gtk_color_selection_parent_class)->unrealize (widget);
+}
+
+/* We override show-all since we have internal widgets that
+ * shouldn't be shown when you call show_all(), like the
+ * palette and opacity sliders.
+ */
+static void
+gtk_color_selection_show_all (GtkWidget *widget)
+{
+ gtk_widget_show (widget);
}
+static gboolean
+gtk_color_selection_grab_broken (GtkWidget *widget,
+ GdkEventGrabBroken *event)
+{
+ shutdown_eyedropper (widget);
+
+ return TRUE;
+}
/*
*
- * The palette area code
+ * The Sample Color
*
*/
-#define CUSTOM_PALETTE_ENTRY_WIDTH 20
-#define CUSTOM_PALETTE_ENTRY_HEIGHT 20
+
+static void color_sample_draw_sample (GtkColorSelection *colorsel, int which);
+static void color_sample_update_samples (GtkColorSelection *colorsel);
static void
-palette_get_color (GtkWidget *drawing_area, gdouble *color)
+set_color_internal (GtkColorSelection *colorsel,
+ gdouble *color)
{
- gdouble *color_val;
-
- g_return_if_fail (color != NULL);
+ ColorSelectionPrivate *priv;
+ gint i;
- color_val = g_object_get_data (G_OBJECT (drawing_area), "color_val");
- if (color_val == NULL)
+ priv = colorsel->private_data;
+ priv->changing = TRUE;
+ priv->color[COLORSEL_RED] = color[0];
+ priv->color[COLORSEL_GREEN] = color[1];
+ priv->color[COLORSEL_BLUE] = color[2];
+ priv->color[COLORSEL_OPACITY] = color[3];
+ gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
+ priv->color[COLORSEL_GREEN],
+ priv->color[COLORSEL_BLUE],
+ &priv->color[COLORSEL_HUE],
+ &priv->color[COLORSEL_SATURATION],
+ &priv->color[COLORSEL_VALUE]);
+ if (priv->default_set == FALSE)
{
- /* Default to white for no good reason */
- color[0] = 1.0;
- color[1] = 1.0;
- color[2] = 1.0;
- color[3] = 1.0;
- return;
+ for (i = 0; i < COLORSEL_NUM_CHANNELS; i++)
+ priv->old_color[i] = priv->color[i];
}
-
- color[0] = color_val[0];
- color[1] = color_val[1];
- color[2] = color_val[2];
- color[3] = 1.0;
+ priv->default_set = TRUE;
+ priv->default_alpha_set = TRUE;
+ update_color (colorsel);
}
-#define INTENSITY(r, g, b) ((r) * 0.30 + (g) * 0.59 + (b) * 0.11)
static void
-palette_paint (GtkWidget *drawing_area,
- GdkRectangle *area,
- gpointer data)
+set_color_icon (GdkDragContext *context,
+ gdouble *colors)
{
- cairo_t *cr;
- gint focus_width;
-
- if (drawing_area->window == NULL)
- return;
-
- cr = gdk_cairo_create (drawing_area->window);
+ GdkPixbuf *pixbuf;
+ guint32 pixel;
- gdk_cairo_set_source_color (cr, &drawing_area->style->bg[GTK_STATE_NORMAL]);
- gdk_cairo_rectangle (cr, area);
- cairo_fill (cr);
-
- if (GTK_WIDGET_HAS_FOCUS (drawing_area))
- {
- set_focus_line_attributes (drawing_area, cr, &focus_width);
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, FALSE,
+ 8, 48, 32);
- cairo_rectangle (cr,
- focus_width / 2., focus_width / 2.,
- drawing_area->allocation.width - focus_width,
- drawing_area->allocation.height - focus_width);
- cairo_stroke (cr);
- }
+ pixel = (((UNSCALE (colors[COLORSEL_RED]) & 0xff00) << 16) |
+ ((UNSCALE (colors[COLORSEL_GREEN]) & 0xff00) << 8) |
+ ((UNSCALE (colors[COLORSEL_BLUE]) & 0xff00)));
- cairo_destroy (cr);
+ gdk_pixbuf_fill (pixbuf, pixel);
+
+ gtk_drag_set_icon_pixbuf (context, pixbuf, -2, -2);
+ g_object_unref (pixbuf);
}
static void
-set_focus_line_attributes (GtkWidget *drawing_area,
- cairo_t *cr,
- gint *focus_width)
+color_sample_drag_begin (GtkWidget *widget,
+ GdkDragContext *context,
+ gpointer data)
{
- gdouble color[4];
- gint8 *dash_list;
+ GtkColorSelection *colorsel = data;
+ ColorSelectionPrivate *priv;
+ gdouble *colsrc;
- gtk_widget_style_get (drawing_area,
- "focus-line-width", focus_width,
- "focus-line-pattern", (gchar *)&dash_list,
- NULL);
-
- palette_get_color (drawing_area, color);
-
- if (INTENSITY (color[0], color[1], color[2]) > 0.5)
- cairo_set_source_rgb (cr, 0., 0., 0.);
+ priv = colorsel->private_data;
+
+ if (widget == priv->old_sample)
+ colsrc = priv->old_color;
else
- cairo_set_source_rgb (cr, 1., 1., 1.);
+ colsrc = priv->color;
- cairo_set_line_width (cr, *focus_width);
+ set_color_icon (context, colsrc);
+}
- if (dash_list[0])
- {
- gint n_dashes = strlen (dash_list);
- gdouble *dashes = g_new (gdouble, n_dashes);
- gdouble total_length = 0;
- gdouble dash_offset;
- gint i;
-
- for (i = 0; i < n_dashes; i++)
- {
- dashes[i] = dash_list[i];
- total_length += dash_list[i];
- }
-
- /* The dash offset here aligns the pattern to integer pixels
- * by starting the dash at the right side of the left border
- * Negative dash offsets in cairo don't work
- * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
- */
- dash_offset = - *focus_width / 2.;
- while (dash_offset < 0)
- dash_offset += total_length;
-
- cairo_set_dash (cr, dashes, n_dashes, dash_offset);
- g_free (dashes);
- }
-
- g_free (dash_list);
-}
+static void
+color_sample_drag_end (GtkWidget *widget,
+ GdkDragContext *context,
+ gpointer data)
+{
+ g_object_set_data (G_OBJECT (widget), I_("gtk-color-selection-drag-window"), NULL);
+}
static void
-palette_drag_begin (GtkWidget *widget,
- GdkDragContext *context,
- gpointer data)
+color_sample_drop_handle (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ gpointer data)
{
- gdouble colors[4];
+ GtkColorSelection *colorsel = data;
+ ColorSelectionPrivate *priv;
+ guint16 *vals;
+ gdouble color[4];
+ priv = colorsel->private_data;
- palette_get_color (widget, colors);
- set_color_icon (context, colors);
+ /* This is currently a guint16 array of the format:
+ * R
+ * G
+ * B
+ * opacity
+ */
+
+ if (selection_data->length < 0)
+ return;
+
+ /* We accept drops with the wrong format, since the KDE color
+ * chooser incorrectly drops application/x-color with format 8.
+ */
+ if (selection_data->length != 8)
+ {
+ g_warning ("Received invalid color data\n");
+ return;
+ }
+
+ vals = (guint16 *)selection_data->data;
+
+ if (widget == priv->cur_sample)
+ {
+ color[0] = (gdouble)vals[0] / 0xffff;
+ color[1] = (gdouble)vals[1] / 0xffff;
+ color[2] = (gdouble)vals[2] / 0xffff;
+ color[3] = (gdouble)vals[3] / 0xffff;
+
+ set_color_internal (colorsel, color);
+ }
}
static void
-palette_drag_handle (GtkWidget *widget,
- GdkDragContext *context,
- GtkSelectionData *selection_data,
- guint info,
- guint time,
- gpointer data)
+color_sample_drag_handle (GtkWidget *widget,
+ GdkDragContext *context,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ gpointer data)
{
+ GtkColorSelection *colorsel = data;
+ ColorSelectionPrivate *priv;
guint16 vals[4];
- gdouble colsrc[4];
+ gdouble *colsrc;
- palette_get_color (widget, colsrc);
+ priv = colorsel->private_data;
+
+ if (widget == priv->old_sample)
+ colsrc = priv->old_color;
+ else
+ colsrc = priv->color;
vals[0] = colsrc[COLORSEL_RED] * 0xffff;
vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
- vals[3] = 0xffff;
+ vals[3] = priv->has_opacity ? colsrc[COLORSEL_OPACITY] * 0xffff : 0xffff;
gtk_selection_data_set (selection_data,
gdk_atom_intern_static_string ("application/x-color"),
16, (guchar *)vals, 8);
}
+/* which = 0 means draw old sample, which = 1 means draw new */
static void
-palette_drag_end (GtkWidget *widget,
- GdkDragContext *context,
- gpointer data)
-{
- g_object_set_data (G_OBJECT (widget), I_("gtk-color-selection-drag-window"), NULL);
-}
-
-static GdkColor *
-get_current_colors (GtkColorSelection *colorsel)
+color_sample_draw_sample (GtkColorSelection *colorsel, int which)
{
- GtkSettings *settings;
- GdkColor *colors = NULL;
- gint n_colors = 0;
- gchar *palette;
-
- settings = gtk_widget_get_settings (GTK_WIDGET (colorsel));
- g_object_get (settings,
- "gtk-color-palette", &palette,
- NULL);
+ GtkWidget *da;
+ gint x, y, wid, heig, goff;
+ ColorSelectionPrivate *priv;
+ cairo_t *cr;
- if (!gtk_color_selection_palette_from_string (palette, &colors, &n_colors))
+ g_return_if_fail (colorsel != NULL);
+ priv = colorsel->private_data;
+
+ g_return_if_fail (priv->sample_area != NULL);
+ if (!GTK_WIDGET_DRAWABLE (priv->sample_area))
+ return;
+
+ if (which == 0)
{
- gtk_color_selection_palette_from_string (default_colors, &colors, &n_colors);
+ da = priv->old_sample;
+ goff = 0;
}
else
{
- /* If there are less colors provided than the number of slots in the
- * color selection, we fill in the rest from the defaults.
- */
- if (n_colors < (GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT))
- {
- GdkColor *tmp_colors = colors;
- gint tmp_n_colors = n_colors;
-
- gtk_color_selection_palette_from_string (default_colors, &colors, &n_colors);
- memcpy (colors, tmp_colors, sizeof (GdkColor) * tmp_n_colors);
-
- g_free (tmp_colors);
- }
+ da = priv->cur_sample;
+ goff = priv->old_sample->allocation.width % 32;
}
- g_assert (n_colors >= GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
- g_free (palette);
+ cr = gdk_cairo_create (da->window);
- return colors;
-}
-
-/* Changes the model color */
-static void
-palette_change_color (GtkWidget *drawing_area,
- GtkColorSelection *colorsel,
- gdouble *color)
-{
- gint x, y;
- ColorSelectionPrivate *priv;
- GdkColor gdk_color;
- GdkColor *current_colors;
- GdkScreen *screen;
+ wid = da->allocation.width;
+ heig = da->allocation.height;
- g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
- g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area));
-
- priv = colorsel->private_data;
+ /* Below needs tweaking for non-power-of-two */
- gdk_color.red = UNSCALE (color[0]);
- gdk_color.green = UNSCALE (color[1]);
- gdk_color.blue = UNSCALE (color[2]);
- gdk_color.pixel = 0;
-
- x = 0;
- y = 0; /* Quiet GCC */
- while (x < GTK_CUSTOM_PALETTE_WIDTH)
+ if (priv->has_opacity)
{
- y = 0;
- while (y < GTK_CUSTOM_PALETTE_HEIGHT)
- {
- if (priv->custom_palette[x][y] == drawing_area)
- goto out;
-
- ++y;
- }
-
- ++x;
- }
+ /* Draw checks in background */
- out:
-
- g_assert (x < GTK_CUSTOM_PALETTE_WIDTH || y < GTK_CUSTOM_PALETTE_HEIGHT);
+ cairo_set_source_rgb (cr, 0.5, 0.5, 0.5);
+ cairo_rectangle (cr, 0, 0, wid, heig);
+ cairo_fill (cr);
- current_colors = get_current_colors (colorsel);
- current_colors[y * GTK_CUSTOM_PALETTE_WIDTH + x] = gdk_color;
+ cairo_set_source_rgb (cr, 0.75, 0.75, 0.75);
+ for (x = goff & -CHECK_SIZE; x < goff + wid; x += CHECK_SIZE)
+ for (y = 0; y < heig; y += CHECK_SIZE)
+ if ((x / CHECK_SIZE + y / CHECK_SIZE) % 2 == 0)
+ cairo_rectangle (cr, x - goff, y, CHECK_SIZE, CHECK_SIZE);
+ cairo_fill (cr);
+ }
- screen = gtk_widget_get_screen (GTK_WIDGET (colorsel));
- if (change_palette_hook != default_change_palette_func)
- (* change_palette_hook) (screen, current_colors,
- GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
- else if (noscreen_change_palette_hook != default_noscreen_change_palette_func)
+ if (which == 0)
{
- if (screen != gdk_screen_get_default ())
- g_warning ("gtk_color_selection_set_change_palette_hook used by widget is not on the default screen.");
- (* noscreen_change_palette_hook) (current_colors,
- GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
+ cairo_set_source_rgba (cr,
+ priv->old_color[COLORSEL_RED],
+ priv->old_color[COLORSEL_GREEN],
+ priv->old_color[COLORSEL_BLUE],
+ priv->has_opacity ?
+ priv->old_color[COLORSEL_OPACITY] : 1.0);
}
else
- (* change_palette_hook) (screen, current_colors,
- GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
+ {
+ cairo_set_source_rgba (cr,
+ priv->color[COLORSEL_RED],
+ priv->color[COLORSEL_GREEN],
+ priv->color[COLORSEL_BLUE],
+ priv->has_opacity ?
+ priv->color[COLORSEL_OPACITY] : 1.0);
+ }
- g_free (current_colors);
+ cairo_rectangle (cr, 0, 0, wid, heig);
+ cairo_fill (cr);
+
+ cairo_destroy (cr);
}
-/* Changes the view color */
+
static void
-palette_set_color (GtkWidget *drawing_area,
- GtkColorSelection *colorsel,
- gdouble *color)
+color_sample_update_samples (GtkColorSelection *colorsel)
{
- gdouble *new_color = g_new (double, 4);
- GdkColor gdk_color;
-
- gdk_color.red = UNSCALE (color[0]);
- gdk_color.green = UNSCALE (color[1]);
- gdk_color.blue = UNSCALE (color[2]);
+ ColorSelectionPrivate *priv = colorsel->private_data;
+ gtk_widget_queue_draw (priv->old_sample);
+ gtk_widget_queue_draw (priv->cur_sample);
+}
- gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &gdk_color);
-
- if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (drawing_area), "color_set")) == 0)
- {
- static const GtkTargetEntry targets[] = {
- { "application/x-color", 0 }
- };
- gtk_drag_source_set (drawing_area,
- GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
- targets, 1,
- GDK_ACTION_COPY | GDK_ACTION_MOVE);
-
- g_signal_connect (drawing_area,
- "drag_begin",
- G_CALLBACK (palette_drag_begin),
- colorsel);
- g_signal_connect (drawing_area,
- "drag_data_get",
- G_CALLBACK (palette_drag_handle),
- colorsel);
-
- g_object_set_data (G_OBJECT (drawing_area), I_("color_set"),
- GINT_TO_POINTER (1));
- }
-
- new_color[0] = color[0];
- new_color[1] = color[1];
- new_color[2] = color[2];
- new_color[3] = 1.0;
-
- g_object_set_data_full (G_OBJECT (drawing_area), I_("color_val"), new_color, (GDestroyNotify)g_free);
+static gboolean
+color_old_sample_expose (GtkWidget *da,
+ GdkEventExpose *event,
+ GtkColorSelection *colorsel)
+{
+ color_sample_draw_sample (colorsel, 0);
+ return FALSE;
}
+
static gboolean
-palette_expose (GtkWidget *drawing_area,
- GdkEventExpose *event,
- gpointer data)
+color_cur_sample_expose (GtkWidget *da,
+ GdkEventExpose *event,
+ GtkColorSelection *colorsel)
{
- if (drawing_area->window == NULL)
- return FALSE;
-
- palette_paint (drawing_area, &(event->area), data);
-
+ color_sample_draw_sample (colorsel, 1);
return FALSE;
}
static void
-popup_position_func (GtkMenu *menu,
- gint *x,
- gint *y,
- gboolean *push_in,
- gpointer user_data)
+color_sample_setup_dnd (GtkColorSelection *colorsel, GtkWidget *sample)
{
- GtkWidget *widget;
- GtkRequisition req;
- gint root_x, root_y;
- GdkScreen *screen;
+ static const GtkTargetEntry targets[] = {
+ { "application/x-color", 0 }
+ };
+ ColorSelectionPrivate *priv;
+ priv = colorsel->private_data;
- widget = GTK_WIDGET (user_data);
+ gtk_drag_source_set (sample,
+ GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
+ targets, 1,
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
- g_return_if_fail (GTK_WIDGET_REALIZED (widget));
-
- gdk_window_get_origin (widget->window, &root_x, &root_y);
+ g_signal_connect (sample,
+ "drag_begin",
+ G_CALLBACK (color_sample_drag_begin),
+ colorsel);
+ if (sample == priv->cur_sample)
+ {
+
+ gtk_drag_dest_set (sample,
+ GTK_DEST_DEFAULT_HIGHLIGHT |
+ GTK_DEST_DEFAULT_MOTION |
+ GTK_DEST_DEFAULT_DROP,
+ targets, 1,
+ GDK_ACTION_COPY);
+
+ g_signal_connect (sample,
+ "drag_end",
+ G_CALLBACK (color_sample_drag_end),
+ colorsel);
+ }
+
+ g_signal_connect (sample,
+ "drag_data_get",
+ G_CALLBACK (color_sample_drag_handle),
+ colorsel);
+ g_signal_connect (sample,
+ "drag_data_received",
+ G_CALLBACK (color_sample_drop_handle),
+ colorsel);
- gtk_widget_size_request (GTK_WIDGET (menu), &req);
-
- /* Put corner of menu centered on color cell */
- *x = root_x + widget->allocation.width / 2;
- *y = root_y + widget->allocation.height / 2;
-
- /* Ensure sanity */
- screen = gtk_widget_get_screen (widget);
- *x = CLAMP (*x, 0, MAX (0, gdk_screen_get_width (screen) - req.width));
- *y = CLAMP (*y, 0, MAX (0, gdk_screen_get_height (screen) - req.height));
}
+
static void
-save_color_selected (GtkWidget *menuitem,
- gpointer data)
+color_sample_new (GtkColorSelection *colorsel)
{
- GtkColorSelection *colorsel;
- GtkWidget *drawing_area;
ColorSelectionPrivate *priv;
-
- drawing_area = GTK_WIDGET (data);
- colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (drawing_area),
- "gtk-color-sel"));
-
priv = colorsel->private_data;
- palette_change_color (drawing_area, colorsel, priv->color);
-}
+ priv->sample_area = gtk_hbox_new (FALSE, 0);
+ priv->old_sample = gtk_drawing_area_new ();
+ priv->cur_sample = gtk_drawing_area_new ();
-static void
-do_popup (GtkColorSelection *colorsel,
- GtkWidget *drawing_area,
- guint32 timestamp)
-{
- GtkWidget *menu;
- GtkWidget *mi;
+ gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->old_sample,
+ TRUE, TRUE, 0);
+ gtk_box_pack_start (GTK_BOX (priv->sample_area), priv->cur_sample,
+ TRUE, TRUE, 0);
- g_object_set_data (G_OBJECT (drawing_area),
- I_("gtk-color-sel"),
- colorsel);
+ g_signal_connect (priv->old_sample, "expose_event",
+ G_CALLBACK (color_old_sample_expose),
+ colorsel);
+ g_signal_connect (priv->cur_sample, "expose_event",
+ G_CALLBACK (color_cur_sample_expose),
+ colorsel);
- menu = gtk_menu_new ();
-
- mi = gtk_menu_item_new_with_mnemonic (_("_Save color here"));
+ color_sample_setup_dnd (colorsel, priv->old_sample);
+ color_sample_setup_dnd (colorsel, priv->cur_sample);
- g_signal_connect (mi, "activate",
- G_CALLBACK (save_color_selected),
- drawing_area);
-
- gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+ gtk_widget_set_tooltip_text (priv->old_sample,
+ _("The previously-selected color, for comparison to the color you're selecting now. You can drag this color to a palette entry, or select this color as current by dragging it to the other color swatch alongside."));
- gtk_widget_show_all (mi);
- gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
- popup_position_func, drawing_area,
- 3, timestamp);
+ gtk_widget_set_tooltip_text (priv->cur_sample,
+ _("The color you've chosen. You can drag this color to a palette entry to save it for use in the future."));
+
+ gtk_widget_show_all (priv->sample_area);
}
-static gboolean
-palette_enter (GtkWidget *drawing_area,
- GdkEventCrossing *event,
- gpointer data)
-{
- g_object_set_data (G_OBJECT (drawing_area),
- I_("gtk-colorsel-have-pointer"),
- GUINT_TO_POINTER (TRUE));
-
- return FALSE;
-}
+/*
+ *
+ * The palette area code
+ *
+ */
-static gboolean
-palette_leave (GtkWidget *drawing_area,
- GdkEventCrossing *event,
- gpointer data)
+static void
+palette_get_color (GtkWidget *drawing_area, gdouble *color)
{
- g_object_set_data (G_OBJECT (drawing_area),
- I_("gtk-colorsel-have-pointer"),
- NULL);
-
- return FALSE;
+ gdouble *color_val;
+
+ g_return_if_fail (color != NULL);
+
+ color_val = g_object_get_data (G_OBJECT (drawing_area), "color_val");
+ if (color_val == NULL)
+ {
+ /* Default to white for no good reason */
+ color[0] = 1.0;
+ color[1] = 1.0;
+ color[2] = 1.0;
+ color[3] = 1.0;
+ return;
+ }
+
+ color[0] = color_val[0];
+ color[1] = color_val[1];
+ color[2] = color_val[2];
+ color[3] = 1.0;
}
-static gboolean
-palette_press (GtkWidget *drawing_area,
- GdkEventButton *event,
- gpointer data)
+static void
+palette_paint (GtkWidget *drawing_area,
+ GdkRectangle *area,
+ gpointer data)
{
- GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
+ cairo_t *cr;
+ gint focus_width;
+
+ if (drawing_area->window == NULL)
+ return;
- gtk_widget_grab_focus (drawing_area);
+ cr = gdk_cairo_create (drawing_area->window);
+
+ gdk_cairo_set_source_color (cr, &drawing_area->style->bg[GTK_STATE_NORMAL]);
+ gdk_cairo_rectangle (cr, area);
+ cairo_fill (cr);
- if (event->button == 3 &&
- event->type == GDK_BUTTON_PRESS)
+ if (GTK_WIDGET_HAS_FOCUS (drawing_area))
{
- do_popup (colorsel, drawing_area, event->time);
- return TRUE;
+ set_focus_line_attributes (drawing_area, cr, &focus_width);
+
+ cairo_rectangle (cr,
+ focus_width / 2., focus_width / 2.,
+ drawing_area->allocation.width - focus_width,
+ drawing_area->allocation.height - focus_width);
+ cairo_stroke (cr);
}
- return FALSE;
+ cairo_destroy (cr);
}
-static gboolean
-palette_release (GtkWidget *drawing_area,
- GdkEventButton *event,
- gpointer data)
+static void
+set_focus_line_attributes (GtkWidget *drawing_area,
+ cairo_t *cr,
+ gint *focus_width)
{
- GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
-
- gtk_widget_grab_focus (drawing_area);
-
- if (event->button == 1 &&
- g_object_get_data (G_OBJECT (drawing_area),
- "gtk-colorsel-have-pointer") != NULL)
+ gdouble color[4];
+ gint8 *dash_list;
+
+ gtk_widget_style_get (drawing_area,
+ "focus-line-width", focus_width,
+ "focus-line-pattern", (gchar *)&dash_list,
+ NULL);
+
+ palette_get_color (drawing_area, color);
+
+ if (INTENSITY (color[0], color[1], color[2]) > 0.5)
+ cairo_set_source_rgb (cr, 0., 0., 0.);
+ else
+ cairo_set_source_rgb (cr, 1., 1., 1.);
+
+ cairo_set_line_width (cr, *focus_width);
+
+ if (dash_list[0])
{
- if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (drawing_area), "color_set")) != 0)
- {
- gdouble color[4];
- palette_get_color (drawing_area, color);
- set_color_internal (colorsel, color);
- }
+ gint n_dashes = strlen (dash_list);
+ gdouble *dashes = g_new (gdouble, n_dashes);
+ gdouble total_length = 0;
+ gdouble dash_offset;
+ gint i;
+
+ for (i = 0; i < n_dashes; i++)
+ {
+ dashes[i] = dash_list[i];
+ total_length += dash_list[i];
+ }
+
+ /* The dash offset here aligns the pattern to integer pixels
+ * by starting the dash at the right side of the left border
+ * Negative dash offsets in cairo don't work
+ * (https://bugs.freedesktop.org/show_bug.cgi?id=2729)
+ */
+ dash_offset = - *focus_width / 2.;
+ while (dash_offset < 0)
+ dash_offset += total_length;
+
+ cairo_set_dash (cr, dashes, n_dashes, dash_offset);
+ g_free (dashes);
}
- return FALSE;
+ g_free (dash_list);
}
static void
-palette_drop_handle (GtkWidget *widget,
+palette_drag_begin (GtkWidget *widget,
+ GdkDragContext *context,
+ gpointer data)
+{
+ gdouble colors[4];
+
+ palette_get_color (widget, colors);
+ set_color_icon (context, colors);
+}
+
+static void
+palette_drag_handle (GtkWidget *widget,
GdkDragContext *context,
- gint x,
- gint y,
GtkSelectionData *selection_data,
guint info,
guint time,
gpointer data)
{
- GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
- guint16 *vals;
- gdouble color[4];
-
- if (selection_data->length < 0)
- return;
+ guint16 vals[4];
+ gdouble colsrc[4];
- /* We accept drops with the wrong format, since the KDE color
- * chooser incorrectly drops application/x-color with format 8.
- */
- if (selection_data->length != 8)
- {
- g_warning ("Received invalid color data\n");
- return;
- }
+ palette_get_color (widget, colsrc);
- vals = (guint16 *)selection_data->data;
+ vals[0] = colsrc[COLORSEL_RED] * 0xffff;
+ vals[1] = colsrc[COLORSEL_GREEN] * 0xffff;
+ vals[2] = colsrc[COLORSEL_BLUE] * 0xffff;
+ vals[3] = 0xffff;
- color[0] = (gdouble)vals[0] / 0xffff;
- color[1] = (gdouble)vals[1] / 0xffff;
- color[2] = (gdouble)vals[2] / 0xffff;
- color[3] = (gdouble)vals[3] / 0xffff;
- palette_change_color (widget, colorsel, color);
- set_color_internal (colorsel, color);
+ gtk_selection_data_set (selection_data,
+ gdk_atom_intern_static_string ("application/x-color"),
+ 16, (guchar *)vals, 8);
}
-static gint
-palette_activate (GtkWidget *widget,
- GdkEventKey *event,
- gpointer data)
+static void
+palette_drag_end (GtkWidget *widget,
+ GdkDragContext *context,
+ gpointer data)
{
- /* should have a drawing area subclass with an activate signal */
- if ((event->keyval == GDK_space) ||
- (event->keyval == GDK_Return) ||
- (event->keyval == GDK_ISO_Enter) ||
- (event->keyval == GDK_KP_Enter) ||
- (event->keyval == GDK_KP_Space))
- {
- if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "color_set")) != 0)
- {
- gdouble color[4];
- palette_get_color (widget, color);
- set_color_internal (GTK_COLOR_SELECTION (data), color);
- }
- return TRUE;
- }
-
- return FALSE;
+ g_object_set_data (G_OBJECT (widget), I_("gtk-color-selection-drag-window"), NULL);
}
-static gboolean
-palette_popup (GtkWidget *widget,
- gpointer data)
+static GdkColor *
+get_current_colors (GtkColorSelection *colorsel)
{
- GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
+ GtkSettings *settings;
+ GdkColor *colors = NULL;
+ gint n_colors = 0;
+ gchar *palette;
- do_popup (colorsel, widget, GDK_CURRENT_TIME);
- return TRUE;
+ settings = gtk_widget_get_settings (GTK_WIDGET (colorsel));
+ g_object_get (settings,
+ "gtk-color-palette", &palette,
+ NULL);
+
+ if (!gtk_color_selection_palette_from_string (palette, &colors, &n_colors))
+ {
+ gtk_color_selection_palette_from_string (default_colors, &colors, &n_colors);
+ }
+ else
+ {
+ /* If there are less colors provided than the number of slots in the
+ * color selection, we fill in the rest from the defaults.
+ */
+ if (n_colors < (GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT))
+ {
+ GdkColor *tmp_colors = colors;
+ gint tmp_n_colors = n_colors;
+
+ gtk_color_selection_palette_from_string (default_colors, &colors, &n_colors);
+ memcpy (colors, tmp_colors, sizeof (GdkColor) * tmp_n_colors);
+
+ g_free (tmp_colors);
+ }
+ }
+
+ g_assert (n_colors >= GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
+ g_free (palette);
+
+ return colors;
}
-
-static GtkWidget*
-palette_new (GtkColorSelection *colorsel)
+/* Changes the model color */
+static void
+palette_change_color (GtkWidget *drawing_area,
+ GtkColorSelection *colorsel,
+ gdouble *color)
{
- GtkWidget *retval;
+ gint x, y;
ColorSelectionPrivate *priv;
-
- static const GtkTargetEntry targets[] = {
- { "application/x-color", 0 }
- };
+ GdkColor gdk_color;
+ GdkColor *current_colors;
+ GdkScreen *screen;
+ g_return_if_fail (GTK_IS_COLOR_SELECTION (colorsel));
+ g_return_if_fail (GTK_IS_DRAWING_AREA (drawing_area));
+
priv = colorsel->private_data;
- retval = gtk_drawing_area_new ();
+ gdk_color.red = UNSCALE (color[0]);
+ gdk_color.green = UNSCALE (color[1]);
+ gdk_color.blue = UNSCALE (color[2]);
+ gdk_color.pixel = 0;
- GTK_WIDGET_SET_FLAGS (retval, GTK_CAN_FOCUS);
-
- g_object_set_data (G_OBJECT (retval), I_("color_set"), GINT_TO_POINTER (0));
- gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK
- | GDK_BUTTON_RELEASE_MASK
- | GDK_EXPOSURE_MASK
- | GDK_ENTER_NOTIFY_MASK
- | GDK_LEAVE_NOTIFY_MASK);
-
- g_signal_connect (retval, "expose_event",
- G_CALLBACK (palette_expose), colorsel);
- g_signal_connect (retval, "button_press_event",
- G_CALLBACK (palette_press), colorsel);
- g_signal_connect (retval, "button_release_event",
- G_CALLBACK (palette_release), colorsel);
- g_signal_connect (retval, "enter_notify_event",
- G_CALLBACK (palette_enter), colorsel);
- g_signal_connect (retval, "leave_notify_event",
- G_CALLBACK (palette_leave), colorsel);
- g_signal_connect (retval, "key_press_event",
- G_CALLBACK (palette_activate), colorsel);
- g_signal_connect (retval, "popup_menu",
- G_CALLBACK (palette_popup), colorsel);
-
- gtk_drag_dest_set (retval,
- GTK_DEST_DEFAULT_HIGHLIGHT |
- GTK_DEST_DEFAULT_MOTION |
- GTK_DEST_DEFAULT_DROP,
- targets, 1,
- GDK_ACTION_COPY);
-
- g_signal_connect (retval, "drag_end",
- G_CALLBACK (palette_drag_end), NULL);
- g_signal_connect (retval, "drag_data_received",
- G_CALLBACK (palette_drop_handle), colorsel);
+ x = 0;
+ y = 0; /* Quiet GCC */
+ while (x < GTK_CUSTOM_PALETTE_WIDTH)
+ {
+ y = 0;
+ while (y < GTK_CUSTOM_PALETTE_HEIGHT)
+ {
+ if (priv->custom_palette[x][y] == drawing_area)
+ goto out;
+
+ ++y;
+ }
- gtk_widget_set_tooltip_text (retval,
- _("Click this palette entry to make it the current color. To change this entry, drag a color swatch here or right-click it and select \"Save color here.\""));
- return retval;
-}
+ ++x;
+ }
+ out:
+
+ g_assert (x < GTK_CUSTOM_PALETTE_WIDTH || y < GTK_CUSTOM_PALETTE_HEIGHT);
-/*
- *
- * The actual GtkColorSelection widget
- *
- */
+ current_colors = get_current_colors (colorsel);
+ current_colors[y * GTK_CUSTOM_PALETTE_WIDTH + x] = gdk_color;
-static GdkCursor *
-make_picker_cursor (GdkScreen *screen)
-{
- GdkCursor *cursor;
+ screen = gtk_widget_get_screen (GTK_WIDGET (colorsel));
+ if (change_palette_hook != default_change_palette_func)
+ (* change_palette_hook) (screen, current_colors,
+ GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
+ else if (noscreen_change_palette_hook != default_noscreen_change_palette_func)
+ {
+ if (screen != gdk_screen_get_default ())
+ g_warning ("gtk_color_selection_set_change_palette_hook used by widget is not on the default screen.");
+ (* noscreen_change_palette_hook) (current_colors,
+ GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
+ }
+ else
+ (* change_palette_hook) (screen, current_colors,
+ GTK_CUSTOM_PALETTE_WIDTH * GTK_CUSTOM_PALETTE_HEIGHT);
- cursor = gdk_cursor_new_from_name (gdk_screen_get_display (screen),
- "color-picker");
+ g_free (current_colors);
+}
- if (!cursor)
- {
- GdkColor bg = { 0, 0xffff, 0xffff, 0xffff };
- GdkColor fg = { 0, 0x0000, 0x0000, 0x0000 };
- GdkWindow *window;
- GdkPixmap *pixmap, *mask;
+/* Changes the view color */
+static void
+palette_set_color (GtkWidget *drawing_area,
+ GtkColorSelection *colorsel,
+ gdouble *color)
+{
+ gdouble *new_color = g_new (double, 4);
+ GdkColor gdk_color;
+
+ gdk_color.red = UNSCALE (color[0]);
+ gdk_color.green = UNSCALE (color[1]);
+ gdk_color.blue = UNSCALE (color[2]);
- window = gdk_screen_get_root_window (screen);
-
- pixmap =
- gdk_bitmap_create_from_data (window, (gchar *) dropper_bits,
- DROPPER_WIDTH, DROPPER_HEIGHT);
-
- mask =
- gdk_bitmap_create_from_data (window, (gchar *) dropper_mask,
- DROPPER_WIDTH, DROPPER_HEIGHT);
+ gtk_widget_modify_bg (drawing_area, GTK_STATE_NORMAL, &gdk_color);
+
+ if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (drawing_area), "color_set")) == 0)
+ {
+ static const GtkTargetEntry targets[] = {
+ { "application/x-color", 0 }
+ };
+ gtk_drag_source_set (drawing_area,
+ GDK_BUTTON1_MASK | GDK_BUTTON3_MASK,
+ targets, 1,
+ GDK_ACTION_COPY | GDK_ACTION_MOVE);
- cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg,
- DROPPER_X_HOT, DROPPER_Y_HOT);
+ g_signal_connect (drawing_area,
+ "drag_begin",
+ G_CALLBACK (palette_drag_begin),
+ colorsel);
+ g_signal_connect (drawing_area,
+ "drag_data_get",
+ G_CALLBACK (palette_drag_handle),
+ colorsel);
- g_object_unref (pixmap);
- g_object_unref (mask);
+ g_object_set_data (G_OBJECT (drawing_area), I_("color_set"),
+ GINT_TO_POINTER (1));
}
-
- return cursor;
+
+ new_color[0] = color[0];
+ new_color[1] = color[1];
+ new_color[2] = color[2];
+ new_color[3] = 1.0;
+
+ g_object_set_data_full (G_OBJECT (drawing_area), I_("color_val"), new_color, (GDestroyNotify)g_free);
}
-static void
-grab_color_at_mouse (GdkScreen *screen,
- gint x_root,
- gint y_root,
- gpointer data)
+static gboolean
+palette_expose (GtkWidget *drawing_area,
+ GdkEventExpose *event,
+ gpointer data)
{
- GdkImage *image;
- guint32 pixel;
- GtkColorSelection *colorsel = data;
- ColorSelectionPrivate *priv;
- GdkColor color;
- GdkColormap *colormap = gdk_screen_get_system_colormap (screen);
- GdkWindow *root_window = gdk_screen_get_root_window (screen);
+ if (drawing_area->window == NULL)
+ return FALSE;
- priv = colorsel->private_data;
+ palette_paint (drawing_area, &(event->area), data);
- image = gdk_drawable_get_image (root_window, x_root, y_root, 1, 1);
- if (!image)
- {
- gint x, y;
- GdkDisplay *display = gdk_screen_get_display (screen);
- GdkWindow *window = gdk_display_get_window_at_pointer (display, &x, &y);
- if (!window)
- return;
- image = gdk_drawable_get_image (window, x, y, 1, 1);
- if (!image)
- return;
- }
- pixel = gdk_image_get_pixel (image, 0, 0);
- g_object_unref (image);
+ return FALSE;
+}
- gdk_colormap_query_color (colormap, pixel, &color);
+static void
+popup_position_func (GtkMenu *menu,
+ gint *x,
+ gint *y,
+ gboolean *push_in,
+ gpointer user_data)
+{
+ GtkWidget *widget;
+ GtkRequisition req;
+ gint root_x, root_y;
+ GdkScreen *screen;
- priv->color[COLORSEL_RED] = SCALE (color.red);
- priv->color[COLORSEL_GREEN] = SCALE (color.green);
- priv->color[COLORSEL_BLUE] = SCALE (color.blue);
+ widget = GTK_WIDGET (user_data);
- gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
- priv->color[COLORSEL_GREEN],
- priv->color[COLORSEL_BLUE],
- &priv->color[COLORSEL_HUE],
- &priv->color[COLORSEL_SATURATION],
- &priv->color[COLORSEL_VALUE]);
+ g_return_if_fail (GTK_WIDGET_REALIZED (widget));
- update_color (colorsel);
+ gdk_window_get_origin (widget->window, &root_x, &root_y);
+
+ gtk_widget_size_request (GTK_WIDGET (menu), &req);
+
+ /* Put corner of menu centered on color cell */
+ *x = root_x + widget->allocation.width / 2;
+ *y = root_y + widget->allocation.height / 2;
+
+ /* Ensure sanity */
+ screen = gtk_widget_get_screen (widget);
+ *x = CLAMP (*x, 0, MAX (0, gdk_screen_get_width (screen) - req.width));
+ *y = CLAMP (*y, 0, MAX (0, gdk_screen_get_height (screen) - req.height));
}
static void
-shutdown_eyedropper (GtkWidget *widget)
+save_color_selected (GtkWidget *menuitem,
+ gpointer data)
{
GtkColorSelection *colorsel;
+ GtkWidget *drawing_area;
ColorSelectionPrivate *priv;
- GdkDisplay *display = gtk_widget_get_display (widget);
- colorsel = GTK_COLOR_SELECTION (widget);
- priv = colorsel->private_data;
-
- if (priv->has_grab)
- {
- gdk_display_keyboard_ungrab (display, priv->grab_time);
- gdk_display_pointer_ungrab (display, priv->grab_time);
- gtk_grab_remove (priv->dropper_grab_widget);
+ drawing_area = GTK_WIDGET (data);
+
+ colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (drawing_area),
+ "gtk-color-sel"));
- priv->has_grab = FALSE;
- }
+ priv = colorsel->private_data;
+
+ palette_change_color (drawing_area, colorsel, priv->color);
}
-static gboolean
-gtk_color_selection_grab_broken (GtkWidget *widget,
- GdkEventGrabBroken *event)
+static void
+do_popup (GtkColorSelection *colorsel,
+ GtkWidget *drawing_area,
+ guint32 timestamp)
{
- shutdown_eyedropper (widget);
+ GtkWidget *menu;
+ GtkWidget *mi;
+
+ g_object_set_data (G_OBJECT (drawing_area),
+ I_("gtk-color-sel"),
+ colorsel);
+
+ menu = gtk_menu_new ();
- return TRUE;
+ mi = gtk_menu_item_new_with_mnemonic (_("_Save color here"));
+
+ g_signal_connect (mi, "activate",
+ G_CALLBACK (save_color_selected),
+ drawing_area);
+
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
+
+ gtk_widget_show_all (mi);
+
+ gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
+ popup_position_func, drawing_area,
+ 3, timestamp);
}
-static void
-mouse_motion (GtkWidget *invisible,
- GdkEventMotion *event,
- gpointer data)
+
+static gboolean
+palette_enter (GtkWidget *drawing_area,
+ GdkEventCrossing *event,
+ gpointer data)
{
- grab_color_at_mouse (gdk_event_get_screen ((GdkEvent *)event),
- event->x_root, event->y_root, data);
+ g_object_set_data (G_OBJECT (drawing_area),
+ I_("gtk-colorsel-have-pointer"),
+ GUINT_TO_POINTER (TRUE));
+
+ return FALSE;
}
static gboolean
-mouse_release (GtkWidget *invisible,
- GdkEventButton *event,
+palette_leave (GtkWidget *drawing_area,
+ GdkEventCrossing *event,
gpointer data)
{
- /* GtkColorSelection *colorsel = data; */
+ g_object_set_data (G_OBJECT (drawing_area),
+ I_("gtk-colorsel-have-pointer"),
+ NULL);
- if (event->button != 1)
- return FALSE;
+ return FALSE;
+}
- grab_color_at_mouse (gdk_event_get_screen ((GdkEvent *)event),
- event->x_root, event->y_root, data);
+static gboolean
+palette_press (GtkWidget *drawing_area,
+ GdkEventButton *event,
+ gpointer data)
+{
+ GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
- shutdown_eyedropper (GTK_WIDGET (data));
+ gtk_widget_grab_focus (drawing_area);
- g_signal_handlers_disconnect_by_func (invisible,
- mouse_motion,
- data);
- g_signal_handlers_disconnect_by_func (invisible,
- mouse_release,
- data);
+ if (event->button == 3 &&
+ event->type == GDK_BUTTON_PRESS)
+ {
+ do_popup (colorsel, drawing_area, event->time);
+ return TRUE;
+ }
- return TRUE;
+ return FALSE;
}
-/* Helper Functions */
-
-static gboolean mouse_press (GtkWidget *invisible,
- GdkEventButton *event,
- gpointer data);
-
-#define BIG_STEP 20
-
static gboolean
-key_press (GtkWidget *invisible,
- GdkEventKey *event,
- gpointer data)
-{
- GdkDisplay *display = gtk_widget_get_display (invisible);
- GdkScreen *screen = gdk_event_get_screen ((GdkEvent *)event);
- guint state = event->state & gtk_accelerator_get_default_mod_mask ();
- gint x, y;
- gint dx, dy;
-
- gdk_display_get_pointer (display, NULL, &x, &y, NULL);
-
- dx = 0;
- dy = 0;
-
- switch (event->keyval)
- {
- case GDK_space:
- case GDK_Return:
- case GDK_ISO_Enter:
- case GDK_KP_Enter:
- case GDK_KP_Space:
- grab_color_at_mouse (screen, x, y, data);
- /* fall through */
-
- case GDK_Escape:
- shutdown_eyedropper (data);
-
- g_signal_handlers_disconnect_by_func (invisible,
- mouse_press,
- data);
- g_signal_handlers_disconnect_by_func (invisible,
- key_press,
- data);
-
- return TRUE;
-
-#if defined GDK_WINDOWING_X11 || defined GDK_WINDOWING_WIN32
- case GDK_Up:
- case GDK_KP_Up:
- dy = state == GDK_MOD1_MASK ? -BIG_STEP : -1;
- break;
-
- case GDK_Down:
- case GDK_KP_Down:
- dy = state == GDK_MOD1_MASK ? BIG_STEP : 1;
- break;
-
- case GDK_Left:
- case GDK_KP_Left:
- dx = state == GDK_MOD1_MASK ? -BIG_STEP : -1;
- break;
-
- case GDK_Right:
- case GDK_KP_Right:
- dx = state == GDK_MOD1_MASK ? BIG_STEP : 1;
- break;
-#endif
-
- default:
- return FALSE;
- }
-
- gdk_display_warp_pointer (display, screen, x + dx, y + dy);
-
- return TRUE;
+palette_release (GtkWidget *drawing_area,
+ GdkEventButton *event,
+ gpointer data)
+{
+ GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
-}
+ gtk_widget_grab_focus (drawing_area);
-static gboolean
-mouse_press (GtkWidget *invisible,
- GdkEventButton *event,
- gpointer data)
-{
- /* GtkColorSelection *colorsel = data; */
-
- if (event->type == GDK_BUTTON_PRESS &&
- event->button == 1)
+ if (event->button == 1 &&
+ g_object_get_data (G_OBJECT (drawing_area),
+ "gtk-colorsel-have-pointer") != NULL)
{
- g_signal_connect (invisible, "motion_notify_event",
- G_CALLBACK (mouse_motion),
- data);
- g_signal_connect (invisible, "button_release_event",
- G_CALLBACK (mouse_release),
- data);
- g_signal_handlers_disconnect_by_func (invisible,
- mouse_press,
- data);
- g_signal_handlers_disconnect_by_func (invisible,
- key_press,
- data);
- return TRUE;
+ if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (drawing_area), "color_set")) != 0)
+ {
+ gdouble color[4];
+ palette_get_color (drawing_area, color);
+ set_color_internal (colorsel, color);
+ }
}
return FALSE;
}
-/* when the button is clicked */
static void
-get_screen_color (GtkWidget *button)
+palette_drop_handle (GtkWidget *widget,
+ GdkDragContext *context,
+ gint x,
+ gint y,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time,
+ gpointer data)
{
- GtkColorSelection *colorsel = g_object_get_data (G_OBJECT (button), "COLORSEL");
- ColorSelectionPrivate *priv = colorsel->private_data;
- GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (button));
- GdkCursor *picker_cursor;
- GdkGrabStatus grab_status;
- GtkWidget *grab_widget, *toplevel;
-
- guint32 time = gtk_get_current_event_time ();
-
- if (priv->dropper_grab_widget == NULL)
- {
- grab_widget = gtk_window_new (GTK_WINDOW_POPUP);
- gtk_window_set_screen (GTK_WINDOW (grab_widget), screen);
- gtk_window_resize (GTK_WINDOW (grab_widget), 1, 1);
- gtk_window_move (GTK_WINDOW (grab_widget), -100, -100);
- gtk_widget_show (grab_widget);
-
- gtk_widget_add_events (grab_widget,
- GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
-
- toplevel = gtk_widget_get_toplevel (GTK_WIDGET (colorsel));
+ GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
+ guint16 *vals;
+ gdouble color[4];
- if (GTK_IS_WINDOW (toplevel))
- {
- if (GTK_WINDOW (toplevel)->group)
- gtk_window_group_add_window (GTK_WINDOW (toplevel)->group,
- GTK_WINDOW (grab_widget));
- }
-
- priv->dropper_grab_widget = grab_widget;
- }
-
- if (gdk_keyboard_grab (priv->dropper_grab_widget->window,
- FALSE, time) != GDK_GRAB_SUCCESS)
+ if (selection_data->length < 0)
return;
- picker_cursor = make_picker_cursor (screen);
- grab_status = gdk_pointer_grab (priv->dropper_grab_widget->window,
- FALSE,
- GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
- NULL,
- picker_cursor,
- time);
- gdk_cursor_unref (picker_cursor);
-
- if (grab_status != GDK_GRAB_SUCCESS)
+ /* We accept drops with the wrong format, since the KDE color
+ * chooser incorrectly drops application/x-color with format 8.
+ */
+ if (selection_data->length != 8)
{
- gdk_display_keyboard_ungrab (gtk_widget_get_display (button), time);
+ g_warning ("Received invalid color data\n");
return;
}
-
- gtk_grab_add (priv->dropper_grab_widget);
- priv->grab_time = time;
- priv->has_grab = TRUE;
- g_signal_connect (priv->dropper_grab_widget, "button_press_event",
- G_CALLBACK (mouse_press), colorsel);
- g_signal_connect (priv->dropper_grab_widget, "key_press_event",
- G_CALLBACK (key_press), colorsel);
+ vals = (guint16 *)selection_data->data;
+
+ color[0] = (gdouble)vals[0] / 0xffff;
+ color[1] = (gdouble)vals[1] / 0xffff;
+ color[2] = (gdouble)vals[2] / 0xffff;
+ color[3] = (gdouble)vals[3] / 0xffff;
+ palette_change_color (widget, colorsel, color);
+ set_color_internal (colorsel, color);
}
-static void
-hex_changed (GtkWidget *hex_entry,
- gpointer data)
+static gint
+palette_activate (GtkWidget *widget,
+ GdkEventKey *event,
+ gpointer data)
{
- GtkColorSelection *colorsel;
- ColorSelectionPrivate *priv;
- GdkColor color;
- gchar *text;
-
- colorsel = GTK_COLOR_SELECTION (data);
- priv = colorsel->private_data;
-
- if (priv->changing)
- return;
-
- text = gtk_editable_get_chars (GTK_EDITABLE (priv->hex_entry), 0, -1);
- if (gdk_color_parse (text, &color))
+ /* should have a drawing area subclass with an activate signal */
+ if ((event->keyval == GDK_space) ||
+ (event->keyval == GDK_Return) ||
+ (event->keyval == GDK_ISO_Enter) ||
+ (event->keyval == GDK_KP_Enter) ||
+ (event->keyval == GDK_KP_Space))
{
- priv->color[COLORSEL_RED] = CLAMP (color.red/65535.0, 0.0, 1.0);
- priv->color[COLORSEL_GREEN] = CLAMP (color.green/65535.0, 0.0, 1.0);
- priv->color[COLORSEL_BLUE] = CLAMP (color.blue/65535.0, 0.0, 1.0);
- gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
- priv->color[COLORSEL_GREEN],
- priv->color[COLORSEL_BLUE],
- &priv->color[COLORSEL_HUE],
- &priv->color[COLORSEL_SATURATION],
- &priv->color[COLORSEL_VALUE]);
- update_color (colorsel);
+ if (GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "color_set")) != 0)
+ {
+ gdouble color[4];
+ palette_get_color (widget, color);
+ set_color_internal (GTK_COLOR_SELECTION (data), color);
+ }
+ return TRUE;
}
- g_free (text);
+
+ return FALSE;
}
static gboolean
-hex_focus_out (GtkWidget *hex_entry,
- GdkEventFocus *event,
- gpointer data)
+palette_popup (GtkWidget *widget,
+ gpointer data)
{
- hex_changed (hex_entry, data);
-
- return FALSE;
+ GtkColorSelection *colorsel = GTK_COLOR_SELECTION (data);
+
+ do_popup (colorsel, widget, GDK_CURRENT_TIME);
+ return TRUE;
}
+
-static void
-hsv_changed (GtkWidget *hsv,
- gpointer data)
+static GtkWidget*
+palette_new (GtkColorSelection *colorsel)
{
- GtkColorSelection *colorsel;
+ GtkWidget *retval;
ColorSelectionPrivate *priv;
- colorsel = GTK_COLOR_SELECTION (data);
- priv = colorsel->private_data;
-
- if (priv->changing)
- return;
+ static const GtkTargetEntry targets[] = {
+ { "application/x-color", 0 }
+ };
+
+ priv = colorsel->private_data;
- gtk_hsv_get_color (GTK_HSV (hsv),
- &priv->color[COLORSEL_HUE],
- &priv->color[COLORSEL_SATURATION],
- &priv->color[COLORSEL_VALUE]);
- gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
- priv->color[COLORSEL_SATURATION],
- priv->color[COLORSEL_VALUE],
- &priv->color[COLORSEL_RED],
- &priv->color[COLORSEL_GREEN],
- &priv->color[COLORSEL_BLUE]);
- update_color (colorsel);
-}
+ retval = gtk_drawing_area_new ();
-static void
-adjustment_changed (GtkAdjustment *adjustment,
- gpointer data)
-{
- GtkColorSelection *colorsel;
- ColorSelectionPrivate *priv;
+ GTK_WIDGET_SET_FLAGS (retval, GTK_CAN_FOCUS);
- colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (adjustment), "COLORSEL"));
- priv = colorsel->private_data;
+ g_object_set_data (G_OBJECT (retval), I_("color_set"), GINT_TO_POINTER (0));
+ gtk_widget_set_events (retval, GDK_BUTTON_PRESS_MASK
+ | GDK_BUTTON_RELEASE_MASK
+ | GDK_EXPOSURE_MASK
+ | GDK_ENTER_NOTIFY_MASK
+ | GDK_LEAVE_NOTIFY_MASK);
- if (priv->changing)
- return;
+ g_signal_connect (retval, "expose_event",
+ G_CALLBACK (palette_expose), colorsel);
+ g_signal_connect (retval, "button_press_event",
+ G_CALLBACK (palette_press), colorsel);
+ g_signal_connect (retval, "button_release_event",
+ G_CALLBACK (palette_release), colorsel);
+ g_signal_connect (retval, "enter_notify_event",
+ G_CALLBACK (palette_enter), colorsel);
+ g_signal_connect (retval, "leave_notify_event",
+ G_CALLBACK (palette_leave), colorsel);
+ g_signal_connect (retval, "key_press_event",
+ G_CALLBACK (palette_activate), colorsel);
+ g_signal_connect (retval, "popup_menu",
+ G_CALLBACK (palette_popup), colorsel);
- switch (GPOINTER_TO_INT (data))
+ gtk_drag_dest_set (retval,
+ GTK_DEST_DEFAULT_HIGHLIGHT |
+ GTK_DEST_DEFAULT_MOTION |
+ GTK_DEST_DEFAULT_DROP,
+ targets, 1,
+ GDK_ACTION_COPY);
+
+ g_signal_connect (retval, "drag_end",
+ G_CALLBACK (palette_drag_end), NULL);
+ g_signal_connect (retval, "drag_data_received",
+ G_CALLBACK (palette_drop_handle), colorsel);
+
+ gtk_widget_set_tooltip_text (retval,
+ _("Click this palette entry to make it the current color. To change this entry, drag a color swatch here or right-click it and select \"Save color here.\""));
+ return retval;
+}
+
+
+/*
+ *
+ * The actual GtkColorSelection widget
+ *
+ */
+
+static GdkCursor *
+make_picker_cursor (GdkScreen *screen)
+{
+ GdkCursor *cursor;
+
+ cursor = gdk_cursor_new_from_name (gdk_screen_get_display (screen),
+ "color-picker");
+
+ if (!cursor)
{
- case COLORSEL_SATURATION:
- case COLORSEL_VALUE:
- priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 100;
- gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
- priv->color[COLORSEL_SATURATION],
- priv->color[COLORSEL_VALUE],
- &priv->color[COLORSEL_RED],
- &priv->color[COLORSEL_GREEN],
- &priv->color[COLORSEL_BLUE]);
- break;
- case COLORSEL_HUE:
- priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 360;
- gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
- priv->color[COLORSEL_SATURATION],
- priv->color[COLORSEL_VALUE],
- &priv->color[COLORSEL_RED],
- &priv->color[COLORSEL_GREEN],
- &priv->color[COLORSEL_BLUE]);
- break;
- case COLORSEL_RED:
- case COLORSEL_GREEN:
- case COLORSEL_BLUE:
- priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
+ GdkColor bg = { 0, 0xffff, 0xffff, 0xffff };
+ GdkColor fg = { 0, 0x0000, 0x0000, 0x0000 };
+ GdkWindow *window;
+ GdkPixmap *pixmap, *mask;
+
+ window = gdk_screen_get_root_window (screen);
- gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
- priv->color[COLORSEL_GREEN],
- priv->color[COLORSEL_BLUE],
- &priv->color[COLORSEL_HUE],
- &priv->color[COLORSEL_SATURATION],
- &priv->color[COLORSEL_VALUE]);
- break;
- default:
- priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
- break;
+ pixmap =
+ gdk_bitmap_create_from_data (window, (gchar *) dropper_bits,
+ DROPPER_WIDTH, DROPPER_HEIGHT);
+
+ mask =
+ gdk_bitmap_create_from_data (window, (gchar *) dropper_mask,
+ DROPPER_WIDTH, DROPPER_HEIGHT);
+
+ cursor = gdk_cursor_new_from_pixmap (pixmap, mask, &fg, &bg,
+ DROPPER_X_HOT, DROPPER_Y_HOT);
+
+ g_object_unref (pixmap);
+ g_object_unref (mask);
}
- update_color (colorsel);
+
+ return cursor;
}
-static void
-opacity_entry_changed (GtkWidget *opacity_entry,
- gpointer data)
+static void
+grab_color_at_mouse (GdkScreen *screen,
+ gint x_root,
+ gint y_root,
+ gpointer data)
{
- GtkColorSelection *colorsel;
+ GdkImage *image;
+ guint32 pixel;
+ GtkColorSelection *colorsel = data;
ColorSelectionPrivate *priv;
- GtkAdjustment *adj;
- gchar *text;
+ GdkColor color;
+ GdkColormap *colormap = gdk_screen_get_system_colormap (screen);
+ GdkWindow *root_window = gdk_screen_get_root_window (screen);
- colorsel = GTK_COLOR_SELECTION (data);
priv = colorsel->private_data;
- if (priv->changing)
- return;
+ image = gdk_drawable_get_image (root_window, x_root, y_root, 1, 1);
+ if (!image)
+ {
+ gint x, y;
+ GdkDisplay *display = gdk_screen_get_display (screen);
+ GdkWindow *window = gdk_display_get_window_at_pointer (display, &x, &y);
+ if (!window)
+ return;
+ image = gdk_drawable_get_image (window, x, y, 1, 1);
+ if (!image)
+ return;
+ }
+ pixel = gdk_image_get_pixel (image, 0, 0);
+ g_object_unref (image);
+
+ gdk_colormap_query_color (colormap, pixel, &color);
- text = gtk_editable_get_chars (GTK_EDITABLE (priv->opacity_entry), 0, -1);
- adj = gtk_range_get_adjustment (GTK_RANGE (priv->opacity_slider));
- gtk_adjustment_set_value (adj, g_strtod (text, NULL));
+ priv->color[COLORSEL_RED] = SCALE (color.red);
+ priv->color[COLORSEL_GREEN] = SCALE (color.green);
+ priv->color[COLORSEL_BLUE] = SCALE (color.blue);
+ gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
+ priv->color[COLORSEL_GREEN],
+ priv->color[COLORSEL_BLUE],
+ &priv->color[COLORSEL_HUE],
+ &priv->color[COLORSEL_SATURATION],
+ &priv->color[COLORSEL_VALUE]);
+
update_color (colorsel);
-
- g_free (text);
}
static void
-make_label_spinbutton (GtkColorSelection *colorsel,
- GtkWidget **spinbutton,
- gchar *text,
- GtkWidget *table,
- gint i,
- gint j,
- gint channel_type,
- const gchar *tooltip)
+shutdown_eyedropper (GtkWidget *widget)
{
- GtkWidget *label;
- GtkAdjustment *adjust;
-
- if (channel_type == COLORSEL_HUE)
- {
- adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 1.0, 1.0));
- }
- else if (channel_type == COLORSEL_SATURATION ||
- channel_type == COLORSEL_VALUE)
- {
- adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 100.0, 1.0, 1.0, 1.0));
- }
- else
- {
- adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 1.0));
- }
- g_object_set_data (G_OBJECT (adjust), I_("COLORSEL"), colorsel);
- *spinbutton = gtk_spin_button_new (adjust, 10.0, 0);
+ GtkColorSelection *colorsel;
+ ColorSelectionPrivate *priv;
+ GdkDisplay *display = gtk_widget_get_display (widget);
- gtk_widget_set_tooltip_text (*spinbutton, tooltip);
+ colorsel = GTK_COLOR_SELECTION (widget);
+ priv = colorsel->private_data;
- g_signal_connect (adjust, "value_changed",
- G_CALLBACK (adjustment_changed),
- GINT_TO_POINTER (channel_type));
- label = gtk_label_new_with_mnemonic (text);
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), *spinbutton);
+ if (priv->has_grab)
+ {
+ gdk_display_keyboard_ungrab (display, priv->grab_time);
+ gdk_display_pointer_ungrab (display, priv->grab_time);
+ gtk_grab_remove (priv->dropper_grab_widget);
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_table_attach_defaults (GTK_TABLE (table), label, i, i+1, j, j+1);
- gtk_table_attach_defaults (GTK_TABLE (table), *spinbutton, i+1, i+2, j, j+1);
+ priv->has_grab = FALSE;
+ }
}
static void
-make_palette_frame (GtkColorSelection *colorsel,
- GtkWidget *table,
- gint i,
- gint j)
+mouse_motion (GtkWidget *invisible,
+ GdkEventMotion *event,
+ gpointer data)
{
- GtkWidget *frame;
- ColorSelectionPrivate *priv;
-
- priv = colorsel->private_data;
- frame = gtk_frame_new (NULL);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
- priv->custom_palette[i][j] = palette_new (colorsel);
- gtk_widget_set_size_request (priv->custom_palette[i][j], CUSTOM_PALETTE_ENTRY_WIDTH, CUSTOM_PALETTE_ENTRY_HEIGHT);
- gtk_container_add (GTK_CONTAINER (frame), priv->custom_palette[i][j]);
- gtk_table_attach_defaults (GTK_TABLE (table), frame, i, i+1, j, j+1);
+ grab_color_at_mouse (gdk_event_get_screen ((GdkEvent *)event),
+ event->x_root, event->y_root, data);
}
-/* Set the palette entry [x][y] to be the currently selected one. */
-static void
-set_selected_palette (GtkColorSelection *colorsel, int x, int y)
+static gboolean
+mouse_release (GtkWidget *invisible,
+ GdkEventButton *event,
+ gpointer data)
{
- ColorSelectionPrivate *priv = colorsel->private_data;
+ /* GtkColorSelection *colorsel = data; */
- gtk_widget_grab_focus (priv->custom_palette[x][y]);
-}
+ if (event->button != 1)
+ return FALSE;
-static double
-scale_round (double val, double factor)
-{
- val = floor (val * factor + 0.5);
- val = MAX (val, 0);
- val = MIN (val, factor);
- return val;
-}
+ grab_color_at_mouse (gdk_event_get_screen ((GdkEvent *)event),
+ event->x_root, event->y_root, data);
-static void
-update_color (GtkColorSelection *colorsel)
-{
- ColorSelectionPrivate *priv = colorsel->private_data;
- gchar entryval[12];
- gchar opacity_text[32];
- gchar *ptr;
-
- priv->changing = TRUE;
- color_sample_update_samples (colorsel);
-
- gtk_hsv_set_color (GTK_HSV (priv->triangle_colorsel),
- priv->color[COLORSEL_HUE],
- priv->color[COLORSEL_SATURATION],
- priv->color[COLORSEL_VALUE]);
- gtk_adjustment_set_value (gtk_spin_button_get_adjustment
- (GTK_SPIN_BUTTON (priv->hue_spinbutton)),
- scale_round (priv->color[COLORSEL_HUE], 360));
- gtk_adjustment_set_value (gtk_spin_button_get_adjustment
- (GTK_SPIN_BUTTON (priv->sat_spinbutton)),
- scale_round (priv->color[COLORSEL_SATURATION], 100));
- gtk_adjustment_set_value (gtk_spin_button_get_adjustment
- (GTK_SPIN_BUTTON (priv->val_spinbutton)),
- scale_round (priv->color[COLORSEL_VALUE], 100));
- gtk_adjustment_set_value (gtk_spin_button_get_adjustment
- (GTK_SPIN_BUTTON (priv->red_spinbutton)),
- scale_round (priv->color[COLORSEL_RED], 255));
- gtk_adjustment_set_value (gtk_spin_button_get_adjustment
- (GTK_SPIN_BUTTON (priv->green_spinbutton)),
- scale_round (priv->color[COLORSEL_GREEN], 255));
- gtk_adjustment_set_value (gtk_spin_button_get_adjustment
- (GTK_SPIN_BUTTON (priv->blue_spinbutton)),
- scale_round (priv->color[COLORSEL_BLUE], 255));
- gtk_adjustment_set_value (gtk_range_get_adjustment
- (GTK_RANGE (priv->opacity_slider)),
- scale_round (priv->color[COLORSEL_OPACITY], 255));
-
- g_snprintf (opacity_text, 32, "%.0f", scale_round (priv->color[COLORSEL_OPACITY], 255));
- gtk_entry_set_text (GTK_ENTRY (priv->opacity_entry), opacity_text);
-
- g_snprintf (entryval, 11, "#%2X%2X%2X",
- (guint) (scale_round (priv->color[COLORSEL_RED], 255)),
- (guint) (scale_round (priv->color[COLORSEL_GREEN], 255)),
- (guint) (scale_round (priv->color[COLORSEL_BLUE], 255)));
+ shutdown_eyedropper (GTK_WIDGET (data));
- for (ptr = entryval; *ptr; ptr++)
- if (*ptr == ' ')
- *ptr = '0';
- gtk_entry_set_text (GTK_ENTRY (priv->hex_entry), entryval);
- priv->changing = FALSE;
+ g_signal_handlers_disconnect_by_func (invisible,
+ mouse_motion,
+ data);
+ g_signal_handlers_disconnect_by_func (invisible,
+ mouse_release,
+ data);
- g_object_ref (colorsel);
-
- g_signal_emit (colorsel, color_selection_signals[COLOR_CHANGED], 0);
-
- g_object_freeze_notify (G_OBJECT (colorsel));
- g_object_notify (G_OBJECT (colorsel), "current-color");
- g_object_notify (G_OBJECT (colorsel), "current-alpha");
- g_object_thaw_notify (G_OBJECT (colorsel));
-
- g_object_unref (colorsel);
+ return TRUE;
}
-static void
-update_palette (GtkColorSelection *colorsel)
-{
- GdkColor *current_colors;
- gint i, j;
+/* Helper Functions */
- current_colors = get_current_colors (colorsel);
-
- for (i = 0; i < GTK_CUSTOM_PALETTE_HEIGHT; i++)
+static gboolean
+key_press (GtkWidget *invisible,
+ GdkEventKey *event,
+ gpointer data)
+{
+ GdkDisplay *display = gtk_widget_get_display (invisible);
+ GdkScreen *screen = gdk_event_get_screen ((GdkEvent *)event);
+ guint state = event->state & gtk_accelerator_get_default_mod_mask ();
+ gint x, y;
+ gint dx, dy;
+
+ gdk_display_get_pointer (display, NULL, &x, &y, NULL);
+
+ dx = 0;
+ dy = 0;
+
+ switch (event->keyval)
{
- for (j = 0; j < GTK_CUSTOM_PALETTE_WIDTH; j++)
- {
- gint index;
+ case GDK_space:
+ case GDK_Return:
+ case GDK_ISO_Enter:
+ case GDK_KP_Enter:
+ case GDK_KP_Space:
+ grab_color_at_mouse (screen, x, y, data);
+ /* fall through */
- index = i * GTK_CUSTOM_PALETTE_WIDTH + j;
-
- gtk_color_selection_set_palette_color (colorsel,
- index,
- ¤t_colors[index]);
- }
- }
+ case GDK_Escape:
+ shutdown_eyedropper (data);
+
+ g_signal_handlers_disconnect_by_func (invisible,
+ mouse_press,
+ data);
+ g_signal_handlers_disconnect_by_func (invisible,
+ key_press,
+ data);
+
+ return TRUE;
- g_free (current_colors);
-}
+#if defined GDK_WINDOWING_X11 || defined GDK_WINDOWING_WIN32
+ case GDK_Up:
+ case GDK_KP_Up:
+ dy = state == GDK_MOD1_MASK ? -BIG_STEP : -1;
+ break;
-static void
-palette_change_notify_instance (GObject *object,
- GParamSpec *pspec,
- gpointer data)
-{
- update_palette (GTK_COLOR_SELECTION (data));
-}
+ case GDK_Down:
+ case GDK_KP_Down:
+ dy = state == GDK_MOD1_MASK ? BIG_STEP : 1;
+ break;
+
+ case GDK_Left:
+ case GDK_KP_Left:
+ dx = state == GDK_MOD1_MASK ? -BIG_STEP : -1;
+ break;
+
+ case GDK_Right:
+ case GDK_KP_Right:
+ dx = state == GDK_MOD1_MASK ? BIG_STEP : 1;
+ break;
+#endif
+
+ default:
+ return FALSE;
+ }
+
+ gdk_display_warp_pointer (display, screen, x + dx, y + dy);
+
+ return TRUE;
-static void
-default_noscreen_change_palette_func (const GdkColor *colors,
- gint n_colors)
-{
- default_change_palette_func (gdk_screen_get_default (), colors, n_colors);
}
-static void
-default_change_palette_func (GdkScreen *screen,
- const GdkColor *colors,
- gint n_colors)
+static gboolean
+mouse_press (GtkWidget *invisible,
+ GdkEventButton *event,
+ gpointer data)
{
- gchar *str;
+ /* GtkColorSelection *colorsel = data; */
- str = gtk_color_selection_palette_to_string (colors, n_colors);
-
- gtk_settings_set_string_property (gtk_settings_get_for_screen (screen),
- "gtk-color-palette",
- str,
- "gtk_color_selection_palette_to_string");
+ if (event->type == GDK_BUTTON_PRESS &&
+ event->button == 1)
+ {
+ g_signal_connect (invisible, "motion_notify_event",
+ G_CALLBACK (mouse_motion),
+ data);
+ g_signal_connect (invisible, "button_release_event",
+ G_CALLBACK (mouse_release),
+ data);
+ g_signal_handlers_disconnect_by_func (invisible,
+ mouse_press,
+ data);
+ g_signal_handlers_disconnect_by_func (invisible,
+ key_press,
+ data);
+ return TRUE;
+ }
- g_free (str);
+ return FALSE;
}
-G_DEFINE_TYPE (GtkColorSelection, gtk_color_selection, GTK_TYPE_VBOX)
-
+/* when the button is clicked */
static void
-gtk_color_selection_class_init (GtkColorSelectionClass *klass)
+get_screen_color (GtkWidget *button)
{
- GObjectClass *gobject_class;
- GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
-
- gobject_class = G_OBJECT_CLASS (klass);
- object_class = GTK_OBJECT_CLASS (klass);
- widget_class = GTK_WIDGET_CLASS (klass);
-
- object_class->destroy = gtk_color_selection_destroy;
- gobject_class->finalize = gtk_color_selection_finalize;
-
- gobject_class->set_property = gtk_color_selection_set_property;
- gobject_class->get_property = gtk_color_selection_get_property;
+ GtkColorSelection *colorsel = g_object_get_data (G_OBJECT (button), "COLORSEL");
+ ColorSelectionPrivate *priv = colorsel->private_data;
+ GdkScreen *screen = gtk_widget_get_screen (GTK_WIDGET (button));
+ GdkCursor *picker_cursor;
+ GdkGrabStatus grab_status;
+ GtkWidget *grab_widget, *toplevel;
- widget_class->realize = gtk_color_selection_realize;
- widget_class->unrealize = gtk_color_selection_unrealize;
- widget_class->show_all = gtk_color_selection_show_all;
- widget_class->grab_broken_event = gtk_color_selection_grab_broken;
+ guint32 time = gtk_get_current_event_time ();
- g_object_class_install_property (gobject_class,
- PROP_HAS_OPACITY_CONTROL,
- g_param_spec_boolean ("has-opacity-control",
- P_("Has Opacity Control"),
- P_("Whether the color selector should allow setting opacity"),
- FALSE,
- GTK_PARAM_READWRITE));
- g_object_class_install_property (gobject_class,
- PROP_HAS_PALETTE,
- g_param_spec_boolean ("has-palette",
- P_("Has palette"),
- P_("Whether a palette should be used"),
- FALSE,
- GTK_PARAM_READWRITE));
- g_object_class_install_property (gobject_class,
- PROP_CURRENT_COLOR,
- g_param_spec_boxed ("current-color",
- P_("Current Color"),
- P_("The current color"),
- GDK_TYPE_COLOR,
- GTK_PARAM_READWRITE));
- g_object_class_install_property (gobject_class,
- PROP_CURRENT_ALPHA,
- g_param_spec_uint ("current-alpha",
- P_("Current Alpha"),
- P_("The current opacity value (0 fully transparent, 65535 fully opaque)"),
- 0, 65535, 65535,
- GTK_PARAM_READWRITE));
+ if (priv->dropper_grab_widget == NULL)
+ {
+ grab_widget = gtk_window_new (GTK_WINDOW_POPUP);
+ gtk_window_set_screen (GTK_WINDOW (grab_widget), screen);
+ gtk_window_resize (GTK_WINDOW (grab_widget), 1, 1);
+ gtk_window_move (GTK_WINDOW (grab_widget), -100, -100);
+ gtk_widget_show (grab_widget);
+
+ gtk_widget_add_events (grab_widget,
+ GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK);
+
+ toplevel = gtk_widget_get_toplevel (GTK_WIDGET (colorsel));
- color_selection_signals[COLOR_CHANGED] =
- g_signal_new (I_("color_changed"),
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (GtkColorSelectionClass, color_changed),
- NULL, NULL,
- _gtk_marshal_VOID__VOID,
- G_TYPE_NONE, 0);
+ if (GTK_IS_WINDOW (toplevel))
+ {
+ if (GTK_WINDOW (toplevel)->group)
+ gtk_window_group_add_window (GTK_WINDOW (toplevel)->group,
+ GTK_WINDOW (grab_widget));
+ }
- gtk_settings_install_property (g_param_spec_string ("gtk-color-palette",
- P_("Custom palette"),
- P_("Palette to use in the color selector"),
- default_colors,
- GTK_PARAM_READWRITE));
+ priv->dropper_grab_widget = grab_widget;
+ }
- g_type_class_add_private (gobject_class, sizeof (ColorSelectionPrivate));
-}
+ if (gdk_keyboard_grab (priv->dropper_grab_widget->window,
+ FALSE, time) != GDK_GRAB_SUCCESS)
+ return;
+
+ picker_cursor = make_picker_cursor (screen);
+ grab_status = gdk_pointer_grab (priv->dropper_grab_widget->window,
+ FALSE,
+ GDK_BUTTON_RELEASE_MASK | GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK,
+ NULL,
+ picker_cursor,
+ time);
+ gdk_cursor_unref (picker_cursor);
+
+ if (grab_status != GDK_GRAB_SUCCESS)
+ {
+ gdk_display_keyboard_ungrab (gtk_widget_get_display (button), time);
+ return;
+ }
-/* widget functions */
+ gtk_grab_add (priv->dropper_grab_widget);
+ priv->grab_time = time;
+ priv->has_grab = TRUE;
+
+ g_signal_connect (priv->dropper_grab_widget, "button_press_event",
+ G_CALLBACK (mouse_press), colorsel);
+ g_signal_connect (priv->dropper_grab_widget, "key_press_event",
+ G_CALLBACK (key_press), colorsel);
+}
static void
-gtk_color_selection_init (GtkColorSelection *colorsel)
+hex_changed (GtkWidget *hex_entry,
+ gpointer data)
{
- GtkWidget *top_hbox;
- GtkWidget *top_right_vbox;
- GtkWidget *table, *label, *hbox, *frame, *vbox, *button;
- GtkAdjustment *adjust;
- GtkWidget *picker_image;
- gint i, j;
+ GtkColorSelection *colorsel;
ColorSelectionPrivate *priv;
- AtkObject *atk_obj;
- GList *focus_chain = NULL;
-
- gtk_widget_push_composite_child ();
-
- priv = colorsel->private_data = G_TYPE_INSTANCE_GET_PRIVATE (colorsel, GTK_TYPE_COLOR_SELECTION, ColorSelectionPrivate);
- priv->changing = FALSE;
- priv->default_set = FALSE;
- priv->default_alpha_set = FALSE;
-
- top_hbox = gtk_hbox_new (FALSE, 12);
- gtk_box_pack_start (GTK_BOX (colorsel), top_hbox, FALSE, FALSE, 0);
-
- vbox = gtk_vbox_new (FALSE, 6);
- priv->triangle_colorsel = gtk_hsv_new ();
- g_signal_connect (priv->triangle_colorsel, "changed",
- G_CALLBACK (hsv_changed), colorsel);
- gtk_hsv_set_metrics (GTK_HSV (priv->triangle_colorsel), 174, 15);
- gtk_box_pack_start (GTK_BOX (top_hbox), vbox, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (vbox), priv->triangle_colorsel, FALSE, FALSE, 0);
- gtk_widget_set_tooltip_text (priv->triangle_colorsel,
- _("Select the color you want from the outer ring. Select the darkness or lightness of that color using the inner triangle."));
+ GdkColor color;
+ gchar *text;
- hbox = gtk_hbox_new (FALSE, 6);
- gtk_box_pack_end (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
+ colorsel = GTK_COLOR_SELECTION (data);
+ priv = colorsel->private_data;
- frame = gtk_frame_new (NULL);
- gtk_widget_set_size_request (frame, -1, 30);
- gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
- color_sample_new (colorsel);
- gtk_container_add (GTK_CONTAINER (frame), priv->sample_area);
- gtk_box_pack_start (GTK_BOX (hbox), frame, TRUE, TRUE, 0);
+ if (priv->changing)
+ return;
- button = gtk_button_new ();
+ text = gtk_editable_get_chars (GTK_EDITABLE (priv->hex_entry), 0, -1);
+ if (gdk_color_parse (text, &color))
+ {
+ priv->color[COLORSEL_RED] = CLAMP (color.red/65535.0, 0.0, 1.0);
+ priv->color[COLORSEL_GREEN] = CLAMP (color.green/65535.0, 0.0, 1.0);
+ priv->color[COLORSEL_BLUE] = CLAMP (color.blue/65535.0, 0.0, 1.0);
+ gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
+ priv->color[COLORSEL_GREEN],
+ priv->color[COLORSEL_BLUE],
+ &priv->color[COLORSEL_HUE],
+ &priv->color[COLORSEL_SATURATION],
+ &priv->color[COLORSEL_VALUE]);
+ update_color (colorsel);
+ }
+ g_free (text);
+}
- gtk_widget_set_events (button, GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK);
- g_object_set_data (G_OBJECT (button), I_("COLORSEL"), colorsel);
- g_signal_connect (button, "clicked",
- G_CALLBACK (get_screen_color), NULL);
- picker_image = gtk_image_new_from_stock (GTK_STOCK_COLOR_PICKER, GTK_ICON_SIZE_BUTTON);
- gtk_container_add (GTK_CONTAINER (button), picker_image);
- gtk_widget_show (GTK_WIDGET (picker_image));
- gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+static gboolean
+hex_focus_out (GtkWidget *hex_entry,
+ GdkEventFocus *event,
+ gpointer data)
+{
+ hex_changed (hex_entry, data);
+
+ return FALSE;
+}
- gtk_widget_set_tooltip_text (button,
- _("Click the eyedropper, then click a color anywhere on your screen to select that color."));
+static void
+hsv_changed (GtkWidget *hsv,
+ gpointer data)
+{
+ GtkColorSelection *colorsel;
+ ColorSelectionPrivate *priv;
- top_right_vbox = gtk_vbox_new (FALSE, 6);
- gtk_box_pack_start (GTK_BOX (top_hbox), top_right_vbox, FALSE, FALSE, 0);
- table = gtk_table_new (8, 6, FALSE);
- gtk_box_pack_start (GTK_BOX (top_right_vbox), table, FALSE, FALSE, 0);
- gtk_table_set_row_spacings (GTK_TABLE (table), 6);
- gtk_table_set_col_spacings (GTK_TABLE (table), 12);
+ colorsel = GTK_COLOR_SELECTION (data);
+ priv = colorsel->private_data;
- make_label_spinbutton (colorsel, &priv->hue_spinbutton, _("_Hue:"), table, 0, 0, COLORSEL_HUE,
- _("Position on the color wheel."));
- gtk_spin_button_set_wrap (GTK_SPIN_BUTTON (priv->hue_spinbutton), TRUE);
- make_label_spinbutton (colorsel, &priv->sat_spinbutton, _("_Saturation:"), table, 0, 1, COLORSEL_SATURATION,
- _("\"Deepness\" of the color."));
- make_label_spinbutton (colorsel, &priv->val_spinbutton, _("_Value:"), table, 0, 2, COLORSEL_VALUE,
- _("Brightness of the color."));
- make_label_spinbutton (colorsel, &priv->red_spinbutton, _("_Red:"), table, 6, 0, COLORSEL_RED,
- _("Amount of red light in the color."));
- make_label_spinbutton (colorsel, &priv->green_spinbutton, _("_Green:"), table, 6, 1, COLORSEL_GREEN,
- _("Amount of green light in the color."));
- make_label_spinbutton (colorsel, &priv->blue_spinbutton, _("_Blue:"), table, 6, 2, COLORSEL_BLUE,
- _("Amount of blue light in the color."));
- gtk_table_attach_defaults (GTK_TABLE (table), gtk_hseparator_new (), 0, 8, 3, 4);
-
- priv->opacity_label = gtk_label_new_with_mnemonic (_("Op_acity:"));
- gtk_misc_set_alignment (GTK_MISC (priv->opacity_label), 0.0, 0.5);
- gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_label, 0, 1, 4, 5);
- adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 0.0));
- g_object_set_data (G_OBJECT (adjust), I_("COLORSEL"), colorsel);
- priv->opacity_slider = gtk_hscale_new (adjust);
- gtk_widget_set_tooltip_text (priv->opacity_slider,
- _("Transparency of the color."));
- gtk_label_set_mnemonic_widget (GTK_LABEL (priv->opacity_label),
- priv->opacity_slider);
- gtk_scale_set_draw_value (GTK_SCALE (priv->opacity_slider), FALSE);
- g_signal_connect (adjust, "value_changed",
- G_CALLBACK (adjustment_changed),
- GINT_TO_POINTER (COLORSEL_OPACITY));
- gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_slider, 1, 7, 4, 5);
- priv->opacity_entry = gtk_entry_new ();
- gtk_widget_set_tooltip_text (priv->opacity_entry,
- _("Transparency of the color."));
- gtk_widget_set_size_request (priv->opacity_entry, 40, -1);
-
- g_signal_connect (priv->opacity_entry, "activate",
- G_CALLBACK (opacity_entry_changed), colorsel);
- gtk_table_attach_defaults (GTK_TABLE (table), priv->opacity_entry, 7, 8, 4, 5);
+ if (priv->changing)
+ return;
- label = gtk_label_new_with_mnemonic (_("Color _name:"));
- gtk_table_attach_defaults (GTK_TABLE (table), label, 0, 1, 5, 6);
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- priv->hex_entry = gtk_entry_new ();
-
- gtk_label_set_mnemonic_widget (GTK_LABEL (label), priv->hex_entry);
-
- g_signal_connect (priv->hex_entry, "activate",
- G_CALLBACK (hex_changed), colorsel);
-
- g_signal_connect (priv->hex_entry, "focus_out_event",
- G_CALLBACK (hex_focus_out), colorsel);
+ gtk_hsv_get_color (GTK_HSV (hsv),
+ &priv->color[COLORSEL_HUE],
+ &priv->color[COLORSEL_SATURATION],
+ &priv->color[COLORSEL_VALUE]);
+ gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
+ priv->color[COLORSEL_SATURATION],
+ priv->color[COLORSEL_VALUE],
+ &priv->color[COLORSEL_RED],
+ &priv->color[COLORSEL_GREEN],
+ &priv->color[COLORSEL_BLUE]);
+ update_color (colorsel);
+}
- gtk_widget_set_tooltip_text (priv->hex_entry,
- _("You can enter an HTML-style hexadecimal color value, or simply a color name such as 'orange' in this entry."));
+static void
+adjustment_changed (GtkAdjustment *adjustment,
+ gpointer data)
+{
+ GtkColorSelection *colorsel;
+ ColorSelectionPrivate *priv;
- gtk_entry_set_width_chars (GTK_ENTRY (priv->hex_entry), 7);
- gtk_table_attach_defaults (GTK_TABLE (table), priv->hex_entry, 1, 5, 5, 6);
-
- focus_chain = g_list_append (focus_chain, priv->hue_spinbutton);
- focus_chain = g_list_append (focus_chain, priv->sat_spinbutton);
- focus_chain = g_list_append (focus_chain, priv->val_spinbutton);
- focus_chain = g_list_append (focus_chain, priv->red_spinbutton);
- focus_chain = g_list_append (focus_chain, priv->green_spinbutton);
- focus_chain = g_list_append (focus_chain, priv->blue_spinbutton);
- focus_chain = g_list_append (focus_chain, priv->opacity_slider);
- focus_chain = g_list_append (focus_chain, priv->opacity_entry);
- focus_chain = g_list_append (focus_chain, priv->hex_entry);
- gtk_container_set_focus_chain (GTK_CONTAINER (table), focus_chain);
- g_list_free (focus_chain);
-
- /* Set up the palette */
- table = gtk_table_new (GTK_CUSTOM_PALETTE_HEIGHT, GTK_CUSTOM_PALETTE_WIDTH, TRUE);
- gtk_table_set_row_spacings (GTK_TABLE (table), 1);
- gtk_table_set_col_spacings (GTK_TABLE (table), 1);
- for (i = 0; i < GTK_CUSTOM_PALETTE_WIDTH; i++)
+ colorsel = GTK_COLOR_SELECTION (g_object_get_data (G_OBJECT (adjustment), "COLORSEL"));
+ priv = colorsel->private_data;
+
+ if (priv->changing)
+ return;
+
+ switch (GPOINTER_TO_INT (data))
{
- for (j = 0; j < GTK_CUSTOM_PALETTE_HEIGHT; j++)
- {
- make_palette_frame (colorsel, table, i, j);
- }
+ case COLORSEL_SATURATION:
+ case COLORSEL_VALUE:
+ priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 100;
+ gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
+ priv->color[COLORSEL_SATURATION],
+ priv->color[COLORSEL_VALUE],
+ &priv->color[COLORSEL_RED],
+ &priv->color[COLORSEL_GREEN],
+ &priv->color[COLORSEL_BLUE]);
+ break;
+ case COLORSEL_HUE:
+ priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 360;
+ gtk_hsv_to_rgb (priv->color[COLORSEL_HUE],
+ priv->color[COLORSEL_SATURATION],
+ priv->color[COLORSEL_VALUE],
+ &priv->color[COLORSEL_RED],
+ &priv->color[COLORSEL_GREEN],
+ &priv->color[COLORSEL_BLUE]);
+ break;
+ case COLORSEL_RED:
+ case COLORSEL_GREEN:
+ case COLORSEL_BLUE:
+ priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
+
+ gtk_rgb_to_hsv (priv->color[COLORSEL_RED],
+ priv->color[COLORSEL_GREEN],
+ priv->color[COLORSEL_BLUE],
+ &priv->color[COLORSEL_HUE],
+ &priv->color[COLORSEL_SATURATION],
+ &priv->color[COLORSEL_VALUE]);
+ break;
+ default:
+ priv->color[GPOINTER_TO_INT (data)] = adjustment->value / 255;
+ break;
}
- set_selected_palette (colorsel, 0, 0);
- priv->palette_frame = gtk_vbox_new (FALSE, 6);
- label = gtk_label_new_with_mnemonic (_("_Palette:"));
- gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
- gtk_box_pack_start (GTK_BOX (priv->palette_frame), label, FALSE, FALSE, 0);
+ update_color (colorsel);
+}
- gtk_label_set_mnemonic_widget (GTK_LABEL (label),
- priv->custom_palette[0][0]);
+static void
+opacity_entry_changed (GtkWidget *opacity_entry,
+ gpointer data)
+{
+ GtkColorSelection *colorsel;
+ ColorSelectionPrivate *priv;
+ GtkAdjustment *adj;
+ gchar *text;
- gtk_box_pack_end (GTK_BOX (top_right_vbox), priv->palette_frame, FALSE, FALSE, 0);
- gtk_box_pack_start (GTK_BOX (priv->palette_frame), table, FALSE, FALSE, 0);
+ colorsel = GTK_COLOR_SELECTION (data);
+ priv = colorsel->private_data;
- gtk_widget_show_all (top_hbox);
-
- /* hide unused stuff */
+ if (priv->changing)
+ return;
- if (priv->has_opacity == FALSE)
+ text = gtk_editable_get_chars (GTK_EDITABLE (priv->opacity_entry), 0, -1);
+ adj = gtk_range_get_adjustment (GTK_RANGE (priv->opacity_slider));
+ gtk_adjustment_set_value (adj, g_strtod (text, NULL));
+
+ update_color (colorsel);
+
+ g_free (text);
+}
+
+static void
+make_label_spinbutton (GtkColorSelection *colorsel,
+ GtkWidget **spinbutton,
+ gchar *text,
+ GtkWidget *table,
+ gint i,
+ gint j,
+ gint channel_type,
+ const gchar *tooltip)
+{
+ GtkWidget *label;
+ GtkAdjustment *adjust;
+
+ if (channel_type == COLORSEL_HUE)
+ {
+ adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 360.0, 1.0, 1.0, 1.0));
+ }
+ else if (channel_type == COLORSEL_SATURATION ||
+ channel_type == COLORSEL_VALUE)
{
- gtk_widget_hide (priv->opacity_label);
- gtk_widget_hide (priv->opacity_slider);
- gtk_widget_hide (priv->opacity_entry);
+ adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 100.0, 1.0, 1.0, 1.0));
}
-
- if (priv->has_palette == FALSE)
+ else
{
- gtk_widget_hide (priv->palette_frame);
+ adjust = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 255.0, 1.0, 1.0, 1.0));
}
+ g_object_set_data (G_OBJECT (adjust), I_("COLORSEL"), colorsel);
+ *spinbutton = gtk_spin_button_new (adjust, 10.0, 0);
- atk_obj = gtk_widget_get_accessible (priv->triangle_colorsel);
- if (GTK_IS_ACCESSIBLE (atk_obj))
- {
- atk_object_set_name (atk_obj, _("Color Wheel"));
- atk_object_set_role (gtk_widget_get_accessible (GTK_WIDGET (colorsel)), ATK_ROLE_COLOR_CHOOSER);
- make_all_relations (atk_obj, priv);
- }
+ gtk_widget_set_tooltip_text (*spinbutton, tooltip);
- gtk_widget_pop_composite_child ();
+ g_signal_connect (adjust, "value_changed",
+ G_CALLBACK (adjustment_changed),
+ GINT_TO_POINTER (channel_type));
+ label = gtk_label_new_with_mnemonic (text);
+ gtk_label_set_mnemonic_widget (GTK_LABEL (label), *spinbutton);
+
+ gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
+ gtk_table_attach_defaults (GTK_TABLE (table), label, i, i+1, j, j+1);
+ gtk_table_attach_defaults (GTK_TABLE (table), *spinbutton, i+1, i+2, j, j+1);
}
static void
-gtk_color_selection_destroy (GtkObject *object)
+make_palette_frame (GtkColorSelection *colorsel,
+ GtkWidget *table,
+ gint i,
+ gint j)
{
- GtkColorSelection *cselection = GTK_COLOR_SELECTION (object);
- ColorSelectionPrivate *priv = cselection->private_data;
+ GtkWidget *frame;
+ ColorSelectionPrivate *priv;
+
+ priv = colorsel->private_data;
+ frame = gtk_frame_new (NULL);
+ gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_IN);
+ priv->custom_palette[i][j] = palette_new (colorsel);
+ gtk_widget_set_size_request (priv->custom_palette[i][j], CUSTOM_PALETTE_ENTRY_WIDTH, CUSTOM_PALETTE_ENTRY_HEIGHT);
+ gtk_container_add (GTK_CONTAINER (frame), priv->custom_palette[i][j]);
+ gtk_table_attach_defaults (GTK_TABLE (table), frame, i, i+1, j, j+1);
+}
- if (priv->dropper_grab_widget)
- {
- gtk_widget_destroy (priv->dropper_grab_widget);
- priv->dropper_grab_widget = NULL;
- }
+/* Set the palette entry [x][y] to be the currently selected one. */
+static void
+set_selected_palette (GtkColorSelection *colorsel, int x, int y)
+{
+ ColorSelectionPrivate *priv = colorsel->private_data;
- GTK_OBJECT_CLASS (gtk_color_selection_parent_class)->destroy (object);
+ gtk_widget_grab_focus (priv->custom_palette[x][y]);
}
-static void
-gtk_color_selection_finalize (GObject *object)
+static double
+scale_round (double val, double factor)
{
- G_OBJECT_CLASS (gtk_color_selection_parent_class)->finalize (object);
+ val = floor (val * factor + 0.5);
+ val = MAX (val, 0);
+ val = MIN (val, factor);
+ return val;
}
static void
-gtk_color_selection_realize (GtkWidget *widget)
+update_color (GtkColorSelection *colorsel)
{
- GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget);
ColorSelectionPrivate *priv = colorsel->private_data;
- GtkSettings *settings = gtk_widget_get_settings (widget);
-
- priv->settings_connection = g_signal_connect (settings,
- "notify::gtk-color-palette",
- G_CALLBACK (palette_change_notify_instance),
- widget);
- update_palette (colorsel);
+ gchar entryval[12];
+ gchar opacity_text[32];
+ gchar *ptr;
+
+ priv->changing = TRUE;
+ color_sample_update_samples (colorsel);
+
+ gtk_hsv_set_color (GTK_HSV (priv->triangle_colorsel),
+ priv->color[COLORSEL_HUE],
+ priv->color[COLORSEL_SATURATION],
+ priv->color[COLORSEL_VALUE]);
+ gtk_adjustment_set_value (gtk_spin_button_get_adjustment
+ (GTK_SPIN_BUTTON (priv->hue_spinbutton)),
+ scale_round (priv->color[COLORSEL_HUE], 360));
+ gtk_adjustment_set_value (gtk_spin_button_get_adjustment
+ (GTK_SPIN_BUTTON (priv->sat_spinbutton)),
+ scale_round (priv->color[COLORSEL_SATURATION], 100));
+ gtk_adjustment_set_value (gtk_spin_button_get_adjustment
+ (GTK_SPIN_BUTTON (priv->val_spinbutton)),
+ scale_round (priv->color[COLORSEL_VALUE], 100));
+ gtk_adjustment_set_value (gtk_spin_button_get_adjustment
+ (GTK_SPIN_BUTTON (priv->red_spinbutton)),
+ scale_round (priv->color[COLORSEL_RED], 255));
+ gtk_adjustment_set_value (gtk_spin_button_get_adjustment
+ (GTK_SPIN_BUTTON (priv->green_spinbutton)),
+ scale_round (priv->color[COLORSEL_GREEN], 255));
+ gtk_adjustment_set_value (gtk_spin_button_get_adjustment
+ (GTK_SPIN_BUTTON (priv->blue_spinbutton)),
+ scale_round (priv->color[COLORSEL_BLUE], 255));
+ gtk_adjustment_set_value (gtk_range_get_adjustment
+ (GTK_RANGE (priv->opacity_slider)),
+ scale_round (priv->color[COLORSEL_OPACITY], 255));
+
+ g_snprintf (opacity_text, 32, "%.0f", scale_round (priv->color[COLORSEL_OPACITY], 255));
+ gtk_entry_set_text (GTK_ENTRY (priv->opacity_entry), opacity_text);
+
+ g_snprintf (entryval, 11, "#%2X%2X%2X",
+ (guint) (scale_round (priv->color[COLORSEL_RED], 255)),
+ (guint) (scale_round (priv->color[COLORSEL_GREEN], 255)),
+ (guint) (scale_round (priv->color[COLORSEL_BLUE], 255)));
+
+ for (ptr = entryval; *ptr; ptr++)
+ if (*ptr == ' ')
+ *ptr = '0';
+ gtk_entry_set_text (GTK_ENTRY (priv->hex_entry), entryval);
+ priv->changing = FALSE;
- GTK_WIDGET_CLASS (gtk_color_selection_parent_class)->realize (widget);
+ g_object_ref (colorsel);
+
+ g_signal_emit (colorsel, color_selection_signals[COLOR_CHANGED], 0);
+
+ g_object_freeze_notify (G_OBJECT (colorsel));
+ g_object_notify (G_OBJECT (colorsel), "current-color");
+ g_object_notify (G_OBJECT (colorsel), "current-alpha");
+ g_object_thaw_notify (G_OBJECT (colorsel));
+
+ g_object_unref (colorsel);
}
static void
-gtk_color_selection_unrealize (GtkWidget *widget)
+update_palette (GtkColorSelection *colorsel)
{
- GtkColorSelection *colorsel = GTK_COLOR_SELECTION (widget);
- ColorSelectionPrivate *priv = colorsel->private_data;
- GtkSettings *settings = gtk_widget_get_settings (widget);
+ GdkColor *current_colors;
+ gint i, j;
- g_signal_handler_disconnect (settings, priv->settings_connection);
+ current_colors = get_current_colors (colorsel);
+
+ for (i = 0; i < GTK_CUSTOM_PALETTE_HEIGHT; i++)
+ {
+ for (j = 0; j < GTK_CUSTOM_PALETTE_WIDTH; j++)
+ {
+ gint index;
- GTK_WIDGET_CLASS (gtk_color_selection_parent_class)->unrealize (widget);
+ index = i * GTK_CUSTOM_PALETTE_WIDTH + j;
+
+ gtk_color_selection_set_palette_color (colorsel,
+ index,
+ ¤t_colors[index]);
+ }
+ }
+
+ g_free (current_colors);
}
-/* We override show-all since we have internal widgets that
- * shouldn't be shown when you call show_all(), like the
- * palette and opacity sliders.
- */
static void
-gtk_color_selection_show_all (GtkWidget *widget)
+palette_change_notify_instance (GObject *object,
+ GParamSpec *pspec,
+ gpointer data)
{
- gtk_widget_show (widget);
+ update_palette (GTK_COLOR_SELECTION (data));
+}
+
+static void
+default_noscreen_change_palette_func (const GdkColor *colors,
+ gint n_colors)
+{
+ default_change_palette_func (gdk_screen_get_default (), colors, n_colors);
+}
+
+static void
+default_change_palette_func (GdkScreen *screen,
+ const GdkColor *colors,
+ gint n_colors)
+{
+ gchar *str;
+
+ str = gtk_color_selection_palette_to_string (colors, n_colors);
+
+ gtk_settings_set_string_property (gtk_settings_get_for_screen (screen),
+ "gtk-color-palette",
+ str,
+ "gtk_color_selection_palette_to_string");
+
+ g_free (str);
}
/**
@@ -2585,67 +2681,6 @@
return (gtk_hsv_is_adjusting (GTK_HSV (priv->triangle_colorsel)));
}
-static void
-gtk_color_selection_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
-
- switch (prop_id)
- {
- case PROP_HAS_OPACITY_CONTROL:
- gtk_color_selection_set_has_opacity_control (colorsel,
- g_value_get_boolean (value));
- break;
- case PROP_HAS_PALETTE:
- gtk_color_selection_set_has_palette (colorsel,
- g_value_get_boolean (value));
- break;
- case PROP_CURRENT_COLOR:
- gtk_color_selection_set_current_color (colorsel, g_value_get_boxed (value));
- break;
- case PROP_CURRENT_ALPHA:
- gtk_color_selection_set_current_alpha (colorsel, g_value_get_uint (value));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-
-}
-
-static void
-gtk_color_selection_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GtkColorSelection *colorsel = GTK_COLOR_SELECTION (object);
- GdkColor color;
-
- switch (prop_id)
- {
- case PROP_HAS_OPACITY_CONTROL:
- g_value_set_boolean (value, gtk_color_selection_get_has_opacity_control (colorsel));
- break;
- case PROP_HAS_PALETTE:
- g_value_set_boolean (value, gtk_color_selection_get_has_palette (colorsel));
- break;
- case PROP_CURRENT_COLOR:
- gtk_color_selection_get_current_color (colorsel, &color);
- g_value_set_boxed (value, &color);
- break;
- case PROP_CURRENT_ALPHA:
- g_value_set_uint (value, gtk_color_selection_get_current_alpha (colorsel));
- break;
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
- break;
- }
-}
-
/**
* gtk_color_selection_palette_from_string:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]