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
26 * SECTION:hildon-color-button
27 * @short_description: A widget to open HildonColorSelector
28 * @see_also: #HildonColorSelector, #HildonColorPopup
30 * HildonColorButton is a widget to open a HildonColorSelector.
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-selector.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_released(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 g_signal_connect(G_OBJECT(cb), "key-release-event",
264 G_CALLBACK(hildon_color_button_key_released), cb);
267 gtk_container_add(GTK_CONTAINER(align), drawing_area);
268 gtk_container_add(GTK_CONTAINER(cb), align);
270 gtk_widget_add_events(GTK_WIDGET(cb), GDK_KEY_RELEASE_MASK);
272 gtk_widget_show_all(align);
274 gtk_widget_pop_composite_child();
277 /* Free memory used by HildonColorButton */
279 hildon_color_button_finalize(GObject *object)
281 HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
283 if (cb->priv->dialog)
285 gtk_widget_destroy(cb->priv->dialog);
286 cb->priv->dialog = NULL;
289 if( G_OBJECT_CLASS(parent_class)->finalize )
290 G_OBJECT_CLASS(parent_class)->finalize(object);
294 hildon_color_button_realize(GtkWidget *widget)
296 HildonColorButton *cb = HILDON_COLOR_BUTTON(widget);
298 GTK_WIDGET_CLASS(parent_class)->realize(widget);
300 cb->priv->gc = gdk_gc_new(widget->window);
304 hildon_color_button_unrealize(GtkWidget *widget)
306 HildonColorButton *cb = HILDON_COLOR_BUTTON(widget);
308 g_object_unref(cb->priv->gc);
311 GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
314 /* Make the widget sensitive with the keyboard event */
316 hildon_color_button_mnemonic_activate( GtkWidget *widget,
317 gboolean group_cycling )
319 gtk_widget_grab_focus( widget );
323 /* Popup a color selector dialog on button click */
325 hildon_color_button_clicked(GtkButton *button)
327 HildonColorButton *cb = HILDON_COLOR_BUTTON(button);
328 HildonColorSelector *cs_dialog = HILDON_COLOR_SELECTOR(cb->priv->dialog);
330 /* Popup the color selector dialog */
333 /* The dialog hasn't been created yet, do it. */
334 GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(cb));
335 cb->priv->dialog = hildon_color_selector_new(GTK_WINDOW(parent));
336 cs_dialog = HILDON_COLOR_SELECTOR(cb->priv->dialog);
339 gtk_window_set_transient_for(GTK_WINDOW(cs_dialog), GTK_WINDOW(parent));
342 /* Set the initial color for the color selector dialog */
343 hildon_color_selector_set_color(cs_dialog, &cb->priv->color);
345 /* Update the color for color button if selection was made */
346 if (gtk_dialog_run(GTK_DIALOG(cs_dialog)) == GTK_RESPONSE_OK)
348 cb->priv->color = *hildon_color_selector_get_color(cs_dialog);
349 hildon_color_button_set_color( HILDON_COLOR_BUTTON( button ),
350 &(cb->priv->color) );
352 gtk_widget_hide(GTK_WIDGET(cs_dialog));
355 /* Popup a color selector dialog on hardkey Select release */
357 hildon_color_button_key_released(GtkWidget * button,
361 g_return_val_if_fail (HILDON_IS_COLOR_BUTTON(button), FALSE);
363 if (event->keyval == HILDON_HARDKEY_SELECT)
364 hildon_color_button_clicked(GTK_BUTTON(button));
368 /* Set_property function for HildonColorButtonClass initialization */
370 hildon_color_button_set_property(GObject *object, guint param_id,
371 const GValue *value, GParamSpec *pspec)
373 HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
378 cb->priv->color = *(GdkColor*)g_value_get_boxed(value);
379 gtk_widget_queue_draw(GTK_WIDGET(cb));
382 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
387 /* Get_property function for HildonColorButtonClass initialization */
389 hildon_color_button_get_property(GObject *object, guint param_id,
390 GValue *value, GParamSpec *pspec)
392 HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
397 g_value_set_boxed(value, &cb->priv->color);
400 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
406 * hildon_color_button_new:
408 * Creates a new color button. This returns a widget in the form of a
409 * small button containing a swatch representing the selected color.
410 * When the button is clicked, a color-selection dialog will open,
411 * allowing the user to select a color. The swatch will be updated to
412 * reflect the new color when the user finishes.
414 * Returns: a new color button
417 hildon_color_button_new(void)
419 return g_object_new( HILDON_TYPE_COLOR_BUTTON, NULL );
423 * hildon_color_button_new_with_color:
424 * @color: a #GdkColor for the initial color
426 * Creates a new color button with @color as the initial color.
428 * Returns: a new color button
431 hildon_color_button_new_with_color(const GdkColor *color)
433 return g_object_new( HILDON_TYPE_COLOR_BUTTON, "color", color, NULL );
437 * hildon_color_button_set_color:
438 * @button: a #HildonColorButton
439 * @color: a color to be set
441 * Sets the color selected by the button.
444 hildon_color_button_set_color( HildonColorButton *button, GdkColor *color )
446 g_object_set( G_OBJECT(button), "color", color, NULL );
450 * hildon_color_button_get_color:
451 * @button: a #HildonColorButton
453 * Returns: the color selected by the button
456 hildon_color_button_get_color( HildonColorButton *button )
458 GdkColor *color = NULL;
459 g_object_get( G_OBJECT(button), "color", &color, NULL );