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>
42 #include "hildon-color-button.h"
43 #include "hildon-color-selector.h"
45 #define HILDON_COLOR_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE\
46 ((obj), HILDON_TYPE_COLOR_BUTTON, HildonColorButtonPrivate))
48 #define COLOR_FILLED_HEIGHT 22
49 #define COLOR_FILLED_WIDTH 22
50 #define COLOR_BUTTON_WIDTH 48
51 #define COLOR_BUTTON_HEIGHT 40
53 /* the outer border color */
54 #define OUTER_BORDER_RED 0
55 #define OUTER_BORDER_BLUE 0
56 #define OUTER_BORDER_GREEN 0
57 #define OUTER_BORDER_THICKNESS 1
59 /* the inner border color */
60 #define INNER_BORDER_RED 65535
61 #define INNER_BORDER_BLUE 65535
62 #define INNER_BORDER_GREEN 65535
63 #define INNER_BORDER_THICKNESS 1
65 struct _HildonColorButtonPrivate
80 hildon_color_button_class_init(HildonColorButtonClass *klass);
82 hildon_color_button_init(HildonColorButton *color_button);
85 hildon_color_button_finalize(GObject *object);
87 hildon_color_button_set_property(GObject *object, guint param_id,
88 const GValue *value, GParamSpec *pspec);
90 hildon_color_button_get_property(GObject *object, guint param_id,
91 GValue *value, GParamSpec *pspec);
93 hildon_color_button_realize(GtkWidget *widget);
95 hildon_color_button_unrealize(GtkWidget *widget);
97 hildon_color_button_clicked(GtkButton *button);
99 hildon_color_field_expose_event(GtkWidget *widget, GdkEventExpose *event,
100 HildonColorButton *cb);
103 hildon_color_button_mnemonic_activate( GtkWidget *widget,
104 gboolean group_cycling );
107 static gpointer parent_class = NULL;
110 hildon_color_button_get_type(void)
112 static GType color_button_type = 0;
114 if (!color_button_type)
116 static const GTypeInfo color_button_info =
118 sizeof (HildonColorButtonClass),
119 NULL, /* base_init */
120 NULL, /* base_finalize */
121 (GClassInitFunc) hildon_color_button_class_init,
122 NULL, /* class_finalize */
123 NULL, /* class_data */
124 sizeof (HildonColorButton),
126 (GInstanceInitFunc) hildon_color_button_init,
130 g_type_register_static (GTK_TYPE_BUTTON, "HildonColorButton",
131 &color_button_info, 0);
134 return color_button_type;
138 hildon_color_button_class_init(HildonColorButtonClass *klass)
140 GObjectClass *gobject_class;
141 GtkButtonClass *button_class;
142 GtkWidgetClass *widget_class;
144 gobject_class = G_OBJECT_CLASS (klass);
145 button_class = GTK_BUTTON_CLASS (klass);
146 widget_class = GTK_WIDGET_CLASS (klass);
148 parent_class = g_type_class_peek_parent (klass);
150 gobject_class->get_property = hildon_color_button_get_property;
151 gobject_class->set_property = hildon_color_button_set_property;
152 gobject_class->finalize = hildon_color_button_finalize;
153 widget_class->realize = hildon_color_button_realize;
154 widget_class->unrealize = hildon_color_button_unrealize;
155 button_class->clicked = hildon_color_button_clicked;
156 widget_class->mnemonic_activate = hildon_color_button_mnemonic_activate;
159 * HildonColorButton:color:
161 * The selected color.
163 g_object_class_install_property (gobject_class, PROP_COLOR,
164 g_param_spec_boxed ("color",
166 "The selected color",
170 g_type_class_add_private (gobject_class, sizeof (HildonColorButtonPrivate));
173 /* Handle exposure events for the color picker's drawing area */
175 hildon_color_field_expose_event(GtkWidget *widget, GdkEventExpose *event,
176 HildonColorButton *cb)
178 GdkColor outer_border, inner_border;
180 /* Create the outer border color */
181 outer_border.pixel = 0;
182 outer_border.red = OUTER_BORDER_RED;
183 outer_border.blue = OUTER_BORDER_BLUE;
184 outer_border.green = OUTER_BORDER_GREEN;
186 /* Create the inner border color */
187 inner_border.pixel = 0;
188 inner_border.red = INNER_BORDER_RED;
189 inner_border.blue = INNER_BORDER_BLUE;
190 inner_border.green = INNER_BORDER_GREEN;
192 /* serve the outer border color to the Graphic Context */
193 gdk_gc_set_rgb_fg_color(cb->priv->gc, &outer_border);
194 /* draw the outer border as a filled rectangle */
195 gdk_draw_rectangle(widget->window,
203 /* serve the inner border color to the Graphic Context */
204 gdk_gc_set_rgb_fg_color(cb->priv->gc, &inner_border);
205 /* draw the inner border as a filled rectangle */
206 gdk_draw_rectangle(widget->window,
209 event->area.x + OUTER_BORDER_THICKNESS,
210 event->area.y + OUTER_BORDER_THICKNESS,
211 event->area.width - (OUTER_BORDER_THICKNESS*2),
212 event->area.height - (OUTER_BORDER_THICKNESS*2));
214 /* serve the actual color to the Graphic Context */
215 gdk_gc_set_rgb_fg_color(cb->priv->gc, &cb->priv->color);
216 /* draw the actual rectangle */
217 gdk_draw_rectangle(widget->window,
220 event->area.x + (INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS),
221 event->area.y + (INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS),
222 event->area.height - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2),
223 event->area.width - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2));
229 hildon_color_button_init(HildonColorButton *cb)
232 GtkWidget *drawing_area;
234 cb->priv = HILDON_COLOR_BUTTON_GET_PRIVATE(cb);
236 cb->priv->dialog = NULL;
239 gtk_widget_push_composite_child();
241 /* create widgets and pixbuf */
242 align = gtk_alignment_new(0.5, 0.5, 0, 0); /*composite widget*/
244 drawing_area = gtk_drawing_area_new(); /*composite widget*/
246 /* setting minimum sizes */
247 gtk_widget_set_size_request(GTK_WIDGET(cb), COLOR_BUTTON_WIDTH,
248 COLOR_BUTTON_HEIGHT);
249 gtk_widget_set_size_request(GTK_WIDGET(drawing_area),
250 COLOR_FILLED_WIDTH, COLOR_FILLED_HEIGHT);
252 /* Connect the callback function for exposure event */
253 g_signal_connect(drawing_area, "expose-event",
254 G_CALLBACK(hildon_color_field_expose_event), cb);
257 gtk_container_add(GTK_CONTAINER(align), drawing_area);
258 gtk_container_add(GTK_CONTAINER(cb), align);
260 gtk_widget_show_all(align);
262 gtk_widget_pop_composite_child();
265 /* Free memory used by HildonColorButton */
267 hildon_color_button_finalize(GObject *object)
269 HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
271 if (cb->priv->dialog)
273 gtk_widget_destroy(cb->priv->dialog);
274 cb->priv->dialog = NULL;
277 if( G_OBJECT_CLASS(parent_class)->finalize )
278 G_OBJECT_CLASS(parent_class)->finalize(object);
282 hildon_color_button_realize(GtkWidget *widget)
284 HildonColorButton *cb = HILDON_COLOR_BUTTON(widget);
286 GTK_WIDGET_CLASS(parent_class)->realize(widget);
288 cb->priv->gc = gdk_gc_new(widget->window);
292 hildon_color_button_unrealize(GtkWidget *widget)
294 HildonColorButton *cb = HILDON_COLOR_BUTTON(widget);
296 g_object_unref(cb->priv->gc);
299 GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
302 /* Make the widget sensitive with the keyboard event */
304 hildon_color_button_mnemonic_activate( GtkWidget *widget,
305 gboolean group_cycling )
307 gtk_widget_grab_focus( widget );
311 /* Popup a color selector dialog on button click */
313 hildon_color_button_clicked(GtkButton *button)
315 HildonColorButton *cb = HILDON_COLOR_BUTTON(button);
316 HildonColorSelector *cs_dialog = HILDON_COLOR_SELECTOR(cb->priv->dialog);
318 /* Popup the color selector dialog */
321 /* The dialog hasn't been created yet, do it. */
322 GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(cb));
323 cb->priv->dialog = hildon_color_selector_new(GTK_WINDOW(parent));
324 cs_dialog = HILDON_COLOR_SELECTOR(cb->priv->dialog);
327 gtk_window_set_transient_for(GTK_WINDOW(cs_dialog), GTK_WINDOW(parent));
330 /* Set the initial color for the color selector dialog */
331 hildon_color_selector_set_color(cs_dialog, &cb->priv->color);
333 /* Update the color for color button if selection was made */
334 if (gtk_dialog_run(GTK_DIALOG(cs_dialog)) == GTK_RESPONSE_OK)
336 cb->priv->color = *hildon_color_selector_get_color(cs_dialog);
337 hildon_color_button_set_color( HILDON_COLOR_BUTTON( button ),
338 &(cb->priv->color) );
340 gtk_widget_hide(GTK_WIDGET(cs_dialog));
343 /* Set_property function for HildonColorButtonClass initialization */
345 hildon_color_button_set_property(GObject *object, guint param_id,
346 const GValue *value, GParamSpec *pspec)
348 HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
353 cb->priv->color = *(GdkColor*)g_value_get_boxed(value);
354 gtk_widget_queue_draw(GTK_WIDGET(cb));
357 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
362 /* Get_property function for HildonColorButtonClass initialization */
364 hildon_color_button_get_property(GObject *object, guint param_id,
365 GValue *value, GParamSpec *pspec)
367 HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
372 g_value_set_boxed(value, &cb->priv->color);
375 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
381 * hildon_color_button_new:
383 * Creates a new color button. This returns a widget in the form of a
384 * small button containing a swatch representing the selected color.
385 * When the button is clicked, a color-selection dialog will open,
386 * allowing the user to select a color. The swatch will be updated to
387 * reflect the new color when the user finishes.
389 * Returns: a new color button
392 hildon_color_button_new(void)
394 return g_object_new( HILDON_TYPE_COLOR_BUTTON, NULL );
398 * hildon_color_button_new_with_color:
399 * @color: a #GdkColor for the initial color
401 * Creates a new color button with @color as the initial color.
403 * Returns: a new color button
406 hildon_color_button_new_with_color(const GdkColor *color)
408 return g_object_new( HILDON_TYPE_COLOR_BUTTON, "color", color, NULL );
412 * hildon_color_button_set_color:
413 * @button: a #HildonColorButton
414 * @color: a color to be set
416 * Sets the color selected by the button.
419 hildon_color_button_set_color( HildonColorButton *button, GdkColor *color )
421 g_object_set( G_OBJECT(button), "color", color, NULL );
425 * hildon_color_button_get_color:
426 * @button: a #HildonColorButton
428 * Returns: the color selected by the button
431 hildon_color_button_get_color( HildonColorButton *button )
433 GdkColor *color = NULL;
434 g_object_get( G_OBJECT(button), "color", &color, NULL );