Code

Improved Color emboss now takes a better account of Blend settings
[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"
18 static void ink_action_class_init( InkActionClass* klass );
19 static void ink_action_init( InkAction* action );
20 static void ink_action_finalize( GObject* obj );
21 static void ink_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
22 static void ink_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
24 static GtkWidget* ink_action_create_menu_item( GtkAction* action );
25 static GtkWidget* ink_action_create_tool_item( GtkAction* action );
27 static GtkActionClass* gInkActionParentClass = 0;
29 struct _InkActionPrivate
30 {
31     gchar* iconId;
32     Inkscape::IconSize iconSize;
33 };
35 #define INK_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_ACTION_TYPE, InkActionPrivate ) )
37 GType ink_action_get_type( void )
38 {
39     static GType myType = 0;
40     if ( !myType ) {
41         static const GTypeInfo myInfo = {
42             sizeof( InkActionClass ),
43             NULL, /* base_init */
44             NULL, /* base_finalize */
45             (GClassInitFunc)ink_action_class_init,
46             NULL, /* class_finalize */
47             NULL, /* class_data */
48             sizeof( InkAction ),
49             0, /* n_preallocs */
50             (GInstanceInitFunc)ink_action_init,
51             NULL
52         };
54         myType = g_type_register_static( GTK_TYPE_ACTION, "InkAction", &myInfo, (GTypeFlags)0 );
55     }
57     return myType;
58 }
60 enum {
61     PROP_INK_ID = 1,
62     PROP_INK_SIZE
63 };
65 static void ink_action_class_init( InkActionClass* klass )
66 {
67     if ( klass ) {
68         gInkActionParentClass = GTK_ACTION_CLASS( g_type_class_peek_parent( klass ) );
69         GObjectClass * objClass = G_OBJECT_CLASS( klass );
71         objClass->finalize = ink_action_finalize;
72         objClass->get_property = ink_action_get_property;
73         objClass->set_property = ink_action_set_property;
75         klass->parent_class.create_menu_item = ink_action_create_menu_item;
76         klass->parent_class.create_tool_item = ink_action_create_tool_item;
77         /*klass->parent_class.connect_proxy = connect_proxy;*/
78         /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/
80         g_object_class_install_property( objClass,
81                                          PROP_INK_ID,
82                                          g_param_spec_string( "iconId",
83                                                               "Icon ID",
84                                                               "The id for the icon",
85                                                               "",
86                                                               (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
88         g_object_class_install_property( objClass,
89                                          PROP_INK_SIZE,
90                                          g_param_spec_int( "iconSize",
91                                                            "Icon Size",
92                                                            "The size the icon",
93                                                            (int)Inkscape::ICON_SIZE_MENU,
94                                                            (int)Inkscape::ICON_SIZE_DECORATION,
95                                                            (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
96                                                            (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
98         g_type_class_add_private( klass, sizeof(InkActionClass) );
99     }
102 static void ink_action_init( InkAction* action )
104     action->private_data = INK_ACTION_GET_PRIVATE( action );
105     action->private_data->iconId = 0;
106     action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
109 static void ink_action_finalize( GObject* obj )
111     InkAction* action = INK_ACTION( obj );
113     g_free( action->private_data->iconId );
114     g_free( action->private_data );
118 //Any strings passed in should already be localised
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)99,
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,
356                            SPAttributeEnum attr)
358     GObject* obj = (GObject*)g_object_new( INK_TOGGLE_ACTION_TYPE,
359                                            "name", name,
360                                            "label", label,
361                                            "tooltip", tooltip,
362                                            "iconId", inkId,
363                                            "iconSize", Inkscape::getRegisteredIconSize(size),
364                                            //"SP_ATTR_INKSCAPE", attr, // Why doesn't this work and do I need to use g_object_set_data below?
365                                            NULL );
367     g_object_set_data(obj, "SP_ATTR_INKSCAPE", GINT_TO_POINTER(attr));
368     InkToggleAction* action = INK_TOGGLE_ACTION( obj );
370     return action;
373 static void ink_toggle_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
375     InkToggleAction* action = INK_TOGGLE_ACTION( obj );
376     (void)action;
377     switch ( propId ) {
378         case PROP_INK_ID:
379         {
380             g_value_set_string( value, action->private_data->iconId );
381         }
382         break;
384         case PROP_INK_SIZE:
385         {
386             g_value_set_int( value, action->private_data->iconSize );
387         }
388         break;
390         default:
391             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
392     }
395 void ink_toggle_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
397     InkToggleAction* action = INK_TOGGLE_ACTION( obj );
398     (void)action;
399     switch ( propId ) {
400         case PROP_INK_ID:
401         {
402             gchar* tmp = action->private_data->iconId;
403             action->private_data->iconId = g_value_dup_string( value );
404             g_free( tmp );
406             ink_toggle_action_update_icon( action );
407         }
408         break;
410         case PROP_INK_SIZE:
411         {
412             action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value );
413         }
414         break;
416         default:
417         {
418             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
419         }
420     }
423 static GtkWidget* ink_toggle_action_create_menu_item( GtkAction* action )
425     GtkWidget* item = gInkToggleActionParentClass->parent_class.create_menu_item(action);
427     return item;
430 static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action )
432     InkToggleAction* act = INK_TOGGLE_ACTION( action );
434     GtkWidget* item = gInkToggleActionParentClass->parent_class.create_tool_item(action);
435     if ( GTK_IS_TOOL_BUTTON(item) ) {
436         GtkToolButton* button = GTK_TOOL_BUTTON(item);
437         if ( act->private_data->iconId ) {
438             GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId );
439             GtkWidget* align = gtk_alignment_new( 0.5, 0.5, 0.0, 0.0 );
440             gtk_container_add( GTK_CONTAINER(align), child );
441             gtk_tool_button_set_icon_widget( button, align );
442         } else {
443             gchar *label;
444             g_object_get (G_OBJECT(action), "short_label", &label, NULL);
445             gtk_tool_button_set_label( button, label );
446         }
447     } else {
448         // For now trigger a warning but don't do anything else
449         GtkToolButton* button = GTK_TOOL_BUTTON(item);
450         (void)button;
451     }
452     gtk_widget_show_all( item );
454     return item;
458 static void ink_toggle_action_update_icon( InkToggleAction* action )
460     if ( action ) {
461         GSList* proxies = gtk_action_get_proxies( GTK_ACTION(action) );
462         while ( proxies ) {
463             if ( GTK_IS_TOOL_ITEM(proxies->data) ) {
464                 if ( GTK_IS_TOOL_BUTTON(proxies->data) ) {
465                     GtkToolButton* button = GTK_TOOL_BUTTON(proxies->data);
467                     GtkWidget* child = sp_icon_new( action->private_data->iconSize, action->private_data->iconId );
468                     gtk_widget_show_all( child );
469                     gtk_tool_button_set_icon_widget( button, child );
470                 }
471             }
473             proxies = g_slist_next( proxies );
474         }
475     }
479 /* --------------------------------------------------------------- */
480 /* --------------------------------------------------------------- */
481 /* --------------------------------------------------------------- */
482 /* --------------------------------------------------------------- */
485 static void ink_radio_action_class_init( InkRadioActionClass* klass );
486 static void ink_radio_action_init( InkRadioAction* action );
487 static void ink_radio_action_finalize( GObject* obj );
488 static void ink_radio_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec );
489 static void ink_radio_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec );
491 static GtkWidget* ink_radio_action_create_menu_item( GtkAction* action );
492 static GtkWidget* ink_radio_action_create_tool_item( GtkAction* action );
494 static GtkRadioActionClass* gInkRadioActionParentClass = 0;
496 struct _InkRadioActionPrivate
498     gchar* iconId;
499     Inkscape::IconSize iconSize;
500 };
502 #define INK_RADIO_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_RADIO_ACTION_TYPE, InkRadioActionPrivate ) )
504 GType ink_radio_action_get_type( void )
506     static GType myType = 0;
507     if ( !myType ) {
508         static const GTypeInfo myInfo = {
509             sizeof( InkRadioActionClass ),
510             NULL, /* base_init */
511             NULL, /* base_finalize */
512             (GClassInitFunc)ink_radio_action_class_init,
513             NULL, /* class_finalize */
514             NULL, /* class_data */
515             sizeof( InkRadioAction ),
516             0, /* n_preallocs */
517             (GInstanceInitFunc)ink_radio_action_init,
518             NULL
519         };
521         myType = g_type_register_static( GTK_TYPE_RADIO_ACTION, "InkRadioAction", &myInfo, (GTypeFlags)0 );
522     }
524     return myType;
528 static void ink_radio_action_class_init( InkRadioActionClass* klass )
530     if ( klass ) {
531         gInkRadioActionParentClass = GTK_RADIO_ACTION_CLASS( g_type_class_peek_parent( klass ) );
532         GObjectClass * objClass = G_OBJECT_CLASS( klass );
534         objClass->finalize = ink_radio_action_finalize;
535         objClass->get_property = ink_radio_action_get_property;
536         objClass->set_property = ink_radio_action_set_property;
538         klass->parent_class.parent_class.parent_class.create_menu_item = ink_radio_action_create_menu_item;
539         klass->parent_class.parent_class.parent_class.create_tool_item = ink_radio_action_create_tool_item;
540         /*klass->parent_class.connect_proxy = connect_proxy;*/
541         /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/
543         g_object_class_install_property( objClass,
544                                          PROP_INK_ID,
545                                          g_param_spec_string( "iconId",
546                                                               "Icon ID",
547                                                               "The id for the icon",
548                                                               "",
549                                                               (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
551         g_object_class_install_property( objClass,
552                                          PROP_INK_SIZE,
553                                          g_param_spec_int( "iconSize",
554                                                            "Icon Size",
555                                                            "The size the icon",
556                                                            (int)Inkscape::ICON_SIZE_MENU,
557                                                            (int)Inkscape::ICON_SIZE_DECORATION,
558                                                            (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR,
559                                                            (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) );
561         g_type_class_add_private( klass, sizeof(InkRadioActionClass) );
562     }
565 static void ink_radio_action_init( InkRadioAction* action )
567     action->private_data = INK_RADIO_ACTION_GET_PRIVATE( action );
568     action->private_data->iconId = 0;
569     action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR;
572 static void ink_radio_action_finalize( GObject* obj )
574     InkRadioAction* action = INK_RADIO_ACTION( obj );
576     g_free( action->private_data->iconId );
577     g_free( action->private_data );
581 InkRadioAction* ink_radio_action_new( const gchar *name,
582                            const gchar *label,
583                            const gchar *tooltip,
584                            const gchar *inkId,
585                            Inkscape::IconSize size )
587     GObject* obj = (GObject*)g_object_new( INK_RADIO_ACTION_TYPE,
588                                            "name", name,
589                                            "label", label,
590                                            "tooltip", tooltip,
591                                            "iconId", inkId,
592                                            "iconSize", Inkscape::getRegisteredIconSize(size),
593                                            NULL );
595     InkRadioAction* action = INK_RADIO_ACTION( obj );
597     return action;
600 static void ink_radio_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec )
602     InkRadioAction* action = INK_RADIO_ACTION( obj );
603     (void)action;
604     switch ( propId ) {
605         case PROP_INK_ID:
606         {
607             g_value_set_string( value, action->private_data->iconId );
608         }
609         break;
611         case PROP_INK_SIZE:
612         {
613             g_value_set_int( value, action->private_data->iconSize );
614         }
615         break;
617         default:
618             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
619     }
622 void ink_radio_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec )
624     InkRadioAction* action = INK_RADIO_ACTION( obj );
625     (void)action;
626     switch ( propId ) {
627         case PROP_INK_ID:
628         {
629             gchar* tmp = action->private_data->iconId;
630             action->private_data->iconId = g_value_dup_string( value );
631             g_free( tmp );
632         }
633         break;
635         case PROP_INK_SIZE:
636         {
637             action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value );
638         }
639         break;
641         default:
642         {
643             G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec );
644         }
645     }
648 static GtkWidget* ink_radio_action_create_menu_item( GtkAction* action )
650     GtkWidget* item = gInkRadioActionParentClass->parent_class.parent_class.create_menu_item(action);
652     return item;
655 static GtkWidget* ink_radio_action_create_tool_item( GtkAction* action )
657     InkRadioAction* act = INK_RADIO_ACTION( action );
658     GtkWidget* item = gInkRadioActionParentClass->parent_class.parent_class.create_tool_item(action);
660     if ( act->private_data->iconId ) {
661         if ( GTK_IS_TOOL_BUTTON(item) ) {
662             GtkToolButton* button = GTK_TOOL_BUTTON(item);
664             GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId );
665             gtk_tool_button_set_icon_widget( button, child );
666         } else {
667             // For now trigger a warning but don't do anything else
668             GtkToolButton* button = GTK_TOOL_BUTTON(item);
669             (void)button;
670         }
671     }
673     // TODO investigate if needed
674     gtk_widget_show_all( item );
676     return item;