3 * Copyright (C) 2008-2009 Jim Evins <evins@snaught.com>.
5 * This file is part of gLabels.
7 * gLabels is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
12 * gLabels is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with gLabels. If not, see <http://www.gnu.org/licenses/>.
23 #include "color-combo-button.h"
25 #include "color-combo-menu.h"
26 #include <glib/gi18n.h>
27 #include <gtk/gtktogglebutton.h>
28 #include <gtk/gtkvbox.h>
29 #include "color-swatch.h"
30 #include <gtk/gtkarrow.h>
41 /*========================================================*/
43 /*========================================================*/
45 /** GL_COLOR_COMBO_BUTTON Private fields */
46 struct _glColorComboButtonPrivate {
49 gboolean is_default_flag;
54 GtkWidget *button_vbox;
56 GtkWidget *dropdown_button;
67 /*========================================================*/
68 /* Private globals. */
69 /*========================================================*/
71 static guint signals[LAST_SIGNAL] = {0};
74 /*========================================================*/
75 /* Private function prototypes. */
76 /*========================================================*/
79 gl_color_combo_button_finalize (GObject *object);
82 button_clicked_cb (glColorComboButton *this);
85 dropdown_button_press_event_cb (GtkWidget *widget,
86 GdkEventButton *event,
87 glColorComboButton *this);
90 menu_color_changed_cb (glColorComboMenu *object,
93 glColorComboButton *this);
96 menu_selection_done_cb (GtkMenuShell *object,
97 glColorComboButton *this);
100 /*****************************************************************************/
101 /* Object infrastructure. */
102 /*****************************************************************************/
103 G_DEFINE_TYPE (glColorComboButton, gl_color_combo_button, GTK_TYPE_HBOX);
106 /*****************************************************************************/
107 /* Class Init Function. */
108 /*****************************************************************************/
110 gl_color_combo_button_class_init (glColorComboButtonClass *class)
112 GObjectClass *gobject_class = (GObjectClass *) class;
114 gl_color_combo_button_parent_class = g_type_class_peek_parent (class);
116 gobject_class->finalize = gl_color_combo_button_finalize;
118 signals[COLOR_CHANGED] =
119 g_signal_new ("color_changed",
120 G_OBJECT_CLASS_TYPE (gobject_class),
122 G_STRUCT_OFFSET (glColorComboButtonClass, color_changed),
124 gl_marshal_VOID__UINT_BOOLEAN,
126 2, G_TYPE_POINTER, G_TYPE_BOOLEAN);
131 /*****************************************************************************/
132 /* Object Instance Init Function. */
133 /*****************************************************************************/
135 gl_color_combo_button_init (glColorComboButton *this)
139 gtk_box_set_spacing (GTK_BOX (this), 0);
141 this->priv = g_new0 (glColorComboButtonPrivate, 1);
143 this->priv->button_vbox = gtk_vbox_new (FALSE, 0);
145 this->priv->button = gtk_toggle_button_new ();
146 gtk_container_add (GTK_CONTAINER (this->priv->button), this->priv->button_vbox);
147 gtk_button_set_focus_on_click (GTK_BUTTON (this->priv->button), FALSE);
148 g_signal_connect_swapped (this->priv->button, "clicked",
149 G_CALLBACK(button_clicked_cb), this);
151 gtk_box_pack_start (GTK_BOX (this), this->priv->button, FALSE, FALSE, 0);
153 this->priv->dropdown_button = gtk_toggle_button_new ();
154 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_IN);
155 gtk_container_add (GTK_CONTAINER (this->priv->dropdown_button), arrow);
156 gtk_button_set_relief (GTK_BUTTON (this->priv->dropdown_button), GTK_RELIEF_NONE);
157 gtk_button_set_focus_on_click (GTK_BUTTON (this->priv->dropdown_button), FALSE);
158 g_signal_connect (this->priv->dropdown_button, "button_press_event",
159 G_CALLBACK(dropdown_button_press_event_cb), this);
161 gtk_box_pack_start (GTK_BOX (this), this->priv->dropdown_button, FALSE, FALSE, 0);
165 /*****************************************************************************/
166 /* Finalize Method. */
167 /*****************************************************************************/
169 gl_color_combo_button_finalize (GObject *object)
171 glColorComboButton *this;
173 g_return_if_fail (object && IS_GL_COLOR_COMBO_BUTTON (object));
174 this = GL_COLOR_COMBO_BUTTON (object);
176 g_object_ref_sink (this->priv->menu);
179 G_OBJECT_CLASS (gl_color_combo_button_parent_class)->finalize (object);
183 /*****************************************************************************/
184 /** New Object Generator. */
185 /*****************************************************************************/
187 gl_color_combo_button_new (GdkPixbuf *icon,
188 const gchar *default_label,
192 glColorComboButton *this;
196 this = g_object_new (TYPE_GL_COLOR_COMBO_BUTTON, NULL);
200 default_label = _("Default Color");
203 this->priv->default_color = default_color;
204 this->priv->color = color;
208 pixbuf = gdk_pixbuf_new_subpixbuf (icon, 0, 0, IMAGE_W, IMAGE_H-SWATCH_H);
209 wimage = gtk_image_new_from_pixbuf (pixbuf);
210 g_object_unref (G_OBJECT (pixbuf));
211 gtk_box_pack_start (GTK_BOX (this->priv->button_vbox), wimage, FALSE, FALSE, 0);
213 this->priv->swatch = gl_color_swatch_new (IMAGE_W, SWATCH_H, color);
217 this->priv->swatch = gl_color_swatch_new (IMAGE_W, IMAGE_H, color);
219 gtk_box_pack_start (GTK_BOX (this->priv->button_vbox), this->priv->swatch, FALSE, FALSE, 0);
221 this->priv->menu = gl_color_combo_menu_new (default_label, color);
222 gtk_widget_show_all (this->priv->menu);
224 g_signal_connect (this->priv->menu, "color_changed",
225 G_CALLBACK (menu_color_changed_cb), this);
226 g_signal_connect (this->priv->menu, "selection_done",
227 G_CALLBACK (menu_selection_done_cb), this);
229 return GTK_WIDGET (this);
233 /*****************************************************************************/
235 /*****************************************************************************/
237 gl_color_combo_button_set_color (glColorComboButton *this,
240 this->priv->color = color;
242 gl_color_swatch_set_color (GL_COLOR_SWATCH (this->priv->swatch), color);
246 /*****************************************************************************/
247 /* Set to default color. */
248 /*****************************************************************************/
250 gl_color_combo_button_set_to_default (glColorComboButton *this)
252 gl_color_combo_button_set_color (this, this->priv->default_color);
255 /*****************************************************************************/
257 /*****************************************************************************/
259 gl_color_combo_button_get_color (glColorComboButton *this,
260 gboolean *is_default)
264 *is_default = this->priv->is_default_flag;
267 return this->priv->color;
271 /*****************************************************************************/
272 /** Set relief style. */
273 /*****************************************************************************/
275 gl_color_combo_button_set_relief( glColorComboButton *this,
276 GtkReliefStyle relief )
278 gtk_button_set_relief (GTK_BUTTON (this->priv->button), relief);
282 /*****************************************************************************/
283 /* Color button "clicked" callback. */
284 /*****************************************************************************/
286 button_clicked_cb( glColorComboButton *this )
288 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this->priv->button),
291 g_signal_emit (this, signals[COLOR_CHANGED], 0,
293 this->priv->is_default_flag);
297 /*****************************************************************************/
298 /* Menu positioning function. */
299 /*****************************************************************************/
301 menu_position_function (GtkMenu *menu,
307 glColorComboButton *this = GL_COLOR_COMBO_BUTTON (user_data);
311 gdk_window_get_origin (GTK_WIDGET (this)->window, &x1, &y1);
312 *x = x1 + GTK_WIDGET (this)->allocation.x;
313 *y = y1 + GTK_WIDGET (this)->allocation.y +
314 GTK_WIDGET (this)->allocation.height;
316 menu_h = this->priv->menu->allocation.height;
317 menu_w = this->priv->menu->allocation.width;
319 if ((*y + menu_h) > gdk_screen_height ())
321 *y = y1 + GTK_WIDGET (this)->allocation.y - menu_h;
324 *y = gdk_screen_height () - menu_h;
328 if ((*x + menu_w) > gdk_screen_width ())
330 *x = gdk_screen_width () - menu_w;
337 /*****************************************************************************/
338 /* Dropdown button "button_press_event" callback. */
339 /*****************************************************************************/
341 dropdown_button_press_event_cb (GtkWidget *widget,
342 GdkEventButton *event,
343 glColorComboButton *this)
345 switch (event->button)
349 g_signal_handlers_block_by_func (G_OBJECT (this->priv->button),
350 button_clicked_cb, this);
351 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this->priv->button),
353 g_signal_handlers_unblock_by_func (G_OBJECT (this->priv->button),
354 button_clicked_cb, this);
355 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this->priv->dropdown_button),
358 gtk_menu_popup (GTK_MENU (this->priv->menu),
360 menu_position_function, this,
361 event->button, event->time);
373 /*****************************************************************************/
374 /* Menu "color changed" callback. */
375 /*****************************************************************************/
377 menu_color_changed_cb (glColorComboMenu *object,
380 glColorComboButton *this)
384 this->priv->color = this->priv->default_color;
388 this->priv->color = color;
390 this->priv->is_default_flag = is_default;
392 gl_color_swatch_set_color (GL_COLOR_SWATCH (this->priv->swatch),
395 g_signal_emit (this, signals[COLOR_CHANGED], 0,
397 this->priv->is_default_flag);
401 /*****************************************************************************/
402 /* Menu "color changed" callback. */
403 /*****************************************************************************/
405 menu_selection_done_cb (GtkMenuShell *object,
406 glColorComboButton *this)
408 g_signal_handlers_block_by_func (G_OBJECT (this->priv->button),
409 button_clicked_cb, this);
410 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this->priv->button),
412 g_signal_handlers_unblock_by_func (G_OBJECT (this->priv->button),
413 button_clicked_cb, this);
415 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this->priv->dropdown_button),
422 * Local Variables: -- emacs
424 * c-basic-offset: 8 -- emacs
425 * tab-width: 8 -- emacs
426 * indent-tabs-mode: nil -- emacs