/*
- * This file is part of hildon-libs
+ * This file is a part of hildon
*
* Copyright (C) 2005, 2006 Nokia Corporation, all rights reserved.
*
*
*/
-
/**
* SECTION:hildon-color-chooser-dialog
- * @short_description: A dialog to choose a color.
- * @see_also: #HildonColorButton, #HildonColorChooser
+ * @short_description: A dialog used to select a color from HSV colorspace.
+ * @see_also: #HildonColorButton
+ *
+ * HildonColorChooserDialog enables the user to
+ * select an arbitrary color from a HSV colorspace.
+ * The color is stored in one of the predefined color
+ * slots and can be reselected later on.
+ *
+ * Additionally the user can choose one of the standard "factory"
+ * colors.
*
- * HildonColorChooserDialog is a widget widget to choose a color.
*/
-#include <gtk/gtk.h>
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <memory.h>
+#include <string.h>
+#include <libintl.h>
+#include <gdk/gdk.h>
+#include <gdk/gdkkeysyms.h>
+#include <gtk/gtk.h>
+#include <gconf/gconf-client.h>
+#include "hildon-color-chooser-dialog.h"
+#include "hildon-color-chooser.h"
+#include "hildon-defines.h"
+#include "hildon-banner.h"
+#include "hildon-color-chooser-dialog-private.h"
+
+#define _(String) dgettext("hildon-libs", String)
+
+static HildonColorChooserDialogClass* parent_class = NULL;
+
+/* darkened EGA palette to be used as predefined colors if style doesn't
+ define anything else (darker colors are darkened 0x8000 -> 0x6666) */
+static GdkColor hardcoded_colors[16] = {{0, 0x0000, 0x0000, 0x0000},
+ {0, 0x6666, 0x6666, 0x6666},
+ {0, 0x6666, 0x0000, 0x0000},
+ {0, 0x0000, 0x6666, 0x0000},
+ {0, 0x0000, 0x0000, 0x6666},
+ {0, 0x6666, 0x6666, 0x0000},
+ {0, 0x6666, 0x0000, 0x6666},
+ {0, 0x0000, 0x6666, 0x6666},
+ {0, 0xffff, 0xffff, 0xffff},
+ {0, 0xc000, 0xc000, 0xc000},
+ {0, 0xffff, 0x0000, 0x0000},
+ {0, 0x0000, 0xffff, 0x0000},
+ {0, 0x0000, 0x0000, 0xffff},
+ {0, 0xffff, 0xffff, 0x0000},
+ {0, 0xffff, 0x0000, 0xffff},
+ {0, 0x0000, 0xffff, 0xffff}};
+
+static void
+hildon_color_chooser_dialog_init (HildonColorChooserDialog *object);
+
+static void
+hildon_color_chooser_dialog_class_init (HildonColorChooserDialogClass *klass);
-#include "hildon-color-chooser-dialog.h"
+static void
+hildon_color_chooser_dialog_size_request (GtkWidget *widget,
+ GtkRequisition *req);
-#include "hildon-plugin-widget.h"
+static void
+hildon_color_chooser_dialog_size_allocate (GtkWidget *widget,
+ GtkAllocation *alloc);
+static void
+hildon_color_chooser_dialog_realize (GtkWidget *widget);
-enum {
- COLOR_CHANGED,
- LAST_SIGNAL
-};
+static void
+hildon_color_chooser_dialog_unrealize (GtkWidget *widget);
+static void
+hildon_color_chooser_dialog_style_set (GtkWidget *widget,
+ GtkStyle *previous_style);
-static HildonPluginWidgetInfo *global_plugin = NULL;
+static void
+hildon_color_chooser_dialog_show (GtkWidget *widget);
+static void
+hildon_color_chooser_dialog_show_all (GtkWidget *widget);
-static guint color_chooser_dialog_signals[LAST_SIGNAL] = { 0 };
+static gboolean
+hildon_color_chooser_dialog_key_press_event (GtkWidget *widget,
+ GdkEventKey *event);
+static gboolean
+hildon_color_chooser_dialog_key_release_event (GtkWidget *widget,
+ GdkEventKey *event);
-static void hildon_color_chooser_dialog_init(HildonColorChooserDialog *object);
-static void hildon_color_chooser_dialog_class_init(HildonColorChooserDialogClass *klass);
+static void
+hildon_color_chooser_dialog_destroy (GtkObject *object);
+static gboolean
+hildon_color_chooser_dialog_area_expose (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer data);
-GtkType hildon_color_chooser_dialog_get_type (void)
+static gboolean
+hildon_color_chooser_dialog_area_button_press (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data);
+
+static void
+hildon_color_chooser_dialog_color_changed (HildonColorChooser *chooser,
+ gpointer data);
+
+static void
+hildon_color_chooser_dialog_insensitive_press (GtkWidget *widget,
+ gpointer data);
+
+static void
+hildon_color_chooser_dialog_refresh_style_info (HildonColorChooserDialog *dialog);
+
+static void
+hildon_color_chooser_dialog_set_color_num (HildonColorChooserDialog *dialog,
+ gint num);
+
+static void
+hildon_color_chooser_dialog_ascii_hex_to_color (gchar *s,
+ GdkColor *color);
+
+static void
+hildon_color_chooser_dialog_color_to_ascii_hex (gchar *s,
+ GdkColor *color);
+
+GType G_GNUC_CONST
+hildon_color_chooser_dialog_get_type (void)
{
- static GtkType chooser_type = 0;
+ static GType dialog_type = 0;
- if (!chooser_type)
- {
- static const GtkTypeInfo chooser_info =
- {
- "HildonColorChooserDialog",
- sizeof (HildonColorChooserDialog),
- sizeof (HildonColorChooserDialogClass),
- (GtkClassInitFunc) hildon_color_chooser_dialog_class_init,
- (GtkObjectInitFunc) hildon_color_chooser_dialog_init,
- /* reserved_1 */ NULL,
- /* reserved_1 */ NULL,
- (GtkClassInitFunc) NULL
- };
+ if (!dialog_type) {
+ static const GTypeInfo dialog_info =
+ {
+ sizeof (HildonColorChooserDialogClass),
+ NULL,
+ NULL,
+ (GClassInitFunc) hildon_color_chooser_dialog_class_init,
+ NULL,
+ NULL,
+ sizeof (HildonColorChooserDialog),
+ 0,
+ (GInstanceInitFunc) hildon_color_chooser_dialog_init,
+ NULL
+ };
- chooser_type = gtk_type_unique (GTK_TYPE_DIALOG, &chooser_info);
+ dialog_type = g_type_register_static (GTK_TYPE_DIALOG,
+ "HildonColorChooserDialog", &dialog_info, 0);
}
- return chooser_type;
+ return dialog_type;
}
+static void
+hildon_color_chooser_dialog_init (HildonColorChooserDialog *object)
+{
+ HildonColorChooserDialogPrivate *priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (object);
+
+ gtk_dialog_set_has_separator (GTK_DIALOG (object), FALSE);
+ gtk_window_set_title (GTK_WINDOW (object), _("ecdg_ti_colour_selector"));
+
+ g_assert (priv);
+
+ priv->hbox = gtk_hbox_new (FALSE, 0);
+ priv->vbox = gtk_vbox_new (FALSE, 0);
+ priv->chooser = hildon_color_chooser_new ();
+
+ gtk_box_pack_start (GTK_BOX (priv->hbox), priv->chooser, TRUE, TRUE, 0);
+ gtk_box_pack_end (GTK_BOX (priv->hbox), priv->vbox, FALSE, FALSE, 0);
+
+ gtk_box_pack_start (GTK_BOX (GTK_DIALOG (object)->vbox), priv->hbox, TRUE, TRUE, 0);
+
+
+ priv->align_custom = gtk_alignment_new (0.5, 1.0, 0.0, 0.0);
+ priv->align_defined = gtk_alignment_new (0.5, 1.0, 0.0, 0.0);
+
+ priv->area_custom = gtk_drawing_area_new ();
+ priv->area_defined = gtk_drawing_area_new ();
+
+ gtk_container_add (GTK_CONTAINER (priv->align_custom), priv->area_custom);
+ gtk_container_add (GTK_CONTAINER (priv->align_defined), priv->area_defined);
+
+ priv->separator = gtk_hseparator_new ();
+
+ gtk_box_pack_start (GTK_BOX (priv->vbox), priv->align_defined, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (priv->vbox), priv->separator, FALSE, FALSE, 0);
+ gtk_box_pack_start (GTK_BOX (priv->vbox), priv->align_custom, FALSE, FALSE, 0);
+
+ gtk_dialog_add_button (GTK_DIALOG (object), _("ecdg_bd_colour_selector_ok"), GTK_RESPONSE_OK);
+ gtk_dialog_add_button (GTK_DIALOG (object), _("ecdg_bd_colour_selector_cancel"), GTK_RESPONSE_CANCEL);
+ gtk_dialog_set_default_response (GTK_DIALOG (object), GTK_RESPONSE_OK);
+
+ g_signal_connect (G_OBJECT (priv->chooser),
+ "insensitive-press", G_CALLBACK (hildon_color_chooser_dialog_insensitive_press), object);
+
+ g_signal_connect (G_OBJECT (priv->area_custom),
+ "expose-event", G_CALLBACK (hildon_color_chooser_dialog_area_expose), object);
+
+ g_signal_connect (G_OBJECT (priv->area_defined),
+ "expose-event", G_CALLBACK (hildon_color_chooser_dialog_area_expose), object);
+
+ g_signal_connect (G_OBJECT (priv->area_custom),
+ "button-press-event", G_CALLBACK (hildon_color_chooser_dialog_area_button_press), object);
+
+ g_signal_connect (G_OBJECT (priv->area_defined),
+ "button-press-event", G_CALLBACK (hildon_color_chooser_dialog_area_button_press), object);
-static void hildon_color_chooser_dialog_init(HildonColorChooserDialog *object)
+ g_signal_connect (G_OBJECT (priv->chooser),
+ "color-changed", G_CALLBACK (hildon_color_chooser_dialog_color_changed), object);
+
+ gtk_widget_add_events (priv->area_custom, GDK_BUTTON_PRESS_MASK);
+ gtk_widget_add_events (priv->area_defined, GDK_BUTTON_PRESS_MASK);
+
+ priv->selected = 0;
+ priv->gconf_client = gconf_client_get_default ();
+
+ memset (&priv->style_info, 0, sizeof (HildonColorChooserStyleInfo));
+
+ priv->colors_custom = NULL;
+ priv->colors_defined = NULL;
+ priv->gc_array = NULL;
+
+ priv->has_style = 0;
+}
+
+static void
+hildon_color_chooser_dialog_class_init (HildonColorChooserDialogClass *klass)
{
- int i;
+ GtkWidgetClass *widget_klass = GTK_WIDGET_CLASS (klass);
+ GtkObjectClass *object_klass = GTK_OBJECT_CLASS (klass);
+ gchar tmp[32];
+ gint i;
+
+ widget_klass->size_request = hildon_color_chooser_dialog_size_request;
+ widget_klass->size_allocate = hildon_color_chooser_dialog_size_allocate;
+ widget_klass->realize = hildon_color_chooser_dialog_realize;
+ widget_klass->unrealize = hildon_color_chooser_dialog_unrealize;
+ widget_klass->style_set = hildon_color_chooser_dialog_style_set;
+ widget_klass->show = hildon_color_chooser_dialog_show;
+ widget_klass->show_all = hildon_color_chooser_dialog_show_all;
+ widget_klass->key_press_event = hildon_color_chooser_dialog_key_press_event;
+ widget_klass->key_release_event = hildon_color_chooser_dialog_key_release_event;
+
+
+ object_klass->destroy = hildon_color_chooser_dialog_destroy;
+ parent_class = g_type_class_peek_parent (klass);
- object->color.red = 0x0000;
- object->color.green = 0x0000;
- object->color.blue = 0x0000;
- object->color.pixel = 0x00000000;
+ gtk_widget_class_install_style_property (widget_klass,
+ g_param_spec_boxed ("container_sizes",
+ "Container sizes",
+ "Container specific sizes",
+ GTK_TYPE_BORDER,
+ G_PARAM_READABLE));
+ gtk_widget_class_install_style_property (widget_klass,
+ g_param_spec_boxed ("radio_sizes",
+ "Color radio sizes",
+ "Color radio specific sizes",
+ GTK_TYPE_BORDER,
+ G_PARAM_READABLE));
- for(i = 0; i < 32; i++) {
- object->reserved[i] = 0;
- }
+ gtk_widget_class_install_style_property (widget_klass,
+ g_param_spec_boxed ("num_buttons",
+ "Number of buttons",
+ "Number of color store buttons",
+ GTK_TYPE_BORDER,
+ G_PARAM_READABLE));
+
+ gtk_widget_class_install_style_property (widget_klass,
+ g_param_spec_boxed ("default_color", "Default color",
+ "Default color for nonpainted custom colors",
+ GDK_TYPE_COLOR,
+ G_PARAM_READABLE));
+
+ for (i = 0; i < 32; i++) {
+ memset (tmp, 0, 32);
+ g_snprintf (tmp, 32, "defined_color%d", i);
+
+ gtk_widget_class_install_style_property (widget_klass,
+ g_param_spec_boxed (tmp, "Defined color",
+ "Pre-defined colors for the dialog",
+ GDK_TYPE_COLOR,
+ G_PARAM_READABLE));
+ }
+
+ g_type_class_add_private (object_klass, sizeof (HildonColorChooserDialogPrivate));
}
-static void hildon_color_chooser_dialog_class_init(HildonColorChooserDialogClass *klass)
+static void
+hildon_color_chooser_dialog_size_request (GtkWidget *widget,
+ GtkRequisition *req)
{
- GtkObjectClass *object_klass = GTK_OBJECT_CLASS(klass);
- int i;
+ HildonColorChooserDialogPrivate *priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (widget);
+
+ g_assert (priv);
+ gtk_container_set_border_width (GTK_CONTAINER (priv->hbox), priv->style_info.cont_sizes.left);
- for(i = 0; i < 32; i++) {
- klass->reserved[i] = 0;
- }
+ gtk_box_set_spacing (GTK_BOX (priv->hbox), priv->style_info.cont_sizes.right);
+ gtk_box_set_spacing (GTK_BOX (priv->vbox), priv->style_info.cont_sizes.top);
+ gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (widget)->vbox), priv->style_info.cont_sizes.bottom);
- klass->set_color = 0;
+ gtk_widget_set_size_request (priv->area_custom,
+ (priv->style_info.radio_sizes.left +
+ 2 * priv->style_info.radio_sizes.bottom) *
+ (priv->style_info.num_buttons.top) +
+ (priv->style_info.num_buttons.top-1) *
+ priv->style_info.radio_sizes.top,
+ (priv->style_info.radio_sizes.right +
+ 2 * priv->style_info.radio_sizes.bottom) *
+ (priv->style_info.num_buttons.bottom) +
+ (priv->style_info.num_buttons.bottom-1) *
+ priv->style_info.radio_sizes.top);
+ gtk_widget_set_size_request (priv->area_defined,
+ (priv->style_info.radio_sizes.left +
+ 2 * priv->style_info.radio_sizes.bottom) *
+ (priv->style_info.num_buttons.left) +
+ (priv->style_info.num_buttons.left-1) *
+ priv->style_info.radio_sizes.top,
+ (priv->style_info.radio_sizes.right +
+ 2 * priv->style_info.radio_sizes.bottom) *
+ (priv->style_info.num_buttons.right) +
+ (priv->style_info.num_buttons.right-1) *
+ priv->style_info.radio_sizes.top);
- color_chooser_dialog_signals[COLOR_CHANGED] = g_signal_new("color-changed", G_OBJECT_CLASS_TYPE (object_klass),
- G_SIGNAL_RUN_FIRST, G_STRUCT_OFFSET (HildonColorChooserDialogClass, color_changed),
- NULL, NULL, g_cclosure_marshal_VOID__BOXED, G_TYPE_NONE, 1, GDK_TYPE_COLOR);
+ GTK_WIDGET_CLASS (parent_class)->size_request (widget, req);
}
-/**
- * hildon_color_chooser_dialog_new:
- *
- * Creates a new color chooser dialog. The dialog is created through
- * HildonPluginWidget API and is loaded from plugin. The initially selected
- * color can be anything, so it's recommended to call
- * hildon_color_chooser_dialog_set_color () after creating the widget.
- *
- * Returns: a new color chooser dialog
- */
-GtkWidget *hildon_color_chooser_dialog_new(void)
+static void
+hildon_color_chooser_dialog_size_allocate (GtkWidget *widget,
+ GtkAllocation *alloc)
+{
+ HildonColorChooserDialogPrivate *priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (widget);
+
+ GdkRectangle rect;
+ int i, tmp, tmp2;
+
+ g_assert (priv);
+
+ GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, alloc);
+
+ if (GTK_WIDGET_REALIZED (widget)) {
+ tmp = (priv->style_info.num_buttons.left * priv->style_info.num_buttons.right);
+ tmp2 = (priv->style_info.num_buttons.top * priv->style_info.num_buttons.bottom);
+
+ for (i = 0; i < tmp; i++) {
+ rect.x = ((i % priv->style_info.num_buttons.left) *
+ (priv->style_info.radio_sizes.left +
+ priv->style_info.radio_sizes.top +
+ 2 * priv->style_info.radio_sizes.bottom)) +
+ priv->style_info.radio_sizes.bottom;
+
+ rect.y = ((i / priv->style_info.num_buttons.left) *
+ (priv->style_info.radio_sizes.right +
+ priv->style_info.radio_sizes.top +
+ 2 * priv->style_info.radio_sizes.bottom)) +
+ priv->style_info.radio_sizes.bottom;
+
+ rect.width = priv->style_info.radio_sizes.left;
+ rect.height = priv->style_info.radio_sizes.right;
+
+ gdk_gc_set_clip_rectangle (priv->gc_array[i], &rect);
+ }
+
+ for (i = 0; i < tmp2; i++) {
+ rect.x = ((i % priv->style_info.num_buttons.top) *
+ (priv->style_info.radio_sizes.left +
+ priv->style_info.radio_sizes.top +
+ 2 * priv->style_info.radio_sizes.bottom)) +
+ priv->style_info.radio_sizes.bottom;
+
+ rect.y = ((i / priv->style_info.num_buttons.top) *
+ (priv->style_info.radio_sizes.right +
+ priv->style_info.radio_sizes.top +
+ 2 * priv->style_info.radio_sizes.bottom)) + priv->style_info.radio_sizes.bottom;
+
+ rect.width = priv->style_info.radio_sizes.left;
+ rect.height = priv->style_info.radio_sizes.right;
+
+ gdk_gc_set_clip_rectangle (priv->gc_array[i + tmp], &rect);
+ }
+ }
+}
+
+static void
+hildon_color_chooser_dialog_realize (GtkWidget *widget)
{
- if(!global_plugin) {
- global_plugin = hildon_plugin_info_initialize(HILDON_TYPE_COLOR_CHOOSER_DIALOG, NULL);
- g_return_val_if_fail (global_plugin != NULL, NULL);
- }
+ HildonColorChooserDialogPrivate *priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (widget);
+
+ GdkRectangle rect;
+ int i, tmp, tmp2;
+
+ g_assert (priv);
+
+ GTK_WIDGET_CLASS(parent_class)->realize (widget);
+
+ tmp = (priv->style_info.num_buttons.left * priv->style_info.num_buttons.right) +
+ (priv->style_info.num_buttons.top * priv->style_info.num_buttons.bottom);
+
+ for (i = 0; i < tmp; i++) {
+ priv->gc_array[i] = gdk_gc_new (widget->window);
+ }
+
+ tmp = (priv->style_info.num_buttons.left * priv->style_info.num_buttons.right);
+ tmp2 = (priv->style_info.num_buttons.top * priv->style_info.num_buttons.bottom);
+
+ for (i = 0; i < tmp; i++) {
+ gdk_gc_set_rgb_fg_color (priv->gc_array[i], &priv->colors_defined[i]);
+
+ rect.x = ((i % priv->style_info.num_buttons.left) *
+ (priv->style_info.radio_sizes.left +
+ priv->style_info.radio_sizes.top +
+ 2 * priv->style_info.radio_sizes.bottom)) +
+ priv->style_info.radio_sizes.bottom;
+
+ rect.y = ((i / priv->style_info.num_buttons.left) *
+ (priv->style_info.radio_sizes.right +
+ priv->style_info.radio_sizes.top +
+ 2 * priv->style_info.radio_sizes.bottom)) +
+ priv->style_info.radio_sizes.bottom;
+
+ rect.width = priv->style_info.radio_sizes.left;
+ rect.height = priv->style_info.radio_sizes.right;
+
+ gdk_gc_set_clip_rectangle (priv->gc_array[i], &rect);
+ }
+
+ for (i = 0; i < tmp2; i++) {
+ gdk_gc_set_rgb_fg_color (priv->gc_array[i + tmp], &priv->colors_custom[i]);
+
+ rect.x = ((i % priv->style_info.num_buttons.top) *
+ (priv->style_info.radio_sizes.left +
+ priv->style_info.radio_sizes.top +
+ 2 * priv->style_info.radio_sizes.bottom)) +
+ priv->style_info.radio_sizes.bottom;
+
+ rect.y = ((i / priv->style_info.num_buttons.top) *
+ (priv->style_info.radio_sizes.right +
+ priv->style_info.radio_sizes.top +
+ 2 * priv->style_info.radio_sizes.bottom)) +
+ priv->style_info.radio_sizes.bottom;
+
+ rect.width = priv->style_info.radio_sizes.left;
+ rect.height = priv->style_info.radio_sizes.right;
- return hildon_plugin_info_construct_widget(global_plugin);
+ gdk_gc_set_clip_rectangle (priv->gc_array[i + tmp], &rect);
+ }
+}
+
+static void
+hildon_color_chooser_dialog_unrealize (GtkWidget *widget)
+{
+ HildonColorChooserDialogPrivate *priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (widget);
+
+ int i, tmp;
+
+ tmp = (priv->style_info.num_buttons.left * priv->style_info.num_buttons.right) +
+ (priv->style_info.num_buttons.top * priv->style_info.num_buttons.bottom);
+
+ for (i = 0; i < tmp; i++) {
+ g_object_unref (priv->gc_array[i]);
+ }
+
+ GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
+}
+
+static void
+hildon_color_chooser_dialog_style_set (GtkWidget *widget,
+ GtkStyle *previous_style)
+{
+ HildonColorChooserDialog *dialog = HILDON_COLOR_CHOOSER_DIALOG (widget);
+ HildonColorChooserDialogPrivate *priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (widget);
+
+ GdkColor *tmpcolor;
+ gchar tmp[32], key[128], *val;
+ int i, tmpn, setcolor = 0;
+
+ g_assert (priv);
+
+ if (! priv->has_style)
+ setcolor = 1;
+
+ priv->has_style = 1;
+
+ gtk_widget_style_get (widget, "default_color", &tmpcolor, NULL);
+
+ if (tmpcolor) {
+ priv->style_info.default_color = *tmpcolor;
+ } else {
+ priv->style_info.default_color.red = 0x0000;
+ priv->style_info.default_color.green = 0x0000;
+ priv->style_info.default_color.blue = 0x0000;
+ priv->style_info.default_color.pixel = 0x00000000;
+ }
+
+ hildon_color_chooser_dialog_refresh_style_info (dialog);
+
+ if (memcmp (&priv->style_info.num_buttons, &priv->style_info.last_num_buttons, sizeof (GtkBorder))) {
+ if (priv->colors_custom) {
+ g_free (priv->colors_custom);
+ } if (priv->colors_defined) {
+ g_free (priv->colors_defined);
+ } if (priv->gc_array) {
+ if (GTK_WIDGET_REALIZED (widget)) {
+ tmpn = (priv->style_info.last_num_buttons.left * priv->style_info.last_num_buttons.right) +
+ (priv->style_info.last_num_buttons.top * priv->style_info.last_num_buttons.bottom);
+
+ for (i = 0; i < tmpn; i++) {
+ g_object_unref (priv->gc_array[i]);
+ }
+ }
+
+ g_free (priv->gc_array);
+ }
+
+ priv->colors_custom = (GdkColor *)
+ g_malloc0 (sizeof (GdkColor) * (priv->style_info.num_buttons.top *
+ priv->style_info.num_buttons.bottom));
+
+ priv->colors_defined = (GdkColor *)
+ g_malloc0 (sizeof(GdkColor) * (priv->style_info.num_buttons.left *
+ priv->style_info.num_buttons.right));
+
+ tmpn = (priv->style_info.num_buttons.left * priv->style_info.num_buttons.right) +
+ (priv->style_info.num_buttons.top * priv->style_info.num_buttons.bottom);
+
+ priv->gc_array = (GdkGC **) g_malloc0 (sizeof (GdkGC *) * tmpn);
+
+ if (priv->gconf_client) {
+
+ for (i = 0; i < (priv->style_info.num_buttons.top * priv->style_info.num_buttons.bottom); i++) {
+ memset (key, 0, 128);
+ /* FIXME Extremally bad hardcoding */
+ g_snprintf (key, 128, "/system/osso/af/color_chooser/custom_color%d", i);
+ val = gconf_client_get_string (priv->gconf_client, key, NULL);
+
+ if (val) {
+ hildon_color_chooser_dialog_ascii_hex_to_color (val, &priv->colors_custom[i]);
+ g_free (val);
+ } else {
+ priv->colors_custom[i] = priv->style_info.default_color;
+ }
+ }
+ } else {
+ for (i = 0; i < (priv->style_info.num_buttons.top * priv->style_info.num_buttons.bottom); i++) {
+ priv->colors_custom[i] = priv->style_info.default_color;
+ }
+ }
+ }
+
+ tmpn = (priv->style_info.num_buttons.left * priv->style_info.num_buttons.right);
+
+ hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (priv->chooser),
+ (priv->selected < tmpn) ?
+ &priv->colors_defined[priv->selected] :
+ &priv->colors_custom[priv->selected - tmpn]);
+
+ for (i = 0; i < (priv->style_info.num_buttons.left * priv->style_info.num_buttons.right); i++) {
+ memset (tmp, 0, 32);
+ g_snprintf (tmp, 32, "defined_color%d", i);
+
+ gtk_widget_style_get (widget, tmp, &tmpcolor, NULL);
+
+ if (tmpcolor) {
+ priv->colors_defined[i] = *tmpcolor;
+ } else {
+ if(i < 16) {
+ priv->colors_defined[i] = hardcoded_colors[i];
+ } else { /* fallback to prevent segfault */
+ priv->colors_defined[i].red = 0x0000;
+ priv->colors_defined[i].green = 0x0000;
+ priv->colors_defined[i].blue = 0x0000;
+ priv->colors_defined[i].pixel = 0x00000000;
+ }
+ }
+ }
+
+ if (GTK_WIDGET_REALIZED (widget)) {
+ for (i = 0; i < (priv->style_info.num_buttons.left *
+ priv->style_info.num_buttons.right); i++) {
+ gdk_gc_set_rgb_fg_color (priv->gc_array[i], &priv->colors_defined[i]);
+ }
+ }
+
+ if (setcolor)
+ hildon_color_chooser_dialog_set_color (HILDON_COLOR_CHOOSER_DIALOG (dialog),
+ &priv->pending_color);
+
+ gtk_widget_queue_resize (widget);
+
+ GTK_WIDGET_CLASS (parent_class)->style_set (widget, previous_style);
+}
+
+static void
+hildon_color_chooser_dialog_show (GtkWidget *widget)
+{
+ HildonColorChooserDialogPrivate *priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (widget);
+
+ g_assert (priv);
+
+ gtk_widget_show (priv->hbox);
+ gtk_widget_show (priv->vbox);
+
+ gtk_widget_show (priv->chooser);
+
+ gtk_widget_show (priv->align_custom);
+ gtk_widget_show (priv->align_defined);
+
+ gtk_widget_show (priv->separator);
+
+ gtk_widget_show (priv->area_custom);
+ gtk_widget_show (priv->area_defined);
+
+ GTK_WIDGET_CLASS (parent_class)->show (widget);
+}
+
+/* FIXME WTF this function is even needed here? */
+static void
+hildon_color_chooser_dialog_show_all (GtkWidget *widget)
+{
+ hildon_color_chooser_dialog_show (widget);
+}
+
+static gboolean
+hildon_color_chooser_dialog_key_press_event (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ HildonColorChooserDialog *dialog = HILDON_COLOR_CHOOSER_DIALOG (widget);
+ HildonColorChooserDialogPrivate *priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (widget);
+ int tmp, tot, sel;
+
+ g_assert (priv);
+
+ if (event->keyval == HILDON_HARDKEY_UP || event->keyval == HILDON_HARDKEY_DOWN ||
+ event->keyval == HILDON_HARDKEY_LEFT || event->keyval == HILDON_HARDKEY_RIGHT) {
+ tmp = (priv->style_info.num_buttons.top * priv->style_info.num_buttons.bottom);
+ tot = (priv->style_info.num_buttons.left * priv->style_info.num_buttons.right) + tmp;
+
+ switch (event->keyval) {
+
+ case HILDON_HARDKEY_UP:
+ if(priv->selected >= priv->style_info.num_buttons.top) {
+ if(priv->selected - priv->style_info.num_buttons.left >= tmp) {
+ sel = priv->selected - priv->style_info.num_buttons.left;
+ } else {
+ sel = priv->selected - priv->style_info.num_buttons.top;
+ }
+
+ hildon_color_chooser_dialog_set_color_num (dialog, sel);
+ }
+ break;
+
+ case HILDON_HARDKEY_DOWN:
+ if(priv->selected < tot - priv->style_info.num_buttons.left) {
+ if(priv->selected < tmp) {
+ sel = priv->selected + priv->style_info.num_buttons.top;
+ } else {
+ sel = priv->selected + priv->style_info.num_buttons.left;
+ }
+
+ hildon_color_chooser_dialog_set_color_num (dialog, sel);
+ }
+ break;
+
+ case HILDON_HARDKEY_LEFT:
+ if ((priv->selected < tmp ?
+ (priv->selected % priv->style_info.num_buttons.top) :
+ ((priv->selected - tmp) % priv->style_info.num_buttons.left)) > 0) {
+ sel = priv->selected - 1;
+
+ hildon_color_chooser_dialog_set_color_num (dialog, sel);
+ }
+ break;
+
+ case HILDON_HARDKEY_RIGHT:
+ if ((priv->selected < tmp) ?
+ (priv->selected % priv->style_info.num_buttons.top < priv->style_info.num_buttons.top - 1) :
+ ((priv->selected - tmp) % priv->style_info.num_buttons.left < priv->style_info.num_buttons.left - 1)) {
+ sel = priv->selected + 1;
+
+ hildon_color_chooser_dialog_set_color_num (dialog, sel);
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ return FALSE;
+ }
+
+ return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
+}
+
+static gboolean
+hildon_color_chooser_dialog_key_release_event (GtkWidget *widget,
+ GdkEventKey *event)
+{
+ if (event->keyval == HILDON_HARDKEY_UP ||
+ event->keyval == HILDON_HARDKEY_DOWN ||
+ event->keyval == HILDON_HARDKEY_LEFT ||
+ event->keyval == HILDON_HARDKEY_RIGHT)
+ {
+ return FALSE;
+ }
+
+ return GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event);
+}
+
+static void
+hildon_color_chooser_dialog_destroy (GtkObject *object)
+{
+ HildonColorChooserDialogPrivate *priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (object);
+
+ gchar key[128], color[13];
+ int i, tmp;
+
+ g_assert (priv);
+
+ if (priv->gconf_client) {
+ memset (color, 0, 13);
+
+ tmp = (priv->style_info.num_buttons.top * priv->style_info.num_buttons.bottom);
+
+ for (i = 0; i < tmp; i++) {
+ memset (key, 0, 128);
+ /* FIXME Extremally bad hardcoding */
+ g_snprintf (key, 128, "/system/osso/af/color_chooser/custom_color%d", i);
+ hildon_color_chooser_dialog_color_to_ascii_hex (color, &priv->colors_custom[i]);
+ gconf_client_set_string (priv->gconf_client, key, color, NULL);
+ }
+
+ g_object_unref (priv->gconf_client);
+ priv->gconf_client = NULL;
+ }
+
+ if (priv->gc_array) {
+ g_free (priv->gc_array);
+ priv->gc_array = NULL;
+ } if (priv->colors_defined) {
+ g_free (priv->colors_defined);
+ priv->colors_defined = NULL;
+ } if (priv->colors_custom) {
+ g_free (priv->colors_custom);
+ priv->colors_custom = NULL;
+ }
+
+ GTK_OBJECT_CLASS (parent_class)->destroy (object);
}
/**
* hildon_color_chooser_dialog_set_color:
- * @chooser: a #HildonColorChooserDialog
- * @color: a color to be set
+ * @dialog: a #HildonColorChooserDialog
+ * @color: a color to set on the #HildonColorChooserDialog
+ *
+ * Sets the dialog to point at the given color. It'll first try to
+ * search the palette of the existing colors to match the passed color.
+ * If the color is not found in the pallette, the color in the currently
+ * selected box will be modified.
*
- * Sets the color selected in the dialog.
*/
-void hildon_color_chooser_dialog_set_color(HildonColorChooserDialog *chooser, GdkColor *color)
+void
+hildon_color_chooser_dialog_set_color (HildonColorChooserDialog *dialog,
+ GdkColor *color)
+{
+ HildonColorChooserDialogPrivate *priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (dialog);
+
+ int i, found = -1, tmp, tmp2;
+
+ g_assert (priv);
+
+ if (! priv->has_style) {
+ priv->pending_color = *color;
+ return;
+ }
+
+ tmp = (priv->style_info.num_buttons.left * priv->style_info.num_buttons.right);
+ tmp2 = (priv->style_info.num_buttons.top * priv->style_info.num_buttons.bottom);
+
+ for (i = 0; i < tmp; i++) {
+ if (priv->colors_defined[i].red == color->red &&
+ priv->colors_defined[i].green == color->green &&
+ priv->colors_defined[i].blue == color->blue) {
+ found = i;
+ break;
+ }
+ }
+
+ if (found == -1) {
+ for (i = 0; i < tmp2; i++) {
+ if (priv->colors_custom[i].red == color->red &&
+ priv->colors_custom[i].green == color->green &&
+ priv->colors_custom[i].blue == color->blue) {
+ found = i + tmp;
+ break;
+ }
+ }
+ }
+
+ if (found == -1) {
+ priv->colors_custom[tmp2-1] = *color;
+ if (GTK_WIDGET_REALIZED (GTK_WIDGET (dialog))) {
+ gdk_gc_set_rgb_fg_color (priv->gc_array[tmp2-1], color);
+ }
+ hildon_color_chooser_dialog_set_color_num (dialog, tmp2 - 1);
+ } else {
+ hildon_color_chooser_dialog_set_color_num (dialog, found);
+ }
+}
+
+static gboolean
+hildon_color_chooser_dialog_area_expose (GtkWidget *widget,
+ GdkEventExpose *event,
+ gpointer data)
{
- HildonColorChooserDialogClass *klass = HILDON_COLOR_CHOOSER_DIALOG_CLASS(G_OBJECT_GET_CLASS(chooser));
+ HildonColorChooserDialogPrivate *priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (data);
+
+ int i, num_selected, tot_w, tot_h, spacing, brd, x, y;
+ GdkGC **start_gc;
+ int tmp, w, h;
+
+ g_assert (priv);
+
+ tmp = (priv->style_info.num_buttons.left * priv->style_info.num_buttons.right);
+
+ if (widget == priv->area_custom) {
+ num_selected = priv->selected - tmp;
+ start_gc = priv->gc_array + tmp;
+ tmp = (priv->style_info.num_buttons.top * priv->style_info.num_buttons.bottom);
+ w = priv->style_info.num_buttons.top;
+ h = priv->style_info.num_buttons.bottom;
+ } else { /* widget == dialog->area_defined */
+ num_selected = priv->selected;
+ start_gc = priv->gc_array;
+ w = priv->style_info.num_buttons.left;
+ h = priv->style_info.num_buttons.right;
+ }
+ spacing = priv->style_info.radio_sizes.top;
+ brd = priv->style_info.radio_sizes.bottom;
+ tot_w = priv->style_info.radio_sizes.left + 2 * brd;
+ tot_h = priv->style_info.radio_sizes.right + 2 * brd;
- chooser->color = *color;
+ for (i = 0; i < tmp; i++) {
+ x = ((i % w) * (tot_w + spacing));
+ y = ((i / w) * (tot_h + spacing));
- if(klass->set_color) {
- klass->set_color(chooser, color);
- }
+ gdk_draw_rectangle (widget->window,
+ widget->style->black_gc,
+ TRUE,
+ (i == num_selected) ? x : x + 2,
+ (i == num_selected) ? y : y + 2,
+ (i == num_selected) ? tot_w : tot_w - 4,
+ (i == num_selected) ? tot_h : tot_h - 4);
+
+ gdk_draw_rectangle(widget->window,
+ widget->style->white_gc,
+ TRUE,
+ x + 3,
+ y + 3,
+ tot_w - 6,
+ tot_h - 6);
+
+ gdk_draw_rectangle(widget->window,
+ start_gc [i],
+ TRUE,
+ x + 3 + 1,
+ y + 3 + 1,
+ tot_w - 6 - 2,
+ tot_h - 6 - 2);
+ }
+
+ return FALSE;
+}
+
+static gboolean
+hildon_color_chooser_dialog_area_button_press (GtkWidget *widget,
+ GdkEventButton *event,
+ gpointer data)
+{
+ HildonColorChooserDialog *dialog = HILDON_COLOR_CHOOSER_DIALOG (data);
+ HildonColorChooserDialogPrivate *priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (data);
+
+ int i, hskip, vskip, brd, selection = -1;
+ int x, y, tmp, tmp2, w;
+
+ g_assert (priv);
+
+ x = event->x;
+ y = event->y;
+
+ brd = priv->style_info.radio_sizes.bottom;
+ hskip = priv->style_info.radio_sizes.left +
+ priv->style_info.radio_sizes.top + 2 * brd;
+ vskip = priv->style_info.radio_sizes.right +
+ priv->style_info.radio_sizes.top + 2 * brd;
+
+ tmp = (priv->style_info.num_buttons.left * priv->style_info.num_buttons.right);
+ tmp2 = (priv->style_info.num_buttons.top * priv->style_info.num_buttons.bottom);
+
+ if (widget == priv->area_defined) {
+ w = priv->style_info.num_buttons.left;
+
+ for (i = 0; i < tmp; i++) {
+ if (x >= hskip * (i % w) + brd && x < hskip * (i % w) + brd + priv->style_info.radio_sizes.left &&
+ y >= vskip * (i / w) + brd && y < hskip * (i / w) + brd + priv->style_info.radio_sizes.right) {
+ selection = i;
+ break;
+ }
+ }
+ } else {
+ w = priv->style_info.num_buttons.top;
+ for (i = 0; i < tmp2; i++) {
+ if (x >= hskip * (i % w) + brd && x < hskip * (i % w) + brd + priv->style_info.radio_sizes.left &&
+ y >= vskip * (i / w) + brd && y < hskip * (i / w) + brd + priv->style_info.radio_sizes.right) {
+ selection = i + tmp;
+ break;
+ }
+ }
+ }
+
+ if (selection != -1) {
+ hildon_color_chooser_dialog_set_color_num (dialog, selection);
+ }
+
+ return FALSE;
+}
+
+static void
+hildon_color_chooser_dialog_color_changed (HildonColorChooser *chooser,
+ gpointer data)
+{
+ HildonColorChooserDialogPrivate *priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (data);
+ char key[128], color_str[13];
+ int tmp;
+ GdkColor *color = g_new (GdkColor, 1);
+
+ g_assert (priv);
+
+ hildon_color_chooser_get_color (chooser, color);
+
+ tmp = (priv->style_info.num_buttons.left * priv->style_info.num_buttons.right);
+
+ if (priv->selected >= tmp) {
+ priv->colors_custom[priv->selected - tmp] = *color;
+
+ gdk_gc_set_rgb_fg_color (priv->gc_array[priv->selected], &priv->colors_custom[priv->selected - tmp]);
+ gtk_widget_queue_draw (priv->area_custom);
+
+ if (priv->gconf_client) {
+ memset (key, 0, 128);
+ memset (color_str, 0, 13);
+ /* FIXME Ugly hardcoded stuff! */
+ g_snprintf (key, 128, "/system/osso/af/color_chooser/custom_color%d", priv->selected - tmp);
+ hildon_color_chooser_dialog_color_to_ascii_hex (color_str, &priv->colors_custom[priv->selected - tmp]);
+ gconf_client_set_string (priv->gconf_client, key, color_str, NULL);
+ }
+ }
+}
+
+static void
+hildon_color_chooser_dialog_insensitive_press (GtkWidget *widget,
+ gpointer data)
+{
+ hildon_banner_show_information (widget, NULL, _("ecdg_ib_colour_selector_predefined"));
+}
+
+/* function has size defaults */
+static void
+hildon_color_chooser_dialog_refresh_style_info (HildonColorChooserDialog *dialog)
+{
+ GtkBorder *tmp1, *tmp2, *tmp3;
+ HildonColorChooserDialogPrivate *priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (dialog);
+
+ g_assert (priv);
+
+ gtk_widget_style_get (GTK_WIDGET (dialog), "container_sizes", &tmp1,
+ "radio_sizes", &tmp2, "num_buttons", &tmp3, NULL);
+
+ priv->style_info.last_num_buttons = priv->style_info.num_buttons;
+
+ if (tmp1) {
+ priv->style_info.cont_sizes = *tmp1;
+ g_free (tmp1);
+ } else {
+ priv->style_info.cont_sizes.left = 0;
+ priv->style_info.cont_sizes.right = 8;
+ priv->style_info.cont_sizes.top = 4;
+ priv->style_info.cont_sizes.bottom = 0;
+ }
+
+ if (tmp2) {
+ priv->style_info.radio_sizes = *tmp2;
+ g_free (tmp2);
+ } else {
+ priv->style_info.radio_sizes.left = 16;
+ priv->style_info.radio_sizes.right = 16;
+ priv->style_info.radio_sizes.top = 4;
+ priv->style_info.radio_sizes.bottom = 2;
+ }
+
+ if (tmp3) {
+ priv->style_info.num_buttons = *tmp3;
+ g_free (tmp3);
+ } else {
+ priv->style_info.num_buttons.left = 8;
+ priv->style_info.num_buttons.right = 2;
+ priv->style_info.num_buttons.top = 8;
+ priv->style_info.num_buttons.bottom = 2;
+ }
+}
+
+static void
+hildon_color_chooser_dialog_set_color_num (HildonColorChooserDialog *dialog,
+ gint num)
+{
+ HildonColorChooserDialogPrivate *priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (dialog);
+
+ int tmp;
+
+ g_assert (priv);
+
+ tmp = (priv->style_info.num_buttons.left * priv->style_info.num_buttons.right);
+
+ if (num < tmp) {
+ gtk_widget_set_sensitive (priv->chooser, FALSE);
+ } else {
+ gtk_widget_set_sensitive (priv->chooser, TRUE);
+ }
+
+ priv->selected = num;
+
+ gtk_widget_queue_draw (priv->area_custom);
+ gtk_widget_queue_draw (priv->area_defined);
+
+ priv->color = (num < tmp) ? priv->colors_defined[num] : priv->colors_custom[num - tmp];
+
+ hildon_color_chooser_set_color (HILDON_COLOR_CHOOSER (priv->chooser),
+ (num < tmp) ? &priv->colors_defined[num] : &priv->colors_custom[num - tmp]);
+}
+
+static void
+hildon_color_chooser_dialog_ascii_hex_to_color (gchar *s,
+ GdkColor *color)
+{
+ int vals[12], i;
+
+ for (i = 0; i < 12; i++) {
+ if (s[i] >= '0' && s[i] <= '9') {
+ vals[i] = s[i] - 0x30;
+ } else if (s[i] >= 'a' && s[i] <= 'f') {
+ vals[i] = s[i] - 0x57;
+ } else {
+ vals[i] = 0;
+ }
+ }
+
+ color->red = (vals[0] << 12) | (vals[1] << 8) | (vals[2 ] << 4) | (vals[3 ]);
+ color->green = (vals[4] << 12) | (vals[5] << 8) | (vals[6 ] << 4) | (vals[7 ]);
+ color->blue = (vals[8] << 12) | (vals[9] << 8) | (vals[10] << 4) | (vals[11]);
+}
+
+static void
+hildon_color_chooser_dialog_color_to_ascii_hex (gchar *s,
+ GdkColor *color)
+{
+ g_snprintf (s, 13, "%x%x%x%x%x%x%x%x%x%x%x%x",
+ (color->red >> 12) & 0xf, (color->red >> 8) & 0xf,
+ (color->red >> 4) & 0xf, (color->red ) & 0xf,
+ (color->green >> 12) & 0xf, (color->green >> 8) & 0xf,
+ (color->green >> 4) & 0xf, (color->green ) & 0xf,
+ (color->blue >> 12) & 0xf, (color->blue >> 8) & 0xf,
+ (color->blue >> 4) & 0xf, (color->blue ) & 0xf);
}
/**
- * hildon_color_chooser_dialog_get_color:
- * @chooser: a #HildonColorChooserDialog
- * @color: a pointer to #GdkColor to be filled by the function
+ * hildon_color_chooser_dialog_new:
*
- * Gets the color selected in the dialog.
+ * Creates a new color chooser dialog.
+ *
+ * Returns: a new color chooser dialog.
*/
-void hildon_color_chooser_dialog_get_color(HildonColorChooserDialog *chooser, GdkColor *color)
+GtkWidget*
+hildon_color_chooser_dialog_new (void)
{
- *color = chooser->color;
+ return g_object_new (HILDON_TYPE_COLOR_CHOOSER_DIALOG, NULL);
}
-
-void hildon_color_chooser_dialog_emit_color_changed(HildonColorChooserDialog *chooser)
+/**
+ * hildon_color_chooser_dialog_get_color:
+ * @dialog: a #HildonColorChooserDialog
+ * @color: a color structure to fill with the currently selected color
+ *
+ * Retrives the currently selected color in the color chooser dialog.
+ *
+ */
+void
+hildon_color_chooser_dialog_get_color (HildonColorChooserDialog *dialog,
+ GdkColor *color)
{
- g_signal_emit(chooser, color_chooser_dialog_signals[COLOR_CHANGED], 0, &chooser->color);
+ /* FIXME Should return pending color? */
+ HildonColorChooserDialogPrivate *priv;
+
+ g_return_if_fail (HILDON_IS_COLOR_CHOOSER_DIALOG (dialog));
+ priv = HILDON_COLOR_CHOOSER_DIALOG_GET_PRIVATE (dialog);
+ g_assert (priv);
+
+ hildon_color_chooser_get_color (HILDON_COLOR_CHOOSER (priv->chooser), color);
}
+