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 <gtk/gtkbutton.h>
28 #include <gtk/gtkalignment.h>
29 #include <gtk/gtkdrawingarea.h>
30 #include <gtk/gtksignal.h>
32 #include "hildon-color-button.h"
33 #include "hildon-color-selector.h"
35 #define HILDON_COLOR_BUTTON_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE\
36 ((obj), HILDON_TYPE_COLOR_BUTTON, HildonColorButtonPrivate))
38 #define COLOR_FILLED_HEIGHT 22
39 #define COLOR_FILLED_WIDTH 22
40 #define COLOR_BUTTON_WIDTH 48
41 #define COLOR_BUTTON_HEIGHT 40
43 /* the outer border color */
44 #define OUTER_BORDER_RED 0
45 #define OUTER_BORDER_BLUE 0
46 #define OUTER_BORDER_GREEN 0
47 #define OUTER_BORDER_THICKNESS 1
49 /* the inner border color */
50 #define INNER_BORDER_RED 65535
51 #define INNER_BORDER_BLUE 65535
52 #define INNER_BORDER_GREEN 65535
53 #define INNER_BORDER_THICKNESS 1
55 struct _HildonColorButtonPrivate
70 hildon_color_button_class_init(HildonColorButtonClass *klass);
72 hildon_color_button_init(HildonColorButton *color_button);
75 hildon_color_button_finalize(GObject *object);
77 hildon_color_button_set_property(GObject *object, guint param_id,
78 const GValue *value, GParamSpec *pspec);
80 hildon_color_button_get_property(GObject *object, guint param_id,
81 GValue *value, GParamSpec *pspec);
83 hildon_color_button_realize(GtkWidget *widget);
85 hildon_color_button_unrealize(GtkWidget *widget);
87 hildon_color_button_clicked(GtkButton *button);
89 hildon_color_field_expose_event(GtkWidget *widget, GdkEventExpose *event,
90 HildonColorButton *cb);
93 hildon_color_button_mnemonic_activate( GtkWidget *widget,
94 gboolean group_cycling );
97 static gpointer parent_class = NULL;
100 hildon_color_button_get_type(void)
102 static GType color_button_type = 0;
104 if (!color_button_type)
106 static const GTypeInfo color_button_info =
108 sizeof (HildonColorButtonClass),
109 NULL, /* base_init */
110 NULL, /* base_finalize */
111 (GClassInitFunc) hildon_color_button_class_init,
112 NULL, /* class_finalize */
113 NULL, /* class_data */
114 sizeof (HildonColorButton),
116 (GInstanceInitFunc) hildon_color_button_init,
120 g_type_register_static (GTK_TYPE_BUTTON, "HildonColorButton",
121 &color_button_info, 0);
124 return color_button_type;
128 hildon_color_button_class_init(HildonColorButtonClass *klass)
130 GObjectClass *gobject_class;
131 GtkButtonClass *button_class;
132 GtkWidgetClass *widget_class;
134 gobject_class = G_OBJECT_CLASS (klass);
135 button_class = GTK_BUTTON_CLASS (klass);
136 widget_class = GTK_WIDGET_CLASS (klass);
138 parent_class = g_type_class_peek_parent (klass);
140 gobject_class->get_property = hildon_color_button_get_property;
141 gobject_class->set_property = hildon_color_button_set_property;
142 gobject_class->finalize = hildon_color_button_finalize;
143 widget_class->realize = hildon_color_button_realize;
144 widget_class->unrealize = hildon_color_button_unrealize;
145 button_class->clicked = hildon_color_button_clicked;
146 widget_class->mnemonic_activate = hildon_color_button_mnemonic_activate;
149 * HildonColorButton:color:
151 * The selected color.
153 g_object_class_install_property (gobject_class, PROP_COLOR,
154 g_param_spec_boxed ("color",
156 "The selected color",
160 g_type_class_add_private (gobject_class, sizeof (HildonColorButtonPrivate));
163 /* Handle exposure events for the color picker's drawing area */
165 hildon_color_field_expose_event(GtkWidget *widget, GdkEventExpose *event,
166 HildonColorButton *cb)
168 GdkColor outer_border, inner_border;
170 /* Create the outer border color */
171 outer_border.pixel = 0;
172 outer_border.red = OUTER_BORDER_RED;
173 outer_border.blue = OUTER_BORDER_BLUE;
174 outer_border.green = OUTER_BORDER_GREEN;
176 /* Create the inner border color */
177 inner_border.pixel = 0;
178 inner_border.red = INNER_BORDER_RED;
179 inner_border.blue = INNER_BORDER_BLUE;
180 inner_border.green = INNER_BORDER_GREEN;
182 /* serve the outer border color to the Graphic Context */
183 gdk_gc_set_rgb_fg_color(cb->priv->gc, &outer_border);
184 /* draw the outer border as a filled rectangle */
185 gdk_draw_rectangle(widget->window,
193 /* serve the inner border color to the Graphic Context */
194 gdk_gc_set_rgb_fg_color(cb->priv->gc, &inner_border);
195 /* draw the inner border as a filled rectangle */
196 gdk_draw_rectangle(widget->window,
199 event->area.x + OUTER_BORDER_THICKNESS,
200 event->area.y + OUTER_BORDER_THICKNESS,
201 event->area.width - (OUTER_BORDER_THICKNESS*2),
202 event->area.height - (OUTER_BORDER_THICKNESS*2));
204 /* serve the actual color to the Graphic Context */
205 gdk_gc_set_rgb_fg_color(cb->priv->gc, &cb->priv->color);
206 /* draw the actual rectangle */
207 gdk_draw_rectangle(widget->window,
210 event->area.x + (INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS),
211 event->area.y + (INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS),
212 event->area.height - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2),
213 event->area.width - ((INNER_BORDER_THICKNESS + OUTER_BORDER_THICKNESS)*2));
219 hildon_color_button_init(HildonColorButton *cb)
222 GtkWidget *drawing_area;
224 cb->priv = HILDON_COLOR_BUTTON_GET_PRIVATE(cb);
226 cb->priv->dialog = NULL;
229 gtk_widget_push_composite_child();
231 /* create widgets and pixbuf */
232 align = gtk_alignment_new(0.5, 0.5, 0, 0); /*composite widget*/
234 drawing_area = gtk_drawing_area_new(); /*composite widget*/
236 /* setting minimum sizes */
237 gtk_widget_set_size_request(GTK_WIDGET(cb), COLOR_BUTTON_WIDTH,
238 COLOR_BUTTON_HEIGHT);
239 gtk_widget_set_size_request(GTK_WIDGET(drawing_area),
240 COLOR_FILLED_WIDTH, COLOR_FILLED_HEIGHT);
242 /* Connect the callback function for exposure event */
243 g_signal_connect(drawing_area, "expose-event",
244 G_CALLBACK(hildon_color_field_expose_event), cb);
247 gtk_container_add(GTK_CONTAINER(align), drawing_area);
248 gtk_container_add(GTK_CONTAINER(cb), align);
250 gtk_widget_show_all(align);
252 gtk_widget_pop_composite_child();
255 /* Free memory used by HildonColorButton */
257 hildon_color_button_finalize(GObject *object)
259 HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
261 if (cb->priv->dialog)
263 gtk_widget_destroy(cb->priv->dialog);
264 cb->priv->dialog = NULL;
267 if( G_OBJECT_CLASS(parent_class)->finalize )
268 G_OBJECT_CLASS(parent_class)->finalize(object);
272 hildon_color_button_realize(GtkWidget *widget)
274 HildonColorButton *cb = HILDON_COLOR_BUTTON(widget);
276 GTK_WIDGET_CLASS(parent_class)->realize(widget);
278 cb->priv->gc = gdk_gc_new(widget->window);
282 hildon_color_button_unrealize(GtkWidget *widget)
284 HildonColorButton *cb = HILDON_COLOR_BUTTON(widget);
286 g_object_unref(cb->priv->gc);
289 GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
292 /* Make the widget sensitive with the keyboard event */
294 hildon_color_button_mnemonic_activate( GtkWidget *widget,
295 gboolean group_cycling )
297 gtk_widget_grab_focus( widget );
301 /* Popup a color selector dialog on button click */
303 hildon_color_button_clicked(GtkButton *button)
305 HildonColorButton *cb = HILDON_COLOR_BUTTON(button);
306 HildonColorSelector *cs_dialog = HILDON_COLOR_SELECTOR(cb->priv->dialog);
308 /* Popup the color selector dialog */
311 /* The dialog hasn't been created yet, do it. */
312 GtkWidget *parent = gtk_widget_get_toplevel(GTK_WIDGET(cb));
313 cb->priv->dialog = hildon_color_selector_new(GTK_WINDOW(parent));
314 cs_dialog = HILDON_COLOR_SELECTOR(cb->priv->dialog);
317 gtk_window_set_transient_for(GTK_WINDOW(cs_dialog), GTK_WINDOW(parent));
320 /* Set the initial color for the color selector dialog */
321 hildon_color_selector_set_color(cs_dialog, &cb->priv->color);
323 /* Update the color for color button if selection was made */
324 if (gtk_dialog_run(GTK_DIALOG(cs_dialog)) == GTK_RESPONSE_OK)
326 cb->priv->color = *hildon_color_selector_get_color(cs_dialog);
327 hildon_color_button_set_color( HILDON_COLOR_BUTTON( button ),
328 &(cb->priv->color) );
330 gtk_widget_hide(GTK_WIDGET(cs_dialog));
333 /* Set_property function for HildonColorButtonClass initialization */
335 hildon_color_button_set_property(GObject *object, guint param_id,
336 const GValue *value, GParamSpec *pspec)
338 HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
343 cb->priv->color = *(GdkColor*)g_value_get_boxed(value);
344 gtk_widget_queue_draw(GTK_WIDGET(cb));
347 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
352 /* Get_property function for HildonColorButtonClass initialization */
354 hildon_color_button_get_property(GObject *object, guint param_id,
355 GValue *value, GParamSpec *pspec)
357 HildonColorButton *cb = HILDON_COLOR_BUTTON(object);
362 g_value_set_boxed(value, &cb->priv->color);
365 G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
371 * hildon_color_button_new:
373 * Creates a new color button. This returns a widget in the form of
374 * a small button containing a swatch representing the current selected
375 * color. When the button is clicked, a color-selection dialog will open,
376 * allowing the user to select a color. The swatch will be updated to reflect
377 * the new color when the user finishes.
379 * Return value: a new color button.
382 hildon_color_button_new(void)
384 return g_object_new( HILDON_TYPE_COLOR_BUTTON, NULL );
388 * hildon_color_button_new_with_color:
389 * @color: A #GdkColor to set the current color with.
391 * Creates a new color button.
393 * Return value: a new color button.
396 hildon_color_button_new_with_color(const GdkColor *color)
398 return g_object_new( HILDON_TYPE_COLOR_BUTTON, "color", color, NULL );
402 * hildon_color_button_set_color:
403 * @button: A #HildonColorButton
404 * @color: A color to be set
406 * Sets a color to the button.
409 hildon_color_button_set_color( HildonColorButton *button, GdkColor *color )
411 g_object_set( G_OBJECT(button), "color", color, NULL );
415 * hildon_color_button_get_color:
416 * @button: A #HildonColorButton
418 * Gets a color from the button.
420 * Return value: The color set to a current button.
423 hildon_color_button_get_color( HildonColorButton *button )
425 GdkColor *color = NULL;
426 g_object_get( G_OBJECT(button), "color", &color, NULL );