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-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_BUTTON Private fields */
46 struct _glColorButtonPrivate {
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_button_finalize (GObject *object);
82 button_clicked_cb (glColorButton *this);
85 create_pixbuf (glColorButton *this,
90 dropdown_button_press_event_cb (GtkWidget *widget,
91 GdkEventButton *event,
95 menu_color_changed_cb (glColorComboMenu *object,
101 menu_selection_done_cb (GtkMenuShell *object,
102 glColorButton *this);
105 /*****************************************************************************/
106 /* Object infrastructure. */
107 /*****************************************************************************/
108 G_DEFINE_TYPE (glColorButton, gl_color_button, GTK_TYPE_HBOX);
111 /*****************************************************************************/
112 /* Class Init Function. */
113 /*****************************************************************************/
115 gl_color_button_class_init (glColorButtonClass *class)
117 GObjectClass *gobject_class = (GObjectClass *) class;
118 GtkWidgetClass *widget_class = (GtkWidgetClass *) class;
119 glColorButtonClass *object_class = (glColorButtonClass *) class;
121 gl_color_button_parent_class = g_type_class_peek_parent (class);
123 gobject_class->finalize = gl_color_button_finalize;
125 signals[COLOR_CHANGED] =
126 g_signal_new ("color_changed",
127 G_OBJECT_CLASS_TYPE (gobject_class),
129 G_STRUCT_OFFSET (glColorButtonClass, color_changed),
131 gl_marshal_VOID__UINT_BOOLEAN,
133 2, G_TYPE_POINTER, G_TYPE_BOOLEAN);
138 /*****************************************************************************/
139 /* Object Instance Init Function. */
140 /*****************************************************************************/
142 gl_color_button_init (glColorButton *this)
146 gtk_box_set_spacing (GTK_BOX (this), 0);
148 this->priv = g_new0 (glColorButtonPrivate, 1);
150 this->priv->button_vbox = gtk_vbox_new (FALSE, 0);
152 this->priv->button = gtk_toggle_button_new ();
153 gtk_container_add (GTK_CONTAINER (this->priv->button), this->priv->button_vbox);
154 gtk_button_set_focus_on_click (GTK_BUTTON (this->priv->button), FALSE);
155 g_signal_connect_swapped (this->priv->button, "clicked",
156 G_CALLBACK(button_clicked_cb), this);
158 gtk_box_pack_start (GTK_BOX (this), this->priv->button, FALSE, FALSE, 0);
160 this->priv->dropdown_button = gtk_toggle_button_new ();
161 arrow = gtk_arrow_new (GTK_ARROW_DOWN, GTK_SHADOW_IN);
162 gtk_container_add (GTK_CONTAINER (this->priv->dropdown_button), arrow);
163 gtk_button_set_relief (GTK_BUTTON (this->priv->dropdown_button), GTK_RELIEF_NONE);
164 gtk_button_set_focus_on_click (GTK_BUTTON (this->priv->dropdown_button), FALSE);
165 g_signal_connect (this->priv->dropdown_button, "button_press_event",
166 G_CALLBACK(dropdown_button_press_event_cb), this);
168 gtk_box_pack_start (GTK_BOX (this), this->priv->dropdown_button, FALSE, FALSE, 0);
172 /*****************************************************************************/
173 /* Finalize Method. */
174 /*****************************************************************************/
176 gl_color_button_finalize (GObject *object)
180 g_return_if_fail (object && IS_GL_COLOR_BUTTON (object));
181 this = GL_COLOR_BUTTON (object);
183 g_object_ref_sink (this->priv->menu);
186 G_OBJECT_CLASS (gl_color_button_parent_class)->finalize (object);
190 /*****************************************************************************/
191 /** New Object Generator. */
192 /*****************************************************************************/
194 gl_color_button_new (GdkPixbuf *icon,
195 const gchar *default_label,
203 this = g_object_new (TYPE_GL_COLOR_BUTTON, NULL);
207 default_label = _("Default Color");
210 this->priv->default_color = default_color;
211 this->priv->color = color;
215 pixbuf = gdk_pixbuf_new_subpixbuf (icon, 0, 0, IMAGE_W, IMAGE_H-SWATCH_H);
216 wimage = gtk_image_new_from_pixbuf (pixbuf);
217 g_object_unref (G_OBJECT (pixbuf));
218 gtk_box_pack_start (GTK_BOX (this->priv->button_vbox), wimage, FALSE, FALSE, 0);
220 this->priv->swatch = gl_color_swatch_new (IMAGE_W, SWATCH_H, color);
224 this->priv->swatch = gl_color_swatch_new (IMAGE_W, IMAGE_H, color);
226 gtk_box_pack_start (GTK_BOX (this->priv->button_vbox), this->priv->swatch, FALSE, FALSE, 0);
228 this->priv->menu = gl_color_combo_menu_new (default_label, color);
229 gtk_widget_show_all (this->priv->menu);
231 g_signal_connect (this->priv->menu, "color_changed",
232 G_CALLBACK (menu_color_changed_cb), this);
233 g_signal_connect (this->priv->menu, "selection_done",
234 G_CALLBACK (menu_selection_done_cb), this);
236 return GTK_WIDGET (this);
240 /*****************************************************************************/
242 /*****************************************************************************/
244 gl_color_button_set_color (glColorButton *this,
247 this->priv->color = color;
249 gl_color_swatch_set_color (GL_COLOR_SWATCH (this->priv->swatch), color);
253 /*****************************************************************************/
254 /* Set to default color. */
255 /*****************************************************************************/
257 gl_color_button_set_to_default (glColorButton *this)
259 gl_color_button_set_color (this, this->priv->default_color);
262 /*****************************************************************************/
264 /*****************************************************************************/
266 gl_color_button_get_color (glColorButton *this,
267 gboolean *is_default)
271 *is_default = this->priv->is_default_flag;
274 return this->priv->color;
278 /*****************************************************************************/
279 /** Set relief style. */
280 /*****************************************************************************/
282 gl_color_button_set_relief( glColorButton *this,
283 GtkReliefStyle relief )
285 gtk_button_set_relief (GTK_BUTTON (this->priv->button), relief);
289 /*****************************************************************************/
290 /* Color button "clicked" callback. */
291 /*****************************************************************************/
293 button_clicked_cb( glColorButton *this )
295 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this->priv->button),
298 g_signal_emit (this, signals[COLOR_CHANGED], 0,
300 this->priv->is_default_flag);
304 /*****************************************************************************/
305 /* Menu positioning function. */
306 /*****************************************************************************/
308 menu_position_function (GtkMenu *menu,
314 glColorButton *this = GL_COLOR_BUTTON (user_data);
318 gdk_window_get_origin (GTK_WIDGET (this)->window, &x1, &y1);
319 *x = x1 + GTK_WIDGET (this)->allocation.x;
320 *y = y1 + GTK_WIDGET (this)->allocation.y +
321 GTK_WIDGET (this)->allocation.height;
323 menu_h = this->priv->menu->allocation.height;
324 menu_w = this->priv->menu->allocation.width;
326 if ((*y + menu_h) > gdk_screen_height ())
328 *y = y1 + GTK_WIDGET (this)->allocation.y - menu_h;
331 *y = gdk_screen_height () - menu_h;
335 if ((*x + menu_w) > gdk_screen_width ())
337 *x = gdk_screen_width () - menu_w;
344 /*****************************************************************************/
345 /* Dropdown button "button_press_event" callback. */
346 /*****************************************************************************/
348 dropdown_button_press_event_cb (GtkWidget *widget,
349 GdkEventButton *event,
352 switch (event->button)
356 g_signal_handlers_block_by_func (G_OBJECT (this->priv->button),
357 button_clicked_cb, this);
358 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this->priv->button),
360 g_signal_handlers_unblock_by_func (G_OBJECT (this->priv->button),
361 button_clicked_cb, this);
362 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this->priv->dropdown_button),
365 gtk_menu_popup (GTK_MENU (this->priv->menu),
367 menu_position_function, this,
368 event->button, event->time);
380 /*****************************************************************************/
381 /* Menu "color changed" callback. */
382 /*****************************************************************************/
384 menu_color_changed_cb (glColorComboMenu *object,
391 this->priv->color = this->priv->default_color;
395 this->priv->color = color;
397 this->priv->is_default_flag = is_default;
399 gl_color_swatch_set_color (GL_COLOR_SWATCH (this->priv->swatch),
402 g_signal_emit (this, signals[COLOR_CHANGED], 0,
404 this->priv->is_default_flag);
408 /*****************************************************************************/
409 /* Menu "color changed" callback. */
410 /*****************************************************************************/
412 menu_selection_done_cb (GtkMenuShell *object,
415 g_signal_handlers_block_by_func (G_OBJECT (this->priv->button),
416 button_clicked_cb, this);
417 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this->priv->button),
419 g_signal_handlers_unblock_by_func (G_OBJECT (this->priv->button),
420 button_clicked_cb, this);
422 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (this->priv->dropdown_button),
429 * Local Variables: -- emacs
431 * c-basic-offset: 8 -- emacs
432 * tab-width: 8 -- emacs
433 * indent-tabs-mode: nil -- emacs