From: joncruz Date: Thu, 19 Oct 2006 04:16:44 +0000 (+0000) Subject: Adding custom action to work with spinbuttons in toolbars X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=a538d96e8f6f16a20dc28b0418031a632e4a7663;p=inkscape.git Adding custom action to work with spinbuttons in toolbars --- diff --git a/src/Makefile_insert b/src/Makefile_insert index d6694a759..fec782544 100644 --- a/src/Makefile_insert +++ b/src/Makefile_insert @@ -270,6 +270,8 @@ libinkpost_a_SOURCES = \ color.cpp color.h \ decimal-round.h \ dir-util.cpp dir-util.h \ + ege-adjustment-action.cpp \ + ege-adjustment-action.h \ fill-or-stroke.h \ filter-chemistry.cpp filter-chemistry.h \ fixes.cpp \ @@ -281,6 +283,8 @@ libinkpost_a_SOURCES = \ gc-soft-ptr.h \ gc.cpp \ gradient-chemistry.cpp gradient-chemistry.h \ + ink-action.cpp \ + ink-action.h \ memeq.h \ round.h \ streq.h \ diff --git a/src/ege-adjustment-action.cpp b/src/ege-adjustment-action.cpp new file mode 100644 index 000000000..52037f1e9 --- /dev/null +++ b/src/ege-adjustment-action.cpp @@ -0,0 +1,328 @@ + + +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is EGE Adjustment Action. + * + * The Initial Developer of the Original Code is + * Jon A. Cruz. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +/* Note: this file should be kept compliable as both .cpp and .c */ + +#include + +#include +#include +#include +#include +#include + +#include "ege-adjustment-action.h" + + +static void ege_adjustment_action_class_init( EgeAdjustmentActionClass* klass ); +static void ege_adjustment_action_init( EgeAdjustmentAction* action ); +static void ege_adjustment_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ); +static void ege_adjustment_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ); + +static GtkWidget* create_menu_item( GtkAction* action ); +static GtkWidget* create_tool_item( GtkAction* action ); +static void connect_proxy( GtkAction *action, GtkWidget *proxy ); +static void disconnect_proxy( GtkAction *action, GtkWidget *proxy ); + +static gboolean focus_in_cb( GtkWidget *widget, GdkEventKey *event, gpointer data ); +static gboolean keypress_cb( GtkWidget *widget, GdkEventKey *event, gpointer data ); + +static GtkActionClass* gParentClass = 0; + + +struct _EgeAdjustmentActionPrivate +{ + GtkAdjustment* adj; + GtkWidget* focusWidget; + gdouble lastVal; + gboolean keepFocus; +}; + +#define EGE_ADJUSTMENT_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), EGE_ADJUSTMENT_ACTION_TYPE, EgeAdjustmentActionPrivate ) ) + +enum { + PROP_ADJUSTMENT = 1, + PROP_FOCUS_WIDGET +}; + +GType ege_adjustment_action_get_type( void ) +{ + static GType myType = 0; + if ( !myType ) { + static const GTypeInfo myInfo = { + sizeof( EgeAdjustmentActionClass ), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)ege_adjustment_action_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof( EgeAdjustmentAction ), + 0, /* n_preallocs */ + (GInstanceInitFunc)ege_adjustment_action_init, + NULL + }; + + myType = g_type_register_static( GTK_TYPE_ACTION, "EgeAdjustmentAction", &myInfo, (GTypeFlags)0 ); + } + + return myType; +} + + +static void ege_adjustment_action_class_init( EgeAdjustmentActionClass* klass ) +{ + if ( klass ) { + gParentClass = GTK_ACTION_CLASS( g_type_class_peek_parent( klass ) ); + GObjectClass * objClass = G_OBJECT_CLASS( klass ); + + objClass->get_property = ege_adjustment_action_get_property; + objClass->set_property = ege_adjustment_action_set_property; + + klass->parent_class.create_menu_item = create_menu_item; + klass->parent_class.create_tool_item = create_tool_item; + klass->parent_class.connect_proxy = connect_proxy; + klass->parent_class.disconnect_proxy = disconnect_proxy; + + g_object_class_install_property( objClass, + PROP_ADJUSTMENT, + g_param_spec_pointer( "adjustment", + "Adjustment", + "The adjustment to change", + (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); + + g_object_class_install_property( objClass, + PROP_FOCUS_WIDGET, + g_param_spec_pointer( "focus-widget", + "Focus Widget", + "The widget to return focus to", + (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); + + g_type_class_add_private( klass, sizeof(EgeAdjustmentActionClass) ); + } +} + +static void ege_adjustment_action_init( EgeAdjustmentAction* action ) +{ + action->private_data = EGE_ADJUSTMENT_ACTION_GET_PRIVATE( action ); + action->private_data->adj = 0; + action->private_data->focusWidget = 0; + action->private_data->lastVal = 0.0; + action->private_data->keepFocus = FALSE; +} + +EgeAdjustmentAction* ege_adjustment_action_new( GtkAdjustment* adjustment, + const gchar *name, + const gchar *label, + const gchar *tooltip, + const gchar *stock_id ) +{ + GObject* obj = (GObject*)g_object_new( EGE_ADJUSTMENT_ACTION_TYPE, + "name", name, + "label", label, + "tooltip", tooltip, + "stock_id", stock_id, + "adjustment", adjustment, + NULL ); + + EgeAdjustmentAction* action = EGE_ADJUSTMENT_ACTION( obj ); + + return action; +} + +static void ege_adjustment_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ) +{ + EgeAdjustmentAction* action = EGE_ADJUSTMENT_ACTION( obj ); + switch ( propId ) { + case PROP_ADJUSTMENT: + { + g_value_set_pointer( value, action->private_data->adj ); + } + break; + + case PROP_FOCUS_WIDGET: + { + g_value_set_pointer( value, action->private_data->focusWidget ); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); + } +} + +void ege_adjustment_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ) +{ + EgeAdjustmentAction* action = EGE_ADJUSTMENT_ACTION( obj ); + switch ( propId ) { + case PROP_ADJUSTMENT: + { + action->private_data->adj = (GtkAdjustment*)g_value_get_pointer( value ); + } + break; + + case PROP_FOCUS_WIDGET: + { + /* TODO unhook prior */ + action->private_data->focusWidget = (GtkWidget*)g_value_get_pointer( value ); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); + } +} + +GtkAdjustment* ege_adjustment_action_get_adjustment( EgeAdjustmentAction* action ) +{ + g_return_val_if_fail( IS_EGE_ADJUSTMENT_ACTION(action), NULL ); + + return action->private_data->adj; +} + +void ege_adjustment_action_set_focuswidget( EgeAdjustmentAction* action, GtkWidget* widget ) +{ + g_return_if_fail( IS_EGE_ADJUSTMENT_ACTION(action) ); + + /* TODO unhook prior */ + + action->private_data->focusWidget = widget; +} + +GtkWidget* ege_adjustment_action_get_focuswidget( EgeAdjustmentAction* action ) +{ + g_return_val_if_fail( IS_EGE_ADJUSTMENT_ACTION(action), NULL ); + + return action->private_data->focusWidget; +} + +static GtkWidget* create_menu_item( GtkAction* action ) +{ + GtkWidget* item = 0; + + item = gParentClass->create_menu_item( action ); + + return item; +} + +/* void flippy(GtkAdjustment *adj, GtkWidget *) */ +/* { */ +/* g_message("flippy on %p to %f", adj, gtk_adjustment_get_value(adj) ); */ +/* } */ + +/* void floppy(GtkSpinButton *spin, GtkWidget *) */ +/* { */ +/* g_message("f__ppy on %p to %f", spin, gtk_spin_button_get_value(spin) ); */ +/* } */ + +static GtkWidget* create_tool_item( GtkAction* action ) +{ + GtkWidget* item = 0; + + if ( IS_EGE_ADJUSTMENT_ACTION(action) ) { + GtkWidget* spinbutton = gtk_spin_button_new( EGE_ADJUSTMENT_ACTION(action)->private_data->adj, 0.1, 2 ); + GtkWidget* hb = gtk_hbox_new( FALSE, 5 ); + GValue value; + + item = GTK_WIDGET( gtk_tool_item_new() ); + + memset( &value, 0, sizeof(value) ); + g_value_init( &value, G_TYPE_STRING ); + g_object_get_property( G_OBJECT(action), "label", &value ); + const gchar* sss = g_value_get_string( &value ); + GtkWidget* lbl = gtk_label_new( sss ? sss : "wwww" ); + + gtk_misc_set_alignment( GTK_MISC(lbl), 1.0, 0.5 ); + + gtk_box_pack_start( GTK_BOX(hb), lbl, FALSE, FALSE, 0 ); + gtk_box_pack_end( GTK_BOX(hb), spinbutton, FALSE, FALSE, 0 ); + gtk_container_add( GTK_CONTAINER(item), hb ); + + g_signal_connect( G_OBJECT(spinbutton), "focus-in-event", G_CALLBACK(focus_in_cb), action ); + g_signal_connect( G_OBJECT(spinbutton), "key-press-event", G_CALLBACK(keypress_cb), action ); + +/* g_signal_connect( G_OBJECT(spinbutton), "value-changed", G_CALLBACK(floppy), action ); */ +/* g_signal_connect( G_OBJECT(EGE_ADJUSTMENT_ACTION(action)->private_data->adj), "value-changed", G_CALLBACK(flippy), action ); */ + + + gtk_widget_show_all( item ); + } else { + item = gParentClass->create_tool_item( action ); + } + + return item; +} + +static void connect_proxy( GtkAction *action, GtkWidget *proxy ) +{ + gParentClass->connect_proxy( action, proxy ); +} + +static void disconnect_proxy( GtkAction *action, GtkWidget *proxy ) +{ + gParentClass->disconnect_proxy( action, proxy ); +} + +void ege_adjustment_action_defocus( EgeAdjustmentAction* action ) +{ + if ( action->private_data->keepFocus ) { + action->private_data->keepFocus = FALSE; + } else { + if ( action->private_data->focusWidget ) { + gtk_widget_grab_focus( action->private_data->focusWidget ); + } + } +} + +gboolean focus_in_cb( GtkWidget *widget, GdkEventKey *event, gpointer data ) +{ + if ( IS_EGE_ADJUSTMENT_ACTION(data) ) { + EgeAdjustmentAction* action = EGE_ADJUSTMENT_ACTION( data ); + action->private_data->lastVal = gtk_spin_button_get_value( GTK_SPIN_BUTTON(widget) ); + } + + return FALSE; /* report event not consumed */ +} + +gboolean keypress_cb( GtkWidget *widget, GdkEventKey *event, gpointer data ) +{ + + return FALSE; /* report event not consumed */ +} diff --git a/src/ege-adjustment-action.h b/src/ege-adjustment-action.h new file mode 100644 index 000000000..ec93ffbaa --- /dev/null +++ b/src/ege-adjustment-action.h @@ -0,0 +1,89 @@ +#ifndef SEEN_EGE_ADJUSTMENT_ACTION +#define SEEN_EGE_ADJUSTMENT_ACTION +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- + * + */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is EGE Adjustment Action. + * + * The Initial Developer of the Original Code is + * Jon A. Cruz. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + + +#include +#include +#include + +G_BEGIN_DECLS + + +#define EGE_ADJUSTMENT_ACTION_TYPE ( ege_adjustment_action_get_type() ) +#define EGE_ADJUSTMENT_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), EGE_ADJUSTMENT_ACTION_TYPE, EgeAdjustmentAction) ) +#define EGE_ADJUSTMENT_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), EGE_ADJUSTMENT_ACTION_TYPE, EgeAdjustmentActionClass) ) +#define IS_EGE_ADJUSTMENT_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), EGE_ADJUSTMENT_ACTION_TYPE) ) +#define IS_EGE_ADJUSTMENT_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), EGE_ADJUSTMENT_ACTION_TYPE) ) +#define EGE_ADJUSTMENT_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), EGE_ADJUSTMENT_ACTION_TYPE, EgeAdjustmentActionClass) ) + +typedef struct _EgeAdjustmentAction EgeAdjustmentAction; +typedef struct _EgeAdjustmentActionClass EgeAdjustmentActionClass; +typedef struct _EgeAdjustmentActionPrivate EgeAdjustmentActionPrivate; + +struct _EgeAdjustmentAction +{ + GtkAction action; + EgeAdjustmentActionPrivate *private_data; +}; + +struct _EgeAdjustmentActionClass +{ + GtkActionClass parent_class; +}; + +GType ege_adjustment_action_get_type( void ); + +EgeAdjustmentAction* ege_adjustment_action_new( GtkAdjustment* adjustment, + const gchar *name, + const gchar *label, + const gchar *tooltip, + const gchar *stock_id ); + +GtkAdjustment* ege_adjustment_action_get_adjustment( EgeAdjustmentAction* action ); + +void ege_adjustment_action_set_focuswidget( EgeAdjustmentAction* action, GtkWidget* widget ); +GtkWidget* ege_adjustment_action_get_focuswidget( EgeAdjustmentAction* action ); + +void ege_adjustment_action_defocus( EgeAdjustmentAction* action ); + +G_END_DECLS + +#endif /* SEEN_EGE_ADJUSTMENT_ACTION */ diff --git a/src/ink-action.cpp b/src/ink-action.cpp new file mode 100644 index 000000000..8ed055bea --- /dev/null +++ b/src/ink-action.cpp @@ -0,0 +1,391 @@ + + + +#include +#include +#include +#include +#include + +#include "icon-size.h" +#include "ink-action.h" + +#include "widgets/button.h" +#include "widgets/icon.h" + + + +static void ink_action_class_init( InkActionClass* klass ); +static void ink_action_init( InkAction* action ); +static void ink_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ); +static void ink_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ); + +static GtkWidget* ink_action_create_menu_item( GtkAction* action ); +static GtkWidget* ink_action_create_tool_item( GtkAction* action ); + +static GtkActionClass* gInkActionParentClass = 0; + +GType ink_action_get_type( void ) +{ + static GType myType = 0; + if ( !myType ) { + static const GTypeInfo myInfo = { + sizeof( InkActionClass ), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)ink_action_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof( InkAction ), + 0, /* n_preallocs */ + (GInstanceInitFunc)ink_action_init, + NULL + }; + + myType = g_type_register_static( GTK_TYPE_ACTION, "InkAction", &myInfo, (GTypeFlags)0 ); + } + + return myType; +} + +enum { + PROP_INK_ID = 1, + PROP_INK_SIZE +}; + +static void ink_action_class_init( InkActionClass* klass ) +{ + if ( klass ) { + gInkActionParentClass = GTK_ACTION_CLASS( g_type_class_peek_parent( klass ) ); + GObjectClass * objClass = G_OBJECT_CLASS( klass ); + + objClass->get_property = ink_action_get_property; + objClass->set_property = ink_action_set_property; + + klass->parent_class.create_menu_item = ink_action_create_menu_item; + klass->parent_class.create_tool_item = ink_action_create_tool_item; + /*klass->parent_class.connect_proxy = connect_proxy;*/ + /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/ + + g_object_class_install_property( objClass, + PROP_INK_ID, + g_param_spec_string( "iconId", + "Icon ID", + "The id for the icon", + "", + (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); + + g_object_class_install_property( objClass, + PROP_INK_SIZE, + g_param_spec_int( "iconSize", + "Icon Size", + "The size the icon", + (int)Inkscape::ICON_SIZE_MENU, + (int)Inkscape::ICON_SIZE_DECORATION, + (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR, + (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); + } +} + +static void ink_action_init( InkAction* action ) +{ +} + +InkAction* ink_action_new( const gchar *name, + const gchar *label, + const gchar *tooltip, + const gchar *inkId, + Inkscape::IconSize size ) +{ + GObject* obj = (GObject*)g_object_new( INK_ACTION_TYPE, + "name", name, + "label", label, + "tooltip", tooltip, + "iconId", inkId, + "iconSize", size, + NULL ); + + InkAction* action = INK_ACTION( obj ); + + return action; +} + +static void ink_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ) +{ + InkAction* action = INK_ACTION( obj ); + (void)action; + switch ( propId ) { + case PROP_INK_ID: + { + //g_value_set_pointer( value, action->private_data->adj ); + } + break; + + case PROP_INK_SIZE: + { + //g_value_set_pointer( value, action->private_data->adj ); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); + } +} + +void ink_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ) +{ + InkAction* action = INK_ACTION( obj ); + (void)action; + switch ( propId ) { + case PROP_INK_ID: + { +// gchar* tmp = action->private_data->iconId; +// action->private_data->iconId = g_value_dup_string( value ); +// g_free( tmp ); + } + break; + + case PROP_INK_SIZE: + { +// action->private_data->iconSize = g_value_get_( value ); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); + } +} + +static GtkWidget* ink_action_create_menu_item( GtkAction* action ) +{ + GtkWidget* item = 0; + g_message("INK ACTION CREATE MENU ITEM"); + item = gInkActionParentClass->create_menu_item( action ); + return item; +} + +static GtkWidget* ink_action_create_tool_item( GtkAction* action ) +{ + GtkWidget* item = 0; + g_message("INK ACTION CREATE TOOL ITEM"); + + + //item = gInkActionParentClass->create_tool_item( action ); + GtkTooltips *tt = gtk_tooltips_new(); + GtkWidget *button = sp_button_new_from_data( Inkscape::ICON_SIZE_DECORATION, + SP_BUTTON_TYPE_NORMAL, + NULL, + "use_pressure", + _("Use the pressure of the input device to alter the width of the pen"), + tt); + //g_signal_connect_after (G_OBJECT (button), "clicked", G_CALLBACK (sp_ddc_pressure_state_changed), NULL); + //gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (button), prefs_get_int_attribute ("tools.calligraphic", "usepressure", 1)); + item = GTK_WIDGET(gtk_tool_item_new()); + gtk_container_add( GTK_CONTAINER(item), button ); + + gtk_widget_show_all( item ); + + return item; +} + + + +/* --------------------------------------------------------------- */ +/* --------------------------------------------------------------- */ +/* --------------------------------------------------------------- */ +/* --------------------------------------------------------------- */ + + +static void ink_toggle_action_class_init( InkToggleActionClass* klass ); +static void ink_toggle_action_init( InkToggleAction* action ); +static void ink_toggle_action_finalize( GObject* obj ); +static void ink_toggle_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ); +static void ink_toggle_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ); + +static GtkWidget* ink_toggle_action_create_menu_item( GtkAction* action ); +static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action ); + +static GtkToggleActionClass* gInkToggleActionParentClass = 0; + +struct _InkToggleActionPrivate +{ + gchar* iconId; + Inkscape::IconSize iconSize; +}; + +#define INK_TOGGLE_ACTION_GET_PRIVATE( o ) ( G_TYPE_INSTANCE_GET_PRIVATE( (o), INK_TOGGLE_ACTION_TYPE, InkToggleActionPrivate ) ) + +GType ink_toggle_action_get_type( void ) +{ + static GType myType = 0; + if ( !myType ) { + static const GTypeInfo myInfo = { + sizeof( InkToggleActionClass ), + NULL, /* base_init */ + NULL, /* base_finalize */ + (GClassInitFunc)ink_toggle_action_class_init, + NULL, /* class_finalize */ + NULL, /* class_data */ + sizeof( InkToggleAction ), + 0, /* n_preallocs */ + (GInstanceInitFunc)ink_toggle_action_init, + NULL + }; + + myType = g_type_register_static( GTK_TYPE_TOGGLE_ACTION, "InkToggleAction", &myInfo, (GTypeFlags)0 ); + } + + return myType; +} + + +static void ink_toggle_action_class_init( InkToggleActionClass* klass ) +{ + if ( klass ) { + gInkToggleActionParentClass = GTK_TOGGLE_ACTION_CLASS( g_type_class_peek_parent( klass ) ); + GObjectClass * objClass = G_OBJECT_CLASS( klass ); + + objClass->finalize = ink_toggle_action_finalize; + objClass->get_property = ink_toggle_action_get_property; + objClass->set_property = ink_toggle_action_set_property; + + klass->parent_class.parent_class.create_menu_item = ink_toggle_action_create_menu_item; + klass->parent_class.parent_class.create_tool_item = ink_toggle_action_create_tool_item; + /*klass->parent_class.connect_proxy = connect_proxy;*/ + /*klass->parent_class.disconnect_proxy = disconnect_proxy;*/ + + g_object_class_install_property( objClass, + PROP_INK_ID, + g_param_spec_string( "iconId", + "Icon ID", + "The id for the icon", + "", + (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); + + g_object_class_install_property( objClass, + PROP_INK_SIZE, + g_param_spec_int( "iconSize", + "Icon Size", + "The size the icon", + (int)Inkscape::ICON_SIZE_MENU, + (int)Inkscape::ICON_SIZE_DECORATION, + (int)Inkscape::ICON_SIZE_SMALL_TOOLBAR, + (GParamFlags)(G_PARAM_READABLE | G_PARAM_WRITABLE | G_PARAM_CONSTRUCT) ) ); + + g_type_class_add_private( klass, sizeof(InkToggleActionClass) ); + } +} + +static void ink_toggle_action_init( InkToggleAction* action ) +{ + action->private_data = INK_TOGGLE_ACTION_GET_PRIVATE( action ); + action->private_data->iconId = 0; + action->private_data->iconSize = Inkscape::ICON_SIZE_SMALL_TOOLBAR; +} + +static void ink_toggle_action_finalize( GObject* obj ) +{ + InkToggleAction* action = INK_TOGGLE_ACTION( obj ); + + g_free( action->private_data->iconId ); + g_free( action->private_data ); + +} + +InkToggleAction* ink_toggle_action_new( const gchar *name, + const gchar *label, + const gchar *tooltip, + const gchar *inkId, + Inkscape::IconSize size ) +{ + GObject* obj = (GObject*)g_object_new( INK_TOGGLE_ACTION_TYPE, + "name", name, + "label", label, + "tooltip", tooltip, + "iconId", inkId, + "iconSize", size, + NULL ); + + InkToggleAction* action = INK_TOGGLE_ACTION( obj ); + + return action; +} + +static void ink_toggle_action_get_property( GObject* obj, guint propId, GValue* value, GParamSpec * pspec ) +{ + InkToggleAction* action = INK_TOGGLE_ACTION( obj ); + (void)action; + switch ( propId ) { + case PROP_INK_ID: + { + g_value_set_string( value, action->private_data->iconId ); + } + break; + + case PROP_INK_SIZE: + { + g_value_set_int( value, action->private_data->iconSize ); + } + break; + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); + } +} + +void ink_toggle_action_set_property( GObject* obj, guint propId, const GValue *value, GParamSpec* pspec ) +{ + InkToggleAction* action = INK_TOGGLE_ACTION( obj ); + (void)action; + switch ( propId ) { + case PROP_INK_ID: + { + gchar* tmp = action->private_data->iconId; + action->private_data->iconId = g_value_dup_string( value ); + g_free( tmp ); + } + break; + + case PROP_INK_SIZE: + { + action->private_data->iconSize = (Inkscape::IconSize)g_value_get_int( value ); + } + break; + + default: + { + G_OBJECT_WARN_INVALID_PROPERTY_ID( obj, propId, pspec ); + } + } +} + +static GtkWidget* ink_toggle_action_create_menu_item( GtkAction* action ) +{ + GtkWidget* item = gInkToggleActionParentClass->parent_class.create_menu_item(action); + + return item; +} + +static GtkWidget* ink_toggle_action_create_tool_item( GtkAction* action ) +{ + InkToggleAction* act = INK_TOGGLE_ACTION( action ); + GtkWidget* item = gInkToggleActionParentClass->parent_class.create_tool_item(action); + + if ( act->private_data->iconId ) { + if ( GTK_IS_TOOL_BUTTON(item) ) { + GtkToolButton* button = GTK_TOOL_BUTTON(item); + + GtkWidget* child = sp_icon_new( act->private_data->iconSize, act->private_data->iconId ); + gtk_tool_button_set_icon_widget( button, child ); + } else { + // For now trigger a warning but don't do anything else + GtkToolButton* button = GTK_TOOL_BUTTON(item); + (void)button; + } + } + + // TODO investigate if needed + gtk_widget_show_all( item ); + + return item; +} diff --git a/src/ink-action.h b/src/ink-action.h new file mode 100644 index 000000000..8122393f9 --- /dev/null +++ b/src/ink-action.h @@ -0,0 +1,85 @@ +#ifndef SEEN_INK_ACTION +#define SEEN_INK_ACTION + + +#include +#include +#include +#include + +G_BEGIN_DECLS + +#define INK_ACTION_TYPE ( ink_action_get_type() ) +#define INK_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), INK_ACTION_TYPE, InkAction) ) +#define INK_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), INK_ACTION_TYPE, InkActionClass) ) +#define IS_INK_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), INK_ACTION_TYPE) ) +#define IS_INK_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), INK_ACTION_TYPE) ) +#define INK_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), INK_ACTION_TYPE, InkActionClass) ) + +typedef struct _InkAction InkAction; +typedef struct _InkActionClass InkActionClass; +typedef struct _InkActionPrivate InkActionPrivate; + +struct _InkAction +{ + GtkAction action; + InkActionPrivate *private_data; +}; + +struct _InkActionClass +{ + GtkActionClass parent_class; +}; + +GType ink_action_get_type( void ); + +InkAction* ink_action_new( const gchar *name, + const gchar *label, + const gchar *tooltip, + const gchar *inkId, + Inkscape::IconSize size ); + + +/* --------------------------------------------------------------- */ +/* --------------------------------------------------------------- */ +/* --------------------------------------------------------------- */ +/* --------------------------------------------------------------- */ + + +#define INK_TOGGLE_ACTION_TYPE ( ink_toggle_action_get_type() ) +#define INK_TOGGLE_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_CAST( (obj), INK_TOGGLE_ACTION_TYPE, InkToggleAction) ) +#define INK_TOGGLE_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( (klass), INK_TOGGLE_ACTION_TYPE, InkToggleActionClass) ) +#define IS_INK_TOGGLE_ACTION( obj ) ( G_TYPE_CHECK_INSTANCE_TYPE( (obj), INK_TOGGLE_ACTION_TYPE) ) +#define IS_INK_TOGGLE_ACTION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE( (klass), INK_TOGGLE_ACTION_TYPE) ) +#define INK_TOGGLE_ACTION_GET_CLASS( obj ) ( G_TYPE_INSTANCE_GET_CLASS( (obj), INK_TOGGLE_ACTION_TYPE, InkToggleActionClass) ) + +typedef struct _InkToggleAction InkToggleAction; +typedef struct _InkToggleActionClass InkToggleActionClass; +typedef struct _InkToggleActionPrivate InkToggleActionPrivate; + +struct _InkToggleAction +{ + GtkToggleAction action; + InkToggleActionPrivate *private_data; +}; + +struct _InkToggleActionClass +{ + GtkToggleActionClass parent_class; +}; + +GType ink_toggle_action_get_type( void ); + +InkToggleAction* ink_toggle_action_new( const gchar *name, + const gchar *label, + const gchar *tooltip, + const gchar *inkId, + Inkscape::IconSize size ); + + + +G_END_DECLS + +#endif /* SEEN_INK_ACTION */ + + diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index 1e4401f10..17fc0e736 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -15,10 +15,11 @@ * John Cliff * David Turner * Josh Andler +* Jon A. Cruz * * Copyright (C) 2004 David Turner * Copyright (C) 2003 MenTaLguY -* Copyright (C) 1999-2005 authors +* Copyright (C) 1999-2006 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -82,6 +83,9 @@ #include "toolbox.h" +#include "ink-action.h" +#include "ege-adjustment-action.h" + typedef void (*SetupFunction)(GtkWidget *toolbox, SPDesktop *desktop); typedef void (*UpdateFunction)(SPDesktop *desktop, SPEventContext *eventcontext, GtkWidget *toolbox); @@ -811,6 +815,32 @@ sp_tb_spinbutton( return hb; } +static EgeAdjustmentAction * create_adjustment_action( gchar const *name, + gchar const *label, gchar const *tooltip, + gchar const *path, gchar const *data, gdouble def, + GtkWidget *us, + GtkWidget *dataKludge, + gboolean altx, gchar const *altx_mark, + gdouble lower, gdouble upper, gdouble step, gdouble page, + void (*callback)(GtkAdjustment *, GtkWidget *), + gdouble climb = 0.1, guint digits = 3, double factor = 1.0 ) +{ + GtkAdjustment* adj = GTK_ADJUSTMENT( gtk_adjustment_new( prefs_get_double_attribute(path, data, def) * factor, + lower, upper, step, page, page ) ); + if (us) { + sp_unit_selector_add_adjustment( SP_UNIT_SELECTOR(us), adj ); + } + + gtk_signal_connect( GTK_OBJECT(adj), "value-changed", GTK_SIGNAL_FUNC(callback), dataKludge ); + + EgeAdjustmentAction* act = ege_adjustment_action_new( adj, name, label, tooltip, 0 ); + + gtk_object_set_data( GTK_OBJECT(dataKludge), data, adj ); + + return act; +} + + #define MODE_LABEL_WIDTH 70 //######################## @@ -1935,6 +1965,94 @@ sp_pencil_toolbox_new(SPDesktop *desktop) //## Calligraphy ## //######################## +static void sp_ddc_mass_value_changed2( GtkAdjustment *adj, GtkWidget *tbl ) +{ + prefs_set_double_attribute( "tools.calligraphic", "mass", adj->value ); + //spinbutton_defocus(GTK_OBJECT(tbl)); +} + +static void sp_ddc_wiggle_value_changed2( GtkAdjustment *adj, GtkWidget *tbl ) +{ + prefs_set_double_attribute( "tools.calligraphic", "wiggle", adj->value ); +// spinbutton_defocus(GTK_OBJECT(tbl)); +} + +static void sp_ddc_angle_value_changed2( GtkAdjustment *adj, GtkWidget *tbl ) +{ + prefs_set_double_attribute( "tools.calligraphic", "angle", adj->value ); +// spinbutton_defocus(GTK_OBJECT(tbl)); +} + +static void sp_ddc_width_value_changed2( GtkAdjustment *adj, GtkWidget *tbl ) +{ + prefs_set_double_attribute( "tools.calligraphic", "width", adj->value * 0.01 ); +// spinbutton_defocus(GTK_OBJECT(tbl)); +} + +static void sp_ddc_velthin_value_changed2( GtkAdjustment *adj, GtkWidget *tbl ) +{ + prefs_set_double_attribute("tools.calligraphic", "thinning", adj->value); +// spinbutton_defocus(GTK_OBJECT(tbl)); +} + +static void sp_ddc_flatness_value_changed2( GtkAdjustment *adj, GtkWidget *tbl ) +{ + prefs_set_double_attribute( "tools.calligraphic", "flatness", adj->value ); +// spinbutton_defocus(GTK_OBJECT(tbl)); +} + +static void sp_ddc_tremor_value_changed2( GtkAdjustment *adj, GtkWidget *tbl ) +{ + prefs_set_double_attribute( "tools.calligraphic", "tremor", adj->value ); +// spinbutton_defocus(GTK_OBJECT(tbl)); +} + +static void sp_ddc_cap_rounding_value_changed2( GtkAdjustment *adj, GtkWidget *tbl ) +{ + prefs_set_double_attribute( "tools.calligraphic", "cap_rounding", adj->value ); +// spinbutton_defocus(GTK_OBJECT(tbl)); +} + +static void sp_ddc_pressure_state_changed2( GtkToggleAction *act, gpointer data ) +{ + prefs_set_int_attribute( "tools.calligraphic", "usepressure", gtk_toggle_action_get_active( act ) ? 1 : 0); +} + +static void sp_ddc_tilt_state_changed2( GtkToggleAction *act, GtkAction *calligraphy_angle ) +{ + prefs_set_int_attribute( "tools.calligraphic", "usetilt", gtk_toggle_action_get_active( act ) ? 1 : 0 ); + + gtk_action_set_sensitive( calligraphy_angle, gtk_toggle_action_get_active( act ) ); +} + +static void sp_ddc_defaults2(GtkWidget *, GtkWidget *dataKludge) +{ + // FIXME: make defaults settable via Inkscape Options + struct KeyValue { + char const *key; + double value; + } const key_values[] = { + {"mass", 0.02}, + {"wiggle", 0.0}, + {"angle", 30.0}, + {"width", 15}, + {"thinning", 0.1}, + {"tremor", 0.0}, + {"flatness", 0.9}, + {"cap_rounding", 0.0} + }; + + for (unsigned i = 0; i < G_N_ELEMENTS(key_values); ++i) { + KeyValue const &kv = key_values[i]; + GtkAdjustment* adj = static_cast(gtk_object_get_data(GTK_OBJECT(dataKludge), kv.key)); + if ( adj ) { + gtk_adjustment_set_value(adj, kv.value); + } + } + +// spinbutton_defocus(GTK_OBJECT(tbl)); +} + static void sp_ddc_mass_value_changed(GtkAdjustment *adj, GtkWidget *tbl) { @@ -2031,9 +2149,186 @@ static void sp_ddc_defaults(GtkWidget *, GtkWidget *tbl) spinbutton_defocus(GTK_OBJECT(tbl)); } + + + static GtkWidget * sp_calligraphy_toolbox_new(SPDesktop *desktop) { + if ( prefs_get_int_attribute_limited( "options.stocktoolbars", "value", 0, 0, 1 ) ) { + GtkWidget *toolBar = 0; + GtkWidget* holder = gtk_table_new( 1, 2, FALSE ); + + gchar const * descr = + "" + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + " " + ""; + GtkUIManager* mgr = gtk_ui_manager_new(); + GError* errVal = 0; + GtkActionGroup* mainActions = gtk_action_group_new("main"); + + { + EgeAdjustmentAction* calligraphy_angle = 0; + EgeAdjustmentAction* eact = 0; + + /* Width */ + eact = create_adjustment_action( "WidthAction", + _("Width:"), _("The width of the calligraphic pen (relative to the visible canvas area)"), + "tools.calligraphic", "width", 15, + NULL, holder, TRUE, "altx-calligraphy", + 1, 100, 1.0, 10.0, + sp_ddc_width_value_changed2, 0.01, 0, 100 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + + /* Thinning */ + eact = create_adjustment_action( "ThinningAction", + _("Thinning:"), _("How much velocity thins the stroke (> 0 makes fast strokes thinner, < 0 makes them broader, 0 makes width independent of velocity)"), + "tools.calligraphic", "thinning", 0.1, + NULL, holder, FALSE, NULL, + -1.0, 1.0, 0.01, 0.1, + sp_ddc_velthin_value_changed2, 0.01, 2); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + + /* Angle */ + eact = create_adjustment_action( "AngleAction", + _("Angle:"), _("The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if fixation = 0)"), + "tools.calligraphic", "angle", 30, + NULL, holder, TRUE, "calligraphy-angle", + -90.0, 90.0, 1.0, 10.0, + sp_ddc_angle_value_changed2, 1, 0 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + calligraphy_angle = eact; + + /* Fixation */ + eact = create_adjustment_action( "FixationAction", + _("Fixation:"), _("Angle behavior (0 = nib always perpendicular to stroke direction, 1 = fixed angle)"), + "tools.calligraphic", "flatness", 0.9, + NULL, holder, FALSE, NULL, + 0.0, 1.0, 0.01, 0.1, + sp_ddc_flatness_value_changed2, 0.01, 2 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + + /* Cap Rounding */ + // TRANSLATORS: "cap" means "end" (both start and finish) here + eact = create_adjustment_action( "CapRoundingAction", + _("Round:"), _("Increase to round the ends of strokes"), + "tools.calligraphic", "cap_rounding", 0.0, + NULL, holder, FALSE, NULL, + 0.0, 1.0, 0.01, 0.1, + sp_ddc_cap_rounding_value_changed2, 0.01, 2 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + + /* Tremor */ + eact = create_adjustment_action( "TremorAction", + _("Tremor:"), _("Increase to make strokes rugged and trembling"), + "tools.calligraphic", "tremor", 0.0, + NULL, holder, FALSE, NULL, + 0.0, 1.0, 0.01, 0.1, + sp_ddc_tremor_value_changed2, 0.01, 2 ); + + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + + /* Wiggle */ + eact = create_adjustment_action( "WiggleAction", + _("Wiggle:"), _("Increase to make the pen waver and wiggle"), + "tools.calligraphic", "wiggle", 0.0, + NULL, holder, FALSE, NULL, + 0.0, 1.0, 0.01, 0.1, + sp_ddc_wiggle_value_changed2, 0.01, 2 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + + /* Mass */ + eact = create_adjustment_action( "MassAction", + _("Mass:"), _("Increase to make the pen drag behind, as if slowed by inertia"), + "tools.calligraphic", "mass", 0.02, + NULL, holder, FALSE, NULL, + 0.0, 1.0, 0.01, 0.1, + sp_ddc_mass_value_changed2, 0.01, 2 ); + gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); + gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); + + + /* Use Pressure button */ + { + InkToggleAction* act = ink_toggle_action_new( "PressureAction", + "Pressure", + "Use the pressure of the input device to alter the width of the pen", + "use_pressure", + Inkscape::ICON_SIZE_DECORATION ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_ddc_pressure_state_changed2), NULL); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.calligraphic", "usepressure", 1 ) ); + } + + /* Use Tilt button */ + { + InkToggleAction* act = ink_toggle_action_new( "TiltAction", + "Tilt", + "Use the tilt of the input device to alter the angle of the pen's nib", + "use_tilt", + Inkscape::ICON_SIZE_DECORATION ); + gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); + g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_ddc_tilt_state_changed2), calligraphy_angle ); + gtk_action_set_sensitive( GTK_ACTION(calligraphy_angle), prefs_get_int_attribute( "tools.calligraphic", "usetilt", 1 ) ); + gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs_get_int_attribute( "tools.calligraphic", "usetilt", 1 ) ); + } + + /* Reset */ + { + GtkAction* act = gtk_action_new( "ResetAction", + _("Defaults"), + _("Reset shape parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), + GTK_STOCK_CLEAR ); + g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_ddc_defaults2), holder ); + gtk_action_group_add_action( mainActions, act ); + gtk_action_set_sensitive( act, TRUE ); + } + } + + + gtk_ui_manager_insert_action_group( mgr, mainActions, 0 ); + gtk_ui_manager_add_ui_from_string( mgr, descr, -1, &errVal ); + + toolBar = gtk_ui_manager_get_widget( mgr, "/ui/CalligraphyToolbar" ); + gtk_toolbar_set_style( GTK_TOOLBAR(toolBar), GTK_TOOLBAR_ICONS ); + gtk_toolbar_set_icon_size( GTK_TOOLBAR(toolBar), GTK_ICON_SIZE_SMALL_TOOLBAR ); + + + gtk_table_attach( GTK_TABLE(holder), toolBar, 0, 1, 0, 1, (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), 0, 0 ); + + Inkscape::UI::Widget::StyleSwatch *swatch = new Inkscape::UI::Widget::StyleSwatch(NULL); + swatch->setWatchedTool ("tools.calligraphic", true); + GtkWidget *swatch_ = GTK_WIDGET(swatch->gobj()); + gtk_table_attach( GTK_TABLE(holder), swatch_, 1, 2, 0, 1, (GtkAttachOptions)(GTK_SHRINK | GTK_FILL), (GtkAttachOptions)(GTK_EXPAND | GTK_FILL), AUX_BETWEEN_BUTTON_GROUPS, 0 ); + + gtk_widget_show_all(holder); + //sp_set_font_size_smaller (tbl); + + return holder; + } else { GtkWidget *tbl = gtk_hbox_new(FALSE, 0); gtk_object_set_data(GTK_OBJECT(tbl), "dtw", desktop->canvas); gtk_object_set_data(GTK_OBJECT(tbl), "desktop", desktop); @@ -2189,6 +2484,7 @@ sp_calligraphy_toolbox_new(SPDesktop *desktop) sp_set_font_size_smaller (tbl); return tbl; + } }