Code

418a9ce4f914b304bbfdf1f037d89f2564416088
[inkscape.git] / src / ink-action.cpp
4 #include <glib/gi18n.h>
5 #include <gtk/gtktooltips.h>
6 #include <gtk/gtktoolitem.h>
7 #include <gtk/gtktoggletoolbutton.h>
8 #include <gtk/gtkcheckmenuitem.h>
9 #include <gtk/gtkimagemenuitem.h>
11 #include "icon-size.h"
12 #include "ink-action.h"
14 #include "widgets/button.h"
15 #include "widgets/icon.h"
19 static void ink_action_class_init( InkActionClass* klass );
20 static void ink_action_init( InkAction* action );
21 static void ink_action_finalize( GObject* obj );
22 static void ink_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
23 static void ink_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
25 static GtkWidget* ink_action_create_menu_item( GtkAction* action );
26 static GtkWidget* ink_action_create_tool_item( GtkAction* action );
28 static GtkActionClass* gInkActionParentClass = 0;
30 struct _InkActionPrivate
31 {
32     gchar* iconId;
33     Inkscape::IconSize iconSize;
34 };
36 #define INK_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_ACTION_TYPE, InkActionPrivate ) )
38 GType ink_action_get_type( void )
39 {
40     static GType myType = 0;
41     if ( !myType ) {
42         static const GTypeInfo myInfo = {
43             sizeof( InkActionClass ),
44             NULL, /* base_init */
45             NULL, /* base_finalize */
46             (GClassInitFunc)ink_action_class_init,
47             NULL, /* class_finalize */
48             NULL, /* class_data */
49             sizeof( InkAction ),
50             0, /* n_preallocs */
51             (GInstanceInitFunc)ink_action_init,
52             NULL
53         };
55         myType = g_type_register_static( GTK_TYPE_ACTION, "InkAction", &myInfo, (GTypeFlags)0 );
56     }
58     return myType;
59 }
61 enum {
62     PROP_INK_ID = 1,
63     PROP_INK_SIZE
64 };
66 static void ink_action_class_init( InkActionClass* klass )
67 {
68     if ( klass ) {
69         gInkActionParentClass = GTK_ACTION_CLASS( g_type_class_peek_parent( klass ) );
70         GObjectClass * objClass = G_OBJECT_CLASS( klass );
72         objClass->finalize = ink_action_finalize;
73         objClass->get_property = ink_action_get_property;
74         objClass->set_property = ink_action_set_property;
76         klass->parent_class.create_menu_item = ink_action_create_menu_item;
77         klass->parent_class.create_tool_item = ink_action_create_tool_item;
78         /*klass->parent_class.connect_proxy = connect_proxy;*/
79         /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/
81         g_object_class_install_property( objClass,
82                                          PROP_INK_ID,
83                                          g_param_spec_string( "iconId",
84                                                               "Icon ID",
85                                                               "The id for the icon",
86                                                               "",
87                                                               (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
89         g_object_class_install_property( objClass,
90                                          PROP_INK_SIZE,
91                                          g_param_spec_int( "iconSize",
92                                                            "Icon Size",
93                                                            "The size the icon",
94                                                            (int)Inkscape::ICON_SIZE_MENU,
95                                                            (int)Inkscape::ICON_SIZE_DECORATION,
96                                                            (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
97                                                            (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
99         g_type_class_add_private( klass, sizeof(InkActionClass) );
100     }
103 static void ink_action_init( InkAction* action )
105     action->private_data = INK_ACTION_GET_PRIVATE( action );
106     action->private_data->iconId = 0;
107     action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
110 static void ink_action_finalize( GObject* obj )
112     InkAction* action = INK_ACTION( obj );
114     g_free( action->private_data->iconId );
115     g_free( action->private_data );
119 InkAction* ink_action_new( const gchar *name,
120                            const gchar *label,
121                            const gchar *tooltip,
122                            const gchar *inkId,
123                            Inkscape::IconSize size )
125     GObject* obj = (GObject*)g_object_new( INK_ACTION_TYPE,
126                                            "name", name,
127                                            "label", label,
128                                            "tooltip", tooltip,
129                                            "iconId", inkId,
130                                            "iconSize", size,
131                                            NULL );
133     InkAction* action = INK_ACTION( obj );
135     return action;
138 static void ink_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
140     InkAction* action = INK_ACTION( obj );
141     (void)action;
142     switch ( propId ) {
143         case PROP_INK_ID:
144         {
145             g_value_set_string( value, action->private_data->iconId );
146         }
147         break;
149         case PROP_INK_SIZE:
150         {
151             g_value_set_int( value, action->private_data->iconSize );
152         }
153         break;
155         default:
156             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
157     }
160 void ink_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
162     InkAction* action = INK_ACTION( obj );
163     (void)action;
164     switch ( propId ) {
165         case PROP_INK_ID:
166         {
167             gchar* tmp = action->private_data->iconId;
168             action->private_data->iconId = g_value_dup_string( value );
169             g_free( tmp );
170         }
171         break;
173         case PROP_INK_SIZE:
174         {
175             action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value );
176         }
177         break;
179         default:
180         {
181             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
182         }
183     }
186 #include <gtk/gtkstock.h>
188 static GtkWidget* ink_action_create_menu_item( GtkAction* action )
190     InkAction* act = INK_ACTION( action );
191     GtkWidget* item = 0;
193     if ( act->private_data->iconId ) {
194         gchar* label = 0;
195         g_object_get( G_OBJECT(act), "label", &label, NULL );
197         item = gtk_image_menu_item_new_with_mnemonic( label );
198         GtkWidget* child = sp_icon_new( Inkscape::ICON_SIZE_MENU, act->private_data->iconId );
199         // TODO this work-around is until SPIcon will live properly inside of a popup menu
200         if ( SP_IS_ICON(child) ) {
201             SPIcon* icon = SP_ICON(child);
202             sp_icon_fetch_pixbuf( icon );
203             GdkPixbuf* target = gtk_action_is_sensitive(action) ? icon->pb : icon->pb_faded;
204             if ( target ) {
205                 child = gtk_image_new_from_pixbuf( target );
206                 gtk_widget_destroy( GTK_WIDGET(icon) );
207             }
208         }
209         gtk_widget_show_all( child );
210         gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM(item), child );
212         g_free( label );
213         label = 0;
214     } else {
215         item = gInkActionParentClass->create_menu_item( action );
216     }
218     return item;
221 static GtkWidget* ink_action_create_tool_item( GtkAction* action )
223     InkAction* act = INK_ACTION( action );
224     GtkWidget* item = gInkActionParentClass->create_tool_item(action);
226     if ( act->private_data->iconId ) {
227         if ( GTK_IS_TOOL_BUTTON(item) ) {
228             GtkToolButton* button = GTK_TOOL_BUTTON(item);
230             GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId );
231             gtk_tool_button_set_icon_widget( button, child );
232         } else {
233             // For now trigger a warning but don't do anything else
234             GtkToolButton* button = GTK_TOOL_BUTTON(item);
235             (void)button;
236         }
237     }
239     // TODO investigate if needed
240     gtk_widget_show_all( item );
242     return item;
247 /* --------------------------------------------------------------- */
248 /* --------------------------------------------------------------- */
249 /* --------------------------------------------------------------- */
250 /* --------------------------------------------------------------- */
253 static void ink_toggle_action_class_init( InkToggleActionClass* klass );
254 static void ink_toggle_action_init( InkToggleAction* action );
255 static void ink_toggle_action_finalize( GObject* obj );
256 static void ink_toggle_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
257 static void ink_toggle_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
259 static GtkWidget* ink_toggle_action_create_menu_item( GtkAction* action );
260 static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action );
262 static void ink_toggle_action_update_icon( InkToggleAction* action );
264 static GtkToggleActionClass* gInkToggleActionParentClass = 0;
266 struct _InkToggleActionPrivate
268     gchar* iconId;
269     Inkscape::IconSize iconSize;
270 };
272 #define INK_TOGGLE_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_TOGGLE_ACTION_TYPE, InkToggleActionPrivate ) )
274 GType ink_toggle_action_get_type( void )
276     static GType myType = 0;
277     if ( !myType ) {
278         static const GTypeInfo myInfo = {
279             sizeof( InkToggleActionClass ),
280             NULL, /* base_init */
281             NULL, /* base_finalize */
282             (GClassInitFunc)ink_toggle_action_class_init,
283             NULL, /* class_finalize */
284             NULL, /* class_data */
285             sizeof( InkToggleAction ),
286             0, /* n_preallocs */
287             (GInstanceInitFunc)ink_toggle_action_init,
288             NULL
289         };
291         myType = g_type_register_static( GTK_TYPE_TOGGLE_ACTION, "InkToggleAction", &myInfo, (GTypeFlags)0 );
292     }
294     return myType;
298 static void ink_toggle_action_class_init( InkToggleActionClass* klass )
300     if ( klass ) {
301         gInkToggleActionParentClass = GTK_TOGGLE_ACTION_CLASS( g_type_class_peek_parent( klass ) );
302         GObjectClass * objClass = G_OBJECT_CLASS( klass );
304         objClass->finalize = ink_toggle_action_finalize;
305         objClass->get_property = ink_toggle_action_get_property;
306         objClass->set_property = ink_toggle_action_set_property;
308         klass->parent_class.parent_class.create_menu_item = ink_toggle_action_create_menu_item;
309         klass->parent_class.parent_class.create_tool_item = ink_toggle_action_create_tool_item;
310         /*klass->parent_class.connect_proxy = connect_proxy;*/
311         /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/
313         g_object_class_install_property( objClass,
314                                          PROP_INK_ID,
315                                          g_param_spec_string( "iconId",
316                                                               "Icon ID",
317                                                               "The id for the icon",
318                                                               "",
319                                                               (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
321         g_object_class_install_property( objClass,
322                                          PROP_INK_SIZE,
323                                          g_param_spec_int( "iconSize",
324                                                            "Icon Size",
325                                                            "The size the icon",
326                                                            (int)Inkscape::ICON_SIZE_MENU,
327                                                            (int)Inkscape::ICON_SIZE_DECORATION,
328                                                            (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
329                                                            (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
331         g_type_class_add_private( klass, sizeof(InkToggleActionClass) );
332     }
335 static void ink_toggle_action_init( InkToggleAction* action )
337     action->private_data = INK_TOGGLE_ACTION_GET_PRIVATE( action );
338     action->private_data->iconId = 0;
339     action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
342 static void ink_toggle_action_finalize( GObject* obj )
344     InkToggleAction* action = INK_TOGGLE_ACTION( obj );
346     g_free( action->private_data->iconId );
347     g_free( action->private_data );
351 InkToggleAction* ink_toggle_action_new( const gchar *name,
352                            const gchar *label,
353                            const gchar *tooltip,
354                            const gchar *inkId,
355                            Inkscape::IconSize size )
357     GObject* obj = (GObject*)g_object_new( INK_TOGGLE_ACTION_TYPE,
358                                            "name", name,
359                                            "label", label,
360                                            "tooltip", tooltip,
361                                            "iconId", inkId,
362                                            "iconSize", size,
363                                            NULL );
365     InkToggleAction* action = INK_TOGGLE_ACTION( obj );
367     return action;
370 static void ink_toggle_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
372     InkToggleAction* action = INK_TOGGLE_ACTION( obj );
373     (void)action;
374     switch ( propId ) {
375         case PROP_INK_ID:
376         {
377             g_value_set_string( value, action->private_data->iconId );
378         }
379         break;
381         case PROP_INK_SIZE:
382         {
383             g_value_set_int( value, action->private_data->iconSize );
384         }
385         break;
387         default:
388             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
389     }
392 void ink_toggle_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
394     InkToggleAction* action = INK_TOGGLE_ACTION( obj );
395     (void)action;
396     switch ( propId ) {
397         case PROP_INK_ID:
398         {
399             gchar* tmp = action->private_data->iconId;
400             action->private_data->iconId = g_value_dup_string( value );
401             g_free( tmp );
403             ink_toggle_action_update_icon( action );
404         }
405         break;
407         case PROP_INK_SIZE:
408         {
409             action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value );
410         }
411         break;
413         default:
414         {
415             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
416         }
417     }
420 static GtkWidget* ink_toggle_action_create_menu_item( GtkAction* action )
422     GtkWidget* item = gInkToggleActionParentClass->parent_class.create_menu_item(action);
424     return item;
427 static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action )
429     InkToggleAction* act = INK_TOGGLE_ACTION( action );
431     GtkWidget* item = gInkToggleActionParentClass->parent_class.create_tool_item(action);
432     if ( GTK_IS_TOOL_BUTTON(item) ) {
433         GtkToolButton* button = GTK_TOOL_BUTTON(item);
434         if ( act->private_data->iconId ) {
435             GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId );
436             gtk_tool_button_set_icon_widget( button, child );
437         } else {
438             gchar *label;
439             g_object_get (G_OBJECT(action), "short_label", &label, NULL);
440             gtk_tool_button_set_label( button, label );
441         }
442     } else {
443         // For now trigger a warning but don't do anything else
444         GtkToolButton* button = GTK_TOOL_BUTTON(item);
445         (void)button;
446     }
447     gtk_widget_show_all( item );
449     return item;
453 static void ink_toggle_action_update_icon( InkToggleAction* action )
455     if ( action ) {
456         GSList* proxies = gtk_action_get_proxies( GTK_ACTION(action) );
457         while ( proxies ) {
458             if ( GTK_IS_TOOL_ITEM(proxies->data) ) {
459                 if ( GTK_IS_TOOL_BUTTON(proxies->data) ) {
460                     GtkToolButton* button = GTK_TOOL_BUTTON(proxies->data);
462                     GtkWidget* child = sp_icon_new( action->private_data->iconSize, action->private_data->iconId );
463                     gtk_widget_show_all( child );
464                     gtk_tool_button_set_icon_widget( button, child );
465                 }
466             }
468             proxies = g_slist_next( proxies );
469         }
470     }
474 /* --------------------------------------------------------------- */
475 /* --------------------------------------------------------------- */
476 /* --------------------------------------------------------------- */
477 /* --------------------------------------------------------------- */
480 static void ink_radio_action_class_init( InkRadioActionClass* klass );
481 static void ink_radio_action_init( InkRadioAction* action );
482 static void ink_radio_action_finalize( GObject* obj );
483 static void ink_radio_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
484 static void ink_radio_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
486 static GtkWidget* ink_radio_action_create_menu_item( GtkAction* action );
487 static GtkWidget* ink_radio_action_create_tool_item( GtkAction* action );
489 static GtkRadioActionClass* gInkRadioActionParentClass = 0;
491 struct _InkRadioActionPrivate
493     gchar* iconId;
494     Inkscape::IconSize iconSize;
495 };
497 #define INK_RADIO_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_RADIO_ACTION_TYPE, InkRadioActionPrivate ) )
499 GType ink_radio_action_get_type( void )
501     static GType myType = 0;
502     if ( !myType ) {
503         static const GTypeInfo myInfo = {
504             sizeof( InkRadioActionClass ),
505             NULL, /* base_init */
506             NULL, /* base_finalize */
507             (GClassInitFunc)ink_radio_action_class_init,
508             NULL, /* class_finalize */
509             NULL, /* class_data */
510             sizeof( InkRadioAction ),
511             0, /* n_preallocs */
512             (GInstanceInitFunc)ink_radio_action_init,
513             NULL
514         };
516         myType = g_type_register_static( GTK_TYPE_RADIO_ACTION, "InkRadioAction", &myInfo, (GTypeFlags)0 );
517     }
519     return myType;
523 static void ink_radio_action_class_init( InkRadioActionClass* klass )
525     if ( klass ) {
526         gInkRadioActionParentClass = GTK_RADIO_ACTION_CLASS( g_type_class_peek_parent( klass ) );
527         GObjectClass * objClass = G_OBJECT_CLASS( klass );
529         objClass->finalize = ink_radio_action_finalize;
530         objClass->get_property = ink_radio_action_get_property;
531         objClass->set_property = ink_radio_action_set_property;
533         klass->parent_class.parent_class.parent_class.create_menu_item = ink_radio_action_create_menu_item;
534         klass->parent_class.parent_class.parent_class.create_tool_item = ink_radio_action_create_tool_item;
535         /*klass->parent_class.connect_proxy = connect_proxy;*/
536         /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/
538         g_object_class_install_property( objClass,
539                                          PROP_INK_ID,
540                                          g_param_spec_string( "iconId",
541                                                               "Icon ID",
542                                                               "The id for the icon",
543                                                               "",
544                                                               (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
546         g_object_class_install_property( objClass,
547                                          PROP_INK_SIZE,
548                                          g_param_spec_int( "iconSize",
549                                                            "Icon Size",
550                                                            "The size the icon",
551                                                            (int)Inkscape::ICON_SIZE_MENU,
552                                                            (int)Inkscape::ICON_SIZE_DECORATION,
553                                                            (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
554                                                            (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
556         g_type_class_add_private( klass, sizeof(InkRadioActionClass) );
557     }
560 static void ink_radio_action_init( InkRadioAction* action )
562     action->private_data = INK_RADIO_ACTION_GET_PRIVATE( action );
563     action->private_data->iconId = 0;
564     action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
567 static void ink_radio_action_finalize( GObject* obj )
569     InkRadioAction* action = INK_RADIO_ACTION( obj );
571     g_free( action->private_data->iconId );
572     g_free( action->private_data );
576 InkRadioAction* ink_radio_action_new( const gchar *name,
577                            const gchar *label,
578                            const gchar *tooltip,
579                            const gchar *inkId,
580                            Inkscape::IconSize size )
582     GObject* obj = (GObject*)g_object_new( INK_RADIO_ACTION_TYPE,
583                                            "name", name,
584                                            "label", label,
585                                            "tooltip", tooltip,
586                                            "iconId", inkId,
587                                            "iconSize", size,
588                                            NULL );
590     InkRadioAction* action = INK_RADIO_ACTION( obj );
592     return action;
595 static void ink_radio_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
597     InkRadioAction* action = INK_RADIO_ACTION( obj );
598     (void)action;
599     switch ( propId ) {
600         case PROP_INK_ID:
601         {
602             g_value_set_string( value, action->private_data->iconId );
603         }
604         break;
606         case PROP_INK_SIZE:
607         {
608             g_value_set_int( value, action->private_data->iconSize );
609         }
610         break;
612         default:
613             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
614     }
617 void ink_radio_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
619     InkRadioAction* action = INK_RADIO_ACTION( obj );
620     (void)action;
621     switch ( propId ) {
622         case PROP_INK_ID:
623         {
624             gchar* tmp = action->private_data->iconId;
625             action->private_data->iconId = g_value_dup_string( value );
626             g_free( tmp );
627         }
628         break;
630         case PROP_INK_SIZE:
631         {
632             action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value );
633         }
634         break;
636         default:
637         {
638             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
639         }
640     }
643 static GtkWidget* ink_radio_action_create_menu_item( GtkAction* action )
645     GtkWidget* item = gInkRadioActionParentClass->parent_class.parent_class.create_menu_item(action);
647     return item;
650 static GtkWidget* ink_radio_action_create_tool_item( GtkAction* action )
652     InkRadioAction* act = INK_RADIO_ACTION( action );
653     GtkWidget* item = gInkRadioActionParentClass->parent_class.parent_class.create_tool_item(action);
655     if ( act->private_data->iconId ) {
656         if ( GTK_IS_TOOL_BUTTON(item) ) {
657             GtkToolButton* button = GTK_TOOL_BUTTON(item);
659             GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId );
660             gtk_tool_button_set_icon_widget( button, child );
661         } else {
662             // For now trigger a warning but don't do anything else
663             GtkToolButton* button = GTK_TOOL_BUTTON(item);
664             (void)button;
665         }
666     }
668     // TODO investigate if needed
669     gtk_widget_show_all( item );
671     return item;