2 * This file is part of hildon-libs
4 * Copyright (C) 2005 Nokia Corporation.
6 * Contact: Luc Pionchon <luc.pionchon@nokia.com>
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1 of
11 * the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
27 #include <gdk-pixbuf/gdk-pixbuf.h>
28 #include <gtk/gtkbutton.h>
29 #include <gtk/gtkalignment.h>
30 #include <gtk/gtkdrawingarea.h>
31 #include <gtk/gtksignal.h>
33 #include "hildon-color-button.h"
34 #include "hildon-color-selector.h"
37 #define _(String) dgettext(PACKAGE, String)
39 #define HILDON_COLOR_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE\
40 ((obj), HILDON_TYPE_COLOR_BUTTON, HildonColorButtonPrivate))
42 #define COLOR_FIELD_HEIGHT 26
43 #define COLOR_FIELD_WIDTH 26
44 #define COLOR_BUTTON_WIDTH 48
45 #define COLOR_BUTTON_HEIGHT 40
47 struct _HildonColorButtonPrivate
51 GtkWidget *drawing_area;
64 hildon_color_button_class_init(HildonColorButtonClass *klass);
66 hildon_color_button_init(HildonColorButton *color_button);
69 hildon_color_button_finalize(GObject *object);
71 hildon_color_button_set_property(GObject *object, guint param_id,
72 const GValue *value, GParamSpec *pspec);
74 hildon_color_button_get_property(GObject *object, guint param_id,
75 GValue *value, GParamSpec *pspec);
77 hildon_color_button_realize(GtkWidget *widget);
79 hildon_color_button_clicked(GtkButton *button);
81 hildon_color_field_expose_event(GtkWidget *widget, GdkEventExpose *event,
82 HildonColorButton *cb);
85 hildon_color_button_mnemonic_activate( GtkWidget *widget,
86 gboolean group_cycling );
88 hildon_color_button_recolor_pixbuf(HildonColorButton *cb);
91 static gpointer parent_class = NULL;
94 hildon_color_button_get_type(void)
96 static GType color_button_type = 0;
98 if (!color_button_type)
100 static const GTypeInfo color_button_info =
102 sizeof (HildonColorButtonClass),
103 NULL, /* base_init */
104 NULL, /* base_finalize */
105 (GClassInitFunc) hildon_color_button_class_init,
106 NULL, /* class_finalize */
107 NULL, /* class_data */
108 sizeof (HildonColorButton),
110 (GInstanceInitFunc) hildon_color_button_init,
114 g_type_register_static (GTK_TYPE_BUTTON, "HildonColorButton",
115 &color_button_info, 0);
118 return color_button_type;
122 hildon_color_button_class_init(HildonColorButtonClass *klass)
124 GObjectClass *gobject_class;
125 GtkButtonClass *button_class;
126 GtkWidgetClass *widget_class;
128 gobject_class = G_OBJECT_CLASS (klass);
129 button_class = GTK_BUTTON_CLASS (klass);
130 widget_class = GTK_WIDGET_CLASS (klass);
132 parent_class = g_type_class_peek_parent (klass);
134 gobject_class->get_property = hildon_color_button_get_property;
135 gobject_class->set_property = hildon_color_button_set_property;
136 gobject_class->finalize = hildon_color_button_finalize;
137 widget_class->realize = hildon_color_button_realize;
138 button_class->clicked = hildon_color_button_clicked;
139 widget_class->mnemonic_activate = hildon_color_button_mnemonic_activate;
142 * HildonColorButton:color:
144 * The selected color.
146 g_object_class_install_property (gobject_class, PROP_COLOR,
147 g_param_spec_boxed ("color",
149 "The selected color",
150 GDK_TYPE_COLOR, G_PARAM_READABLE |
153 g_type_class_add_private (gobject_class, sizeof (HildonColorButtonPrivate));
156 /* Handle exposure events for the color picker's drawing area */
158 hildon_color_field_expose_event(GtkWidget *widget, GdkEventExpose *event,
159 HildonColorButton *cb)
161 gdk_draw_pixbuf(widget->window, cb->priv->gc,
162 cb->priv->pixbuf, event->area.x,
163 event->area.y, event->area.x,
164 event->area.y, event->area.width,
165 event->area.height, GDK_RGB_DITHER_MAX,
166 event->area.x, event->area.y);
171 hildon_color_button_init(HildonColorButton *cb)
175 cb->priv = HILDON_COLOR_BUTTON_GET_PRIVATE(cb);
177 cb->priv->dialog = NULL;
180 gtk_widget_push_composite_child();
182 align = gtk_alignment_new(0.5, 0.5, 0, 0);
184 cb->priv->pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB, FALSE, 8,
185 COLOR_FIELD_WIDTH, COLOR_FIELD_HEIGHT);
187 cb->priv->drawing_area = gtk_drawing_area_new();
189 gtk_widget_set_size_request(GTK_WIDGET(cb), COLOR_BUTTON_WIDTH,
190 COLOR_BUTTON_HEIGHT);
191 gtk_widget_set_size_request(GTK_WIDGET(cb->priv->drawing_area),
192 COLOR_FIELD_WIDTH, COLOR_FIELD_HEIGHT);
194 g_signal_connect(G_OBJECT(cb->priv->drawing_area), "expose-event",
195 G_CALLBACK(hildon_color_field_expose_event), cb);
197 gtk_container_add(GTK_CONTAINER(align), cb->priv->drawing_area);
198 gtk_container_add(GTK_CONTAINER(cb), align);
200 hildon_color_button_recolor_pixbuf(cb);
202 gtk_widget_show_all(align);
204 gtk_widget_pop_composite_child();
208 hildon_color_button_finalize(GObject *object)
210 HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
212 if (cb->priv->dialog)
214 gtk_widget_destroy(cb->priv->dialog);
215 cb->priv->dialog = NULL;
218 if (cb->priv->pixbuf)
220 g_object_unref(G_OBJECT(cb->priv->pixbuf));
221 cb->priv->pixbuf = NULL;
226 g_object_unref(G_OBJECT(cb->priv->gc));
229 if( G_OBJECT_CLASS(parent_class)->finalize )
230 G_OBJECT_CLASS(parent_class)->finalize(object);
234 hildon_color_button_realize(GtkWidget *widget)
236 HildonColorButton *cb = HILDON_COLOR_BUTTON(widget);
238 GTK_WIDGET_CLASS(parent_class)->realize(widget);
241 cb->priv->gc = gdk_gc_new(widget->window);
243 hildon_color_button_recolor_pixbuf(cb);
247 hildon_color_button_mnemonic_activate( GtkWidget *widget,
248 gboolean group_cycling )
250 gtk_widget_grab_focus( widget );
255 hildon_color_button_recolor_pixbuf(HildonColorButton *cb)
257 gint i, j, rowstride;
260 GdkPixbuf *pb = cb->priv->pixbuf;
261 GdkColor *color = &cb->priv->color;
263 r = (color->red >> 8);
264 g = (color->green >> 8);
265 b = (color->blue >> 8);
267 pixels = gdk_pixbuf_get_pixels(pb);
268 rowstride = gdk_pixbuf_get_rowstride(pb);
270 for (j=0; j<COLOR_FIELD_HEIGHT; j++)
271 for (i=0; i<COLOR_FIELD_WIDTH; i++)
273 *(j * rowstride + pixels + i * 3) = r;
274 *(j * rowstride + pixels + i * 3 + 1) = g;
275 *(j * rowstride + pixels + i * 3 + 2) = b;
277 gtk_widget_queue_draw(GTK_WIDGET(cb));
281 hildon_color_button_clicked(GtkButton *button)
284 HildonColorButton *cb = HILDON_COLOR_BUTTON(button);
285 HildonColorSelector *csd = HILDON_COLOR_SELECTOR(cb->priv->dialog);
289 GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(cb));
290 cb->priv->dialog = hildon_color_selector_new(GTK_WINDOW(parent));
291 csd = HILDON_COLOR_SELECTOR(cb->priv->dialog);
294 gtk_window_set_transient_for(GTK_WINDOW(csd), GTK_WINDOW(parent));
297 hildon_color_selector_set_color(csd, &cb->priv->color);
299 result = gtk_dialog_run(GTK_DIALOG(csd));
300 if (result == GTK_RESPONSE_OK)
302 cb->priv->color = *hildon_color_selector_get_color(csd);
303 g_object_set( G_OBJECT(cb), "color", &cb->priv->color, NULL );
305 gtk_widget_hide(GTK_WIDGET(csd));
309 hildon_color_button_set_property(GObject *object, guint param_id,
310 const GValue *value, GParamSpec *pspec)
312 HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
317 cb->priv->color = *(GdkColor*)g_value_get_boxed(value);
318 hildon_color_button_recolor_pixbuf(cb);
321 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
327 hildon_color_button_get_property(GObject *object, guint param_id,
328 GValue *value, GParamSpec *pspec)
330 HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
335 g_value_set_boxed(value, &cb->priv->color);
338 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
344 * hildon_color_button_new:
346 * Creates a new color button. This returns a widget in the form of
347 * a small button containing a swatch representing the current selected
348 * color. When the button is clicked, a color-selection dialog will open,
349 * allowing the user to select a color. The swatch will be updated to reflect
350 * the new color when the user finishes.
352 * Return value: a new color button.
355 hildon_color_button_new(void)
357 return g_object_new( HILDON_TYPE_COLOR_BUTTON, NULL );
361 * hildon_color_button_new_with_color:
362 * @color: A #GdkColor to set the current color with.
364 * Creates a new color button.
366 * Return value: a new color button.
369 hildon_color_button_new_with_color(const GdkColor *color)
371 return g_object_new( HILDON_TYPE_COLOR_BUTTON, "color", color, NULL );
375 * hildon_color_button_set_color:
376 * @button: A #HildonColorButton
377 * @color: A color to be set
379 * Sets a color to the button.
382 hildon_color_button_set_color( HildonColorButton *button, GdkColor *color )
384 g_object_set( G_OBJECT(button), "color", color, NULL );
388 * hildon_color_button_get_color:
389 * @button: A #HildonColorButton
391 * Gets a color from the button.
393 * Return value: The color set to a current button.
396 hildon_color_button_get_color( HildonColorButton *button )
398 GdkColor *color = NULL;
399 g_object_get( G_OBJECT(button), "color", &color, NULL );