2 * Copyright (C) 2009 Intel Corporation
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) version 3.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 /* TODO: should probably ensure specific icon size? */
22 #include "mux-icon-button.h"
31 PROP_PIXBUF_INSENSITIVE
34 G_DEFINE_TYPE (MuxIconButton, mux_icon_button, GTK_TYPE_BUTTON)
38 mux_icon_button_get_property (GObject *object, guint property_id,
39 GValue *value, GParamSpec *pspec)
41 MuxIconButton *btn = MUX_ICON_BUTTON (object);
43 switch (property_id) {
45 g_value_set_boolean (value, btn->toggleable);
47 case PROP_PIXBUF_NORMAL:
48 g_value_set_object (value, mux_icon_button_get_pixbuf (btn, GTK_STATE_NORMAL));
50 case PROP_PIXBUF_ACTIVE:
51 g_value_set_object (value, mux_icon_button_get_pixbuf (btn, GTK_STATE_ACTIVE));
53 case PROP_PIXBUF_PRELIGHT:
54 g_value_set_object (value, mux_icon_button_get_pixbuf (btn, GTK_STATE_PRELIGHT));
56 case PROP_PIXBUF_SELECTED:
57 g_value_set_object (value, mux_icon_button_get_pixbuf (btn, GTK_STATE_SELECTED));
59 case PROP_PIXBUF_INSENSITIVE:
60 g_value_set_object (value, mux_icon_button_get_pixbuf (btn, GTK_STATE_INSENSITIVE));
63 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
68 mux_icon_button_set_property (GObject *object, guint property_id,
69 const GValue *value, GParamSpec *pspec)
71 MuxIconButton *btn = MUX_ICON_BUTTON (object);
74 switch (property_id) {
76 btn->toggleable = g_value_get_boolean (value);
78 case PROP_PIXBUF_NORMAL:
79 pixbuf = GDK_PIXBUF (g_value_get_object (value));
80 mux_icon_button_set_pixbuf (btn, GTK_STATE_NORMAL, pixbuf);
82 case PROP_PIXBUF_ACTIVE:
83 pixbuf = GDK_PIXBUF (g_value_get_object (value));
84 mux_icon_button_set_pixbuf (btn, GTK_STATE_ACTIVE, pixbuf);
86 case PROP_PIXBUF_PRELIGHT:
87 pixbuf = GDK_PIXBUF (g_value_get_object (value));
88 mux_icon_button_set_pixbuf (btn, GTK_STATE_PRELIGHT, pixbuf);
90 case PROP_PIXBUF_SELECTED:
91 pixbuf = GDK_PIXBUF (g_value_get_object (value));
92 mux_icon_button_set_pixbuf (btn, GTK_STATE_SELECTED, pixbuf);
94 case PROP_PIXBUF_INSENSITIVE:
95 pixbuf = GDK_PIXBUF (g_value_get_object (value));
96 mux_icon_button_set_pixbuf (btn, GTK_STATE_INSENSITIVE, pixbuf);
99 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
104 mux_icon_button_dispose (GObject *object)
107 MuxIconButton *btn = MUX_ICON_BUTTON (object);
109 for (i = 0; i < 5; i++) {
110 if (btn->pixbufs[i]) {
111 g_object_unref (btn->pixbufs[i]);
112 btn->pixbufs[i] = NULL;
115 G_OBJECT_CLASS (mux_icon_button_parent_class)->dispose (object);
119 mux_icon_button_size_request (GtkWidget *widget,
120 GtkRequisition *requisition)
122 MuxIconButton *btn = MUX_ICON_BUTTON (widget);
124 if (btn->pixbufs[GTK_STATE_NORMAL]) {
125 requisition->width = gdk_pixbuf_get_width (btn->pixbufs[GTK_STATE_NORMAL]);
126 requisition->height = gdk_pixbuf_get_height (btn->pixbufs[GTK_STATE_NORMAL]);
131 mux_icon_button_expose (GtkWidget *widget,
132 GdkEventExpose *event)
134 GdkRectangle dirty_area, btn_area;
135 MuxIconButton *btn = MUX_ICON_BUTTON (widget);
140 /* this is a active toggle button */
141 state = GTK_STATE_ACTIVE;
143 state = GTK_WIDGET_STATE (widget);
146 if (btn->pixbufs[state]) {
147 pixbuf = btn->pixbufs[state];
149 pixbuf = btn->pixbufs[GTK_STATE_NORMAL];
155 btn_area.width = gdk_pixbuf_get_width (pixbuf);
156 btn_area.height = gdk_pixbuf_get_height (pixbuf);
157 btn_area.x = widget->allocation.x + (widget->allocation.width - btn_area.width) / 2;
158 btn_area.y = widget->allocation.y + (widget->allocation.height - btn_area.height) / 2;
160 if (gdk_rectangle_intersect (&event->area, &widget->allocation, &dirty_area) &&
161 gdk_rectangle_intersect (&btn_area, &dirty_area, &dirty_area)) {
163 gdk_draw_pixbuf (widget->window, NULL, pixbuf,
164 dirty_area.x - btn_area.x, dirty_area.y - btn_area.y,
165 dirty_area.x, dirty_area.y,
166 dirty_area.width, dirty_area.height,
167 GDK_RGB_DITHER_NORMAL, 0, 0);
173 mux_icon_button_clicked (GtkButton *button)
175 MuxIconButton *icon_button = MUX_ICON_BUTTON (button);
177 if (icon_button->toggleable) {
178 icon_button->active = !icon_button->active;
183 mux_icon_button_class_init (MuxIconButtonClass *klass)
185 GObjectClass *object_class = G_OBJECT_CLASS (klass);
186 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
187 GtkButtonClass *button_class = GTK_BUTTON_CLASS (klass);
190 object_class->get_property = mux_icon_button_get_property;
191 object_class->set_property = mux_icon_button_set_property;
192 object_class->dispose = mux_icon_button_dispose;
194 widget_class->size_request = mux_icon_button_size_request;
195 widget_class->expose_event = mux_icon_button_expose;
197 button_class->clicked = mux_icon_button_clicked;
199 pspec = g_param_spec_boolean ("toggleable",
201 "Is icon button button a toggle or normal",
204 g_object_class_install_property (object_class, PROP_TOGGLEABLE, pspec);
205 pspec = g_param_spec_object ("normal-state-pixbuf",
206 "Normal state pixbuf",
207 "GdkPixbuf for GTK_STATE_NORMAL",
210 g_object_class_install_property (object_class, PROP_PIXBUF_NORMAL, pspec);
211 pspec = g_param_spec_object ("active-state-pixbuf",
212 "Active state pixbuf",
213 "GdkPixbuf for GTK_STATE_ACTIVE",
216 g_object_class_install_property (object_class, PROP_PIXBUF_ACTIVE, pspec);
217 pspec = g_param_spec_object ("prelight-state-pixbuf",
218 "Prelight state pixbuf",
219 "GdkPixbuf for GTK_STATE_PRELIGHT",
222 g_object_class_install_property (object_class, PROP_PIXBUF_PRELIGHT, pspec);
223 pspec = g_param_spec_object ("selected-state-pixbuf",
224 "Selected state pixbuf",
225 "GdkPixbuf for GTK_STATE_SELECTED",
228 g_object_class_install_property (object_class, PROP_PIXBUF_SELECTED, pspec);
229 pspec = g_param_spec_object ("insensitive-state-pixbuf",
230 "Insensitive state pixbuf",
231 "GdkPixbuf for GTK_STATE_INSENSITIVE",
234 g_object_class_install_property (object_class, PROP_PIXBUF_INSENSITIVE, pspec);
238 mux_icon_button_init (MuxIconButton *self)
243 mux_icon_button_new (GdkPixbuf *normal_pixbuf, gboolean toggleable)
245 return g_object_new (MUX_TYPE_ICON_BUTTON,
246 "normal-state-pixbuf", normal_pixbuf,
247 "toggleable", toggleable,
252 mux_icon_button_set_pixbuf (MuxIconButton *button, GtkStateType state, GdkPixbuf *pixbuf)
254 if (button->pixbufs[state]) {
255 g_object_unref (button->pixbufs[state]);
257 button->pixbufs[state] = g_object_ref (pixbuf);
259 if (state == GTK_STATE_NORMAL) {
260 gtk_widget_queue_resize (GTK_WIDGET (button));
261 } else if (state == GTK_WIDGET_STATE (GTK_WIDGET (button))) {
262 gtk_widget_queue_draw (GTK_WIDGET (button));
267 mux_icon_button_get_pixbuf (MuxIconButton *button, GtkStateType state)
269 return button->pixbufs[state];
273 mux_icon_button_set_active (MuxIconButton *button, gboolean active)
275 button->active = active;
276 gtk_widget_queue_draw (GTK_WIDGET (button));
280 mux_icon_button_get_active (MuxIconButton *button)
282 return button->active;