2 * This file is part of hildon-libs
4 * Copyright (C) 2005, 2006 Nokia Corporation.
6 * Contact: Michael Dominic Kostrzewa <michael.kostrzewa@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; version 2.1 of
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
26 * SECTION:hildon-color-button
27 * @short_description: A widget to open HildonColorChooserDialog
28 * @see_also: #HildonColorChooserDialog, #HildonColorPopup
30 * HildonColorButton is a widget to open a HildonColorChooserDialog.
31 * The selected color is shown in the button.
32 * The selected color is a property of the button.
33 * The property name is "color" and its type is GtkColor.
37 #include <gtk/gtkbutton.h>
38 #include <gtk/gtkalignment.h>
39 #include <gtk/gtkdrawingarea.h>
40 #include <gtk/gtksignal.h>
41 #include <gdk/gdkkeysyms.h>
42 #include <hildon-widgets/hildon-defines.h>
44 #include "hildon-color-button.h"
45 #include "hildon-color-chooser-dialog.h"
47 #define HILDON_COLOR_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE\
48 ((obj), HILDON_TYPE_COLOR_BUTTON, HildonColorButtonPrivate))
50 #define COLOR_FILLED_HEIGHT 22
51 #define COLOR_FILLED_WIDTH 22
53 #define COLOR_BUTTON_WIDTH 52
54 #define COLOR_BUTTON_HEIGHT 48
56 /* the outer border color */
57 #define OUTER_BORDER_RED 0
58 #define OUTER_BORDER_BLUE 0
59 #define OUTER_BORDER_GREEN 0
60 #define OUTER_BORDER_THICKNESS 1
62 /* the inner border color */
63 #define INNER_BORDER_RED 65535
64 #define INNER_BORDER_BLUE 65535
65 #define INNER_BORDER_GREEN 65535
66 #define INNER_BORDER_THICKNESS 2
68 struct _HildonColorButtonPrivate
83 hildon_color_button_class_init(HildonColorButtonClass *klass);
85 hildon_color_button_init(HildonColorButton *color_button);
88 hildon_color_button_finalize(GObject *object);
90 hildon_color_button_set_property(GObject *object, guint param_id,
91 const GValue *value, GParamSpec *pspec);
93 hildon_color_button_get_property(GObject *object, guint param_id,
94 GValue *value, GParamSpec *pspec);
96 hildon_color_button_realize(GtkWidget *widget);
98 hildon_color_button_unrealize(GtkWidget *widget);
100 hildon_color_button_clicked(GtkButton *button);
102 hildon_color_button_key_pressed(GtkWidget * button,
106 hildon_color_field_expose_event(GtkWidget *widget, GdkEventExpose *event,
107 HildonColorButton *cb);
110 hildon_color_button_mnemonic_activate( GtkWidget *widget,
111 gboolean group_cycling );
114 static gpointer parent_class = NULL;
117 hildon_color_button_get_type(void)
119 static GType color_button_type = 0;
121 if (!color_button_type)
123 static const GTypeInfo color_button_info =
125 sizeof (HildonColorButtonClass),
126 NULL, /* base_init */
127 NULL, /* base_finalize */
128 (GClassInitFunc) hildon_color_button_class_init,
129 NULL, /* class_finalize */
130 NULL, /* class_data */
131 sizeof (HildonColorButton),
133 (GInstanceInitFunc) hildon_color_button_init,
137 g_type_register_static (GTK_TYPE_BUTTON, "HildonColorButton",
138 &color_button_info, 0);
141 return color_button_type;
145 hildon_color_button_class_init(HildonColorButtonClass *klass)
147 GObjectClass *gobject_class;
148 GtkButtonClass *button_class;
149 GtkWidgetClass *widget_class;
151 gobject_class = G_OBJECT_CLASS (klass);
152 button_class = GTK_BUTTON_CLASS (klass);
153 widget_class = GTK_WIDGET_CLASS (klass);
155 parent_class = g_type_class_peek_parent (klass);
157 gobject_class->get_property = hildon_color_button_get_property;
158 gobject_class->set_property = hildon_color_button_set_property;
159 gobject_class->finalize = hildon_color_button_finalize;
160 widget_class->realize = hildon_color_button_realize;
161 widget_class->unrealize = hildon_color_button_unrealize;
162 button_class->clicked = hildon_color_button_clicked;
163 widget_class->mnemonic_activate = hildon_color_button_mnemonic_activate;
166 * HildonColorButton:color:
168 * The selected color.
170 g_object_class_install_property (gobject_class, PROP_COLOR,
171 g_param_spec_boxed ("color",
173 "The selected color",
177 g_type_class_add_private (gobject_class, sizeof (HildonColorButtonPrivate));
180 /* Handle exposure events for the color picker's drawing area */
182 hildon_color_field_expose_event(GtkWidget *widget, GdkEventExpose *event,
183 HildonColorButton *cb)
185 GdkColor outer_border, inner_border;
187 /* Create the outer border color */
188 outer_border.pixel = 0;
189 outer_border.red = OUTER_BORDER_RED;
190 outer_border.blue = OUTER_BORDER_BLUE;
191 outer_border.green = OUTER_BORDER_GREEN;
193 /* Create the inner border color */
194 inner_border.pixel = 0;
195 inner_border.red = INNER_BORDER_RED;
196 inner_border.blue = INNER_BORDER_BLUE;
197 inner_border.green = INNER_BORDER_GREEN;
199 /* serve the outer border color to the Graphic Context */
200 gdk_gc_set_rgb_fg_color(cb->priv->gc, &outer_border);
201 /* draw the outer border as a filled rectangle */
202 gdk_draw_rectangle(widget->window,
210 /* serve the inner border color to the Graphic Context */
211 gdk_gc_set_rgb_fg_color(cb->priv->gc, &inner_border);
212 /* draw the inner border as a filled rectangle */
213 gdk_draw_rectangle(widget->window,
216 event->area.x + OUTER_BORDER_THICKNESS,
217 event->area.y + OUTER_BORDER_THICKNESS,
218 event->area.width - (OUTER_BORDER_THICKNESS*2),
219 event->area.height - (OUTER_BORDER_THICKNESS*2));
221 /* serve the actual color to the Graphic Context */
222 gdk_gc_set_rgb_fg_color(cb->priv->gc, &cb->priv->color);
223 /* draw the actual rectangle */
224 gdk_draw_rectangle(widget->window,
227 event->area.x + (INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS),
228 event->area.y + (INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS),
229 event->area.width - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2),
230 event->area.height - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2));
236 hildon_color_button_init(HildonColorButton *cb)
239 GtkWidget *drawing_area;
241 cb->priv = HILDON_COLOR_BUTTON_GET_PRIVATE(cb);
243 cb->priv->dialog = NULL;
246 gtk_widget_push_composite_child();
248 /* create widgets and pixbuf */
249 align = gtk_alignment_new(0.5, 0.5, 0, 0); /*composite widget*/
251 drawing_area = gtk_drawing_area_new(); /*composite widget*/
253 /* setting minimum sizes */
254 gtk_widget_set_size_request(GTK_WIDGET(cb), COLOR_BUTTON_WIDTH,
255 COLOR_BUTTON_HEIGHT);
256 gtk_widget_set_size_request(GTK_WIDGET(drawing_area),
257 COLOR_FILLED_WIDTH, COLOR_FILLED_HEIGHT);
259 /* Connect the callback function for exposure event */
260 g_signal_connect(drawing_area, "expose-event",
261 G_CALLBACK(hildon_color_field_expose_event), cb);
263 /* Connect to callback function for key press event */
264 g_signal_connect(G_OBJECT(cb), "key-press-event",
265 G_CALLBACK(hildon_color_button_key_pressed), cb);
268 gtk_container_add(GTK_CONTAINER(align), drawing_area);
269 gtk_container_add(GTK_CONTAINER(cb), align);
271 gtk_widget_show_all(align);
273 gtk_widget_pop_composite_child();
276 /* Free memory used by HildonColorButton */
278 hildon_color_button_finalize(GObject *object)
280 HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
282 if (cb->priv->dialog)
284 gtk_widget_destroy(cb->priv->dialog);
285 cb->priv->dialog = NULL;
288 if( G_OBJECT_CLASS(parent_class)->finalize )
289 G_OBJECT_CLASS(parent_class)->finalize(object);
293 hildon_color_button_realize(GtkWidget *widget)
295 HildonColorButton *cb = HILDON_COLOR_BUTTON(widget);
297 GTK_WIDGET_CLASS(parent_class)->realize(widget);
299 cb->priv->gc = gdk_gc_new(widget->window);
303 hildon_color_button_unrealize(GtkWidget *widget)
305 HildonColorButton *cb = HILDON_COLOR_BUTTON(widget);
307 g_object_unref(cb->priv->gc);
310 GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
313 /* Make the widget sensitive with the keyboard event */
315 hildon_color_button_mnemonic_activate( GtkWidget *widget,
316 gboolean group_cycling )
318 gtk_widget_grab_focus( widget );
322 /* Popup a color selector dialog on button click */
324 hildon_color_button_clicked(GtkButton *button)
326 HildonColorButton *cb = HILDON_COLOR_BUTTON(button);
327 HildonColorChooserDialog *cs_dialog = HILDON_COLOR_CHOOSER_DIALOG(cb->priv->dialog);
329 /* Popup the color selector dialog */
332 /* The dialog hasn't been created yet, do it. */
333 GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(cb));
334 cb->priv->dialog = hildon_color_chooser_dialog_new(GTK_WINDOW(parent));
335 cs_dialog = HILDON_COLOR_CHOOSER_DIALOG(cb->priv->dialog);
337 gtk_window_set_transient_for(GTK_WINDOW(cs_dialog), GTK_WINDOW(parent));
340 /* Set the initial color for the color selector dialog */
341 hildon_color_chooser_dialog_set_color(cs_dialog, &cb->priv->color);
343 /* Update the color for color button if selection was made */
344 if (gtk_dialog_run(GTK_DIALOG(cs_dialog)) == GTK_RESPONSE_OK)
346 hildon_color_chooser_dialog_get_color(cs_dialog, &cb->priv->color);
347 hildon_color_button_set_color( HILDON_COLOR_BUTTON( button ),
348 &(cb->priv->color) );
350 gtk_widget_hide(GTK_WIDGET(cs_dialog));
353 /* Popup a color selector dialog on hardkey Select press */
355 hildon_color_button_key_pressed(GtkWidget * button,
359 g_return_val_if_fail (HILDON_IS_COLOR_BUTTON(button), FALSE);
361 if (event->keyval == HILDON_HARDKEY_SELECT)
363 hildon_color_button_clicked(GTK_BUTTON(button));
370 /* Set_property function for HildonColorButtonClass initialization */
372 hildon_color_button_set_property(GObject *object, guint param_id,
373 const GValue *value, GParamSpec *pspec)
375 HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
380 cb->priv->color = *(GdkColor*)g_value_get_boxed(value);
381 gtk_widget_queue_draw(GTK_WIDGET(cb));
384 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
389 /* Get_property function for HildonColorButtonClass initialization */
391 hildon_color_button_get_property(GObject *object, guint param_id,
392 GValue *value, GParamSpec *pspec)
394 HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
399 g_value_set_boxed(value, &cb->priv->color);
402 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
408 * hildon_color_button_new:
410 * Creates a new color button. This returns a widget in the form of a
411 * small button containing a swatch representing the selected color.
412 * When the button is clicked, a color-selection dialog will open,
413 * allowing the user to select a color. The swatch will be updated to
414 * reflect the new color when the user finishes.
416 * Returns: a new color button
419 hildon_color_button_new(void)
421 return g_object_new( HILDON_TYPE_COLOR_BUTTON, NULL );
425 * hildon_color_button_new_with_color:
426 * @color: a #GdkColor for the initial color
428 * Creates a new color button with @color as the initial color.
430 * Returns: a new color button
433 hildon_color_button_new_with_color(const GdkColor *color)
435 return g_object_new( HILDON_TYPE_COLOR_BUTTON, "color", color, NULL );
439 * hildon_color_button_set_color:
440 * @button: a #HildonColorButton
441 * @color: a color to be set
443 * Sets the color selected by the button.
446 hildon_color_button_set_color( HildonColorButton *button, GdkColor *color )
448 g_object_set( G_OBJECT(button), "color", color, NULL );
452 * hildon_color_button_get_color:
453 * @button: a #HildonColorButton
455 * Returns: the color selected by the button
458 hildon_color_button_get_color( HildonColorButton *button )
460 GdkColor *color = NULL;
461 g_object_get( G_OBJECT(button), "color", &color, NULL );