Code

init matrix variable, removes compiler warnings
[inkscape.git] / src / widgets / button.cpp
1 #define __SP_BUTTON_C__
3 /*
4  * Generic button widget
5  *
6  * Authors:
7  *   MenTaLguY <mental@rydia.net>
8  *   Lauris Kaplinski <lauris@kaplinski.com>
9  *   bulia byak <buliabyak@users.sf.net>
10  *
11  * Copyright (C) 2002 Lauris Kaplinski
12  *
13  * This code is in public domain
14  */
16 #ifdef HAVE_CONFIG_H
17 # include "config.h"
18 #endif
21 #if HAVE_STRING_H
22 #endif
27 #include "shortcuts.h"
28 #include "interface.h"
30 #include "icon.h"
31 #include "button.h"
33 static void sp_button_class_init (SPButtonClass *klass);
34 static void sp_button_init (SPButton *button);
35 static void sp_button_destroy (GtkObject *object);
37 static void sp_button_size_request (GtkWidget *widget, GtkRequisition *requisition);
38 static void sp_button_clicked (GtkButton *button);
39 static void sp_button_perform_action (SPButton *button, gpointer data);
40 static gint sp_button_process_event (SPButton *button, GdkEvent *event);
42 static void sp_button_set_action (SPButton *button, SPAction *action);
43 static void sp_button_set_doubleclick_action (SPButton *button, SPAction *action);
44 static void sp_button_action_set_active (SPAction *action, unsigned int active, void *data);
45 static void sp_button_action_set_sensitive (SPAction *action, unsigned int sensitive, void *data);
46 static void sp_button_action_set_shortcut (SPAction *action, unsigned int shortcut, void *data);
47 static void sp_button_set_composed_tooltip (GtkTooltips *tooltips, GtkWidget *widget, SPAction *action);
49 static GtkToggleButtonClass *parent_class;
50 SPActionEventVector button_event_vector = {
51         {NULL},
52          NULL,
53          sp_button_action_set_active,
54          sp_button_action_set_sensitive,
55          sp_button_action_set_shortcut
56 };
58 GtkType
59 sp_button_get_type (void)
60 {
61         static GtkType type = 0;
62         if (!type) {
63                 GtkTypeInfo info = {
64                         "SPButton",
65                         sizeof (SPButton),
66                         sizeof (SPButtonClass),
67                         (GtkClassInitFunc) sp_button_class_init,
68                         (GtkObjectInitFunc) sp_button_init,
69                         NULL, NULL, NULL
70                 };
71                 type = gtk_type_unique (GTK_TYPE_TOGGLE_BUTTON, &info);
72         }
73         return type;
74 }
76 static void
77 sp_button_class_init (SPButtonClass *klass)
78 {
79         GtkObjectClass *object_class=(GtkObjectClass *)klass;
80         GtkWidgetClass *widget_class=(GtkWidgetClass *)klass;
81         GtkButtonClass *button_class=(GtkButtonClass *)klass;
83         parent_class = (GtkToggleButtonClass *)g_type_class_peek_parent (klass);
85         object_class->destroy = sp_button_destroy;
86         widget_class->size_request = sp_button_size_request;
87         button_class->clicked = sp_button_clicked;
88 }
90 static void
91 sp_button_init (SPButton *button)
92 {
93         button->action = NULL;
94         button->doubleclick_action = NULL;
95         button->tooltips = NULL;
97         gtk_container_set_border_width (GTK_CONTAINER (button), 0);
99         GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (button), GTK_CAN_FOCUS);
100         GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (button), GTK_CAN_DEFAULT);
102         g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (sp_button_perform_action), NULL);
103         g_signal_connect_after (G_OBJECT (button), "event", G_CALLBACK (sp_button_process_event), NULL);
106 static void
107 sp_button_destroy (GtkObject *object)
109         SPButton *button;
111         button = SP_BUTTON (object);
113         if (button->tooltips) {
114                 g_object_unref (G_OBJECT (button->tooltips));
115                 button->tooltips = NULL;
116         }
118         if (button->action) {
119                 sp_button_set_action (button, NULL);
120         }
122         if (button->doubleclick_action) {
123                 sp_button_set_doubleclick_action (button, NULL);
124         }
126         ((GtkObjectClass *) (parent_class))->destroy (object);
129 static void
130 sp_button_size_request (GtkWidget *widget, GtkRequisition *requisition)
132         GtkWidget *child;
134         child = gtk_bin_get_child (GTK_BIN (widget));
135         if (child) {
136                 gtk_widget_size_request (GTK_WIDGET (child), requisition);
137         } else {
138                 requisition->width = 0;
139                 requisition->height = 0;
140         }
142         requisition->width += 2 + 2 * MAX (2, widget->style->xthickness);
143         requisition->height += 2 + 2 * MAX (2, widget->style->ythickness);
146 static void
147 sp_button_clicked (GtkButton *button)
149         SPButton *sp_button=SP_BUTTON (button);
151         if (sp_button->type == SP_BUTTON_TYPE_TOGGLE) {
152                 ((GtkButtonClass *) (parent_class))->clicked (button);
153         }
156 static gint 
157 sp_button_process_event (SPButton *button, GdkEvent *event)
159         switch (event->type) {
160         case GDK_2BUTTON_PRESS:
161                 if (button->doubleclick_action) {
162                         sp_action_perform (button->doubleclick_action, NULL);
163                 }
164                 return TRUE;
165                 break;
166         default:
167                 break;
168         }
170         return FALSE;
173 static void
174 sp_button_perform_action (SPButton *button, gpointer data)
176         if (button->action) {
177                 sp_action_perform (button->action, NULL);
178         }
182 GtkWidget *
183 sp_button_new( Inkscape::IconSize size, SPButtonType type, SPAction *action, SPAction *doubleclick_action, GtkTooltips *tooltips )
185         SPButton *button;
187         button = (SPButton *)g_object_new (SP_TYPE_BUTTON, NULL);
189         button->type = type;
190         button->lsize = CLAMP( size, Inkscape::ICON_SIZE_MENU, Inkscape::ICON_SIZE_DECORATION );
191         button->tooltips = tooltips;
193         if (tooltips) g_object_ref ((GObject *) tooltips);
195         sp_button_set_action (button, action);
196         if (doubleclick_action)
197                 sp_button_set_doubleclick_action (button, doubleclick_action);
199         // The Inkscape style is no-relief buttons
200         gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
202         return (GtkWidget *) button;
205 void
206 sp_button_toggle_set_down (SPButton *button, gboolean down)
208         g_return_if_fail (button->type == SP_BUTTON_TYPE_TOGGLE);
209         g_signal_handlers_block_by_func (G_OBJECT (button), (gpointer)G_CALLBACK (sp_button_perform_action), NULL);
210         gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), (unsigned int)down);
211         g_signal_handlers_unblock_by_func (G_OBJECT (button), (gpointer)G_CALLBACK (sp_button_perform_action), NULL);
214 static void
215 sp_button_set_doubleclick_action (SPButton *button, SPAction *action)
217         if (button->doubleclick_action) {
218                 nr_object_unref ((NRObject *) button->doubleclick_action);
219         }
220         button->doubleclick_action = action;
221         if (action) {
222                 button->doubleclick_action = (SPAction *) nr_object_ref ((NRObject *) action);
223         }
226 static void
227 sp_button_set_action (SPButton *button, SPAction *action)
229         GtkWidget *child;
231         if (button->action) {
232                 nr_active_object_remove_listener_by_data ((NRActiveObject *) button->action, button);
233                 nr_object_unref ((NRObject *) button->action);
234                 child = gtk_bin_get_child (GTK_BIN (button));
235                 if (child) {
236                         gtk_container_remove (GTK_CONTAINER (button), child);
237                 }
238         }
239         button->action = action;
240         if (action) {
241                 button->action = (SPAction *) nr_object_ref ((NRObject *) action);
242                 nr_active_object_add_listener ((NRActiveObject *) action, (NRObjectEventVector *) &button_event_vector, sizeof (SPActionEventVector), button);
243                 if (action->image) {
244                         child = sp_icon_new (button->lsize, action->image);
245                         gtk_widget_show (child);
246                         gtk_container_add (GTK_CONTAINER (button), child);
247                 }
248         }
250         if (button->tooltips) {
251                 sp_button_set_composed_tooltip (button->tooltips, (GtkWidget *) button, action);
252         }
255 static void
256 sp_button_action_set_active (SPAction *action, unsigned int active, void *data)
258         SPButton *button;
259         button = (SPButton *) data;
260         if (button->type != SP_BUTTON_TYPE_TOGGLE) {
261                 return;
262         }
264         /* temporarily lobotomized until SPActions are per-view */
265         if (0 && !active != !SP_BUTTON_IS_DOWN (button)) {
266                 sp_button_toggle_set_down (button, active);
267         }
270 static void
271 sp_button_action_set_sensitive (SPAction *action, unsigned int sensitive, void *data)
273         gtk_widget_set_sensitive (GTK_WIDGET (data), sensitive);
276 static void
277 sp_button_action_set_shortcut (SPAction *action, unsigned int shortcut, void *data)
279         SPButton *button=SP_BUTTON (data);
280         if (button->tooltips) {
281                 sp_button_set_composed_tooltip (button->tooltips, GTK_WIDGET (button), action);
282         }
285 static void
286 sp_button_set_composed_tooltip (GtkTooltips *tooltips, GtkWidget *widget, SPAction *action)
288         if (action) {
289                 unsigned int shortcut = sp_shortcut_get_primary (action->verb);
290                 if (shortcut) {
291                         // there's both action and shortcut
293                         gchar        key[256];
294                         sp_ui_shortcut_string (shortcut, key);
296                         gchar *tip = g_strdup_printf ("%s (%s)", action->tip, key);
297                         gtk_tooltips_set_tip (tooltips, widget, tip, NULL);
298                         g_free (tip);
300                 } else {
301                         // action has no shortcut
302                         gtk_tooltips_set_tip (tooltips, widget, action->tip, NULL);
303                 }
304         } else {
305                 // no action
306                 gtk_tooltips_set_tip (tooltips, widget, NULL, NULL);
307         }
310 GtkWidget *
311 sp_button_new_from_data( Inkscape::IconSize size,
312                          SPButtonType type,
313                          Inkscape::UI::View::View *view,
314                          const gchar *name,
315                          const gchar *tip,
316                          GtkTooltips *tooltips )
318         GtkWidget *button;
319         SPAction *action=sp_action_new(view, name, name, tip, name, 0);
320         button = sp_button_new (size, type, action, NULL, tooltips);
321         nr_object_unref ((NRObject *) action);
322         return button;