Code

Corrected initialization order.
[inkscape.git] / src / ink-action.cpp
4 #include <glib/gi18n.h>
5 #include <gtk/gtkalignment.h>
6 #include <gtk/gtktooltips.h>
7 #include <gtk/gtktoolitem.h>
8 #include <gtk/gtktoggletoolbutton.h>
9 #include <gtk/gtkcheckmenuitem.h>
10 #include <gtk/gtkimagemenuitem.h>
12 #include "icon-size.h"
13 #include "ink-action.h"
15 #include "widgets/button.h"
16 #include "widgets/icon.h"
20 static void ink_action_class_init( InkActionClass* klass );
21 static void ink_action_init( InkAction* action );
22 static void ink_action_finalize( GObject* obj );
23 static void ink_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
24 static void ink_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
26 static GtkWidget* ink_action_create_menu_item( GtkAction* action );
27 static GtkWidget* ink_action_create_tool_item( GtkAction* action );
29 static GtkActionClass* gInkActionParentClass = 0;
31 struct _InkActionPrivate
32 {
33     gchar* iconId;
34     Inkscape::IconSize iconSize;
35 };
37 #define INK_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_ACTION_TYPE, InkActionPrivate ) )
39 GType ink_action_get_type( void )
40 {
41     static GType myType = 0;
42     if ( !myType ) {
43         static const GTypeInfo myInfo = {
44             sizeof( InkActionClass ),
45             NULL, /* base_init */
46             NULL, /* base_finalize */
47             (GClassInitFunc)ink_action_class_init,
48             NULL, /* class_finalize */
49             NULL, /* class_data */
50             sizeof( InkAction ),
51             0, /* n_preallocs */
52             (GInstanceInitFunc)ink_action_init,
53             NULL
54         };
56         myType = g_type_register_static( GTK_TYPE_ACTION, "InkAction", &myInfo, (GTypeFlags)0 );
57     }
59     return myType;
60 }
62 enum {
63     PROP_INK_ID = 1,
64     PROP_INK_SIZE
65 };
67 static void ink_action_class_init( InkActionClass* klass )
68 {
69     if ( klass ) {
70         gInkActionParentClass = GTK_ACTION_CLASS( g_type_class_peek_parent( klass ) );
71         GObjectClass * objClass = G_OBJECT_CLASS( klass );
73         objClass->finalize = ink_action_finalize;
74         objClass->get_property = ink_action_get_property;
75         objClass->set_property = ink_action_set_property;
77         klass->parent_class.create_menu_item = ink_action_create_menu_item;
78         klass->parent_class.create_tool_item = ink_action_create_tool_item;
79         /*klass->parent_class.connect_proxy = connect_proxy;*/
80         /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/
82         g_object_class_install_property( objClass,
83                                          PROP_INK_ID,
84                                          g_param_spec_string( "iconId",
85                                                               "Icon ID",
86                                                               "The id for the icon",
87                                                               "",
88                                                               (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
90         g_object_class_install_property( objClass,
91                                          PROP_INK_SIZE,
92                                          g_param_spec_int( "iconSize",
93                                                            "Icon Size",
94                                                            "The size the icon",
95                                                            (int)Inkscape::ICON_SIZE_MENU,
96                                                            (int)Inkscape::ICON_SIZE_DECORATION,
97                                                            (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
98                                                            (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
100         g_type_class_add_private( klass, sizeof(InkActionClass) );
101     }
104 static void ink_action_init( InkAction* action )
106     action->private_data = INK_ACTION_GET_PRIVATE( action );
107     action->private_data->iconId = 0;
108     action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
111 static void ink_action_finalize( GObject* obj )
113     InkAction* action = INK_ACTION( obj );
115     g_free( action->private_data->iconId );
116     g_free( action->private_data );
120 //Any strings passed in should already be localised
121 InkAction* ink_action_new( const gchar *name,
122                            const gchar *label,
123                            const gchar *tooltip,
124                            const gchar *inkId,
125                            Inkscape::IconSize size )
127     GObject* obj = (GObject*)g_object_new( INK_ACTION_TYPE,
128                                            "name", name,
129                                            "label", label,
130                                            "tooltip", tooltip,
131                                            "iconId", inkId,
132                                            "iconSize", size,
133                                            NULL );
135     InkAction* action = INK_ACTION( obj );
137     return action;
140 static void ink_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
142     InkAction* action = INK_ACTION( obj );
143     (void)action;
144     switch ( propId ) {
145         case PROP_INK_ID:
146         {
147             g_value_set_string( value, action->private_data->iconId );
148         }
149         break;
151         case PROP_INK_SIZE:
152         {
153             g_value_set_int( value, action->private_data->iconSize );
154         }
155         break;
157         default:
158             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
159     }
162 void ink_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
164     InkAction* action = INK_ACTION( obj );
165     (void)action;
166     switch ( propId ) {
167         case PROP_INK_ID:
168         {
169             gchar* tmp = action->private_data->iconId;
170             action->private_data->iconId = g_value_dup_string( value );
171             g_free( tmp );
172         }
173         break;
175         case PROP_INK_SIZE:
176         {
177             action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value );
178         }
179         break;
181         default:
182         {
183             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
184         }
185     }
188 #include <gtk/gtkstock.h>
190 static GtkWidget* ink_action_create_menu_item( GtkAction* action )
192     InkAction* act = INK_ACTION( action );
193     GtkWidget* item = 0;
195     if ( act->private_data->iconId ) {
196         gchar* label = 0;
197         g_object_get( G_OBJECT(act), "label", &label, NULL );
199         item = gtk_image_menu_item_new_with_mnemonic( label );
200         GtkWidget* child = sp_icon_new( Inkscape::ICON_SIZE_MENU, act->private_data->iconId );
201         // TODO this work-around is until SPIcon will live properly inside of a popup menu
202         if ( SP_IS_ICON(child) ) {
203             SPIcon* icon = SP_ICON(child);
204             sp_icon_fetch_pixbuf( icon );
205             GdkPixbuf* target = gtk_action_is_sensitive(action) ? icon->pb : icon->pb_faded;
206             if ( target ) {
207                 child = gtk_image_new_from_pixbuf( target );
208                 gtk_widget_destroy( GTK_WIDGET(icon) );
209             }
210         }
211         gtk_widget_show_all( child );
212         gtk_image_menu_item_set_image( GTK_IMAGE_MENU_ITEM(item), child );
214         g_free( label );
215         label = 0;
216     } else {
217         item = gInkActionParentClass->create_menu_item( action );
218     }
220     return item;
223 static GtkWidget* ink_action_create_tool_item( GtkAction* action )
225     InkAction* act = INK_ACTION( action );
226     GtkWidget* item = gInkActionParentClass->create_tool_item(action);
228     if ( act->private_data->iconId ) {
229         if ( GTK_IS_TOOL_BUTTON(item) ) {
230             GtkToolButton* button = GTK_TOOL_BUTTON(item);
232             GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId );
233             gtk_tool_button_set_icon_widget( button, child );
234         } else {
235             // For now trigger a warning but don't do anything else
236             GtkToolButton* button = GTK_TOOL_BUTTON(item);
237             (void)button;
238         }
239     }
241     // TODO investigate if needed
242     gtk_widget_show_all( item );
244     return item;
249 /* --------------------------------------------------------------- */
250 /* --------------------------------------------------------------- */
251 /* --------------------------------------------------------------- */
252 /* --------------------------------------------------------------- */
255 static void ink_toggle_action_class_init( InkToggleActionClass* klass );
256 static void ink_toggle_action_init( InkToggleAction* action );
257 static void ink_toggle_action_finalize( GObject* obj );
258 static void ink_toggle_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
259 static void ink_toggle_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
261 static GtkWidget* ink_toggle_action_create_menu_item( GtkAction* action );
262 static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action );
264 static void ink_toggle_action_update_icon( InkToggleAction* action );
266 static GtkToggleActionClass* gInkToggleActionParentClass = 0;
268 struct _InkToggleActionPrivate
270     gchar* iconId;
271     Inkscape::IconSize iconSize;
272 };
274 #define INK_TOGGLE_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_TOGGLE_ACTION_TYPE, InkToggleActionPrivate ) )
276 GType ink_toggle_action_get_type( void )
278     static GType myType = 0;
279     if ( !myType ) {
280         static const GTypeInfo myInfo = {
281             sizeof( InkToggleActionClass ),
282             NULL, /* base_init */
283             NULL, /* base_finalize */
284             (GClassInitFunc)ink_toggle_action_class_init,
285             NULL, /* class_finalize */
286             NULL, /* class_data */
287             sizeof( InkToggleAction ),
288             0, /* n_preallocs */
289             (GInstanceInitFunc)ink_toggle_action_init,
290             NULL
291         };
293         myType = g_type_register_static( GTK_TYPE_TOGGLE_ACTION, "InkToggleAction", &myInfo, (GTypeFlags)0 );
294     }
296     return myType;
300 static void ink_toggle_action_class_init( InkToggleActionClass* klass )
302     if ( klass ) {
303         gInkToggleActionParentClass = GTK_TOGGLE_ACTION_CLASS( g_type_class_peek_parent( klass ) );
304         GObjectClass * objClass = G_OBJECT_CLASS( klass );
306         objClass->finalize = ink_toggle_action_finalize;
307         objClass->get_property = ink_toggle_action_get_property;
308         objClass->set_property = ink_toggle_action_set_property;
310         klass->parent_class.parent_class.create_menu_item = ink_toggle_action_create_menu_item;
311         klass->parent_class.parent_class.create_tool_item = ink_toggle_action_create_tool_item;
312         /*klass->parent_class.connect_proxy = connect_proxy;*/
313         /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/
315         g_object_class_install_property( objClass,
316                                          PROP_INK_ID,
317                                          g_param_spec_string( "iconId",
318                                                               "Icon ID",
319                                                               "The id for the icon",
320                                                               "",
321                                                               (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
323         g_object_class_install_property( objClass,
324                                          PROP_INK_SIZE,
325                                          g_param_spec_int( "iconSize",
326                                                            "Icon Size",
327                                                            "The size the icon",
328                                                            (int)Inkscape::ICON_SIZE_MENU,
329                                                            (int)99,
330                                                            (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
331                                                            (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
333         g_type_class_add_private( klass, sizeof(InkToggleActionClass) );
334     }
337 static void ink_toggle_action_init( InkToggleAction* action )
339     action->private_data = INK_TOGGLE_ACTION_GET_PRIVATE( action );
340     action->private_data->iconId = 0;
341     action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
344 static void ink_toggle_action_finalize( GObject* obj )
346     InkToggleAction* action = INK_TOGGLE_ACTION( obj );
348     g_free( action->private_data->iconId );
349     g_free( action->private_data );
353 InkToggleAction* ink_toggle_action_new( const gchar *name,
354                            const gchar *label,
355                            const gchar *tooltip,
356                            const gchar *inkId,
357                            Inkscape::IconSize size )
359     GObject* obj = (GObject*)g_object_new( INK_TOGGLE_ACTION_TYPE,
360                                            "name", name,
361                                            "label", label,
362                                            "tooltip", tooltip,
363                                            "iconId", inkId,
364                                            "iconSize", Inkscape::getRegisteredIconSize(size),
365                                            NULL );
367     InkToggleAction* action = INK_TOGGLE_ACTION( obj );
369     return action;
372 static void ink_toggle_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
374     InkToggleAction* action = INK_TOGGLE_ACTION( obj );
375     (void)action;
376     switch ( propId ) {
377         case PROP_INK_ID:
378         {
379             g_value_set_string( value, action->private_data->iconId );
380         }
381         break;
383         case PROP_INK_SIZE:
384         {
385             g_value_set_int( value, action->private_data->iconSize );
386         }
387         break;
389         default:
390             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
391     }
394 void ink_toggle_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
396     InkToggleAction* action = INK_TOGGLE_ACTION( obj );
397     (void)action;
398     switch ( propId ) {
399         case PROP_INK_ID:
400         {
401             gchar* tmp = action->private_data->iconId;
402             action->private_data->iconId = g_value_dup_string( value );
403             g_free( tmp );
405             ink_toggle_action_update_icon( action );
406         }
407         break;
409         case PROP_INK_SIZE:
410         {
411             action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value );
412         }
413         break;
415         default:
416         {
417             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
418         }
419     }
422 static GtkWidget* ink_toggle_action_create_menu_item( GtkAction* action )
424     GtkWidget* item = gInkToggleActionParentClass->parent_class.create_menu_item(action);
426     return item;
429 static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action )
431     InkToggleAction* act = INK_TOGGLE_ACTION( action );
433     GtkWidget* item = gInkToggleActionParentClass->parent_class.create_tool_item(action);
434     if ( GTK_IS_TOOL_BUTTON(item) ) {
435         GtkToolButton* button = GTK_TOOL_BUTTON(item);
436         if ( act->private_data->iconId ) {
437             GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId );
438             GtkWidget* align = gtk_alignment_new( 0.5, 0.5, 0.0, 0.0 );
439             gtk_container_add( GTK_CONTAINER(align), child );
440             gtk_tool_button_set_icon_widget( button, align );
441         } else {
442             gchar *label;
443             g_object_get (G_OBJECT(action), "short_label", &label, NULL);
444             gtk_tool_button_set_label( button, label );
445         }
446     } else {
447         // For now trigger a warning but don't do anything else
448         GtkToolButton* button = GTK_TOOL_BUTTON(item);
449         (void)button;
450     }
451     gtk_widget_show_all( item );
453     return item;
457 static void ink_toggle_action_update_icon( InkToggleAction* action )
459     if ( action ) {
460         GSList* proxies = gtk_action_get_proxies( GTK_ACTION(action) );
461         while ( proxies ) {
462             if ( GTK_IS_TOOL_ITEM(proxies->data) ) {
463                 if ( GTK_IS_TOOL_BUTTON(proxies->data) ) {
464                     GtkToolButton* button = GTK_TOOL_BUTTON(proxies->data);
466                     GtkWidget* child = sp_icon_new( action->private_data->iconSize, action->private_data->iconId );
467                     gtk_widget_show_all( child );
468                     gtk_tool_button_set_icon_widget( button, child );
469                 }
470             }
472             proxies = g_slist_next( proxies );
473         }
474     }
478 /* --------------------------------------------------------------- */
479 /* --------------------------------------------------------------- */
480 /* --------------------------------------------------------------- */
481 /* --------------------------------------------------------------- */
484 static void ink_radio_action_class_init( InkRadioActionClass* klass );
485 static void ink_radio_action_init( InkRadioAction* action );
486 static void ink_radio_action_finalize( GObject* obj );
487 static void ink_radio_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
488 static void ink_radio_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
490 static GtkWidget* ink_radio_action_create_menu_item( GtkAction* action );
491 static GtkWidget* ink_radio_action_create_tool_item( GtkAction* action );
493 static GtkRadioActionClass* gInkRadioActionParentClass = 0;
495 struct _InkRadioActionPrivate
497     gchar* iconId;
498     Inkscape::IconSize iconSize;
499 };
501 #define INK_RADIO_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_RADIO_ACTION_TYPE, InkRadioActionPrivate ) )
503 GType ink_radio_action_get_type( void )
505     static GType myType = 0;
506     if ( !myType ) {
507         static const GTypeInfo myInfo = {
508             sizeof( InkRadioActionClass ),
509             NULL, /* base_init */
510             NULL, /* base_finalize */
511             (GClassInitFunc)ink_radio_action_class_init,
512             NULL, /* class_finalize */
513             NULL, /* class_data */
514             sizeof( InkRadioAction ),
515             0, /* n_preallocs */
516             (GInstanceInitFunc)ink_radio_action_init,
517             NULL
518         };
520         myType = g_type_register_static( GTK_TYPE_RADIO_ACTION, "InkRadioAction", &myInfo, (GTypeFlags)0 );
521     }
523     return myType;
527 static void ink_radio_action_class_init( InkRadioActionClass* klass )
529     if ( klass ) {
530         gInkRadioActionParentClass = GTK_RADIO_ACTION_CLASS( g_type_class_peek_parent( klass ) );
531         GObjectClass * objClass = G_OBJECT_CLASS( klass );
533         objClass->finalize = ink_radio_action_finalize;
534         objClass->get_property = ink_radio_action_get_property;
535         objClass->set_property = ink_radio_action_set_property;
537         klass->parent_class.parent_class.parent_class.create_menu_item = ink_radio_action_create_menu_item;
538         klass->parent_class.parent_class.parent_class.create_tool_item = ink_radio_action_create_tool_item;
539         /*klass->parent_class.connect_proxy = connect_proxy;*/
540         /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/
542         g_object_class_install_property( objClass,
543                                          PROP_INK_ID,
544                                          g_param_spec_string( "iconId",
545                                                               "Icon ID",
546                                                               "The id for the icon",
547                                                               "",
548                                                               (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
550         g_object_class_install_property( objClass,
551                                          PROP_INK_SIZE,
552                                          g_param_spec_int( "iconSize",
553                                                            "Icon Size",
554                                                            "The size the icon",
555                                                            (int)Inkscape::ICON_SIZE_MENU,
556                                                            (int)Inkscape::ICON_SIZE_DECORATION,
557                                                            (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
558                                                            (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
560         g_type_class_add_private( klass, sizeof(InkRadioActionClass) );
561     }
564 static void ink_radio_action_init( InkRadioAction* action )
566     action->private_data = INK_RADIO_ACTION_GET_PRIVATE( action );
567     action->private_data->iconId = 0;
568     action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
571 static void ink_radio_action_finalize( GObject* obj )
573     InkRadioAction* action = INK_RADIO_ACTION( obj );
575     g_free( action->private_data->iconId );
576     g_free( action->private_data );
580 InkRadioAction* ink_radio_action_new( const gchar *name,
581                            const gchar *label,
582                            const gchar *tooltip,
583                            const gchar *inkId,
584                            Inkscape::IconSize size )
586     GObject* obj = (GObject*)g_object_new( INK_RADIO_ACTION_TYPE,
587                                            "name", name,
588                                            "label", label,
589                                            "tooltip", tooltip,
590                                            "iconId", inkId,
591                                            "iconSize", Inkscape::getRegisteredIconSize(size),
592                                            NULL );
594     InkRadioAction* action = INK_RADIO_ACTION( obj );
596     return action;
599 static void ink_radio_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
601     InkRadioAction* action = INK_RADIO_ACTION( obj );
602     (void)action;
603     switch ( propId ) {
604         case PROP_INK_ID:
605         {
606             g_value_set_string( value, action->private_data->iconId );
607         }
608         break;
610         case PROP_INK_SIZE:
611         {
612             g_value_set_int( value, action->private_data->iconSize );
613         }
614         break;
616         default:
617             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
618     }
621 void ink_radio_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
623     InkRadioAction* action = INK_RADIO_ACTION( obj );
624     (void)action;
625     switch ( propId ) {
626         case PROP_INK_ID:
627         {
628             gchar* tmp = action->private_data->iconId;
629             action->private_data->iconId = g_value_dup_string( value );
630             g_free( tmp );
631         }
632         break;
634         case PROP_INK_SIZE:
635         {
636             action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value );
637         }
638         break;
640         default:
641         {
642             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
643         }
644     }
647 static GtkWidget* ink_radio_action_create_menu_item( GtkAction* action )
649     GtkWidget* item = gInkRadioActionParentClass->parent_class.parent_class.create_menu_item(action);
651     return item;
654 static GtkWidget* ink_radio_action_create_tool_item( GtkAction* action )
656     InkRadioAction* act = INK_RADIO_ACTION( action );
657     GtkWidget* item = gInkRadioActionParentClass->parent_class.parent_class.create_tool_item(action);
659     if ( act->private_data->iconId ) {
660         if ( GTK_IS_TOOL_BUTTON(item) ) {
661             GtkToolButton* button = GTK_TOOL_BUTTON(item);
663             GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId );
664             gtk_tool_button_set_icon_widget( button, child );
665         } else {
666             // For now trigger a warning but don't do anything else
667             GtkToolButton* button = GTK_TOOL_BUTTON(item);
668             (void)button;
669         }
670     }
672     // TODO investigate if needed
673     gtk_widget_show_all( item );
675     return item;