diff options
| author | John Smith <john.smith7545@yahoo.com> | 2012-05-08 05:21:59 +0000 |
|---|---|---|
| committer | John Smith <removethis.john.q.public@bigmail.com> | 2012-05-08 05:21:59 +0000 |
| commit | 7572ee2641532716d219a9a11f03e87511ed0bab (patch) | |
| tree | 72c9ccfe5b54a179a32ddbf4cae9ee07f34ce90b /src/widgets/toolbox.cpp | |
| parent | Fixing to use explicit enum types instead of generic guint & bool. (diff) | |
| download | inkscape-7572ee2641532716d219a9a11f03e87511ed0bab.tar.gz inkscape-7572ee2641532716d219a9a11f03e87511ed0bab.zip | |
Fix for 986446 : Refactor toolbox into tool specific files
(bzr r11346)
Diffstat (limited to 'src/widgets/toolbox.cpp')
| -rw-r--r-- | src/widgets/toolbox.cpp | 6849 |
1 files changed, 31 insertions, 6818 deletions
diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp index f29ac581d..50e4b1504 100644 --- a/src/widgets/toolbox.cpp +++ b/src/widgets/toolbox.cpp @@ -1,7 +1,7 @@ /** * @file - * Controls bars for some of Inkscape's tools (for some tools, - * they are in their own files). + * Inkscape toolbar definitions and general utility functions. + * Each tool should have its own xxx-toolbar implementation file */ /* Authors: * MenTaLguY <mental@rydia.net> @@ -29,33 +29,19 @@ # include "config.h" #endif -#include <cstring> -#include <string> -#include "live_effects/lpe-line_segment.h" +#include <gtkmm/box.h> #include <gtkmm/action.h> #include <gtkmm/actiongroup.h> #include <gtkmm/toolitem.h> - -#include "../libnrtype/font-lister.h" -#include <iostream> -#include <sstream> #include <glibmm/i18n.h> -#include "../box3d-context.h" -#include "../box3d.h" -#include "../conn-avoid-ref.h" -#include "../connection-pool.h" -#include "../connector-context.h" #include "../desktop.h" #include "../desktop-handles.h" #include "../desktop-style.h" -#include "../dialogs/dialog-events.h" -#include "../document-private.h" +#include "document-undo.h" #include "../ege-adjustment-action.h" #include "../ege-output-action.h" #include "../ege-select-one-action.h" -#include "../flood-context.h" -#include "gradient-toolbar.h" #include "../graphlayout.h" #include "../helper/unit-menu.h" #include "../helper/units.h" @@ -65,39 +51,10 @@ #include "../ink-comboboxentry-action.h" #include "../inkscape.h" #include "../interface.h" -#include "../libnrtype/font-instance.h" -#include "../live_effects/effect.h" -#include "../live_effects/lpe-angle_bisector.h" -#include "../lpe-tool-context.h" -#include "../mod360.h" -#include "../pen-context.h" -#include "../preferences.h" -#include "../selection-chemistry.h" -#include "../selection.h" -#include "select-toolbar.h" -#include "../shape-editor.h" #include "../shortcuts.h" -#include "../sp-clippath.h" -#include "../sp-ellipse.h" -#include "../sp-flowtext.h" -#include "../sp-mask.h" #include "../sp-namedview.h" -#include "../sp-rect.h" -#include "../sp-spiral.h" -#include "../sp-star.h" -#include "../sp-text.h" -#include "../style.h" -#include "../svg/css-ostringstream.h" -#include "../text-context.h" -#include "../text-editing.h" #include "../tools-switch.h" -#include "../tweak-context.h" -#include "../spray-context.h" -#include "../ui/dialog/calligraphic-profile-rename.h" #include "../ui/icon-names.h" -#include "../ui/tool/control-point-selection.h" -#include "../ui/tool/node-tool.h" -#include "../ui/tool/multi-path-manipulator.h" #include "../ui/widget/style-swatch.h" #include "../verbs.h" #include "../widgets/button.h" @@ -110,6 +67,28 @@ #include "../xml/repr.h" #include "ui/uxmanager.h" + +#include "arc-toolbar.h" +#include "box3d-toolbar.h" +#include "calligraphy-toolbar.h" +#include "connector-toolbar.h" +#include "dropper-toolbar.h" +#include "erasor-toolbar.h" +#include "gradient-toolbar.h" +#include "lpe-toolbar.h" +#include "measure-toolbar.h" +#include "node-toolbar.h" +#include "rect-toolbar.h" +#include "paintbucket-toolbar.h" +#include "pencil-toolbar.h" +#include "select-toolbar.h" +#include "spray-toolbar.h" +#include "spiral-toolbar.h" +#include "star-toolbar.h" +#include "tweak-toolbar.h" +#include "text-toolbar.h" +#include "zoom-toolbar.h" + #include "toolbox.h" #include <gtk/gtk.h> @@ -122,6 +101,8 @@ using Inkscape::UnitTracker; using Inkscape::UI::UXManager; using Inkscape::DocumentUndo; +using Inkscape::UI::PrefPusher; +using Inkscape::UI::ToolboxFactory; typedef void (*SetupFunction)(GtkWidget *toolbox, SPDesktop *desktop); typedef void (*UpdateFunction)(SPDesktop *desktop, SPEventContext *eventcontext, GtkWidget *toolbox); @@ -136,28 +117,7 @@ enum BarId { #define BAR_ID_KEY "BarIdValue" #define HANDLE_POS_MARK "x-inkscape-pos" -static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_zoom_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_measure_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_pen_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_dropper_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); static GtkWidget *sp_empty_toolbox_new(SPDesktop *desktop); -static void sp_connector_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); -static void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder); - -using Inkscape::UI::ToolboxFactory; Inkscape::IconSize ToolboxFactory::prefToSize( Glib::ustring const &path, int base ) { @@ -256,8 +216,6 @@ static struct { { NULL, NULL, NULL, NULL, NULL, SP_VERB_INVALID, NULL, NULL } }; -#define TOOLBAR_SLIDER_HINT "full" - static gchar const * ui_descr = "<ui>" " <toolbar name='SelectToolbar'>" @@ -719,13 +677,13 @@ void VerbAction::on_activate() *dropper_opacity_entry ; */ // should be made a private member once this is converted to class -static void delete_connection(GObject * /*obj*/, sigc::connection *connection) +void delete_connection(GObject * /*obj*/, sigc::connection *connection) { connection->disconnect(); delete connection; } -static void purge_repr_listener( GObject* /*obj*/, GObject* tbl ) +void purge_repr_listener( GObject* /*obj*/, GObject* tbl ) { Inkscape::XML::Node* oldrepr = reinterpret_cast<Inkscape::XML::Node *>( g_object_get_data( tbl, "repr" ) ); if (oldrepr) { // remove old listener @@ -736,56 +694,6 @@ static void purge_repr_listener( GObject* /*obj*/, GObject* tbl ) } } -// ------------------------------------------------------ - -/** - * A simple mediator class that keeps UI controls matched to the preference values they set. - */ -class PrefPusher : public Inkscape::Preferences::Observer -{ -public: - /** - * Constructor for a boolean value that syncs to the supplied path. - * Initializes the widget to the current preference stored state and registers callbacks - * for widget changes and preference changes. - * - * @param act the widget to synchronize preference with. - * @param path the path to the preference the widget is synchronized with. - * @param callback function to invoke when changes are pushed. - * @param cbData data to be passed on to the callback function. - */ - PrefPusher( GtkToggleAction *act, Glib::ustring const &path, void (*callback)(GObject*) = 0, GObject *cbData = 0 ); - - /** - * Destructor that unregisters the preference callback. - */ - virtual ~PrefPusher(); - - /** - * Callback method invoked when the preference setting changes. - */ - virtual void notify(Inkscape::Preferences::Entry const &new_val); - -private: - /** - * Callback hook invoked when the widget changes. - * - * @param act the toggle action widget that was changed. - * @param self the PrefPusher instance the callback was registered to. - */ - static void toggleCB( GtkToggleAction *act, PrefPusher *self ); - - /** - * Method to handle the widget change. - */ - void handleToggled(); - - GtkToggleAction *act; - void (*callback)(GObject*); - GObject *cbData; - bool freeze; -}; - PrefPusher::PrefPusher( GtkToggleAction *act, Glib::ustring const &path, void (*callback)(GObject*), GObject *cbData ) : Observer(path), act(act), @@ -835,7 +743,7 @@ void PrefPusher::notify(Inkscape::Preferences::Entry const &newVal) } } -static void delete_prefspusher(GObject * /*obj*/, PrefPusher *watcher ) +void delete_prefspusher(GObject * /*obj*/, PrefPusher *watcher ) { delete watcher; } @@ -1187,653 +1095,6 @@ EgeAdjustmentAction * create_adjustment_action( gchar const *name, } -//#################################### -//# node editing callbacks -//#################################### - -/** Temporary hack: Returns the node tool in the active desktop. - * Will go away during tool refactoring. */ -static InkNodeTool *get_node_tool() -{ - InkNodeTool *tool = 0; - if (SP_ACTIVE_DESKTOP ) { - SPEventContext *ec = SP_ACTIVE_DESKTOP->event_context; - if (INK_IS_NODE_TOOL(ec)) { - tool = static_cast<InkNodeTool*>(ec); - } - } - return tool; -} - -static void sp_node_path_edit_add(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->insertNodes(); - } -} - -static void sp_node_path_edit_add_min_x(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->insertNodesAtExtrema(Inkscape::UI::PointManipulator::EXTR_MIN_X); - } -} -static void sp_node_path_edit_add_max_x(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->insertNodesAtExtrema(Inkscape::UI::PointManipulator::EXTR_MAX_X); - } -} -static void sp_node_path_edit_add_min_y(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->insertNodesAtExtrema(Inkscape::UI::PointManipulator::EXTR_MIN_Y); - } -} -static void sp_node_path_edit_add_max_y(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->insertNodesAtExtrema(Inkscape::UI::PointManipulator::EXTR_MAX_Y); - } -} - -static void sp_node_path_edit_delete(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - nt->_multipath->deleteNodes(prefs->getBool("/tools/nodes/delete_preserves_shape", true)); - } -} - -static void sp_node_path_edit_delete_segment(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->deleteSegments(); - } -} - -static void sp_node_path_edit_break(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->breakNodes(); - } -} - -static void sp_node_path_edit_join(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->joinNodes(); - } -} - -static void sp_node_path_edit_join_segment(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->joinSegments(); - } -} - -static void sp_node_path_edit_toline(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->setSegmentType(Inkscape::UI::SEGMENT_STRAIGHT); - } -} - -static void sp_node_path_edit_tocurve(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->setSegmentType(Inkscape::UI::SEGMENT_CUBIC_BEZIER); - } -} - -static void sp_node_path_edit_cusp(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->setNodeType(Inkscape::UI::NODE_CUSP); - } -} - -static void sp_node_path_edit_smooth(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->setNodeType(Inkscape::UI::NODE_SMOOTH); - } -} - -static void sp_node_path_edit_symmetrical(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->setNodeType(Inkscape::UI::NODE_SYMMETRIC); - } -} - -static void sp_node_path_edit_auto(void) -{ - InkNodeTool *nt = get_node_tool(); - if (nt) { - nt->_multipath->setNodeType(Inkscape::UI::NODE_AUTO); - } -} - -static void sp_node_path_edit_nextLPEparam(GtkAction * /*act*/, gpointer data) { - sp_selection_next_patheffect_param( reinterpret_cast<SPDesktop*>(data) ); -} - -/* is called when the node selection is modified */ -static void sp_node_toolbox_coord_changed(gpointer /*shape_editor*/, GObject *tbl) -{ - GtkAction* xact = GTK_ACTION( g_object_get_data( tbl, "nodes_x_action" ) ); - GtkAction* yact = GTK_ACTION( g_object_get_data( tbl, "nodes_y_action" ) ); - GtkAdjustment *xadj = ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION(xact)); - GtkAdjustment *yadj = ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION(yact)); - - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); - - UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) ); - if (!tracker) { - return; - } - SPUnit const *unit = tracker->getActiveUnit(); - - InkNodeTool *nt = get_node_tool(); - if (!nt || nt->_selected_nodes->empty()) { - // no path selected - gtk_action_set_sensitive(xact, FALSE); - gtk_action_set_sensitive(yact, FALSE); - } else { - gtk_action_set_sensitive(xact, TRUE); - gtk_action_set_sensitive(yact, TRUE); - Geom::Coord oldx = sp_units_get_pixels(gtk_adjustment_get_value(xadj), *unit); - Geom::Coord oldy = sp_units_get_pixels(gtk_adjustment_get_value(xadj), *unit); - Geom::Point mid = nt->_selected_nodes->pointwiseBounds()->midpoint(); - - if (oldx != mid[Geom::X]) { - gtk_adjustment_set_value(xadj, sp_pixels_get_units(mid[Geom::X], *unit)); - } - if (oldy != mid[Geom::Y]) { - gtk_adjustment_set_value(yadj, sp_pixels_get_units(mid[Geom::Y], *unit)); - } - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_node_path_value_changed(GtkAdjustment *adj, GObject *tbl, Geom::Dim2 d) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - UnitTracker* tracker = reinterpret_cast<UnitTracker*>(g_object_get_data( tbl, "tracker" )); - if (!tracker) { - return; - } - SPUnit const *unit = tracker->getActiveUnit(); - - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { - prefs->setDouble(Glib::ustring("/tools/nodes/") + (d == Geom::X ? "x" : "y"), - sp_units_get_pixels(gtk_adjustment_get_value(adj), *unit)); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); - - InkNodeTool *nt = get_node_tool(); - if (nt && !nt->_selected_nodes->empty()) { - double val = sp_units_get_pixels(gtk_adjustment_get_value(adj), *unit); - double oldval = nt->_selected_nodes->pointwiseBounds()->midpoint()[d]; - Geom::Point delta(0,0); - delta[d] = val - oldval; - nt->_multipath->move(delta); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_node_path_x_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_node_path_value_changed(adj, tbl, Geom::X); -} - -static void sp_node_path_y_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_node_path_value_changed(adj, tbl, Geom::Y); -} - -static void sp_node_toolbox_sel_changed(Inkscape::Selection *selection, GObject *tbl) -{ - { - GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "nodes_lpeedit" ) ); - SPItem *item = selection->singleItem(); - if (item && SP_IS_LPE_ITEM(item)) { - if (sp_lpe_item_has_path_effect(SP_LPE_ITEM(item))) { - gtk_action_set_sensitive(w, TRUE); - } else { - gtk_action_set_sensitive(w, FALSE); - } - } else { - gtk_action_set_sensitive(w, FALSE); - } - } -} - -static void sp_node_toolbox_sel_modified(Inkscape::Selection *selection, guint /*flags*/, GObject *tbl) -{ - sp_node_toolbox_sel_changed (selection, tbl); -} - - - -//################################ -//## Node Editing Toolbox ## -//################################ - -static void sp_node_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - UnitTracker* tracker = new UnitTracker( SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE ); - tracker->setActiveUnit( sp_desktop_namedview(desktop)->doc_units ); - g_object_set_data( holder, "tracker", tracker ); - - Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - { - InkToolMenuAction* inky = ink_tool_menu_action_new( "NodeInsertAction", - _("Insert node"), - _("Insert new nodes into selected segments"), - INKSCAPE_ICON("node-add"), - secondarySize ); - g_object_set( INK_ACTION(inky), "short_label", _("Insert"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - GtkToolItem *menu_tool_button = gtk_menu_tool_button_new (NULL, NULL); - gtk_activatable_set_related_action (GTK_ACTIVATABLE (menu_tool_button), GTK_ACTION(inky)); - // also create dummy menu action: - gtk_action_group_add_action( mainActions, gtk_action_new("NodeInsertActionMenu", NULL, NULL, NULL) ); - } - - { - InkAction* inky = ink_action_new( "NodeInsertActionMinX", - _("Insert node at min X"), - _("Insert new nodes at min X into selected segments"), - INKSCAPE_ICON("node_insert_min_x"), - secondarySize ); - g_object_set( inky, "short_label", _("Insert min X"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add_min_x), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - { - InkAction* inky = ink_action_new( "NodeInsertActionMaxX", - _("Insert node at max X"), - _("Insert new nodes at max X into selected segments"), - INKSCAPE_ICON("node_insert_max_x"), - secondarySize ); - g_object_set( inky, "short_label", _("Insert max X"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add_max_x), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - { - InkAction* inky = ink_action_new( "NodeInsertActionMinY", - _("Insert node at min Y"), - _("Insert new nodes at min Y into selected segments"), - INKSCAPE_ICON("node_insert_min_y"), - secondarySize ); - g_object_set( inky, "short_label", _("Insert min Y"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add_min_y), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - { - InkAction* inky = ink_action_new( "NodeInsertActionMaxY", - _("Insert node at max Y"), - _("Insert new nodes at max Y into selected segments"), - INKSCAPE_ICON("node_insert_max_y"), - secondarySize ); - g_object_set( inky, "short_label", _("Insert max Y"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_add_max_y), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeDeleteAction", - _("Delete node"), - _("Delete selected nodes"), - INKSCAPE_ICON("node-delete"), - secondarySize ); - g_object_set( inky, "short_label", _("Delete"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_delete), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeJoinAction", - _("Join nodes"), - _("Join selected nodes"), - INKSCAPE_ICON("node-join"), - secondarySize ); - g_object_set( inky, "short_label", _("Join"), NULL ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_join), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeBreakAction", - _("Break nodes"), - _("Break path at selected nodes"), - INKSCAPE_ICON("node-break"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_break), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - - { - InkAction* inky = ink_action_new( "NodeJoinSegmentAction", - _("Join with segment"), - _("Join selected endnodes with a new segment"), - INKSCAPE_ICON("node-join-segment"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_join_segment), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeDeleteSegmentAction", - _("Delete segment"), - _("Delete segment between two non-endpoint nodes"), - INKSCAPE_ICON("node-delete-segment"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_delete_segment), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeCuspAction", - _("Node Cusp"), - _("Make selected nodes corner"), - INKSCAPE_ICON("node-type-cusp"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_cusp), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeSmoothAction", - _("Node Smooth"), - _("Make selected nodes smooth"), - INKSCAPE_ICON("node-type-smooth"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_smooth), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeSymmetricAction", - _("Node Symmetric"), - _("Make selected nodes symmetric"), - INKSCAPE_ICON("node-type-symmetric"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_symmetrical), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeAutoAction", - _("Node Auto"), - _("Make selected nodes auto-smooth"), - INKSCAPE_ICON("node-type-auto-smooth"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_auto), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeLineAction", - _("Node Line"), - _("Make selected segments lines"), - INKSCAPE_ICON("node-segment-line"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_toline), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "NodeCurveAction", - _("Node Curve"), - _("Make selected segments curves"), - INKSCAPE_ICON("node-segment-curve"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_tocurve), 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkToggleAction* act = ink_toggle_action_new( "NodesShowTransformHandlesAction", - _("Show Transform Handles"), - _("Show transformation handles for selected nodes"), - "node-transform", - secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/nodes/show_transform_handles"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - } - - { - InkToggleAction* act = ink_toggle_action_new( "NodesShowHandlesAction", - _("Show Handles"), - _("Show Bezier handles of selected nodes"), - INKSCAPE_ICON("show-node-handles"), - secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/nodes/show_handles"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - } - - { - InkToggleAction* act = ink_toggle_action_new( "NodesShowHelperpath", - _("Show Outline"), - _("Show path outline (without path effects)"), - INKSCAPE_ICON("show-path-outline"), - secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/nodes/show_outline"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - } - - { - Inkscape::Verb* verb = Inkscape::Verb::get(SP_VERB_EDIT_NEXT_PATHEFFECT_PARAMETER); - InkAction* inky = ink_action_new( verb->get_id(), - verb->get_name(), - verb->get_tip(), - INKSCAPE_ICON("path-effect-parameter-next"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_node_path_edit_nextLPEparam), desktop ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - g_object_set_data( holder, "nodes_lpeedit", inky); - } - - { - InkToggleAction* inky = ink_toggle_action_new( "ObjectEditClipPathAction", - _("Edit clipping paths"), - _("Show clipping path(s) of selected object(s)"), - INKSCAPE_ICON("path-clip-edit"), - secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(inky), "/tools/nodes/edit_clipping_paths"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - } - - { - InkToggleAction* inky = ink_toggle_action_new( "ObjectEditMaskPathAction", - _("Edit masks"), - _("Show mask(s) of selected object(s)"), - INKSCAPE_ICON("path-mask-edit"), - secondarySize ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(inky), "/tools/nodes/edit_masks"); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - } - - /* X coord of selected node(s) */ - { - EgeAdjustmentAction* eact = 0; - gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; - eact = create_adjustment_action( "NodeXAction", - _("X coordinate:"), _("X:"), _("X coordinate of selected node(s)"), - "/tools/nodes/Xcoord", 0, - GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, TRUE, "altx-nodes", - -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - labels, values, G_N_ELEMENTS(labels), - sp_node_path_x_value_changed ); - tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); - g_object_set_data( holder, "nodes_x_action", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* Y coord of selected node(s) */ - { - EgeAdjustmentAction* eact = 0; - gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; - eact = create_adjustment_action( "NodeYAction", - _("Y coordinate:"), _("Y:"), _("Y coordinate of selected node(s)"), - "/tools/nodes/Ycoord", 0, - GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, FALSE, NULL, - -1e6, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - labels, values, G_N_ELEMENTS(labels), - sp_node_path_y_value_changed ); - tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); - g_object_set_data( holder, "nodes_y_action", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - // add the units menu - { - GtkAction* act = tracker->createAction( "NodeUnitsAction", _("Units"), ("") ); - gtk_action_group_add_action( mainActions, act ); - } - - - sp_node_toolbox_sel_changed(sp_desktop_selection(desktop), holder); - - //watch selection - Inkscape::ConnectionPool* pool = Inkscape::ConnectionPool::new_connection_pool ("ISNodeToolbox"); - - sigc::connection *c_selection_changed = - new sigc::connection (sp_desktop_selection (desktop)->connectChanged - (sigc::bind (sigc::ptr_fun (sp_node_toolbox_sel_changed), (GObject*)holder))); - pool->add_connection ("selection-changed", c_selection_changed); - - sigc::connection *c_selection_modified = - new sigc::connection (sp_desktop_selection (desktop)->connectModified - (sigc::bind (sigc::ptr_fun (sp_node_toolbox_sel_modified), (GObject*)holder))); - pool->add_connection ("selection-modified", c_selection_modified); - - sigc::connection *c_subselection_changed = - new sigc::connection (desktop->connectToolSubselectionChanged - (sigc::bind (sigc::ptr_fun (sp_node_toolbox_coord_changed), (GObject*)holder))); - pool->add_connection ("tool-subselection-changed", c_subselection_changed); - - Inkscape::ConnectionPool::connect_destroy (G_OBJECT (holder), pool); - - g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); -} // end of sp_node_toolbox_prep() - - -//######################## -//## Zoom Toolbox ## -//######################## - -static void sp_zoom_toolbox_prep(SPDesktop * /*desktop*/, GtkActionGroup* /*mainActions*/, GObject* /*holder*/) -{ - // no custom GtkAction setup needed -} // end of sp_zoom_toolbox_prep() - -static void -sp_measure_fontsize_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); - - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt(Glib::ustring("/tools/measure/fontsize"), - gtk_adjustment_get_value(adj)); - } -} - -static void measure_unit_changed(GtkAction* /*act*/, GObject* tbl) -{ - UnitTracker* tracker = reinterpret_cast<UnitTracker*>(g_object_get_data(tbl, "tracker")); - SPUnit const *unit = tracker->getActiveUnit(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/measure/unitid", unit->unit_id); -} - -static void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObject* holder) -{ - UnitTracker* tracker = new UnitTracker( SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE ); - tracker->setActiveUnit( sp_desktop_namedview(desktop)->doc_units ); - g_object_set_data( holder, "tracker", tracker ); - - EgeAdjustmentAction *eact = 0; - - /* Font Size */ - { - eact = create_adjustment_action( "MeasureFontSizeAction", - _("Font Size"), _("Font Size:"), - _("The font size to be used in the measurement labels"), - "/tools/measure/fontsize", 0.0, - GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL, - 10, 36, 1.0, 4.0, - 0, 0, 0, - sp_measure_fontsize_value_changed); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - - // units label - { - EgeOutputAction* act = ege_output_action_new( "measure_units_label", _("Units:"), _("The units to be used for the measurements"), 0 ); - ege_output_action_set_use_markup( act, TRUE ); - g_object_set( act, "visible-overflown", FALSE, NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - } - - // units menu - { - GtkAction* act = tracker->createAction( "MeasureUnitsAction", _("Units:"), _("The units to be used for the measurements") ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(measure_unit_changed), (GObject*)holder ); - gtk_action_group_add_action( mainActions, act ); - } -} // end of sp_measure_toolbox_prep() - void ToolboxFactory::setToolboxDesktop(GtkWidget *toolbox, SPDesktop *desktop) { sigc::connection *conn = static_cast<sigc::connection*>(g_object_get_data(G_OBJECT(toolbox), @@ -2741,6054 +2002,6 @@ static GtkWidget *sp_empty_toolbox_new(SPDesktop *desktop) #define MODE_LABEL_WIDTH 70 -//######################## -//## Star ## -//######################## - -static void sp_stb_magnitude_value_changed( GtkAdjustment *adj, GObject *dataKludge ) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" ); - - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { - // do not remember prefs if this call is initiated by an undo change, because undoing object - // creation sets bogus values to its attributes before it is deleted - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/shapes/star/magnitude", - (gint)gtk_adjustment_get_value(adj)); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( dataKludge, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); - - bool modmade = false; - - Inkscape::Selection *selection = sp_desktop_selection(desktop); - GSList const *items = selection->itemList(); - for (; items != NULL; items = items->next) { - SPItem *item = reinterpret_cast<SPItem*>(items->data); - if (SP_IS_STAR(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - sp_repr_set_int(repr,"sodipodi:sides", - (gint)gtk_adjustment_get_value(adj)); - double arg1 = 0.5; - sp_repr_get_double(repr, "sodipodi:arg1", &arg1); - sp_repr_set_svg_double(repr, "sodipodi:arg2", - (arg1 + M_PI / (gint)gtk_adjustment_get_value(adj))); - item->updateRepr(); - modmade = true; - } - } - if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, - _("Star: Change number of corners")); - } - - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_stb_proportion_value_changed( GtkAdjustment *adj, GObject *dataKludge ) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" ); - - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { - if (!IS_NAN(gtk_adjustment_get_value(adj))) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/shapes/star/proportion", - gtk_adjustment_get_value(adj)); - } - } - - // quit if run by the attr_changed listener - if (g_object_get_data( dataKludge, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); - - bool modmade = false; - Inkscape::Selection *selection = sp_desktop_selection(desktop); - GSList const *items = selection->itemList(); - for (; items != NULL; items = items->next) { - SPItem *item = reinterpret_cast<SPItem *>(items->data); - if (SP_IS_STAR(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - - gdouble r1 = 1.0; - gdouble r2 = 1.0; - sp_repr_get_double(repr, "sodipodi:r1", &r1); - sp_repr_get_double(repr, "sodipodi:r2", &r2); - if (r2 < r1) { - sp_repr_set_svg_double(repr, "sodipodi:r2", - r1*gtk_adjustment_get_value(adj)); - } else { - sp_repr_set_svg_double(repr, "sodipodi:r1", - r2*gtk_adjustment_get_value(adj)); - } - - item->updateRepr(); - modmade = true; - } - } - - if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, - _("Star: Change spoke ratio")); - } - - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_stb_sides_flat_state_changed( EgeSelectOneAction *act, GObject *dataKludge ) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" ); - bool flat = ege_select_one_action_get_active( act ) == 0; - - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool( "/tools/shapes/star/isflatsided", flat); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( dataKludge, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); - - Inkscape::Selection *selection = sp_desktop_selection(desktop); - GSList const *items = selection->itemList(); - GtkAction* prop_action = GTK_ACTION( g_object_get_data( dataKludge, "prop_action" ) ); - bool modmade = false; - - if ( prop_action ) { - gtk_action_set_sensitive( prop_action, !flat ); - } - - for (; items != NULL; items = items->next) { - SPItem *item = reinterpret_cast<SPItem *>(items->data); - if (SP_IS_STAR(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - repr->setAttribute("inkscape:flatsided", flat ? "true" : "false" ); - item->updateRepr(); - modmade = true; - } - } - - if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, - flat ? _("Make polygon") : _("Make star")); - } - - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_stb_rounded_value_changed( GtkAdjustment *adj, GObject *dataKludge ) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" ); - - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/shapes/star/rounded", (gdouble) gtk_adjustment_get_value(adj)); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( dataKludge, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); - - bool modmade = false; - - Inkscape::Selection *selection = sp_desktop_selection(desktop); - GSList const *items = selection->itemList(); - for (; items != NULL; items = items->next) { - SPItem *item = reinterpret_cast<SPItem*>(items->data); - if (SP_IS_STAR(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - sp_repr_set_svg_double(repr, "inkscape:rounded", - (gdouble) gtk_adjustment_get_value(adj)); - item->updateRepr(); - modmade = true; - } - } - if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, - _("Star: Change rounding")); - } - - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_stb_randomized_value_changed( GtkAdjustment *adj, GObject *dataKludge ) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" ); - - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/shapes/star/randomized", - (gdouble) gtk_adjustment_get_value(adj)); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( dataKludge, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(TRUE) ); - - bool modmade = false; - - Inkscape::Selection *selection = sp_desktop_selection(desktop); - GSList const *items = selection->itemList(); - for (; items != NULL; items = items->next) { - SPItem *item = reinterpret_cast<SPItem *>(items->data); - if (SP_IS_STAR(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - sp_repr_set_svg_double(repr, "inkscape:randomized", - (gdouble) gtk_adjustment_get_value(adj)); - item->updateRepr(); - modmade = true; - } - } - if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_STAR, - _("Star: Change randomization")); - } - - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); -} - - -static void star_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const *name, - gchar const * /*old_value*/, gchar const * /*new_value*/, - bool /*is_interactive*/, gpointer data) -{ - GtkWidget *tbl = GTK_WIDGET(data); - - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - - // in turn, prevent callbacks from responding - g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE)); - - GtkAdjustment *adj = 0; - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool isFlatSided = prefs->getBool("/tools/shapes/star/isflatsided", true); - - if (!strcmp(name, "inkscape:randomized")) { - adj = GTK_ADJUSTMENT( g_object_get_data(G_OBJECT(tbl), "randomized") ); - double randomized = 0.0; - sp_repr_get_double(repr, "inkscape:randomized", &randomized); - gtk_adjustment_set_value(adj, randomized); - } else if (!strcmp(name, "inkscape:rounded")) { - adj = GTK_ADJUSTMENT( g_object_get_data(G_OBJECT(tbl), "rounded") ); - double rounded = 0.0; - sp_repr_get_double(repr, "inkscape:rounded", &rounded); - gtk_adjustment_set_value(adj, rounded); - } else if (!strcmp(name, "inkscape:flatsided")) { - GtkAction* prop_action = GTK_ACTION( g_object_get_data(G_OBJECT(tbl), "prop_action") ); - char const *flatsides = repr->attribute("inkscape:flatsided"); - EgeSelectOneAction* flat_action = EGE_SELECT_ONE_ACTION( g_object_get_data( G_OBJECT(tbl), "flat_action" ) ); - if ( flatsides && !strcmp(flatsides,"false") ) { - ege_select_one_action_set_active( flat_action, 1 ); - gtk_action_set_sensitive( prop_action, TRUE ); - } else { - ege_select_one_action_set_active( flat_action, 0 ); - gtk_action_set_sensitive( prop_action, FALSE ); - } - } else if ((!strcmp(name, "sodipodi:r1") || !strcmp(name, "sodipodi:r2")) && (!isFlatSided) ) { - adj = (GtkAdjustment*)g_object_get_data(G_OBJECT(tbl), "proportion"); - gdouble r1 = 1.0; - gdouble r2 = 1.0; - sp_repr_get_double(repr, "sodipodi:r1", &r1); - sp_repr_get_double(repr, "sodipodi:r2", &r2); - if (r2 < r1) { - gtk_adjustment_set_value(adj, r2/r1); - } else { - gtk_adjustment_set_value(adj, r1/r2); - } - } else if (!strcmp(name, "sodipodi:sides")) { - adj = (GtkAdjustment*)g_object_get_data(G_OBJECT(tbl), "magnitude"); - int sides = 0; - sp_repr_get_int(repr, "sodipodi:sides", &sides); - gtk_adjustment_set_value(adj, sides); - } - - g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE)); -} - - -static Inkscape::XML::NodeEventVector star_tb_repr_events = -{ - NULL, /* child_added */ - NULL, /* child_removed */ - star_tb_event_attr_changed, - NULL, /* content_changed */ - NULL /* order_changed */ -}; - - -/** - * \param selection Should not be NULL. - */ -static void -sp_star_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) -{ - int n_selected = 0; - Inkscape::XML::Node *repr = NULL; - - purge_repr_listener( tbl, tbl ); - - for (GSList const *items = selection->itemList(); - items != NULL; - items = items->next) - { - SPItem* item = reinterpret_cast<SPItem *>(items->data); - if (SP_IS_STAR(item)) { - n_selected++; - repr = item->getRepr(); - } - } - - EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) ); - - if (n_selected == 0) { - g_object_set( G_OBJECT(act), "label", _("<b>New:</b>"), NULL ); - } else if (n_selected == 1) { - g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL ); - - if (repr) { - g_object_set_data( tbl, "repr", repr ); - Inkscape::GC::anchor(repr); - sp_repr_add_listener(repr, &star_tb_repr_events, tbl); - sp_repr_synthesize_events(repr, &star_tb_repr_events, tbl); - } - } else { - // FIXME: implement averaging of all parameters for multiple selected stars - //gtk_label_set_markup(GTK_LABEL(l), _("<b>Average:</b>")); - //gtk_label_set_markup(GTK_LABEL(l), _("<b>Change:</b>")); - } -} - - -static void sp_stb_defaults( GtkWidget * /*widget*/, GObject *dataKludge ) -{ - // FIXME: in this and all other _default functions, set some flag telling the value_changed - // callbacks to lump all the changes for all selected objects in one undo step - - GtkAdjustment *adj = 0; - - // fixme: make settable in prefs! - gint mag = 5; - gdouble prop = 0.5; - gboolean flat = FALSE; - gdouble randomized = 0; - gdouble rounded = 0; - - EgeSelectOneAction* flat_action = EGE_SELECT_ONE_ACTION( g_object_get_data( dataKludge, "flat_action" ) ); - ege_select_one_action_set_active( flat_action, flat ? 0 : 1 ); - - GtkAction* sb2 = GTK_ACTION( g_object_get_data( dataKludge, "prop_action" ) ); - gtk_action_set_sensitive( sb2, !flat ); - - adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "magnitude" ) ); - gtk_adjustment_set_value(adj, mag); - gtk_adjustment_value_changed(adj); - - adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "proportion" ) ); - gtk_adjustment_set_value(adj, prop); - gtk_adjustment_value_changed(adj); - - adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "rounded" ) ); - gtk_adjustment_set_value(adj, rounded); - gtk_adjustment_value_changed(adj); - - adj = GTK_ADJUSTMENT( g_object_get_data( dataKludge, "randomized" ) ); - gtk_adjustment_set_value(adj, randomized); - gtk_adjustment_value_changed(adj); -} - - -// public: -void sp_toolbox_add_label(GtkWidget *tbl, gchar const *title, bool wide) -{ -#if GTK_CHECK_VERSION(3,0,0) - GtkWidget *boxl = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0); - gtk_box_set_homogeneous(GTK_BOX(boxl), FALSE); -#else - GtkWidget *boxl = gtk_hbox_new(FALSE, 0); -#endif - if (wide) { - gtk_widget_set_size_request(boxl, MODE_LABEL_WIDTH, -1); - } - GtkWidget *l = gtk_label_new(NULL); - gtk_label_set_markup(GTK_LABEL(l), title); - gtk_box_pack_end(GTK_BOX(boxl), l, FALSE, FALSE, 0); - if ( GTK_IS_TOOLBAR(tbl) ) { - GtkToolItem *boxl_toolitem = gtk_tool_item_new(); - gtk_container_add(GTK_CONTAINER(boxl_toolitem), boxl); - gtk_toolbar_insert(GTK_TOOLBAR(tbl), boxl_toolitem, -1); - } else { - gtk_box_pack_start(GTK_BOX(tbl), boxl, FALSE, FALSE, 0); - } - g_object_set_data(G_OBJECT(tbl), "mode_label", l); -} - - -static void sp_star_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - { - EgeOutputAction* act = ege_output_action_new( "StarStateAction", _("<b>New:</b>"), "", 0 ); - ege_output_action_set_use_markup( act, TRUE ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "mode_action", act ); - } - - { - EgeAdjustmentAction* eact = 0; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool isFlatSided = prefs->getBool("/tools/shapes/star/isflatsided", true); - - /* Flatsided checkbox */ - { - GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); - - GtkTreeIter iter; - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Polygon"), - 1, _("Regular polygon (with one handle) instead of a star"), - 2, INKSCAPE_ICON("draw-polygon"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Star"), - 1, _("Star instead of a regular polygon (with one handle)"), - 2, INKSCAPE_ICON("draw-star"), - -1 ); - - EgeSelectOneAction* act = ege_select_one_action_new( "FlatAction", (""), (""), NULL, GTK_TREE_MODEL(model) ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - g_object_set_data( holder, "flat_action", act ); - - ege_select_one_action_set_appearance( act, "full" ); - ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE ); - g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL ); - ege_select_one_action_set_icon_column( act, 2 ); - ege_select_one_action_set_icon_size( act, secondarySize ); - ege_select_one_action_set_tooltip_column( act, 1 ); - - ege_select_one_action_set_active( act, isFlatSided ? 0 : 1 ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_stb_sides_flat_state_changed), holder); - } - - /* Magnitude */ - { - gchar const* labels[] = {_("triangle/tri-star"), _("square/quad-star"), _("pentagon/five-pointed star"), _("hexagon/six-pointed star"), 0, 0, 0, 0, 0}; - gdouble values[] = {3, 4, 5, 6, 7, 8, 10, 12, 20}; - eact = create_adjustment_action( "MagnitudeAction", - _("Corners"), _("Corners:"), _("Number of corners of a polygon or star"), - "/tools/shapes/star/magnitude", 3, - GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL, - 3, 1024, 1, 5, - labels, values, G_N_ELEMENTS(labels), - sp_stb_magnitude_value_changed, - 1.0, 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - /* Spoke ratio */ - { - gchar const* labels[] = {_("thin-ray star"), 0, _("pentagram"), _("hexagram"), _("heptagram"), _("octagram"), _("regular polygon")}; - gdouble values[] = {0.01, 0.2, 0.382, 0.577, 0.692, 0.765, 1}; - eact = create_adjustment_action( "SpokeAction", - _("Spoke ratio"), _("Spoke ratio:"), - // TRANSLATORS: Tip radius of a star is the distance from the center to the farthest handle. - // Base radius is the same for the closest handle. - _("Base radius to tip radius ratio"), - "/tools/shapes/star/proportion", 0.5, - GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL, - 0.01, 1.0, 0.01, 0.1, - labels, values, G_N_ELEMENTS(labels), - sp_stb_proportion_value_changed ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( holder, "prop_action", eact ); - } - - if ( !isFlatSided ) { - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } else { - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - } - - /* Roundedness */ - { - gchar const* labels[] = {_("stretched"), _("twisted"), _("slightly pinched"), _("NOT rounded"), _("slightly rounded"), _("visibly rounded"), _("well rounded"), _("amply rounded"), 0, _("stretched"), _("blown up")}; - gdouble values[] = {-1, -0.2, -0.03, 0, 0.05, 0.1, 0.2, 0.3, 0.5, 1, 10}; - eact = create_adjustment_action( "RoundednessAction", - _("Rounded"), _("Rounded:"), _("How much rounded are the corners (0 for sharp)"), - "/tools/shapes/star/rounded", 0.0, - GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL, - -10.0, 10.0, 0.01, 0.1, - labels, values, G_N_ELEMENTS(labels), - sp_stb_rounded_value_changed ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - /* Randomization */ - { - gchar const* labels[] = {_("NOT randomized"), _("slightly irregular"), _("visibly randomized"), _("strongly randomized"), _("blown up")}; - gdouble values[] = {0, 0.01, 0.1, 0.5, 10}; - eact = create_adjustment_action( "RandomizationAction", - _("Randomized"), _("Randomized:"), _("Scatter randomly the corners and angles"), - "/tools/shapes/star/randomized", 0.0, - GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL, - -10.0, 10.0, 0.001, 0.01, - labels, values, G_N_ELEMENTS(labels), - sp_stb_randomized_value_changed, 0.1, 3 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - } - - { - /* Reset */ - { - GtkAction* act = gtk_action_new( "StarResetAction", - _("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_stb_defaults), holder ); - gtk_action_group_add_action( mainActions, act ); - gtk_action_set_sensitive( act, TRUE ); - } - } - - sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_star_toolbox_selection_changed), (GObject *)holder)) - ); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection ); - g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); -} - - -//######################## -//## Rect ## -//######################## - -static void sp_rtb_sensitivize( GObject *tbl ) -{ - GtkAdjustment *adj1 = GTK_ADJUSTMENT( g_object_get_data(tbl, "rx") ); - GtkAdjustment *adj2 = GTK_ADJUSTMENT( g_object_get_data(tbl, "ry") ); - GtkAction* not_rounded = GTK_ACTION( g_object_get_data(tbl, "not_rounded") ); - - if (gtk_adjustment_get_value(adj1) == 0 && gtk_adjustment_get_value(adj2) == 0 && g_object_get_data(tbl, "single")) { // only for a single selected rect (for now) - gtk_action_set_sensitive( not_rounded, FALSE ); - } else { - gtk_action_set_sensitive( not_rounded, TRUE ); - } -} - - -static void sp_rtb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name, - void (*setter)(SPRect *, gdouble)) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); - - UnitTracker* tracker = reinterpret_cast<UnitTracker*>(g_object_get_data( tbl, "tracker" )); - SPUnit const *unit = tracker->getActiveUnit(); - - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble(Glib::ustring("/tools/shapes/rect/") + value_name, - sp_units_get_pixels(gtk_adjustment_get_value(adj), *unit)); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); - - bool modmade = false; - Inkscape::Selection *selection = sp_desktop_selection(desktop); - for (GSList const *items = selection->itemList(); items != NULL; items = items->next) { - if (SP_IS_RECT(items->data)) { - if (gtk_adjustment_get_value(adj) != 0) { - setter(SP_RECT(items->data), - sp_units_get_pixels(gtk_adjustment_get_value(adj), *unit)); - } else { - SP_OBJECT(items->data)->getRepr()->setAttribute(value_name, NULL); - } - modmade = true; - } - } - - sp_rtb_sensitivize( tbl ); - - if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_RECT, - _("Change rectangle")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_rtb_rx_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_rtb_value_changed(adj, tbl, "rx", sp_rect_set_visible_rx); -} - -static void sp_rtb_ry_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_rtb_value_changed(adj, tbl, "ry", sp_rect_set_visible_ry); -} - -static void sp_rtb_width_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_rtb_value_changed(adj, tbl, "width", sp_rect_set_visible_width); -} - -static void sp_rtb_height_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_rtb_value_changed(adj, tbl, "height", sp_rect_set_visible_height); -} - - - -static void sp_rtb_defaults( GtkWidget * /*widget*/, GObject *obj) -{ - GtkAdjustment *adj = 0; - - adj = GTK_ADJUSTMENT( g_object_get_data(obj, "rx") ); - gtk_adjustment_set_value(adj, 0.0); - // this is necessary if the previous value was 0, but we still need to run the callback to change all selected objects - gtk_adjustment_value_changed(adj); - - adj = GTK_ADJUSTMENT( g_object_get_data(obj, "ry") ); - gtk_adjustment_set_value(adj, 0.0); - gtk_adjustment_value_changed(adj); - - sp_rtb_sensitivize( obj ); -} - -static void rect_tb_event_attr_changed(Inkscape::XML::Node * /*repr*/, gchar const * /*name*/, - gchar const * /*old_value*/, gchar const * /*new_value*/, - bool /*is_interactive*/, gpointer data) -{ - GObject *tbl = G_OBJECT(data); - - // quit if run by the _changed callbacks - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent callbacks from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) ); - SPUnit const *unit = tracker->getActiveUnit(); - - gpointer item = g_object_get_data( tbl, "item" ); - if (item && SP_IS_RECT(item)) { - { - GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "rx" ) ); - gdouble rx = sp_rect_get_visible_rx(SP_RECT(item)); - gtk_adjustment_set_value(adj, sp_pixels_get_units(rx, *unit)); - } - - { - GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "ry" ) ); - gdouble ry = sp_rect_get_visible_ry(SP_RECT(item)); - gtk_adjustment_set_value(adj, sp_pixels_get_units(ry, *unit)); - } - - { - GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "width" ) ); - gdouble width = sp_rect_get_visible_width (SP_RECT(item)); - gtk_adjustment_set_value(adj, sp_pixels_get_units(width, *unit)); - } - - { - GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "height" ) ); - gdouble height = sp_rect_get_visible_height (SP_RECT(item)); - gtk_adjustment_set_value(adj, sp_pixels_get_units(height, *unit)); - } - } - - sp_rtb_sensitivize( tbl ); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - - -static Inkscape::XML::NodeEventVector rect_tb_repr_events = { - NULL, /* child_added */ - NULL, /* child_removed */ - rect_tb_event_attr_changed, - NULL, /* content_changed */ - NULL /* order_changed */ -}; - -/** - * \param selection should not be NULL. - */ -static void sp_rect_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) -{ - int n_selected = 0; - Inkscape::XML::Node *repr = NULL; - SPItem *item = NULL; - - if ( g_object_get_data( tbl, "repr" ) ) { - g_object_set_data( tbl, "item", NULL ); - } - purge_repr_listener( tbl, tbl ); - - for (GSList const *items = selection->itemList(); - items != NULL; - items = items->next) { - if (SP_IS_RECT(reinterpret_cast<SPItem *>(items->data))) { - n_selected++; - item = reinterpret_cast<SPItem *>(items->data); - repr = item->getRepr(); - } - } - - EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) ); - - g_object_set_data( tbl, "single", GINT_TO_POINTER(FALSE) ); - - if (n_selected == 0) { - g_object_set( G_OBJECT(act), "label", _("<b>New:</b>"), NULL ); - - GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "width_action" ) ); - gtk_action_set_sensitive(w, FALSE); - GtkAction* h = GTK_ACTION( g_object_get_data( tbl, "height_action" ) ); - gtk_action_set_sensitive(h, FALSE); - - } else if (n_selected == 1) { - g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL ); - g_object_set_data( tbl, "single", GINT_TO_POINTER(TRUE) ); - - GtkAction* w = GTK_ACTION( g_object_get_data( tbl, "width_action" ) ); - gtk_action_set_sensitive(w, TRUE); - GtkAction* h = GTK_ACTION( g_object_get_data( tbl, "height_action" ) ); - gtk_action_set_sensitive(h, TRUE); - - if (repr) { - g_object_set_data( tbl, "repr", repr ); - g_object_set_data( tbl, "item", item ); - Inkscape::GC::anchor(repr); - sp_repr_add_listener(repr, &rect_tb_repr_events, tbl); - sp_repr_synthesize_events(repr, &rect_tb_repr_events, tbl); - } - } else { - // FIXME: implement averaging of all parameters for multiple selected - //gtk_label_set_markup(GTK_LABEL(l), _("<b>Average:</b>")); - g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL ); - sp_rtb_sensitivize( tbl ); - } -} - - -static void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - EgeAdjustmentAction* eact = 0; - Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - { - EgeOutputAction* act = ege_output_action_new( "RectStateAction", _("<b>New:</b>"), "", 0 ); - ege_output_action_set_use_markup( act, TRUE ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "mode_action", act ); - } - - // rx/ry units menu: create - UnitTracker* tracker = new UnitTracker( SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE ); - //tracker->addUnit( SP_UNIT_PERCENT, 0 ); - // fixme: add % meaning per cent of the width/height - tracker->setActiveUnit( sp_desktop_namedview(desktop)->doc_units ); - g_object_set_data( holder, "tracker", tracker ); - - /* W */ - { - gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; - eact = create_adjustment_action( "RectWidthAction", - _("Width"), _("W:"), _("Width of rectangle"), - "/tools/shapes/rect/width", 0, - GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, TRUE, "altx-rect", - 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - labels, values, G_N_ELEMENTS(labels), - sp_rtb_width_value_changed ); - tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); - g_object_set_data( holder, "width_action", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* H */ - { - gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; - gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500}; - eact = create_adjustment_action( "RectHeightAction", - _("Height"), _("H:"), _("Height of rectangle"), - "/tools/shapes/rect/height", 0, - GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, FALSE, NULL, - 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - labels, values, G_N_ELEMENTS(labels), - sp_rtb_height_value_changed ); - tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); - g_object_set_data( holder, "height_action", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* rx */ - { - gchar const* labels[] = {_("not rounded"), 0, 0, 0, 0, 0, 0, 0, 0}; - gdouble values[] = {0.5, 1, 2, 3, 5, 10, 20, 50, 100}; - eact = create_adjustment_action( "RadiusXAction", - _("Horizontal radius"), _("Rx:"), _("Horizontal radius of rounded corners"), - "/tools/shapes/rect/rx", 0, - GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, FALSE, NULL, - 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - labels, values, G_N_ELEMENTS(labels), - sp_rtb_rx_value_changed); - tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* ry */ - { - gchar const* labels[] = {_("not rounded"), 0, 0, 0, 0, 0, 0, 0, 0}; - gdouble values[] = {0.5, 1, 2, 3, 5, 10, 20, 50, 100}; - eact = create_adjustment_action( "RadiusYAction", - _("Vertical radius"), _("Ry:"), _("Vertical radius of rounded corners"), - "/tools/shapes/rect/ry", 0, - GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, FALSE, NULL, - 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP, - labels, values, G_N_ELEMENTS(labels), - sp_rtb_ry_value_changed); - tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - // add the units menu - { - GtkAction* act = tracker->createAction( "RectUnitsAction", _("Units"), ("") ); - gtk_action_group_add_action( mainActions, act ); - } - - /* Reset */ - { - InkAction* inky = ink_action_new( "RectResetAction", - _("Not rounded"), - _("Make corners sharp"), - INKSCAPE_ICON("rectangle-make-corners-sharp"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_rtb_defaults), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - gtk_action_set_sensitive( GTK_ACTION(inky), TRUE ); - g_object_set_data( holder, "not_rounded", inky ); - } - - g_object_set_data( holder, "single", GINT_TO_POINTER(TRUE) ); - sp_rtb_sensitivize( holder ); - - sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_rect_toolbox_selection_changed), (GObject *)holder)) - ); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection ); - g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); -} - -//######################## -//## 3D Box ## -//######################## - -// normalize angle so that it lies in the interval [0,360] -static double box3d_normalize_angle (double a) { - double angle = a + ((int) (a/360.0))*360; - if (angle < 0) { - angle += 360.0; - } - return angle; -} - -static void box3d_set_button_and_adjustment(Persp3D *persp, - Proj::Axis axis, - GtkAdjustment *adj, - GtkAction *act, - GtkToggleAction *tact) -{ - // TODO: Take all selected perspectives into account but don't touch the state button if not all of them - // have the same state (otherwise a call to box3d_vp_z_state_changed() is triggered and the states - // are reset). - bool is_infinite = !persp3d_VP_is_finite(persp->perspective_impl, axis); - - if (is_infinite) { - gtk_toggle_action_set_active(tact, TRUE); - gtk_action_set_sensitive(act, TRUE); - - double angle = persp3d_get_infinite_angle(persp, axis); - if (angle != Geom::infinity()) { // FIXME: We should catch this error earlier (don't show the spinbutton at all) - gtk_adjustment_set_value(adj, box3d_normalize_angle(angle)); - } - } else { - gtk_toggle_action_set_active(tact, FALSE); - gtk_action_set_sensitive(act, FALSE); - } -} - -static void box3d_resync_toolbar(Inkscape::XML::Node *persp_repr, GObject *data) -{ - if (!persp_repr) { - g_print ("No perspective given to box3d_resync_toolbar().\n"); - return; - } - - GtkWidget *tbl = GTK_WIDGET(data); - GtkAdjustment *adj = 0; - GtkAction *act = 0; - GtkToggleAction *tact = 0; - Persp3D *persp = persp3d_get_from_repr(persp_repr); - if (!persp) { - // Hmm, is it an error if this happens? - return; - } - { - adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "box3d_angle_x")); - act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_x_action")); - tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_x_state_action"))->action; - - box3d_set_button_and_adjustment(persp, Proj::X, adj, act, tact); - } - { - adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "box3d_angle_y")); - act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_y_action")); - tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_y_state_action"))->action; - - box3d_set_button_and_adjustment(persp, Proj::Y, adj, act, tact); - } - { - adj = GTK_ADJUSTMENT(g_object_get_data(G_OBJECT(tbl), "box3d_angle_z")); - act = GTK_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_angle_z_action")); - tact = &INK_TOGGLE_ACTION(g_object_get_data(G_OBJECT(tbl), "box3d_vp_z_state_action"))->action; - - box3d_set_button_and_adjustment(persp, Proj::Z, adj, act, tact); - } -} - -static void box3d_persp_tb_event_attr_changed(Inkscape::XML::Node *repr, - gchar const * /*name*/, - gchar const * /*old_value*/, - gchar const * /*new_value*/, - bool /*is_interactive*/, - gpointer data) -{ - GtkWidget *tbl = GTK_WIDGET(data); - - // quit if run by the attr_changed or selection changed listener - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - - // set freeze so that it can be caught in box3d_angle_z_value_changed() (to avoid calling - // SPDocumentUndo::maybeDone() when the document is undo insensitive) - g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE)); - - // TODO: Only update the appropriate part of the toolbar -// if (!strcmp(name, "inkscape:vp_z")) { - box3d_resync_toolbar(repr, G_OBJECT(tbl)); -// } - - Persp3D *persp = persp3d_get_from_repr(repr); - persp3d_update_box_reprs(persp); - - g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE)); -} - -static Inkscape::XML::NodeEventVector box3d_persp_tb_repr_events = -{ - NULL, /* child_added */ - NULL, /* child_removed */ - box3d_persp_tb_event_attr_changed, - NULL, /* content_changed */ - NULL /* order_changed */ -}; - -/** - * \param selection Should not be NULL. - */ -// FIXME: This should rather be put into persp3d-reference.cpp or something similar so that it reacts upon each -// Change of the perspective, and not of the current selection (but how to refer to the toolbar then?) -static void box3d_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) -{ - // Here the following should be done: If all selected boxes have finite VPs in a certain direction, - // disable the angle entry fields for this direction (otherwise entering a value in them should only - // update the perspectives with infinite VPs and leave the other ones untouched). - - Inkscape::XML::Node *persp_repr = NULL; - purge_repr_listener(tbl, tbl); - - SPItem *item = selection->singleItem(); - if (item && SP_IS_BOX3D(item)) { - // FIXME: Also deal with multiple selected boxes - SPBox3D *box = SP_BOX3D(item); - Persp3D *persp = box3d_get_perspective(box); - persp_repr = persp->getRepr(); - if (persp_repr) { - g_object_set_data(tbl, "repr", persp_repr); - Inkscape::GC::anchor(persp_repr); - sp_repr_add_listener(persp_repr, &box3d_persp_tb_repr_events, tbl); - sp_repr_synthesize_events(persp_repr, &box3d_persp_tb_repr_events, tbl); - } - - inkscape_active_document()->setCurrentPersp3D(persp3d_get_from_repr(persp_repr)); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString("/tools/shapes/3dbox/persp", persp_repr->attribute("id")); - - g_object_set_data(tbl, "freeze", GINT_TO_POINTER(TRUE)); - box3d_resync_toolbar(persp_repr, tbl); - g_object_set_data(tbl, "freeze", GINT_TO_POINTER(FALSE)); - } -} - -static void box3d_angle_value_changed(GtkAdjustment *adj, GObject *dataKludge, Proj::Axis axis) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( dataKludge, "desktop" ); - SPDocument *document = sp_desktop_document(desktop); - - // quit if run by the attr_changed or selection changed listener - if (g_object_get_data( dataKludge, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data(dataKludge, "freeze", GINT_TO_POINTER(TRUE)); - - std::list<Persp3D *> sel_persps = sp_desktop_selection(desktop)->perspList(); - if (sel_persps.empty()) { - // this can happen when the document is created; we silently ignore it - return; - } - Persp3D *persp = sel_persps.front(); - - persp->perspective_impl->tmat.set_infinite_direction (axis, - gtk_adjustment_get_value(adj)); - persp->updateRepr(); - - // TODO: use the correct axis here, too - DocumentUndo::maybeDone(document, "perspangle", SP_VERB_CONTEXT_3DBOX, _("3D Box: Change perspective (angle of infinite axis)")); - - g_object_set_data( dataKludge, "freeze", GINT_TO_POINTER(FALSE) ); -} - - -static void box3d_angle_x_value_changed(GtkAdjustment *adj, GObject *dataKludge) -{ - box3d_angle_value_changed(adj, dataKludge, Proj::X); -} - -static void box3d_angle_y_value_changed(GtkAdjustment *adj, GObject *dataKludge) -{ - box3d_angle_value_changed(adj, dataKludge, Proj::Y); -} - -static void box3d_angle_z_value_changed(GtkAdjustment *adj, GObject *dataKludge) -{ - box3d_angle_value_changed(adj, dataKludge, Proj::Z); -} - - -static void box3d_vp_state_changed( GtkToggleAction *act, GtkAction * /*box3d_angle*/, Proj::Axis axis ) -{ - // TODO: Take all selected perspectives into account - std::list<Persp3D *> sel_persps = sp_desktop_selection(inkscape_active_desktop())->perspList(); - if (sel_persps.empty()) { - // this can happen when the document is created; we silently ignore it - return; - } - Persp3D *persp = sel_persps.front(); - - bool set_infinite = gtk_toggle_action_get_active(act); - persp3d_set_VP_state (persp, axis, set_infinite ? Proj::VP_INFINITE : Proj::VP_FINITE); -} - -static void box3d_vp_x_state_changed( GtkToggleAction *act, GtkAction *box3d_angle ) -{ - box3d_vp_state_changed(act, box3d_angle, Proj::X); -} - -static void box3d_vp_y_state_changed( GtkToggleAction *act, GtkAction *box3d_angle ) -{ - box3d_vp_state_changed(act, box3d_angle, Proj::Y); -} - -static void box3d_vp_z_state_changed( GtkToggleAction *act, GtkAction *box3d_angle ) -{ - box3d_vp_state_changed(act, box3d_angle, Proj::Z); -} - -static void box3d_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - EgeAdjustmentAction* eact = 0; - SPDocument *document = sp_desktop_document (desktop); - Persp3DImpl *persp_impl = document->getCurrentPersp3DImpl(); - - EgeAdjustmentAction* box3d_angle_x = 0; - EgeAdjustmentAction* box3d_angle_y = 0; - EgeAdjustmentAction* box3d_angle_z = 0; - - /* Angle X */ - { - gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 }; - gdouble values[] = {-90, -60, -30, 0, 30, 60, 90}; - eact = create_adjustment_action( "3DBoxAngleXAction", - _("Angle in X direction"), _("Angle X:"), - // Translators: PL is short for 'perspective line' - _("Angle of PLs in X direction"), - "/tools/shapes/3dbox/box3d_angle_x", 30, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-box3d", - -360.0, 360.0, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - box3d_angle_x_value_changed ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( holder, "box3d_angle_x_action", eact ); - box3d_angle_x = eact; - } - - if (!persp_impl || !persp3d_VP_is_finite(persp_impl, Proj::X)) { - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } else { - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - } - - - /* VP X state */ - { - InkToggleAction* act = ink_toggle_action_new( "3DBoxVPXStateAction", - // Translators: VP is short for 'vanishing point' - _("State of VP in X direction"), - _("Toggle VP in X direction between 'finite' and 'infinite' (=parallel)"), - INKSCAPE_ICON("perspective-parallel"), - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "box3d_vp_x_state_action", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_x_state_changed), box3d_angle_x ); - gtk_action_set_sensitive( GTK_ACTION(box3d_angle_x), !prefs->getBool("/tools/shapes/3dbox/vp_x_state", true) ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/shapes/3dbox/vp_x_state", true) ); - } - - /* Angle Y */ - { - gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 }; - gdouble values[] = {-90, -60, -30, 0, 30, 60, 90}; - eact = create_adjustment_action( "3DBoxAngleYAction", - _("Angle in Y direction"), _("Angle Y:"), - // Translators: PL is short for 'perspective line' - _("Angle of PLs in Y direction"), - "/tools/shapes/3dbox/box3d_angle_y", 30, - GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL, - -360.0, 360.0, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - box3d_angle_y_value_changed ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( holder, "box3d_angle_y_action", eact ); - box3d_angle_y = eact; - } - - if (!persp_impl || !persp3d_VP_is_finite(persp_impl, Proj::Y)) { - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } else { - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - } - - /* VP Y state */ - { - InkToggleAction* act = ink_toggle_action_new( "3DBoxVPYStateAction", - // Translators: VP is short for 'vanishing point' - _("State of VP in Y direction"), - _("Toggle VP in Y direction between 'finite' and 'infinite' (=parallel)"), - INKSCAPE_ICON("perspective-parallel"), - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "box3d_vp_y_state_action", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_y_state_changed), box3d_angle_y ); - gtk_action_set_sensitive( GTK_ACTION(box3d_angle_y), !prefs->getBool("/tools/shapes/3dbox/vp_y_state", true) ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/shapes/3dbox/vp_y_state", true) ); - } - - /* Angle Z */ - { - gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0 }; - gdouble values[] = {-90, -60, -30, 0, 30, 60, 90}; - eact = create_adjustment_action( "3DBoxAngleZAction", - _("Angle in Z direction"), _("Angle Z:"), - // Translators: PL is short for 'perspective line' - _("Angle of PLs in Z direction"), - "/tools/shapes/3dbox/box3d_angle_z", 30, - GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL, - -360.0, 360.0, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - box3d_angle_z_value_changed ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( holder, "box3d_angle_z_action", eact ); - box3d_angle_z = eact; - } - - if (!persp_impl || !persp3d_VP_is_finite(persp_impl, Proj::Z)) { - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } else { - gtk_action_set_sensitive( GTK_ACTION(eact), FALSE ); - } - - /* VP Z state */ - { - InkToggleAction* act = ink_toggle_action_new( "3DBoxVPZStateAction", - // Translators: VP is short for 'vanishing point' - _("State of VP in Z direction"), - _("Toggle VP in Z direction between 'finite' and 'infinite' (=parallel)"), - INKSCAPE_ICON("perspective-parallel"), - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "box3d_vp_z_state_action", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(box3d_vp_z_state_changed), box3d_angle_z ); - gtk_action_set_sensitive( GTK_ACTION(box3d_angle_z), !prefs->getBool("/tools/shapes/3dbox/vp_z_state", true) ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/shapes/3dbox/vp_z_state", true) ); - } - - sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(box3d_toolbox_selection_changed), (GObject *)holder)) - ); - g_signal_connect(holder, "destroy", G_CALLBACK(delete_connection), connection); - g_signal_connect(holder, "destroy", G_CALLBACK(purge_repr_listener), holder); -} - -//######################## -//## Spiral ## -//######################## - -static void sp_spl_tb_value_changed(GtkAdjustment *adj, GObject *tbl, Glib::ustring const &value_name) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); - - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/shapes/spiral/" + value_name, - gtk_adjustment_get_value(adj)); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gchar* namespaced_name = g_strconcat("sodipodi:", value_name.data(), NULL); - - bool modmade = false; - for (GSList const *items = sp_desktop_selection(desktop)->itemList(); - items != NULL; - items = items->next) - { - SPItem *item = reinterpret_cast<SPItem*>(items->data); - if (SP_IS_SPIRAL(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - sp_repr_set_svg_double( repr, namespaced_name, - gtk_adjustment_get_value(adj) ); - item->updateRepr(); - modmade = true; - } - } - - g_free(namespaced_name); - - if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_SPIRAL, - _("Change spiral")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_spl_tb_revolution_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_spl_tb_value_changed(adj, tbl, "revolution"); -} - -static void sp_spl_tb_expansion_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_spl_tb_value_changed(adj, tbl, "expansion"); -} - -static void sp_spl_tb_t0_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_spl_tb_value_changed(adj, tbl, "t0"); -} - -static void sp_spl_tb_defaults(GtkWidget * /*widget*/, GObject *obj) -{ - GtkWidget *tbl = GTK_WIDGET(obj); - - GtkAdjustment *adj; - - // fixme: make settable - gdouble rev = 5; - gdouble exp = 1.0; - gdouble t0 = 0.0; - - adj = (GtkAdjustment*)g_object_get_data(obj, "revolution"); - gtk_adjustment_set_value(adj, rev); - gtk_adjustment_value_changed(adj); - - adj = (GtkAdjustment*)g_object_get_data(obj, "expansion"); - gtk_adjustment_set_value(adj, exp); - gtk_adjustment_value_changed(adj); - - adj = (GtkAdjustment*)g_object_get_data(obj, "t0"); - gtk_adjustment_set_value(adj, t0); - gtk_adjustment_value_changed(adj); - - spinbutton_defocus(tbl); -} - - -static void spiral_tb_event_attr_changed(Inkscape::XML::Node *repr, - gchar const * /*name*/, - gchar const * /*old_value*/, - gchar const * /*new_value*/, - bool /*is_interactive*/, - gpointer data) -{ - GtkWidget *tbl = GTK_WIDGET(data); - - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - - // in turn, prevent callbacks from responding - g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(TRUE)); - - GtkAdjustment *adj; - adj = (GtkAdjustment*)g_object_get_data(G_OBJECT(tbl), "revolution"); - double revolution = 3.0; - sp_repr_get_double(repr, "sodipodi:revolution", &revolution); - gtk_adjustment_set_value(adj, revolution); - - adj = (GtkAdjustment*)g_object_get_data(G_OBJECT(tbl), "expansion"); - double expansion = 1.0; - sp_repr_get_double(repr, "sodipodi:expansion", &expansion); - gtk_adjustment_set_value(adj, expansion); - - adj = (GtkAdjustment*)g_object_get_data(G_OBJECT(tbl), "t0"); - double t0 = 0.0; - sp_repr_get_double(repr, "sodipodi:t0", &t0); - gtk_adjustment_set_value(adj, t0); - - g_object_set_data(G_OBJECT(tbl), "freeze", GINT_TO_POINTER(FALSE)); -} - - -static Inkscape::XML::NodeEventVector spiral_tb_repr_events = { - NULL, /* child_added */ - NULL, /* child_removed */ - spiral_tb_event_attr_changed, - NULL, /* content_changed */ - NULL /* order_changed */ -}; - -static void sp_spiral_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) -{ - int n_selected = 0; - Inkscape::XML::Node *repr = NULL; - - purge_repr_listener( tbl, tbl ); - - for (GSList const *items = selection->itemList(); - items != NULL; - items = items->next) - { - SPItem *item = reinterpret_cast<SPItem*>(items->data); - if (SP_IS_SPIRAL(item)) { - n_selected++; - repr = item->getRepr(); - } - } - - EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) ); - - if (n_selected == 0) { - g_object_set( G_OBJECT(act), "label", _("<b>New:</b>"), NULL ); - } else if (n_selected == 1) { - g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL ); - - if (repr) { - g_object_set_data( tbl, "repr", repr ); - Inkscape::GC::anchor(repr); - sp_repr_add_listener(repr, &spiral_tb_repr_events, tbl); - sp_repr_synthesize_events(repr, &spiral_tb_repr_events, tbl); - } - } else { - // FIXME: implement averaging of all parameters for multiple selected - //gtk_label_set_markup(GTK_LABEL(l), _("<b>Average:</b>")); - g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL ); - } -} - - -static void sp_spiral_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - EgeAdjustmentAction* eact = 0; - Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - { - EgeOutputAction* act = ege_output_action_new( "SpiralStateAction", _("<b>New:</b>"), "", 0 ); - ege_output_action_set_use_markup( act, TRUE ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "mode_action", act ); - } - - /* Revolution */ - { - gchar const* labels[] = {_("just a curve"), 0, _("one full revolution"), 0, 0, 0, 0, 0, 0}; - gdouble values[] = {0.01, 0.5, 1, 2, 3, 5, 10, 20, 50, 100}; - eact = create_adjustment_action( "SpiralRevolutionAction", - _("Number of turns"), _("Turns:"), _("Number of revolutions"), - "/tools/shapes/spiral/revolution", 3.0, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-spiral", - 0.01, 1024.0, 0.1, 1.0, - labels, values, G_N_ELEMENTS(labels), - sp_spl_tb_revolution_value_changed, 1, 2); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* Expansion */ - { - gchar const* labels[] = {_("circle"), _("edge is much denser"), _("edge is denser"), _("even"), _("center is denser"), _("center is much denser"), 0}; - gdouble values[] = {0, 0.1, 0.5, 1, 1.5, 5, 20}; - eact = create_adjustment_action( "SpiralExpansionAction", - _("Divergence"), _("Divergence:"), _("How much denser/sparser are outer revolutions; 1 = uniform"), - "/tools/shapes/spiral/expansion", 1.0, - GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL, - 0.0, 1000.0, 0.01, 1.0, - labels, values, G_N_ELEMENTS(labels), - sp_spl_tb_expansion_value_changed); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* T0 */ - { - gchar const* labels[] = {_("starts from center"), _("starts mid-way"), _("starts near edge")}; - gdouble values[] = {0, 0.5, 0.9}; - eact = create_adjustment_action( "SpiralT0Action", - _("Inner radius"), _("Inner radius:"), _("Radius of the innermost revolution (relative to the spiral size)"), - "/tools/shapes/spiral/t0", 0.0, - GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL, - 0.0, 0.999, 0.01, 1.0, - labels, values, G_N_ELEMENTS(labels), - sp_spl_tb_t0_value_changed); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* Reset */ - { - InkAction* inky = ink_action_new( "SpiralResetAction", - _("Defaults"), - _("Reset shape parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), - GTK_STOCK_CLEAR, - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_spl_tb_defaults), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - - sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_spiral_toolbox_selection_changed), (GObject *)holder)) - ); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection ); - g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); -} - -//######################## -//## Pen/Pencil ## -//######################## - -/* This is used in generic functions below to share large portions of code between pen and pencil tool */ -static Glib::ustring const freehand_tool_name(GObject *dataKludge) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data(dataKludge, "desktop"); - return ( tools_isactive(desktop, TOOLS_FREEHAND_PEN) - ? "/tools/freehand/pen" - : "/tools/freehand/pencil" ); -} - -static void freehand_mode_changed(EgeSelectOneAction* act, GObject* tbl) -{ - gint mode = ege_select_one_action_get_active(act); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt(freehand_tool_name(tbl) + "/freehand-mode", mode); - - SPDesktop *desktop = (SPDesktop *) g_object_get_data(tbl, "desktop"); - - // in pen tool we have more options than in pencil tool; if one of them was chosen, we do any - // preparatory work here - if (SP_IS_PEN_CONTEXT(desktop->event_context)) { - SPPenContext *pc = SP_PEN_CONTEXT(desktop->event_context); - sp_pen_context_set_polyline_mode(pc); - } -} - -static void sp_add_freehand_mode_toggle(GtkActionGroup* mainActions, GObject* holder, bool tool_is_pencil) -{ - /* Freehand mode toggle buttons */ - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - guint freehandMode = prefs->getInt(( tool_is_pencil ? "/tools/freehand/pencil/freehand-mode" : "/tools/freehand/pen/freehand-mode" ), 0); - Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - { - GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); - - GtkTreeIter iter; - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Bezier"), - 1, _("Create regular Bezier path"), - 2, INKSCAPE_ICON("path-mode-bezier"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Spiro"), - 1, _("Create Spiro path"), - 2, INKSCAPE_ICON("path-mode-spiro"), - -1 ); - - if (!tool_is_pencil) { - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Zigzag"), - 1, _("Create a sequence of straight line segments"), - 2, INKSCAPE_ICON("path-mode-polyline"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Paraxial"), - 1, _("Create a sequence of paraxial line segments"), - 2, INKSCAPE_ICON("path-mode-polyline-paraxial"), - -1 ); - } - - EgeSelectOneAction* act = ege_select_one_action_new(tool_is_pencil ? - "FreehandModeActionPencil" : - "FreehandModeActionPen", - (_("Mode:")), (_("Mode of new lines drawn by this tool")), NULL, GTK_TREE_MODEL(model) ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - - ege_select_one_action_set_appearance( act, "full" ); - ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE ); - g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL ); - ege_select_one_action_set_icon_column( act, 2 ); - ege_select_one_action_set_icon_size( act, secondarySize ); - ege_select_one_action_set_tooltip_column( act, 1 ); - - ege_select_one_action_set_active( act, freehandMode); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(freehand_mode_changed), holder); - } - } -} - -static void freehand_change_shape(EgeSelectOneAction* act, GObject *dataKludge) { - gint shape = ege_select_one_action_get_active( act ); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt(freehand_tool_name(dataKludge) + "/shape", shape); -} - -/** - * Generate the list of freehand advanced shape option entries. - */ -static GList * freehand_shape_dropdown_items_list() { - GList *glist = NULL; - - glist = g_list_append (glist, _("None")); - glist = g_list_append (glist, _("Triangle in")); - glist = g_list_append (glist, _("Triangle out")); - glist = g_list_append (glist, _("Ellipse")); - glist = g_list_append (glist, _("From clipboard")); - - return glist; -} - -static void freehand_add_advanced_shape_options(GtkActionGroup* mainActions, GObject* holder, bool tool_is_pencil) -{ - /*advanced shape options */ - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - GtkListStore* model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT ); - - GList* items = 0; - gint count = 0; - for ( items = freehand_shape_dropdown_items_list(); items ; items = g_list_next(items) ) - { - GtkTreeIter iter; - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, reinterpret_cast<gchar*>(items->data), 1, count, -1 ); - count++; - } - g_list_free( items ); - items = 0; - EgeSelectOneAction* act1 = ege_select_one_action_new( - tool_is_pencil ? "SetPencilShapeAction" : "SetPenShapeAction", - _("Shape:"), (_("Shape of new paths drawn by this tool")), NULL, GTK_TREE_MODEL(model)); - g_object_set( act1, "short_label", _("Shape:"), NULL ); - ege_select_one_action_set_appearance( act1, "compact" ); - ege_select_one_action_set_active( act1, prefs->getInt(( tool_is_pencil ? "/tools/freehand/pencil/shape" : "/tools/freehand/pen/shape" ), 0) ); - g_signal_connect( G_OBJECT(act1), "changed", G_CALLBACK(freehand_change_shape), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act1) ); - g_object_set_data( holder, "shape_action", act1 ); - } -} - -static void sp_pen_toolbox_prep(SPDesktop * /*desktop*/, GtkActionGroup* mainActions, GObject* holder) -{ - sp_add_freehand_mode_toggle(mainActions, holder, false); - freehand_add_advanced_shape_options(mainActions, holder, false); -} - - -static void sp_pencil_tb_defaults(GtkWidget * /*widget*/, GObject *obj) -{ - GtkWidget *tbl = GTK_WIDGET(obj); - - GtkAdjustment *adj; - - // fixme: make settable - gdouble tolerance = 4; - - adj = (GtkAdjustment*)g_object_get_data(obj, "tolerance"); - gtk_adjustment_set_value(adj, tolerance); - gtk_adjustment_value_changed(adj); - - spinbutton_defocus(tbl); -} - -static void sp_pencil_tb_tolerance_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - // in turn, prevent listener from responding - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - prefs->setDouble("/tools/freehand/pencil/tolerance", - gtk_adjustment_get_value(adj)); - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -/* -class PencilToleranceObserver : public Inkscape::Preferences::Observer { -public: - PencilToleranceObserver(Glib::ustring const &path, GObject *x) : Observer(path), _obj(x) - { - g_object_set_data(_obj, "prefobserver", this); - } - virtual ~PencilToleranceObserver() { - if (g_object_get_data(_obj, "prefobserver") == this) { - g_object_set_data(_obj, "prefobserver", NULL); - } - } - virtual void notify(Inkscape::Preferences::Entry const &val) { - GObject* tbl = _obj; - if (g_object_get_data( tbl, "freeze" )) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - GtkAdjustment * adj = (GtkAdjustment*)g_object_get_data(tbl, "tolerance"); - - double v = val.getDouble(adj->value); - gtk_adjustment_set_value(adj, v); - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); - } -private: - GObject *_obj; -}; -*/ - -static void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - sp_add_freehand_mode_toggle(mainActions, holder, true); - - EgeAdjustmentAction* eact = 0; - - /* Tolerance */ - { - gchar const* labels[] = {_("(many nodes, rough)"), _("(default)"), 0, 0, 0, 0, _("(few nodes, smooth)")}; - gdouble values[] = {1, 10, 20, 30, 50, 75, 100}; - eact = create_adjustment_action( "PencilToleranceAction", - _("Smoothing:"), _("Smoothing: "), - _("How much smoothing (simplifying) is applied to the line"), - "/tools/freehand/pencil/tolerance", - 3.0, - GTK_WIDGET(desktop->canvas), NULL, - holder, TRUE, "altx-pencil", - 1, 100.0, 0.5, 1.0, - labels, values, G_N_ELEMENTS(labels), - sp_pencil_tb_tolerance_value_changed, - 1, 2); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* advanced shape options */ - freehand_add_advanced_shape_options(mainActions, holder, true); - - /* Reset */ - { - InkAction* inky = ink_action_new( "PencilResetAction", - _("Defaults"), - _("Reset pencil parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), - GTK_STOCK_CLEAR, - Inkscape::ICON_SIZE_SMALL_TOOLBAR ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_pencil_tb_defaults), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); - -} - - -//######################## -//## Tweak ## -//######################## - -static void sp_tweak_width_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/tweak/width", - gtk_adjustment_get_value(adj) * 0.01 ); -} - -static void sp_tweak_force_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/tweak/force", - gtk_adjustment_get_value(adj) * 0.01 ); -} - -static void sp_tweak_pressure_state_changed( GtkToggleAction *act, gpointer /*data*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/tweak/usepressure", gtk_toggle_action_get_active(act)); -} - -static void sp_tweak_mode_changed( EgeSelectOneAction *act, GObject *tbl ) -{ - int mode = ege_select_one_action_get_active( act ); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/tweak/mode", mode); - - static gchar const* names[] = {"tweak_doh", "tweak_dos", "tweak_dol", "tweak_doo", "tweak_channels_label"}; - bool flag = ((mode == TWEAK_MODE_COLORPAINT) || (mode == TWEAK_MODE_COLORJITTER)); - for (size_t i = 0; i < G_N_ELEMENTS(names); ++i) { - GtkAction *act = GTK_ACTION(g_object_get_data( tbl, names[i] )); - if (act) { - gtk_action_set_sensitive(act, flag); - } - } - GtkAction *fid = GTK_ACTION(g_object_get_data( tbl, "tweak_fidelity")); - if (fid) { - gtk_action_set_sensitive(fid, !flag); - } -} - -static void sp_tweak_fidelity_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/tweak/fidelity", - gtk_adjustment_get_value(adj) * 0.01 ); -} - -static void tweak_toggle_doh(GtkToggleAction *act, gpointer /*data*/) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/tweak/doh", gtk_toggle_action_get_active(act)); -} -static void tweak_toggle_dos(GtkToggleAction *act, gpointer /*data*/) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/tweak/dos", gtk_toggle_action_get_active(act)); -} -static void tweak_toggle_dol(GtkToggleAction *act, gpointer /*data*/) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/tweak/dol", gtk_toggle_action_get_active(act)); -} -static void tweak_toggle_doo(GtkToggleAction *act, gpointer /*data*/) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/tweak/doo", gtk_toggle_action_get_active(act)); -} - -static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - { - /* Width */ - gchar const* labels[] = {_("(pinch tweak)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad tweak)")}; - gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "TweakWidthAction", - _("Width"), _("Width:"), _("The width of the tweak area (relative to the visible canvas area)"), - "/tools/tweak/width", 15, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-tweak", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_tweak_width_value_changed, 0.01, 0, 100 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - - { - /* Force */ - gchar const* labels[] = {_("(minimum force)"), 0, 0, _("(default)"), 0, 0, 0, _("(maximum force)")}; - gdouble values[] = {1, 5, 10, 20, 30, 50, 70, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "TweakForceAction", - _("Force"), _("Force:"), _("The force of the tweak action"), - "/tools/tweak/force", 20, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "tweak-force", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_tweak_force_value_changed, 0.01, 0, 100 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - /* Mode */ - { - GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); - - GtkTreeIter iter; - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Move mode"), - 1, _("Move objects in any direction"), - 2, INKSCAPE_ICON("object-tweak-push"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Move in/out mode"), - 1, _("Move objects towards cursor; with Shift from cursor"), - 2, INKSCAPE_ICON("object-tweak-attract"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Move jitter mode"), - 1, _("Move objects in random directions"), - 2, INKSCAPE_ICON("object-tweak-randomize"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Scale mode"), - 1, _("Shrink objects, with Shift enlarge"), - 2, INKSCAPE_ICON("object-tweak-shrink"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Rotate mode"), - 1, _("Rotate objects, with Shift counterclockwise"), - 2, INKSCAPE_ICON("object-tweak-rotate"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Duplicate/delete mode"), - 1, _("Duplicate objects, with Shift delete"), - 2, INKSCAPE_ICON("object-tweak-duplicate"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Push mode"), - 1, _("Push parts of paths in any direction"), - 2, INKSCAPE_ICON("path-tweak-push"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Shrink/grow mode"), - 1, _("Shrink (inset) parts of paths; with Shift grow (outset)"), - 2, INKSCAPE_ICON("path-tweak-shrink"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Attract/repel mode"), - 1, _("Attract parts of paths towards cursor; with Shift from cursor"), - 2, INKSCAPE_ICON("path-tweak-attract"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Roughen mode"), - 1, _("Roughen parts of paths"), - 2, INKSCAPE_ICON("path-tweak-roughen"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Color paint mode"), - 1, _("Paint the tool's color upon selected objects"), - 2, INKSCAPE_ICON("object-tweak-paint"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Color jitter mode"), - 1, _("Jitter the colors of selected objects"), - 2, INKSCAPE_ICON("object-tweak-jitter-color"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Blur mode"), - 1, _("Blur selected objects more; with Shift, blur less"), - 2, INKSCAPE_ICON("object-tweak-blur"), - -1 ); - - - EgeSelectOneAction* act = ege_select_one_action_new( "TweakModeAction", _("Mode"), (""), NULL, GTK_TREE_MODEL(model) ); - g_object_set( act, "short_label", _("Mode:"), NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - g_object_set_data( holder, "mode_action", act ); - - ege_select_one_action_set_appearance( act, "full" ); - ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE ); - g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL ); - ege_select_one_action_set_icon_column( act, 2 ); - ege_select_one_action_set_icon_size( act, secondarySize ); - ege_select_one_action_set_tooltip_column( act, 1 ); - - gint mode = prefs->getInt("/tools/tweak/mode", 0); - ege_select_one_action_set_active( act, mode ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_tweak_mode_changed), holder ); - - g_object_set_data( G_OBJECT(holder), "tweak_tool_mode", act); - } - - guint mode = prefs->getInt("/tools/tweak/mode", 0); - - { - EgeOutputAction* act = ege_output_action_new( "TweakChannelsLabel", _("Channels:"), "", 0 ); - ege_output_action_set_use_markup( act, TRUE ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - if (mode != TWEAK_MODE_COLORPAINT && mode != TWEAK_MODE_COLORJITTER) { - gtk_action_set_sensitive (GTK_ACTION(act), FALSE); - } - g_object_set_data( holder, "tweak_channels_label", act); - } - - { - InkToggleAction* act = ink_toggle_action_new( "TweakDoH", - _("Hue"), - _("In color mode, act on objects' hue"), - NULL, - Inkscape::ICON_SIZE_DECORATION ); - //TRANSLATORS: "H" here stands for hue - g_object_set( act, "short_label", _("H"), NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doh), desktop ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/doh", true) ); - if (mode != TWEAK_MODE_COLORPAINT && mode != TWEAK_MODE_COLORJITTER) { - gtk_action_set_sensitive (GTK_ACTION(act), FALSE); - } - g_object_set_data( holder, "tweak_doh", act); - } - { - InkToggleAction* act = ink_toggle_action_new( "TweakDoS", - _("Saturation"), - _("In color mode, act on objects' saturation"), - NULL, - Inkscape::ICON_SIZE_DECORATION ); - //TRANSLATORS: "S" here stands for Saturation - g_object_set( act, "short_label", _("S"), NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dos), desktop ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/dos", true) ); - if (mode != TWEAK_MODE_COLORPAINT && mode != TWEAK_MODE_COLORJITTER) { - gtk_action_set_sensitive (GTK_ACTION(act), FALSE); - } - g_object_set_data( holder, "tweak_dos", act ); - } - { - InkToggleAction* act = ink_toggle_action_new( "TweakDoL", - _("Lightness"), - _("In color mode, act on objects' lightness"), - NULL, - Inkscape::ICON_SIZE_DECORATION ); - //TRANSLATORS: "L" here stands for Lightness - g_object_set( act, "short_label", _("L"), NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_dol), desktop ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/dol", true) ); - if (mode != TWEAK_MODE_COLORPAINT && mode != TWEAK_MODE_COLORJITTER) { - gtk_action_set_sensitive (GTK_ACTION(act), FALSE); - } - g_object_set_data( holder, "tweak_dol", act ); - } - { - InkToggleAction* act = ink_toggle_action_new( "TweakDoO", - _("Opacity"), - _("In color mode, act on objects' opacity"), - NULL, - Inkscape::ICON_SIZE_DECORATION ); - //TRANSLATORS: "O" here stands for Opacity - g_object_set( act, "short_label", _("O"), NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(tweak_toggle_doo), desktop ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/doo", true) ); - if (mode != TWEAK_MODE_COLORPAINT && mode != TWEAK_MODE_COLORJITTER) { - gtk_action_set_sensitive (GTK_ACTION(act), FALSE); - } - g_object_set_data( holder, "tweak_doo", act ); - } - - { /* Fidelity */ - gchar const* labels[] = {_("(rough, simplified)"), 0, 0, _("(default)"), 0, 0, _("(fine, but many nodes)")}; - gdouble values[] = {10, 25, 35, 50, 60, 80, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "TweakFidelityAction", - _("Fidelity"), _("Fidelity:"), - _("Low fidelity simplifies paths; high fidelity preserves path features but may generate a lot of new nodes"), - "/tools/tweak/fidelity", 50, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "tweak-fidelity", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_tweak_fidelity_value_changed, 0.01, 0, 100 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - if (mode == TWEAK_MODE_COLORPAINT || mode == TWEAK_MODE_COLORJITTER) { - gtk_action_set_sensitive (GTK_ACTION(eact), FALSE); - } - g_object_set_data( holder, "tweak_fidelity", eact ); - } - - - /* Use Pressure button */ - { - InkToggleAction* act = ink_toggle_action_new( "TweakPressureAction", - _("Pressure"), - _("Use the pressure of the input device to alter the force of tweak action"), - INKSCAPE_ICON("draw-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_tweak_pressure_state_changed), NULL); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/tweak/usepressure", true) ); - } - -} - - -//######################## -//## Spray ## -//######################## - -static void sp_spray_width_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/spray/width", - gtk_adjustment_get_value(adj)); -} - -static void sp_spray_mean_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/spray/mean", - gtk_adjustment_get_value(adj)); -} - -static void sp_spray_standard_deviation_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/spray/standard_deviation", - gtk_adjustment_get_value(adj)); -} - -static void sp_spray_mode_changed( EgeSelectOneAction *act, GObject * /*tbl*/ ) -{ - int mode = ege_select_one_action_get_active( act ); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/spray/mode", mode); -} - -static void sp_spray_population_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/spray/population", - gtk_adjustment_get_value(adj)); -} - -static void sp_spray_rotation_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/spray/rotation_variation", - gtk_adjustment_get_value(adj)); -} - -static void sp_spray_scale_value_changed( GtkAdjustment *adj, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/spray/scale_variation", - gtk_adjustment_get_value(adj)); -} - - -static void sp_spray_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - { - /* Width */ - gchar const* labels[] = {_("(narrow spray)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad spray)")}; - gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "SprayWidthAction", - _("Width"), _("Width:"), _("The width of the spray area (relative to the visible canvas area)"), - "/tools/spray/width", 15, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-spray", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_spray_width_value_changed, 1, 0 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - { - /* Mean */ - gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(maximum mean)")}; - gdouble values[] = {0, 5, 10, 20, 30, 50, 70, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "SprayMeanAction", - _("Focus"), _("Focus:"), _("0 to spray a spot; increase to enlarge the ring radius"), - "/tools/spray/mean", 0, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "spray-mean", - 0, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_spray_mean_value_changed, 1, 0 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - { - /* Standard_deviation */ - gchar const* labels[] = {_("(minimum scatter)"), 0, 0, 0, 0, 0, _("(default)"), _("(maximum scatter)")}; - gdouble values[] = {1, 5, 10, 20, 30, 50, 70, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "SprayStandard_deviationAction", - C_("Spray tool", "Scatter"), C_("Spray tool", "Scatter:"), _("Increase to scatter sprayed objects"), - "/tools/spray/standard_deviation", 70, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "spray-standard_deviation", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_spray_standard_deviation_value_changed, 1, 0 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - /* Mode */ - { - GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); - - GtkTreeIter iter; - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Spray with copies"), - 1, _("Spray copies of the initial selection"), - 2, INKSCAPE_ICON("spray-mode-copy"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Spray with clones"), - 1, _("Spray clones of the initial selection"), - 2, INKSCAPE_ICON("spray-mode-clone"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Spray single path"), - 1, _("Spray objects in a single path"), - 2, INKSCAPE_ICON("spray-mode-union"), - -1 ); - - EgeSelectOneAction* act = ege_select_one_action_new( "SprayModeAction", _("Mode"), (""), NULL, GTK_TREE_MODEL(model) ); - g_object_set( act, "short_label", _("Mode:"), NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - g_object_set_data( holder, "mode_action", act ); - - ege_select_one_action_set_appearance( act, "full" ); - ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE ); - g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL ); - ege_select_one_action_set_icon_column( act, 2 ); - ege_select_one_action_set_icon_size( act, secondarySize ); - ege_select_one_action_set_tooltip_column( act, 1 ); - - gint mode = prefs->getInt("/tools/spray/mode", 1); - ege_select_one_action_set_active( act, mode ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_spray_mode_changed), holder ); - - g_object_set_data( G_OBJECT(holder), "spray_tool_mode", act); - } - - { /* Population */ - gchar const* labels[] = {_("(low population)"), 0, 0, 0, _("(default)"), 0, _("(high population)")}; - gdouble values[] = {5, 20, 35, 50, 70, 85, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "SprayPopulationAction", - _("Amount"), _("Amount:"), - _("Adjusts the number of items sprayed per click"), - "/tools/spray/population", 70, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "spray-population", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_spray_population_value_changed, 1, 0 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - g_object_set_data( holder, "spray_population", eact ); - } - - /* Use Pressure button */ - { - InkToggleAction* act = ink_toggle_action_new( "SprayPressureAction", - _("Pressure"), - _("Use the pressure of the input device to alter the amount of sprayed objects"), - "use_pressure", - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/spray/usepressure"); - g_signal_connect(holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - - } - - { /* Rotation */ - gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(high rotation variation)")}; - gdouble values[] = {0, 10, 25, 35, 50, 60, 80, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "SprayRotationAction", - _("Rotation"), _("Rotation:"), - // xgettext:no-c-format - _("Variation of the rotation of the sprayed objects; 0% for the same rotation than the original object"), - "/tools/spray/rotation_variation", 0, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "spray-rotation", - 0, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_spray_rotation_value_changed, 1, 0 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - g_object_set_data( holder, "spray_rotation", eact ); - } - - { /* Scale */ - gchar const* labels[] = {_("(default)"), 0, 0, 0, 0, 0, 0, _("(high scale variation)")}; - gdouble values[] = {0, 10, 25, 35, 50, 60, 80, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "SprayScaleAction", - C_("Spray tool", "Scale"), C_("Spray tool", "Scale:"), - // xgettext:no-c-format - _("Variation in the scale of the sprayed objects; 0% for the same scale than the original object"), - "/tools/spray/scale_variation", 0, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "spray-scale", - 0, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_spray_scale_value_changed, 1, 0 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - g_object_set_data( holder, "spray_scale", eact ); - } - - - -} - - -//######################## -//## Calligraphy ## -//######################## -static void update_presets_list(GObject *tbl) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - if (g_object_get_data(tbl, "presets_blocked")) { - return; - } - - EgeSelectOneAction *sel = static_cast<EgeSelectOneAction *>(g_object_get_data(tbl, "profile_selector")); - if (!sel) { - // WTF!? This will cause a segfault if ever reached - //ege_select_one_action_set_active(sel, 0); - return; - } - - std::vector<Glib::ustring> presets = prefs->getAllDirs("/tools/calligraphic/preset"); - - int ege_index = 1; - for (std::vector<Glib::ustring>::iterator i = presets.begin(); i != presets.end(); ++i, ++ege_index) { - bool match = true; - - std::vector<Inkscape::Preferences::Entry> preset = prefs->getAllEntries(*i); - for (std::vector<Inkscape::Preferences::Entry>::iterator j = preset.begin(); j != preset.end(); ++j) { - Glib::ustring entry_name = j->getEntryName(); - if (entry_name == "id" || entry_name == "name") { - continue; - } - - void *widget = g_object_get_data(tbl, entry_name.data()); - if (widget) { - if (GTK_IS_ADJUSTMENT(widget)) { - double v = j->getDouble(); - GtkAdjustment* adj = static_cast<GtkAdjustment *>(widget); - //std::cout << "compared adj " << attr_name << gtk_adjustment_get_value(adj) << " to " << v << "\n"; - if (fabs(gtk_adjustment_get_value(adj) - v) > 1e-6) { - match = false; - break; - } - } else if (GTK_IS_TOGGLE_ACTION(widget)) { - bool v = j->getBool(); - GtkToggleAction* toggle = static_cast<GtkToggleAction *>(widget); - //std::cout << "compared toggle " << attr_name << gtk_toggle_action_get_active(toggle) << " to " << v << "\n"; - if ( static_cast<bool>(gtk_toggle_action_get_active(toggle)) != v ) { - match = false; - break; - } - } - } - } - - if (match) { - // newly added item is at the same index as the - // save command, so we need to change twice for it to take effect - ege_select_one_action_set_active(sel, 0); - ege_select_one_action_set_active(sel, ege_index); // one-based index - return; - } - } - - // no match found - ege_select_one_action_set_active(sel, 0); -} - -static void sp_ddc_mass_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/calligraphic/mass", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_wiggle_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/calligraphic/wiggle", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_angle_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/calligraphic/angle", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_width_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/calligraphic/width", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_velthin_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/calligraphic/thinning", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_flatness_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/calligraphic/flatness", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_tremor_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/calligraphic/tremor", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_cap_rounding_value_changed( GtkAdjustment *adj, GObject* tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/calligraphic/cap_rounding", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_ddc_tilt_state_changed( GtkToggleAction *act, GObject* tbl ) -{ - // TODO merge into PrefPusher - GtkAction * calligraphy_angle = static_cast<GtkAction *> (g_object_get_data(tbl,"angle_action")); - if (calligraphy_angle ) { - gtk_action_set_sensitive( calligraphy_angle, !gtk_toggle_action_get_active( act ) ); - } -} - - -static gchar const *const widget_names[] = { - "width", - "mass", - "wiggle", - "angle", - "thinning", - "tremor", - "flatness", - "cap_rounding", - "usepressure", - "tracebackground", - "usetilt" -}; - - -static void sp_dcc_build_presets_list(GObject *tbl) -{ - g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(TRUE)); - - EgeSelectOneAction* selector = static_cast<EgeSelectOneAction *>(g_object_get_data(tbl, "profile_selector")); - GtkListStore* model = GTK_LIST_STORE(ege_select_one_action_get_model(selector)); - gtk_list_store_clear (model); - - { - GtkTreeIter iter; - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, _("No preset"), 1, 0, -1 ); - } - - // iterate over all presets to populate the list - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - std::vector<Glib::ustring> presets = prefs->getAllDirs("/tools/calligraphic/preset"); - int ii=1; - - for (std::vector<Glib::ustring>::iterator i = presets.begin(); i != presets.end(); ++i) { - GtkTreeIter iter; - Glib::ustring preset_name = prefs->getString(*i + "/name"); - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, _(preset_name.data()), 1, ii++, -1 ); - } - - { - GtkTreeIter iter; - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, _("Save..."), 1, ii, -1 ); - g_object_set_data(tbl, "save_presets_index", GINT_TO_POINTER(ii)); - } - - g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE)); - - update_presets_list (tbl); -} - -static void sp_dcc_save_profile(GtkWidget * /*widget*/, GObject *tbl) -{ - using Inkscape::UI::Dialog::CalligraphicProfileRename; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - SPDesktop *desktop = (SPDesktop *) g_object_get_data(tbl, "desktop" ); - if (! desktop) { - return; - } - - if (g_object_get_data(tbl, "presets_blocked")) { - return; - } - - CalligraphicProfileRename::show(desktop); - if ( !CalligraphicProfileRename::applied()) { - // dialog cancelled - update_presets_list (tbl); - return; - } - Glib::ustring profile_name = CalligraphicProfileRename::getProfileName(); - - if (profile_name.empty()) { - // empty name entered - update_presets_list (tbl); - return; - } - - g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(TRUE)); - - // If there's a preset with the given name, find it and set save_path appropriately - std::vector<Glib::ustring> presets = prefs->getAllDirs("/tools/calligraphic/preset"); - int total_presets = presets.size(); - int new_index = -1; - Glib::ustring save_path; // profile pref path without a trailing slash - - int temp_index = 0; - for (std::vector<Glib::ustring>::iterator i = presets.begin(); i != presets.end(); ++i, ++temp_index) { - Glib::ustring name = prefs->getString(*i + "/name"); - if (!name.empty() && profile_name == name) { - new_index = temp_index; - save_path = *i; - break; - } - } - - if (new_index == -1) { - // no preset with this name, create - new_index = total_presets + 1; - gchar *profile_id = g_strdup_printf("/dcc%d", new_index); - save_path = Glib::ustring("/tools/calligraphic/preset") + profile_id; - g_free(profile_id); - } - - for (unsigned i = 0; i < G_N_ELEMENTS(widget_names); ++i) { - gchar const *const widget_name = widget_names[i]; - void *widget = g_object_get_data(tbl, widget_name); - if (widget) { - if (GTK_IS_ADJUSTMENT(widget)) { - GtkAdjustment* adj = static_cast<GtkAdjustment *>(widget); - prefs->setDouble(save_path + "/" + widget_name, gtk_adjustment_get_value(adj)); - //std::cout << "wrote adj " << widget_name << ": " << v << "\n"; - } else if (GTK_IS_TOGGLE_ACTION(widget)) { - GtkToggleAction* toggle = static_cast<GtkToggleAction *>(widget); - prefs->setBool(save_path + "/" + widget_name, gtk_toggle_action_get_active(toggle)); - //std::cout << "wrote tog " << widget_name << ": " << v << "\n"; - } else { - g_warning("Unknown widget type for preset: %s\n", widget_name); - } - } else { - g_warning("Bad key when writing preset: %s\n", widget_name); - } - } - prefs->setString(save_path + "/name", profile_name); - - g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE)); - sp_dcc_build_presets_list (tbl); -} - - -static void sp_ddc_change_profile(EgeSelectOneAction* act, GObject* tbl) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - gint preset_index = ege_select_one_action_get_active( act ); - // This is necessary because EgeSelectOneAction spams us with GObject "changed" signal calls - // even when the preset is not changed. It would be good to replace it with something more - // modern. Index 0 means "No preset", so we don't do anything. - if (preset_index == 0) { - return; - } - - gint save_presets_index = GPOINTER_TO_INT(g_object_get_data(tbl, "save_presets_index")); - - if (preset_index == save_presets_index) { - // this is the Save command - sp_dcc_save_profile(NULL, tbl); - return; - } - - if (g_object_get_data(tbl, "presets_blocked")) { - return; - } - - // preset_index is one-based so we subtract 1 - std::vector<Glib::ustring> presets = prefs->getAllDirs("/tools/calligraphic/preset"); - Glib::ustring preset_path = presets.at(preset_index - 1); - - if (!preset_path.empty()) { - g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(TRUE)); //temporarily block the selector so no one will updadte it while we're reading it - - std::vector<Inkscape::Preferences::Entry> preset = prefs->getAllEntries(preset_path); - - // Shouldn't this be std::map? - for (std::vector<Inkscape::Preferences::Entry>::iterator i = preset.begin(); i != preset.end(); ++i) { - Glib::ustring entry_name = i->getEntryName(); - if (entry_name == "id" || entry_name == "name") { - continue; - } - void *widget = g_object_get_data(tbl, entry_name.data()); - if (widget) { - if (GTK_IS_ADJUSTMENT(widget)) { - GtkAdjustment* adj = static_cast<GtkAdjustment *>(widget); - gtk_adjustment_set_value(adj, i->getDouble()); - //std::cout << "set adj " << attr_name << " to " << v << "\n"; - } else if (GTK_IS_TOGGLE_ACTION(widget)) { - GtkToggleAction* toggle = static_cast<GtkToggleAction *>(widget); - gtk_toggle_action_set_active(toggle, i->getBool()); - //std::cout << "set toggle " << attr_name << " to " << v << "\n"; - } else { - g_warning("Unknown widget type for preset: %s\n", entry_name.data()); - } - } else { - g_warning("Bad key found in a preset record: %s\n", entry_name.data()); - } - } - g_object_set_data(tbl, "presets_blocked", GINT_TO_POINTER(FALSE)); - } -} - -static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - { - g_object_set_data(holder, "presets_blocked", GINT_TO_POINTER(TRUE)); - - EgeAdjustmentAction* calligraphy_angle = 0; - - { - /* Width */ - gchar const* labels[] = {_("(hairline)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad stroke)")}; - gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "CalligraphyWidthAction", - _("Pen Width"), _("Width:"), - _("The width of the calligraphic pen (relative to the visible canvas area)"), - "/tools/calligraphic/width", 15, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-calligraphy", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_width_value_changed, 1, 0 ); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - { - /* Thinning */ - gchar const* labels[] = {_("(speed blows up stroke)"), 0, 0, _("(slight widening)"), _("(constant width)"), _("(slight thinning, default)"), 0, 0, _("(speed deflates stroke)")}; - gdouble values[] = {-100, -40, -20, -10, 0, 10, 20, 40, 100}; - EgeAdjustmentAction* eact = create_adjustment_action( "ThinningAction", - _("Stroke Thinning"), _("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", 10, - GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL, - -100, 100, 1, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_velthin_value_changed, 1, 0); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - { - /* Angle */ - gchar const* labels[] = {_("(left edge up)"), 0, 0, _("(horizontal)"), _("(default)"), 0, _("(right edge up)")}; - gdouble values[] = {-90, -60, -30, 0, 30, 60, 90}; - EgeAdjustmentAction* eact = create_adjustment_action( "AngleAction", - _("Pen Angle"), _("Angle:"), - _("The angle of the pen's nib (in degrees; 0 = horizontal; has no effect if fixation = 0)"), - "/tools/calligraphic/angle", 30, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "calligraphy-angle", - -90.0, 90.0, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_angle_value_changed, 1, 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - g_object_set_data( holder, "angle_action", eact ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - calligraphy_angle = eact; - } - - { - /* Fixation */ - gchar const* labels[] = {_("(perpendicular to stroke, \"brush\")"), 0, 0, 0, _("(almost fixed, default)"), _("(fixed by Angle, \"pen\")")}; - gdouble values[] = {0, 20, 40, 60, 90, 100}; - EgeAdjustmentAction* eact = create_adjustment_action( "FixationAction", - _("Fixation"), _("Fixation:"), - _("Angle behavior (0 = nib always perpendicular to stroke direction, 100 = fixed angle)"), - "/tools/calligraphic/flatness", 90, - GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL, - 0.0, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_flatness_value_changed, 1, 0); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - { - /* Cap Rounding */ - gchar const* labels[] = {_("(blunt caps, default)"), _("(slightly bulging)"), 0, 0, _("(approximately round)"), _("(long protruding caps)")}; - gdouble values[] = {0, 0.3, 0.5, 1.0, 1.4, 5.0}; - // TRANSLATORS: "cap" means "end" (both start and finish) here - EgeAdjustmentAction* eact = create_adjustment_action( "CapRoundingAction", - _("Cap rounding"), _("Caps:"), - _("Increase to make caps at the ends of strokes protrude more (0 = no caps, 1 = round caps)"), - "/tools/calligraphic/cap_rounding", 0.0, - GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL, - 0.0, 5.0, 0.01, 0.1, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_cap_rounding_value_changed, 0.01, 2 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - { - /* Tremor */ - gchar const* labels[] = {_("(smooth line)"), _("(slight tremor)"), _("(noticeable tremor)"), 0, 0, _("(maximum tremor)")}; - gdouble values[] = {0, 10, 20, 40, 60, 100}; - EgeAdjustmentAction* eact = create_adjustment_action( "TremorAction", - _("Stroke Tremor"), _("Tremor:"), - _("Increase to make strokes rugged and trembling"), - "/tools/calligraphic/tremor", 0.0, - GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL, - 0.0, 100, 1, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_tremor_value_changed, 1, 0); - - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - { - /* Wiggle */ - gchar const* labels[] = {_("(no wiggle)"), _("(slight deviation)"), 0, 0, _("(wild waves and curls)")}; - gdouble values[] = {0, 20, 40, 60, 100}; - EgeAdjustmentAction* eact = create_adjustment_action( "WiggleAction", - _("Pen Wiggle"), _("Wiggle:"), - _("Increase to make the pen waver and wiggle"), - "/tools/calligraphic/wiggle", 0.0, - GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL, - 0.0, 100, 1, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_wiggle_value_changed, 1, 0); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - { - /* Mass */ - gchar const* labels[] = {_("(no inertia)"), _("(slight smoothing, default)"), _("(noticeable lagging)"), 0, 0, _("(maximum inertia)")}; - gdouble values[] = {0.0, 2, 10, 20, 50, 100}; - EgeAdjustmentAction* eact = create_adjustment_action( "MassAction", - _("Pen Mass"), _("Mass:"), - _("Increase to make the pen drag behind, as if slowed by inertia"), - "/tools/calligraphic/mass", 2.0, - GTK_WIDGET(desktop->canvas), NULL, holder, FALSE, NULL, - 0.0, 100, 1, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_ddc_mass_value_changed, 1, 0); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - - - /* Trace Background button */ - { - InkToggleAction* act = ink_toggle_action_new( "TraceAction", - _("Trace Background"), - _("Trace the lightness of the background by the width of the pen (white - minimum width, black - maximum width)"), - INKSCAPE_ICON("draw-trace-background"), - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/calligraphic/tracebackground", update_presets_list, holder); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - g_object_set_data( holder, "tracebackground", act ); - } - - /* 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"), - INKSCAPE_ICON("draw-use-pressure"), - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/calligraphic/usepressure", update_presets_list, holder); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - g_object_set_data( holder, "usepressure", act ); - } - - /* 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"), - INKSCAPE_ICON("draw-use-tilt"), - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - PrefPusher *pusher = new PrefPusher(GTK_TOGGLE_ACTION(act), "/tools/calligraphic/usetilt", update_presets_list, holder); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_prefspusher), pusher); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_ddc_tilt_state_changed), holder ); - gtk_action_set_sensitive( GTK_ACTION(calligraphy_angle), !prefs->getBool("/tools/calligraphic/usetilt", true) ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/calligraphic/usetilt", true) ); - g_object_set_data( holder, "usetilt", act ); - } - - /*calligraphic profile */ - { - GtkListStore* model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT); - EgeSelectOneAction* act1 = ege_select_one_action_new ("SetProfileAction", "" , (_("Choose a preset")), NULL, GTK_TREE_MODEL(model)); - ege_select_one_action_set_appearance (act1, "compact"); - g_object_set_data (holder, "profile_selector", act1 ); - - g_object_set_data(holder, "presets_blocked", GINT_TO_POINTER(FALSE)); - - sp_dcc_build_presets_list (holder); - - g_signal_connect(G_OBJECT(act1), "changed", G_CALLBACK(sp_ddc_change_profile), holder); - gtk_action_group_add_action(mainActions, GTK_ACTION(act1)); - } - } -} - - -//######################## -//## Circle / Arc ## -//######################## - -static void sp_arctb_sensitivize( GObject *tbl, double v1, double v2 ) -{ - GtkAction *ocb = GTK_ACTION( g_object_get_data( tbl, "open_action" ) ); - GtkAction *make_whole = GTK_ACTION( g_object_get_data( tbl, "make_whole" ) ); - - if (v1 == 0 && v2 == 0) { - if (g_object_get_data( tbl, "single" )) { // only for a single selected ellipse (for now) - gtk_action_set_sensitive( ocb, FALSE ); - gtk_action_set_sensitive( make_whole, FALSE ); - } - } else { - gtk_action_set_sensitive( ocb, TRUE ); - gtk_action_set_sensitive( make_whole, TRUE ); - } -} - -static void -sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name, gchar const *other_name) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); - - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble(Glib::ustring("/tools/shapes/arc/") + value_name, gtk_adjustment_get_value(adj)); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gchar* namespaced_name = g_strconcat("sodipodi:", value_name, NULL); - - bool modmade = false; - for (GSList const *items = sp_desktop_selection(desktop)->itemList(); - items != NULL; - items = items->next) - { - SPItem *item = SP_ITEM(items->data); - - if (SP_IS_ARC(item) && SP_IS_GENERICELLIPSE(item)) { - - SPGenericEllipse *ge = SP_GENERICELLIPSE(item); - SPArc *arc = SP_ARC(item); - - if (!strcmp(value_name, "start")) { - ge->start = (gtk_adjustment_get_value(adj) * M_PI)/ 180; - } else { - ge->end = (gtk_adjustment_get_value(adj) * M_PI)/ 180; - } - - sp_genericellipse_normalize(ge); - ((SPObject *)arc)->updateRepr(); - ((SPObject *)arc)->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - - modmade = true; - } - } - - g_free(namespaced_name); - - GtkAdjustment *other = GTK_ADJUSTMENT( g_object_get_data( tbl, other_name ) ); - - sp_arctb_sensitivize( tbl, gtk_adjustment_get_value(adj), gtk_adjustment_get_value(other) ); - - if (modmade) { - DocumentUndo::maybeDone(sp_desktop_document(desktop), value_name, SP_VERB_CONTEXT_ARC, - _("Arc: Change start/end")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - - -static void sp_arctb_start_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_arctb_startend_value_changed(adj, tbl, "start", "end"); -} - -static void sp_arctb_end_value_changed(GtkAdjustment *adj, GObject *tbl) -{ - sp_arctb_startend_value_changed(adj, tbl, "end", "start"); -} - - -static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl ) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/shapes/arc/open", ege_select_one_action_get_active(act) != 0); - } - - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - bool modmade = false; - - if ( ege_select_one_action_get_active(act) != 0 ) { - for (GSList const *items = sp_desktop_selection(desktop)->itemList(); - items != NULL; - items = items->next) - { - SPItem *item = reinterpret_cast<SPItem*>(items->data); - if (SP_IS_ARC(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - repr->setAttribute("sodipodi:open", "true"); - item->updateRepr(); - modmade = true; - } - } - } else { - for (GSList const *items = sp_desktop_selection(desktop)->itemList(); - items != NULL; - items = items->next) - { - SPItem *item = reinterpret_cast<SPItem *>(items->data); - if (SP_IS_ARC(item)) { - Inkscape::XML::Node *repr = item->getRepr(); - repr->setAttribute("sodipodi:open", NULL); - item->updateRepr(); - modmade = true; - } - } - } - - if (modmade) { - DocumentUndo::done(sp_desktop_document(desktop), SP_VERB_CONTEXT_ARC, - _("Arc: Change open/closed")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_arctb_defaults(GtkWidget *, GObject *obj) -{ - GtkAdjustment *adj; - adj = GTK_ADJUSTMENT( g_object_get_data(obj, "start") ); - gtk_adjustment_set_value(adj, 0.0); - gtk_adjustment_value_changed(adj); - - adj = GTK_ADJUSTMENT( g_object_get_data(obj, "end") ); - gtk_adjustment_set_value(adj, 0.0); - gtk_adjustment_value_changed(adj); - - spinbutton_defocus(GTK_WIDGET(obj)); -} - -static void arc_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const * /*name*/, - gchar const * /*old_value*/, gchar const * /*new_value*/, - bool /*is_interactive*/, gpointer data) -{ - GObject *tbl = G_OBJECT(data); - - // quit if run by the _changed callbacks - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent callbacks from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gdouble start = 0.; - gdouble end = 0.; - sp_repr_get_double(repr, "sodipodi:start", &start); - sp_repr_get_double(repr, "sodipodi:end", &end); - - GtkAdjustment *adj1,*adj2; - adj1 = GTK_ADJUSTMENT( g_object_get_data( tbl, "start" ) ); - gtk_adjustment_set_value(adj1, mod360((start * 180)/M_PI)); - adj2 = GTK_ADJUSTMENT( g_object_get_data( tbl, "end" ) ); - gtk_adjustment_set_value(adj2, mod360((end * 180)/M_PI)); - - sp_arctb_sensitivize( tbl, gtk_adjustment_get_value(adj1), gtk_adjustment_get_value(adj2) ); - - char const *openstr = NULL; - openstr = repr->attribute("sodipodi:open"); - EgeSelectOneAction *ocb = EGE_SELECT_ONE_ACTION( g_object_get_data( tbl, "open_action" ) ); - - if (openstr) { - ege_select_one_action_set_active( ocb, 1 ); - } else { - ege_select_one_action_set_active( ocb, 0 ); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static Inkscape::XML::NodeEventVector arc_tb_repr_events = { - NULL, /* child_added */ - NULL, /* child_removed */ - arc_tb_event_attr_changed, - NULL, /* content_changed */ - NULL /* order_changed */ -}; - - -static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) -{ - int n_selected = 0; - Inkscape::XML::Node *repr = NULL; - - purge_repr_listener( tbl, tbl ); - - for (GSList const *items = selection->itemList(); - items != NULL; - items = items->next) - { - SPItem *item = reinterpret_cast<SPItem *>(items->data); - if (SP_IS_ARC(item)) { - n_selected++; - repr = item->getRepr(); - } - } - - EgeOutputAction* act = EGE_OUTPUT_ACTION( g_object_get_data( tbl, "mode_action" ) ); - - g_object_set_data( tbl, "single", GINT_TO_POINTER(FALSE) ); - if (n_selected == 0) { - g_object_set( G_OBJECT(act), "label", _("<b>New:</b>"), NULL ); - } else if (n_selected == 1) { - g_object_set_data( tbl, "single", GINT_TO_POINTER(TRUE) ); - g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL ); - - if (repr) { - g_object_set_data( tbl, "repr", repr ); - Inkscape::GC::anchor(repr); - sp_repr_add_listener(repr, &arc_tb_repr_events, tbl); - sp_repr_synthesize_events(repr, &arc_tb_repr_events, tbl); - } - } else { - // FIXME: implement averaging of all parameters for multiple selected - //gtk_label_set_markup(GTK_LABEL(l), _("<b>Average:</b>")); - g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL ); - sp_arctb_sensitivize( tbl, 1, 0 ); - } -} - - -static void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - EgeAdjustmentAction* eact = 0; - Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - - { - EgeOutputAction* act = ege_output_action_new( "ArcStateAction", _("<b>New:</b>"), "", 0 ); - ege_output_action_set_use_markup( act, TRUE ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "mode_action", act ); - } - - /* Start */ - { - eact = create_adjustment_action( "ArcStartAction", - _("Start"), _("Start:"), - _("The angle (in degrees) from the horizontal to the arc's start point"), - "/tools/shapes/arc/start", 0.0, - GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, TRUE, "altx-arc", - -360.0, 360.0, 1.0, 10.0, - 0, 0, 0, - sp_arctb_start_value_changed); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* End */ - { - eact = create_adjustment_action( "ArcEndAction", - _("End"), _("End:"), - _("The angle (in degrees) from the horizontal to the arc's end point"), - "/tools/shapes/arc/end", 0.0, - GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, FALSE, NULL, - -360.0, 360.0, 1.0, 10.0, - 0, 0, 0, - sp_arctb_end_value_changed); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* Segments / Pie checkbox */ - { - GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); - - GtkTreeIter iter; - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Closed arc"), - 1, _("Switch to segment (closed shape with two radii)"), - 2, INKSCAPE_ICON("draw-ellipse-segment"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Open Arc"), - 1, _("Switch to arc (unclosed shape)"), - 2, INKSCAPE_ICON("draw-ellipse-arc"), - -1 ); - - EgeSelectOneAction* act = ege_select_one_action_new( "ArcOpenAction", (""), (""), NULL, GTK_TREE_MODEL(model) ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - g_object_set_data( holder, "open_action", act ); - - ege_select_one_action_set_appearance( act, "full" ); - ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE ); - g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL ); - ege_select_one_action_set_icon_column( act, 2 ); - ege_select_one_action_set_icon_size( act, secondarySize ); - ege_select_one_action_set_tooltip_column( act, 1 ); - - bool isClosed = !prefs->getBool("/tools/shapes/arc/open", false); - ege_select_one_action_set_active( act, isClosed ? 0 : 1 ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_arctb_open_state_changed), holder ); - } - - /* Make Whole */ - { - InkAction* inky = ink_action_new( "ArcResetAction", - _("Make whole"), - _("Make the shape a whole ellipse, not arc or segment"), - INKSCAPE_ICON("draw-ellipse-whole"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_arctb_defaults), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - gtk_action_set_sensitive( GTK_ACTION(inky), TRUE ); - g_object_set_data( holder, "make_whole", inky ); - } - - g_object_set_data( G_OBJECT(holder), "single", GINT_TO_POINTER(TRUE) ); - // sensitivize make whole and open checkbox - { - GtkAdjustment *adj1 = GTK_ADJUSTMENT( g_object_get_data( holder, "start" ) ); - GtkAdjustment *adj2 = GTK_ADJUSTMENT( g_object_get_data( holder, "end" ) ); - sp_arctb_sensitivize( holder, gtk_adjustment_get_value(adj1), gtk_adjustment_get_value(adj2) ); - } - - - sigc::connection *connection = new sigc::connection( - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_arc_toolbox_selection_changed), (GObject *)holder)) - ); - g_signal_connect( holder, "destroy", G_CALLBACK(delete_connection), connection ); - g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); -} - - - - -// toggle button callbacks and updaters - -//######################## -//## Dropper ## -//######################## - -static void toggle_dropper_pick_alpha( GtkToggleAction* act, gpointer tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt( "/tools/dropper/pick", gtk_toggle_action_get_active( act ) ); - GtkAction* set_action = GTK_ACTION( g_object_get_data(G_OBJECT(tbl), "set_action") ); - if ( set_action ) { - if ( gtk_toggle_action_get_active( act ) ) { - gtk_action_set_sensitive( set_action, TRUE ); - } else { - gtk_action_set_sensitive( set_action, FALSE ); - } - } - - spinbutton_defocus(GTK_WIDGET(tbl)); -} - -static void toggle_dropper_set_alpha( GtkToggleAction* act, gpointer tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool( "/tools/dropper/setalpha", gtk_toggle_action_get_active( act ) ); - spinbutton_defocus(GTK_WIDGET(tbl)); -} - - -/** - * Dropper auxiliary toolbar construction and setup. - * - * TODO: Would like to add swatch of current color. - * TODO: Add queue of last 5 or so colors selected with new swatches so that - * can drag and drop places. Will provide a nice mixing palette. - */ -static void sp_dropper_toolbox_prep(SPDesktop * /*desktop*/, GtkActionGroup* mainActions, GObject* holder) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gint pickAlpha = prefs->getInt( "/tools/dropper/pick", 1 ); - - { - EgeOutputAction* act = ege_output_action_new( "DropperOpacityAction", _("Opacity:"), "", 0 ); - ege_output_action_set_use_markup( act, TRUE ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - } - - { - InkToggleAction* act = ink_toggle_action_new( "DropperPickAlphaAction", - _("Pick opacity"), - _("Pick both the color and the alpha (transparency) under cursor; otherwise, pick only the visible color premultiplied by alpha"), - NULL, - Inkscape::ICON_SIZE_DECORATION ); - g_object_set( act, "short_label", _("Pick"), NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "pick_action", act ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), pickAlpha ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_dropper_pick_alpha), holder ); - } - - { - InkToggleAction* act = ink_toggle_action_new( "DropperSetAlphaAction", - _("Assign opacity"), - _("If alpha was picked, assign it to selection as fill or stroke transparency"), - NULL, - Inkscape::ICON_SIZE_DECORATION ); - g_object_set( act, "short_label", _("Assign"), NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_object_set_data( holder, "set_action", act ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool( "/tools/dropper/setalpha", true) ); - // make sure it's disabled if we're not picking alpha - gtk_action_set_sensitive( GTK_ACTION(act), pickAlpha ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(toggle_dropper_set_alpha), holder ); - } -} - - -//######################## -//## LPETool ## -//######################## - -// the subtools from which the toolbar is built automatically are listed in lpe-tool-context.h - -// this is called when the mode is changed via the toolbar (i.e., one of the subtool buttons is pressed) -static void sp_lpetool_mode_changed(EgeSelectOneAction *act, GObject *tbl) -{ - using namespace Inkscape::LivePathEffect; - - SPDesktop *desktop = (SPDesktop *) g_object_get_data(tbl, "desktop"); - SPEventContext *ec = desktop->event_context; - if (!SP_IS_LPETOOL_CONTEXT(ec)) { - return; - } - - // only take action if run by the attr_changed listener - if (!g_object_get_data(tbl, "freeze")) { - // in turn, prevent listener from responding - g_object_set_data(tbl, "freeze", GINT_TO_POINTER(TRUE)); - - gint mode = ege_select_one_action_get_active(act); - EffectType type = lpesubtools[mode].type; - - SPLPEToolContext *lc = SP_LPETOOL_CONTEXT(desktop->event_context); - bool success = lpetool_try_construction(lc, type); - if (success) { - // since the construction was already performed, we set the state back to inactive - ege_select_one_action_set_active(act, 0); - mode = 0; - } else { - // switch to the chosen subtool - SP_LPETOOL_CONTEXT(desktop->event_context)->mode = type; - } - - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt( "/tools/lpetool/mode", mode ); - } - - g_object_set_data(tbl, "freeze", GINT_TO_POINTER(FALSE)); - } -} - -static void sp_lpetool_toolbox_sel_modified(Inkscape::Selection *selection, guint /*flags*/, GObject * /*tbl*/) -{ - SPEventContext *ec = selection->desktop()->event_context; - if (SP_IS_LPETOOL_CONTEXT(ec)) { - lpetool_update_measuring_items(SP_LPETOOL_CONTEXT(ec)); - } -} - -static void sp_lpetool_toolbox_sel_changed(Inkscape::Selection *selection, GObject *tbl) -{ - using namespace Inkscape::LivePathEffect; - SPEventContext *ec = selection->desktop()->event_context; - if (!SP_IS_LPETOOL_CONTEXT(ec)) { - return; - } - SPLPEToolContext *lc = SP_LPETOOL_CONTEXT(ec); - - lpetool_delete_measuring_items(lc); - lpetool_create_measuring_items(lc, selection); - - // activate line segment combo box if a single item with LPELineSegment is selected - GtkAction* w = GTK_ACTION(g_object_get_data(tbl, "lpetool_line_segment_action")); - SPItem *item = selection->singleItem(); - if (item && SP_IS_LPE_ITEM(item) && lpetool_item_has_construction(lc, item)) { - SPLPEItem *lpeitem = SP_LPE_ITEM(item); - Effect* lpe = sp_lpe_item_get_current_lpe(lpeitem); - if (lpe && lpe->effectType() == LINE_SEGMENT) { - LPELineSegment *lpels = static_cast<LPELineSegment*>(lpe); - g_object_set_data(tbl, "currentlpe", lpe); - g_object_set_data(tbl, "currentlpeitem", lpeitem); - gtk_action_set_sensitive(w, TRUE); - ege_select_one_action_set_active(EGE_SELECT_ONE_ACTION(w), lpels->end_type.get_value()); - } else { - g_object_set_data(tbl, "currentlpe", NULL); - g_object_set_data(tbl, "currentlpeitem", NULL); - gtk_action_set_sensitive(w, FALSE); - } - } else { - g_object_set_data(tbl, "currentlpe", NULL); - g_object_set_data(tbl, "currentlpeitem", NULL); - gtk_action_set_sensitive(w, FALSE); - } -} - -static void lpetool_toggle_show_bbox(GtkToggleAction *act, gpointer data) { - SPDesktop *desktop = static_cast<SPDesktop *>(data); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - bool show = gtk_toggle_action_get_active( act ); - prefs->setBool("/tools/lpetool/show_bbox", show); - - if (tools_isactive(desktop, TOOLS_LPETOOL)) { - SPLPEToolContext *lc = SP_LPETOOL_CONTEXT(desktop->event_context); - lpetool_context_reset_limiting_bbox(lc); - } -} - -static void lpetool_toggle_show_measuring_info(GtkToggleAction *act, GObject *tbl) -{ - SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data(tbl, "desktop")); - if (!tools_isactive(desktop, TOOLS_LPETOOL)) { - return; - } - - GtkAction *unitact = static_cast<GtkAction*>(g_object_get_data(tbl, "lpetool_units_action")); - SPLPEToolContext *lc = SP_LPETOOL_CONTEXT(desktop->event_context); - if (tools_isactive(desktop, TOOLS_LPETOOL)) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - bool show = gtk_toggle_action_get_active( act ); - prefs->setBool("/tools/lpetool/show_measuring_info", show); - lpetool_show_measuring_info(lc, show); - gtk_action_set_sensitive(GTK_ACTION(unitact), show); - } -} - -static void lpetool_unit_changed(GtkAction* /*act*/, GObject* tbl) -{ - UnitTracker* tracker = reinterpret_cast<UnitTracker*>(g_object_get_data(tbl, "tracker")); - SPUnit const *unit = tracker->getActiveUnit(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/lpetool/unitid", unit->unit_id); - - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); - if (SP_IS_LPETOOL_CONTEXT(desktop->event_context)) { - SPLPEToolContext *lc = SP_LPETOOL_CONTEXT(desktop->event_context); - lpetool_delete_measuring_items(lc); - lpetool_create_measuring_items(lc); - } -} - -static void lpetool_toggle_set_bbox(GtkToggleAction *act, gpointer data) -{ - SPDesktop *desktop = static_cast<SPDesktop *>(data); - Inkscape::Selection *selection = desktop->selection; - - Geom::OptRect bbox = selection->visualBounds(); - - if (bbox) { - Geom::Point A(bbox->min()); - Geom::Point B(bbox->max()); - - A *= desktop->doc2dt(); - B *= desktop->doc2dt(); - - // TODO: should we provide a way to store points in prefs? - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/lpetool/bbox_upperleftx", A[Geom::X]); - prefs->setDouble("/tools/lpetool/bbox_upperlefty", A[Geom::Y]); - prefs->setDouble("/tools/lpetool/bbox_lowerrightx", B[Geom::X]); - prefs->setDouble("/tools/lpetool/bbox_lowerrighty", B[Geom::Y]); - - lpetool_context_reset_limiting_bbox(SP_LPETOOL_CONTEXT(desktop->event_context)); - } - - gtk_toggle_action_set_active(act, false); -} - -static void sp_line_segment_build_list(GObject *tbl) -{ - g_object_set_data(tbl, "line_segment_list_blocked", GINT_TO_POINTER(TRUE)); - - EgeSelectOneAction* selector = static_cast<EgeSelectOneAction *>(g_object_get_data(tbl, "lpetool_line_segment_action")); - GtkListStore* model = GTK_LIST_STORE(ege_select_one_action_get_model(selector)); - gtk_list_store_clear (model); - - // TODO: we add the entries of rht combo box manually; later this should be done automatically - { - GtkTreeIter iter; - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, _("Closed"), 1, 0, -1 ); - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, _("Open start"), 1, 1, -1 ); - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, _("Open end"), 1, 2, -1 ); - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, _("Open both"), 1, 3, -1 ); - } - - g_object_set_data(tbl, "line_segment_list_blocked", GINT_TO_POINTER(FALSE)); -} - -static void sp_lpetool_change_line_segment_type(EgeSelectOneAction* act, GObject* tbl) -{ - using namespace Inkscape::LivePathEffect; - - // quit if run by the attr_changed listener - if (g_object_get_data(tbl, "freeze")) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data(tbl, "freeze", GINT_TO_POINTER(TRUE)); - - LPELineSegment *lpe = static_cast<LPELineSegment *>(g_object_get_data(tbl, "currentlpe")); - SPLPEItem *lpeitem = static_cast<SPLPEItem *>(g_object_get_data(tbl, "currentlpeitem")); - if (lpeitem) { - SPLPEItem *lpeitem = static_cast<SPLPEItem *>(g_object_get_data(tbl, "currentlpeitem")); - lpe->end_type.param_set_value(static_cast<Inkscape::LivePathEffect::EndType>(ege_select_one_action_get_active(act))); - sp_lpe_item_update_patheffect(lpeitem, true, true); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void lpetool_open_lpe_dialog(GtkToggleAction *act, gpointer data) -{ - SPDesktop *desktop = static_cast<SPDesktop *>(data); - - if (tools_isactive(desktop, TOOLS_LPETOOL)) { - sp_action_perform(Inkscape::Verb::get(SP_VERB_DIALOG_LIVE_PATH_EFFECT)->get_action(desktop), NULL); - } - gtk_toggle_action_set_active(act, false); -} - -static void sp_lpetool_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - UnitTracker* tracker = new UnitTracker(SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE); - tracker->setActiveUnit(sp_desktop_namedview(desktop)->doc_units); - g_object_set_data(holder, "tracker", tracker); - SPUnit const *unit = tracker->getActiveUnit(); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/lpetool/unitid", unit->unit_id); - - /** Automatically create a list of LPEs that get added to the toolbar **/ - { - GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); - - GtkTreeIter iter; - - // the first toggle button represents the state that no subtool is active (remove this when - // this can be modeled by EgeSelectOneAction or some other action) - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("All inactive"), - 1, _("No geometric tool is active"), - 2, "draw-geometry-inactive", - -1 ); - - Inkscape::LivePathEffect::EffectType type; - for (int i = 1; i < num_subtools; ++i) { // we start with i = 1 because INVALID_LPE was already added - type = lpesubtools[i].type; - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, Inkscape::LivePathEffect::LPETypeConverter.get_label(type).c_str(), - 1, Inkscape::LivePathEffect::LPETypeConverter.get_label(type).c_str(), - 2, lpesubtools[i].icon_name, - -1 ); - } - - EgeSelectOneAction* act = ege_select_one_action_new( "LPEToolModeAction", (""), (""), NULL, GTK_TREE_MODEL(model) ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - g_object_set_data( holder, "lpetool_mode_action", act ); - - ege_select_one_action_set_appearance( act, "full" ); - ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE ); - g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL ); - ege_select_one_action_set_icon_column( act, 2 ); - ege_select_one_action_set_tooltip_column( act, 1 ); - - gint lpeToolMode = prefs->getInt("/tools/lpetool/mode", 0); - ege_select_one_action_set_active( act, lpeToolMode ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_lpetool_mode_changed), holder ); - } - - /* Show limiting bounding box */ - { - InkToggleAction* act = ink_toggle_action_new( "LPEShowBBoxAction", - _("Show limiting bounding box"), - _("Show bounding box (used to cut infinite lines)"), - "show-bounding-box", - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(lpetool_toggle_show_bbox), desktop ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool( "/tools/lpetool/show_bbox", true ) ); - } - - /* Set limiting bounding box to bbox of current selection */ - { - InkToggleAction* act = ink_toggle_action_new( "LPEBBoxFromSelectionAction", - _("Get limiting bounding box from selection"), - _("Set limiting bounding box (used to cut infinite lines) to the bounding box of current selection"), - "draw-geometry-set-bounding-box", - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(lpetool_toggle_set_bbox), desktop ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), FALSE ); - } - - - /* Combo box to choose line segment type */ - { - GtkListStore* model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT); - EgeSelectOneAction* act = ege_select_one_action_new ("LPELineSegmentAction", "" , (_("Choose a line segment type")), NULL, GTK_TREE_MODEL(model)); - ege_select_one_action_set_appearance (act, "compact"); - g_object_set_data (holder, "lpetool_line_segment_action", act ); - - g_object_set_data(holder, "line_segment_list_blocked", GINT_TO_POINTER(FALSE)); - - sp_line_segment_build_list (holder); - - g_signal_connect(G_OBJECT(act), "changed", G_CALLBACK(sp_lpetool_change_line_segment_type), holder); - gtk_action_set_sensitive( GTK_ACTION(act), FALSE ); - gtk_action_group_add_action(mainActions, GTK_ACTION(act)); - } - - /* Display measuring info for selected items */ - { - InkToggleAction* act = ink_toggle_action_new( "LPEMeasuringAction", - _("Display measuring info"), - _("Display measuring info for selected items"), - "draw-geometry-show-measuring-info", - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(lpetool_toggle_show_measuring_info), holder ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool( "/tools/lpetool/show_measuring_info", true ) ); - } - - // add the units menu - { - GtkAction* act = tracker->createAction( "LPEToolUnitsAction", _("Units"), ("") ); - gtk_action_group_add_action( mainActions, act ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(lpetool_unit_changed), (GObject*)holder ); - g_object_set_data(holder, "lpetool_units_action", act); - gtk_action_set_sensitive(act, prefs->getBool("/tools/lpetool/show_measuring_info", true)); - } - - /* Open LPE dialog (to adapt parameters numerically) */ - { - InkToggleAction* act = ink_toggle_action_new( "LPEOpenLPEDialogAction", - _("Open LPE dialog"), - _("Open LPE dialog (to adapt parameters numerically)"), - "dialog-geometry", - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(lpetool_open_lpe_dialog), desktop ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), FALSE ); - } - - //watch selection - Inkscape::ConnectionPool* pool = Inkscape::ConnectionPool::new_connection_pool ("ISNodeToolbox"); - - sigc::connection *c_selection_modified = - new sigc::connection (sp_desktop_selection (desktop)->connectModified - (sigc::bind (sigc::ptr_fun (sp_lpetool_toolbox_sel_modified), (GObject*)holder))); - pool->add_connection ("selection-modified", c_selection_modified); - - sigc::connection *c_selection_changed = - new sigc::connection (sp_desktop_selection (desktop)->connectChanged - (sigc::bind (sigc::ptr_fun(sp_lpetool_toolbox_sel_changed), (GObject*)holder))); - pool->add_connection ("selection-changed", c_selection_changed); -} - -//######################## -//## Eraser ## -//######################## - -static void sp_erc_width_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble( "/tools/eraser/width", gtk_adjustment_get_value(adj) ); - update_presets_list(tbl); -} - -static void sp_erasertb_mode_changed( EgeSelectOneAction *act, GObject *tbl ) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); - bool eraserMode = ege_select_one_action_get_active( act ) != 0; - if (DocumentUndo::getUndoSensitive(sp_desktop_document(desktop))) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool( "/tools/eraser/mode", eraserMode ); - } - - // only take action if run by the attr_changed listener - if (!g_object_get_data( tbl, "freeze" )) { - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - if ( eraserMode != 0 ) { - } else { - } - // TODO finish implementation - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); - } -} - -static void sp_eraser_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - { - GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); - - GtkTreeIter iter; - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Delete"), - 1, _("Delete objects touched by the eraser"), - 2, INKSCAPE_ICON("draw-eraser-delete-objects"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Cut"), - 1, _("Cut out from objects"), - 2, INKSCAPE_ICON("path-difference"), - -1 ); - - EgeSelectOneAction* act = ege_select_one_action_new( "EraserModeAction", (""), (""), NULL, GTK_TREE_MODEL(model) ); - g_object_set( act, "short_label", _("Mode:"), NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - g_object_set_data( holder, "eraser_mode_action", act ); - - ege_select_one_action_set_appearance( act, "full" ); - ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE ); - g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL ); - ege_select_one_action_set_icon_column( act, 2 ); - ege_select_one_action_set_tooltip_column( act, 1 ); - - /// @todo Convert to boolean? - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - gint eraserMode = prefs->getBool("/tools/eraser/mode") ? 1 : 0; - ege_select_one_action_set_active( act, eraserMode ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_erasertb_mode_changed), holder ); - } - - { - /* Width */ - gchar const* labels[] = {_("(hairline)"), 0, 0, 0, _("(default)"), 0, 0, 0, 0, _("(broad stroke)")}; - gdouble values[] = {1, 3, 5, 10, 15, 20, 30, 50, 75, 100}; - EgeAdjustmentAction *eact = create_adjustment_action( "EraserWidthAction", - _("Pen Width"), _("Width:"), - _("The width of the eraser pen (relative to the visible canvas area)"), - "/tools/eraser/width", 15, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "altx-eraser", - 1, 100, 1.0, 10.0, - labels, values, G_N_ELEMENTS(labels), - sp_erc_width_value_changed, 1, 0); - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - } - -} - -//######################## -//## Text Toolbox ## -//######################## - -// Functions for debugging: -#ifdef DEBUG_TEXT - -static void sp_print_font( SPStyle *query ) { - - bool family_set = query->text->font_family.set; - bool style_set = query->font_style.set; - bool fontspec_set = query->text->font_specification.set; - - std::cout << " Family set? " << family_set - << " Style set? " << style_set - << " FontSpec set? " << fontspec_set - << std::endl; - std::cout << " Family: " - << (query->text->font_family.value ? query->text->font_family.value : "No value") - << " Style: " << query->font_style.computed - << " Weight: " << query->font_weight.computed - << " FontSpec: " - << (query->text->font_specification.value ? query->text->font_specification.value : "No value") - << std::endl; -} - -static void sp_print_fontweight( SPStyle *query ) { - const gchar* names[] = {"100", "200", "300", "400", "500", "600", "700", "800", "900", - "NORMAL", "BOLD", "LIGHTER", "BOLDER", "Out of range"}; - // Missing book = 380 - int index = query->font_weight.computed; - if( index < 0 || index > 13 ) index = 13; - std::cout << " Weight: " << names[ index ] - << " (" << query->font_weight.computed << ")" << std::endl; - -} - -static void sp_print_fontstyle( SPStyle *query ) { - - const gchar* names[] = {"NORMAL", "ITALIC", "OBLIQUE", "Out of range"}; - int index = query->font_style.computed; - if( index < 0 || index > 3 ) index = 3; - std::cout << " Style: " << names[ index ] << std::endl; - -} -#endif - -// Format family drop-down menu. -static void cell_data_func(GtkCellLayout * /*cell_layout*/, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer /*data*/) -{ - gchar *family; - gtk_tree_model_get(tree_model, iter, 0, &family, -1); - gchar *const family_escaped = g_markup_escape_text(family, -1); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - int show_sample = prefs->getInt("/tools/text/show_sample_in_list", 1); - if (show_sample) { - - Glib::ustring sample = prefs->getString("/tools/text/font_sample"); - gchar *const sample_escaped = g_markup_escape_text(sample.data(), -1); - - std::stringstream markup; - markup << family_escaped << " <span foreground='gray' font_family='" - << family_escaped << "'>" << sample_escaped << "</span>"; - g_object_set (G_OBJECT (cell), "markup", markup.str().c_str(), NULL); - - g_free(sample_escaped); - } else { - g_object_set (G_OBJECT (cell), "markup", family_escaped, NULL); - } - // This doesn't work for two reasons... it set both selected and not selected backgrounds - // to white.. which means that white foreground text is invisible. It also only effects - // the text region, leaving the padding untouched. - // g_object_set (G_OBJECT (cell), "cell-background", "white", "cell-background-set", true, NULL); - - g_free(family); - g_free(family_escaped); -} - -// Font family -// -// In most cases we should just be able to set the new family name -// but there may be cases where a font family doesn't follow the -// standard naming pattern. To handle those cases, we do a song and -// dance to use Pango to find the best match. To do that we start -// with the old "fontSpec" (which is the returned string from -// pango_font_description_to_string() with the size unset). This -// has the form "[family-list] [style-options]" where the -// family-list is a comma separated list of font-family names -// (optionally terminated by a comma). An example would be -// "DejaVu Sans, Sans Bold". Only a "fontSpec" containing a -// single font-family will work with Pango's best match routine. -// If we can't obtain a good "fontSpec", we then resort to blindly -// changing the font-family. -static void sp_text_fontfamily_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) -{ -#ifdef DEBUG_TEXT - std::cout << std::endl; - std::cout << "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" << std::endl; - std::cout << "sp_text_fontfamily_value_changed: " << std::endl; -#endif - - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gchar *family = ink_comboboxentry_action_get_active_text( act ); -#ifdef DEBUG_TEXT - std::cout << " New family: " << family << std::endl; -#endif - - // First try to get the old font spec from the stored value - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); - - Glib::ustring fontSpec = query->text->font_specification.set ? query->text->font_specification.value : ""; -#ifdef DEBUG_TEXT - std::cout << " fontSpec from query :" << fontSpec << ":" << std::endl; -#endif - - // If that didn't work, try to get font spec from style - if (fontSpec.empty()) { - - // Must query all to fill font-family, font-style, font-weight, font-specification - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - - // Construct a new font specification if it does not yet exist - font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query); - if( fontFromStyle ) { - fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle); - fontFromStyle->Unref(); - } - -#ifdef DEBUG_TEXT - std::cout << " fontSpec empty, try from style" << std::endl; - std::cout << " from style :" << fontSpec << ":" << std::endl; - sp_print_font( query ); -#endif - - } - - // And if that didn't work use default. DO WE REALLY WANT TO DO THIS? - if ( fontSpec.empty() ) { - - sp_style_read_from_prefs(query, "/tools/text"); - - // Construct a new font specification if it does not yet exist - font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query); - if ( fontFromStyle ) { - fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle); - fontFromStyle->Unref(); - } - -#ifdef DEBUG_TEXT - std::cout << " fontSpec empty, trying from prefs" << std::endl; - std::cout << " from prefs :" << fontSpec << ":" << std::endl; - sp_print_font( query ); -#endif - } - - // Now we have a font specification, replace family. - Glib::ustring newFontSpec = ""; - SPCSSAttr *css = sp_repr_css_attr_new (); - - if (!fontSpec.empty()) newFontSpec = font_factory::Default()->ReplaceFontSpecificationFamily(fontSpec, family); - -#ifdef DEBUG_TEXT - std::cout << " New FontSpec from ReplaceFontSpecificationFamily :" << newFontSpec << ":" << std::endl; -#endif - - if (!fontSpec.empty() && !newFontSpec.empty() ) { - - if (fontSpec != newFontSpec) { - - font_instance *font = font_factory::Default()->FaceFromFontSpecification(newFontSpec.c_str()); - - if (font) { - sp_repr_css_set_property (css, "-inkscape-font-specification", newFontSpec.c_str()); - - // Set all the these just in case they were altered when finding the best - // match for the new family and old style... Unnecessary? - - gchar c[256]; - - font->Family(c, 256); - - sp_repr_css_set_property (css, "font-family", c); - - font->Attribute( "weight", c, 256); - sp_repr_css_set_property (css, "font-weight", c); - - font->Attribute("style", c, 256); - sp_repr_css_set_property (css, "font-style", c); - - font->Attribute("stretch", c, 256); - sp_repr_css_set_property (css, "font-stretch", c); - - font->Attribute("variant", c, 256); - sp_repr_css_set_property (css, "font-variant", c); - - font->Unref(); - } else { - g_warning(_("Failed to find font matching: %s\n"), newFontSpec.c_str()); - } - } - } else { - - // Either old font does not exist on system or ReplaceFontSpecificationFamily() failed. - // Blindly fall back to setting the family to text in the font-family chooser. - -#ifdef DEBUG_TEXT - std::cout << " Failed to find new font, blindly setting family: " << family << std::endl; -#endif - sp_repr_css_set_property (css, "-inkscape-font-specification", family); - sp_repr_css_set_property (css, "font-family", family); - } - - // If querying returned nothing, update default style. - if (result_fontspec == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - //sp_text_edit_dialog_default_set_insensitive (); //FIXME: Replace through a verb - } - else - { - sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); - } - - sp_style_unref(query); - - g_free (family); - - // Save for undo - if (result_fontspec != QUERY_STYLE_NOTHING) { - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, - _("Text: Change font family")); - } - sp_repr_css_attr_unref (css); - - // unfreeze - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); - - // focus to canvas - gtk_widget_grab_focus (GTK_WIDGET((SP_ACTIVE_DESKTOP)->canvas)); - -#ifdef DEBUG_TEXT - std::cout << "sp_text_toolbox_fontfamily_changes: exit" << std::endl; - std::cout << "MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM" << std::endl; - std::cout << std::endl; -#endif -} - -// Font size -static void sp_text_fontsize_value_changed( Ink_ComboBoxEntry_Action *act, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gchar *text = ink_comboboxentry_action_get_active_text( act ); - gchar *endptr; - gdouble size = g_strtod( text, &endptr ); - if (endptr == text) { // Conversion failed, non-numeric input. - g_warning( "Conversion of size text to double failed, input: %s\n", text ); - g_free( text ); - return; - } - g_free( text ); - - // Set css font size. - SPCSSAttr *css = sp_repr_css_attr_new (); - Inkscape::CSSOStringStream osfs; - osfs << size << "px"; // For now always use px - sp_repr_css_set_property (css, "font-size", osfs.str().c_str()); - - // Apply font size to selected objects. - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, true); - - // If no selected objects, set default. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } else { - // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:size", SP_VERB_NONE, - _("Text: Change font size")); - } - - sp_style_unref(query); - - sp_repr_css_attr_unref (css); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -// Handles both Bold and Italic/Oblique -static void sp_text_style_changed( InkToggleAction* act, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - // Called by Bold or Italics button? - const gchar* name = gtk_action_get_name( GTK_ACTION( act ) ); - gint prop = (strcmp(name, "TextBoldAction") == 0) ? 0 : 1; - - // First query font-specification, this is the most complete font face description. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_fontspec = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); - - // font_specification will not be set unless defined explicitely on a tspan. - // This should be fixed! - Glib::ustring fontSpec = query->text->font_specification.set ? query->text->font_specification.value : ""; - - if (fontSpec.empty()) { - // Construct a new font specification if it does not yet exist - // Must query font-family, font-style, font-weight, to find correct font face. - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - - font_instance * fontFromStyle = font_factory::Default()->FaceFromStyle(query); - if ( fontFromStyle ) { - fontSpec = font_factory::Default()->ConstructFontSpecification(fontFromStyle); - fontFromStyle->Unref(); - } - } - - // Now that we have the old face, find the new face. - Glib::ustring newFontSpec = ""; - SPCSSAttr *css = sp_repr_css_attr_new (); - gboolean active = gtk_toggle_action_get_active( GTK_TOGGLE_ACTION(act) ); - - switch (prop) - { - case 0: - { - // Bold - if (!fontSpec.empty()) newFontSpec = font_factory::Default()->FontSpecificationSetBold(fontSpec, active); - if ( !fontSpec.empty() && !newFontSpec.empty() ) { - - // Set weight using new font if found. - font_instance * font = font_factory::Default()->FaceFromFontSpecification(newFontSpec.c_str()); - if (font) { - gchar c[256]; - font->Attribute( "weight", c, 256); - sp_repr_css_set_property (css, "font-weight", c); - font->Unref(); - font = NULL; - } - } else { - - // Blindly set weight. - sp_repr_css_set_property (css, "font-weight", (active == 0 ? "normal" : "bold") ); - } - break; - } - - case 1: - { - // Italic/Oblique - if (!fontSpec.empty()) newFontSpec = font_factory::Default()->FontSpecificationSetItalic(fontSpec, active); - - if ( !fontSpec.empty() && !newFontSpec.empty() ) { - - // Don't even set the italic/oblique if the font didn't exist on the system - if ( active ) { - if ( newFontSpec.find( "Italic" ) != Glib::ustring::npos ) { - sp_repr_css_set_property (css, "font-style", "italic"); - } else { - sp_repr_css_set_property (css, "font-style", "oblique"); - } - } else { - sp_repr_css_set_property (css, "font-style", "normal"); - } - - } else { - - // Blindly set style. - sp_repr_css_set_property (css, "font-style", (active == 0 ? "normal" : "italic") ); - } - break; - } - } - - if (!newFontSpec.empty()) { - sp_repr_css_set_property (css, "-inkscape-font-specification", newFontSpec.c_str()); - } - - // If querying returned nothing, update default style. - if (result_fontspec == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } - - sp_style_unref(query); - - // Do we need to update other CSS values? - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, true); - if (result_fontspec != QUERY_STYLE_NOTHING) { - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, - _("Text: Change font style")); - } - sp_repr_css_attr_unref (css); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -// Handles both Superscripts and Subscripts -static void sp_text_script_changed( InkToggleAction* act, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - // Called by Superscript or Subscript button? - const gchar* name = gtk_action_get_name( GTK_ACTION( act ) ); - gint prop = (strcmp(name, "TextSuperscriptAction") == 0) ? 0 : 1; - -#ifdef DEBUG_TEXT - std::cout << "sp_text_script_changed: " << prop << std::endl; -#endif - - // Query baseline - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_BASELINES); - - bool setSuper = false; - bool setSub = false; - - if(result_baseline == QUERY_STYLE_NOTHING || result_baseline == QUERY_STYLE_MULTIPLE_DIFFERENT ) { - // If not set or mixed, turn on superscript or subscript - if( prop == 0 ) { - setSuper = true; - } else { - setSub = true; - } - } else { - // Superscript - gboolean superscriptSet = (query->baseline_shift.set && - query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); - - // Subscript - gboolean subscriptSet = (query->baseline_shift.set && - query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); - - setSuper = !superscriptSet && prop == 0; - setSub = !subscriptSet && prop == 1; - } - - // Set css properties - SPCSSAttr *css = sp_repr_css_attr_new (); - if( setSuper || setSub ) { - // Openoffice 2.3 and Adobe use 58%, Microsoft Word 2002 uses 65%, LaTex about 70%. - // 58% looks too small to me, especially if a superscript is placed on a superscript. - // If you make a change here, consider making a change to baseline-shift amount - // in style.cpp. - sp_repr_css_set_property (css, "font-size", "65%"); - } else { - sp_repr_css_set_property (css, "font-size", ""); - } - if( setSuper ) { - sp_repr_css_set_property (css, "baseline-shift", "super"); - } else if( setSub ) { - sp_repr_css_set_property (css, "baseline-shift", "sub"); - } else { - sp_repr_css_set_property (css, "baseline-shift", "baseline"); - } - - // Apply css to selected objects. - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, false); - - // Save for undo - if(result_baseline != QUERY_STYLE_NOTHING) { - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:script", SP_VERB_NONE, - _("Text: Change superscript or subscript")); - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_text_align_mode_changed( EgeSelectOneAction *act, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - int mode = ege_select_one_action_get_active( act ); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/text/align_mode", mode); - - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - - // move the x of all texts to preserve the same bbox - Inkscape::Selection *selection = sp_desktop_selection(desktop); - for (GSList const *items = selection->itemList(); items != NULL; items = items->next) { - if (SP_IS_TEXT((SPItem *) items->data)) { - SPItem *item = SP_ITEM(items->data); - - unsigned writing_mode = item->style->writing_mode.value; - // below, variable names suggest horizontal move, but we check the writing direction - // and move in the corresponding axis - Geom::Dim2 axis; - if (writing_mode == SP_CSS_WRITING_MODE_LR_TB || writing_mode == SP_CSS_WRITING_MODE_RL_TB) { - axis = Geom::X; - } else { - axis = Geom::Y; - } - - Geom::OptRect bbox = item->geometricBounds(); - if (!bbox) - continue; - double width = bbox->dimensions()[axis]; - // If you want to align within some frame, other than the text's own bbox, calculate - // the left and right (or top and bottom for tb text) slacks of the text inside that - // frame (currently unused) - double left_slack = 0; - double right_slack = 0; - unsigned old_align = item->style->text_align.value; - double move = 0; - if (old_align == SP_CSS_TEXT_ALIGN_START || old_align == SP_CSS_TEXT_ALIGN_LEFT) { - switch (mode) { - case 0: - move = -left_slack; - break; - case 1: - move = width/2 + (right_slack - left_slack)/2; - break; - case 2: - move = width + right_slack; - break; - } - } else if (old_align == SP_CSS_TEXT_ALIGN_CENTER) { - switch (mode) { - case 0: - move = -width/2 - left_slack; - break; - case 1: - move = (right_slack - left_slack)/2; - break; - case 2: - move = width/2 + right_slack; - break; - } - } else if (old_align == SP_CSS_TEXT_ALIGN_END || old_align == SP_CSS_TEXT_ALIGN_RIGHT) { - switch (mode) { - case 0: - move = -width - left_slack; - break; - case 1: - move = -width/2 + (right_slack - left_slack)/2; - break; - case 2: - move = right_slack; - break; - } - } - Geom::Point XY = SP_TEXT(item)->attributes.firstXY(); - if (axis == Geom::X) { - XY = XY + Geom::Point (move, 0); - } else { - XY = XY + Geom::Point (0, move); - } - SP_TEXT(item)->attributes.setFirstXY(XY); - item->updateRepr(); - item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } - } - - SPCSSAttr *css = sp_repr_css_attr_new (); - switch (mode) - { - case 0: - { - sp_repr_css_set_property (css, "text-anchor", "start"); - sp_repr_css_set_property (css, "text-align", "start"); - break; - } - case 1: - { - sp_repr_css_set_property (css, "text-anchor", "middle"); - sp_repr_css_set_property (css, "text-align", "center"); - break; - } - - case 2: - { - sp_repr_css_set_property (css, "text-anchor", "end"); - sp_repr_css_set_property (css, "text-align", "end"); - break; - } - - case 3: - { - sp_repr_css_set_property (css, "text-anchor", "start"); - sp_repr_css_set_property (css, "text-align", "justify"); - break; - } - } - - SPStyle *query = - sp_style_new (SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - - // If querying returned nothing, update default style. - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } - - sp_style_unref(query); - - sp_desktop_set_style (desktop, css, true, true); - if (result_numbers != QUERY_STYLE_NOTHING) - { - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, - _("Text: Change alignment")); - } - sp_repr_css_attr_unref (css); - - gtk_widget_grab_focus (GTK_WIDGET(desktop->canvas)); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_text_lineheight_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - // At the moment this handles only numerical values (i.e. no percent). - // Set css line height. - SPCSSAttr *css = sp_repr_css_attr_new (); - Inkscape::CSSOStringStream osfs; - osfs << gtk_adjustment_get_value(adj)*100 << "%"; - sp_repr_css_set_property (css, "line-height", osfs.str().c_str()); - - // Apply line-height to selected objects. - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, false); - - - // Until deprecated sodipodi:linespacing purged: - Inkscape::Selection *selection = sp_desktop_selection(desktop); - GSList const *items = selection->itemList(); - bool modmade = false; - for (; items != NULL; items = items->next) { - if (SP_IS_TEXT (items->data)) { - SP_OBJECT(items->data)->getRepr()->setAttribute("sodipodi:linespacing", sp_repr_css_property (css, "line-height", NULL)); - modmade = true; - } - } - - // Save for undo - if(modmade) { - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:line-height", SP_VERB_NONE, - _("Text: Change line-height")); - } - - // If no selected objects, set default. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } - sp_style_unref(query); - - sp_repr_css_attr_unref (css); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_text_wordspacing_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - // At the moment this handles only numerical values (i.e. no em unit). - // Set css word-spacing - SPCSSAttr *css = sp_repr_css_attr_new (); - Inkscape::CSSOStringStream osfs; - osfs << gtk_adjustment_get_value(adj) << "px"; // For now always use px - sp_repr_css_set_property (css, "word-spacing", osfs.str().c_str()); - - // Apply word-spacing to selected objects. - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, false); - - // If no selected objects, set default. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } else { - // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:word-spacing", SP_VERB_NONE, - _("Text: Change word-spacing")); - } - sp_style_unref(query); - - sp_repr_css_attr_unref (css); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_text_letterspacing_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - // At the moment this handles only numerical values (i.e. no em unit). - // Set css letter-spacing - SPCSSAttr *css = sp_repr_css_attr_new (); - Inkscape::CSSOStringStream osfs; - osfs << gtk_adjustment_get_value(adj) << "px"; // For now always use px - sp_repr_css_set_property (css, "letter-spacing", osfs.str().c_str()); - - // Apply letter-spacing to selected objects. - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - sp_desktop_set_style (desktop, css, true, false); - - - // If no selected objects, set default. - SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } - else - { - // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:letter-spacing", SP_VERB_NONE, - _("Text: Change letter-spacing")); - } - - sp_style_unref(query); - - - sp_repr_css_attr_unref (css); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - - -static void sp_text_dx_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gdouble new_dx = gtk_adjustment_get_value(adj); - bool modmade = false; - - if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { - SPTextContext *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); - if( tc ) { - unsigned char_index = -1; - TextTagAttributes *attributes = - text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); - if( attributes ) { - double old_dx = attributes->getDx( char_index ); - double delta_dx = new_dx - old_dx; - sp_te_adjust_dx( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_dx ); - modmade = true; - } - } - } - - if(modmade) { - // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:dx", SP_VERB_NONE, - _("Text: Change dx (kern)")); - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_text_dy_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gdouble new_dy = gtk_adjustment_get_value(adj); - bool modmade = false; - - if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { - SPTextContext *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); - if( tc ) { - unsigned char_index = -1; - TextTagAttributes *attributes = - text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); - if( attributes ) { - double old_dy = attributes->getDy( char_index ); - double delta_dy = new_dy - old_dy; - sp_te_adjust_dy( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_dy ); - modmade = true; - } - } - } - - if(modmade) { - // Save for undo - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:dy", SP_VERB_NONE, - _("Text: Change dy")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_text_rotation_value_changed( GtkAdjustment *adj, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gdouble new_degrees = gtk_adjustment_get_value(adj); - - bool modmade = false; - if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { - SPTextContext *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); - if( tc ) { - unsigned char_index = -1; - TextTagAttributes *attributes = - text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); - if( attributes ) { - double old_degrees = attributes->getRotate( char_index ); - double delta_deg = new_degrees - old_degrees; - sp_te_adjust_rotation( tc->text, tc->text_sel_start, tc->text_sel_end, SP_ACTIVE_DESKTOP, delta_deg ); - modmade = true; - } - } - } - - // Save for undo - if(modmade) { - DocumentUndo::maybeDone(sp_desktop_document(SP_ACTIVE_DESKTOP), "ttb:rotate", SP_VERB_NONE, - _("Text: Change rotate")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_text_orientation_mode_changed( EgeSelectOneAction *act, GObject *tbl ) -{ - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - int mode = ege_select_one_action_get_active( act ); - - SPCSSAttr *css = sp_repr_css_attr_new (); - switch (mode) - { - case 0: - { - sp_repr_css_set_property (css, "writing-mode", "lr"); - break; - } - - case 1: - { - sp_repr_css_set_property (css, "writing-mode", "tb"); - break; - } - } - - SPStyle *query = - sp_style_new (SP_ACTIVE_DOCUMENT); - int result_numbers = - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - - // If querying returned nothing, update default style. - if (result_numbers == QUERY_STYLE_NOTHING) - { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->mergeStyle("/tools/text/style", css); - } - - sp_desktop_set_style (SP_ACTIVE_DESKTOP, css, true, true); - if(result_numbers != QUERY_STYLE_NOTHING) - { - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_CONTEXT_TEXT, - _("Text: Change orientation")); - } - sp_repr_css_attr_unref (css); - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -/* - * This function sets up the text-tool tool-controls, setting the entry boxes - * etc. to the values from the current selection or the default if no selection. - * It is called whenever a text selection is changed, including stepping cursor - * through text, or setting focus to text. - */ -static void sp_text_toolbox_selection_changed(Inkscape::Selection */*selection*/, GObject *tbl) -{ -#ifdef DEBUG_TEXT - static int count = 0; - ++count; - std::cout << std::endl; - std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; - std::cout << "sp_text_toolbox_selection_changed: start " << count << std::endl; - - std::cout << " Selected items:" << std::endl; - for (GSList const *items = sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList(); - items != NULL; - items = items->next) - { - const gchar* id = reinterpret_cast<SPItem *>(items->data)->getId(); - std::cout << " " << id << std::endl; - } - Glib::ustring selected_text = sp_text_get_selected_text((SP_ACTIVE_DESKTOP)->event_context); - std::cout << " Selected text:" << std::endl; - std::cout << selected_text << std::endl; -#endif - - // quit if run by the _changed callbacks - if (g_object_get_data(G_OBJECT(tbl), "freeze")) { -#ifdef DEBUG_TEXT - std::cout << " Frozen, returning" << std::endl; - std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; - std::cout << std::endl; -#endif - return; - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - // Only flowed text can be justified, only normal text can be kerned... - // Find out if we have flowed text now so we can use it several places - gboolean isFlow = false; - for (GSList const *items = sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList(); - items != NULL; - items = items->next) { - // const gchar* id = reinterpret_cast<SPItem *>(items->data)->getId(); - // std::cout << " " << id << std::endl; - if( SP_IS_FLOWTEXT(( SPItem *) items->data )) { - isFlow = true; - // std::cout << " Found flowed text" << std::endl; - break; - } - } - - /* - * Query from current selection: - * Font family (font-family) - * Style (font-weight, font-style, font-stretch, font-variant, font-align) - * Numbers (font-size, letter-spacing, word-spacing, line-height, text-anchor, writing-mode) - * Font specification (Inkscape private attribute) - */ - SPStyle *query = - sp_style_new (SP_ACTIVE_DOCUMENT); - int result_family = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTFAMILY); - int result_style = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTSTYLE); - int result_numbers = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONTNUMBERS); - int result_baseline = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_BASELINES); - - // Used later: - sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FONT_SPECIFICATION); - - /* - * If no text in selection (querying returned nothing), read the style from - * the /tools/text preferencess (default style for new texts). Return if - * tool bar already set to these preferences. - */ - if (result_family == QUERY_STYLE_NOTHING || result_style == QUERY_STYLE_NOTHING || result_numbers == QUERY_STYLE_NOTHING) { - // There are no texts in selection, read from preferences. - sp_style_read_from_prefs(query, "/tools/text"); -#ifdef DEBUG_TEXT - std::cout << " read style from prefs:" << std::endl; - sp_print_font( query ); -#endif - if (g_object_get_data(tbl, "text_style_from_prefs")) { - // Do not reset the toolbar style from prefs if we already did it last time - sp_style_unref(query); - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -#ifdef DEBUG_TEXT - std::cout << " text_style_from_prefs: toolbar already set" << std:: endl; - std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; - std::cout << std::endl; -#endif - return; - } - - g_object_set_data(tbl, "text_style_from_prefs", GINT_TO_POINTER(TRUE)); - } else { - g_object_set_data(tbl, "text_style_from_prefs", GINT_TO_POINTER(FALSE)); - } - - // If we have valid query data for text (font-family, font-specification) set toolbar accordingly. - if (query->text) - { - // Font family - if( query->text->font_family.value ) { - gchar *fontFamily = query->text->font_family.value; - - Ink_ComboBoxEntry_Action* fontFamilyAction = - INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontFamilyAction" ) ); - ink_comboboxentry_action_set_active_text( fontFamilyAction, fontFamily ); - } - - - // Size (average of text selected) - double size = query->font_size.computed; - gchar size_text[G_ASCII_DTOSTR_BUF_SIZE]; - g_ascii_dtostr (size_text, sizeof (size_text), size); - - Ink_ComboBoxEntry_Action* fontSizeAction = - INK_COMBOBOXENTRY_ACTION( g_object_get_data( tbl, "TextFontSizeAction" ) ); - ink_comboboxentry_action_set_active_text( fontSizeAction, size_text ); - - - // Weight (Bold) - // Note: in the enumeration, normal and lighter come at the end so we must explicitly test for them. - gboolean boldSet = ((query->font_weight.computed >= SP_CSS_FONT_WEIGHT_700) && - (query->font_weight.computed != SP_CSS_FONT_WEIGHT_NORMAL) && - (query->font_weight.computed != SP_CSS_FONT_WEIGHT_LIGHTER)); - - InkToggleAction* textBoldAction = INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextBoldAction" ) ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(textBoldAction), boldSet ); - - - // Style (Italic/Oblique) - gboolean italicSet = (query->font_style.computed != SP_CSS_FONT_STYLE_NORMAL); - - InkToggleAction* textItalicAction = INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextItalicAction" ) ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(textItalicAction), italicSet ); - - - // Superscript - gboolean superscriptSet = - ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && - query->baseline_shift.set && - query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUPER ); - - InkToggleAction* textSuperscriptAction = INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextSuperscriptAction" ) ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(textSuperscriptAction), superscriptSet ); - - - // Subscript - gboolean subscriptSet = - ((result_baseline == QUERY_STYLE_SINGLE || result_baseline == QUERY_STYLE_MULTIPLE_SAME ) && - query->baseline_shift.set && - query->baseline_shift.type == SP_BASELINE_SHIFT_LITERAL && - query->baseline_shift.literal == SP_CSS_BASELINE_SHIFT_SUB ); - - InkToggleAction* textSubscriptAction = INK_TOGGLE_ACTION( g_object_get_data( tbl, "TextSubscriptAction" ) ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(textSubscriptAction), subscriptSet ); - - - // Alignment - EgeSelectOneAction* textAlignAction = EGE_SELECT_ONE_ACTION( g_object_get_data( tbl, "TextAlignAction" ) ); - - // Note: SVG 1.1 doesn't include text-align, SVG 1.2 Tiny doesn't include text-align="justify" - // text-align="justify" was a draft SVG 1.2 item (along with flowed text). - // Only flowed text can be left and right justified at the same time. - // Disable button if we don't have flowed text. - - // The GtkTreeModel class doesn't have a set function so we can't - // simply add an ege_select_one_action_set_sensitive method! - // We must set values directly with the GtkListStore and then - // ask that the GtkAction update the sensitive parameters. - GtkListStore * model = GTK_LIST_STORE( ege_select_one_action_get_model( textAlignAction ) ); - GtkTreePath * path = gtk_tree_path_new_from_string("3"); // Justify entry - GtkTreeIter iter; - gtk_tree_model_get_iter( GTK_TREE_MODEL (model), &iter, path ); - gtk_list_store_set( model, &iter, /* column */ 3, isFlow, -1 ); - ege_select_one_action_update_sensitive( textAlignAction ); - // ege_select_one_action_set_sensitive( textAlignAction, 3, isFlow ); - - int activeButton = 0; - if (query->text_align.computed == SP_CSS_TEXT_ALIGN_JUSTIFY) - { - activeButton = 3; - } else { - if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_START) activeButton = 0; - if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_MIDDLE) activeButton = 1; - if (query->text_anchor.computed == SP_CSS_TEXT_ANCHOR_END) activeButton = 2; - } - ege_select_one_action_set_active( textAlignAction, activeButton ); - - - // Line height (spacing) - double height; - if (query->line_height.normal) { - height = Inkscape::Text::Layout::LINE_HEIGHT_NORMAL; - } else { - if (query->line_height.unit == SP_CSS_UNIT_PERCENT) { - height = query->line_height.value; - } else { - height = query->line_height.computed; - } - } - - GtkAction* lineHeightAction = GTK_ACTION( g_object_get_data( tbl, "TextLineHeightAction" ) ); - GtkAdjustment *lineHeightAdjustment = - ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( lineHeightAction )); - gtk_adjustment_set_value( lineHeightAdjustment, height ); - - - // Word spacing - double wordSpacing; - if (query->word_spacing.normal) wordSpacing = 0.0; - else wordSpacing = query->word_spacing.computed; // Assume no units (change in desktop-style.cpp) - - GtkAction* wordSpacingAction = GTK_ACTION( g_object_get_data( tbl, "TextWordSpacingAction" ) ); - GtkAdjustment *wordSpacingAdjustment = - ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( wordSpacingAction )); - gtk_adjustment_set_value( wordSpacingAdjustment, wordSpacing ); - - - // Letter spacing - double letterSpacing; - if (query->letter_spacing.normal) letterSpacing = 0.0; - else letterSpacing = query->letter_spacing.computed; // Assume no units (change in desktop-style.cpp) - - GtkAction* letterSpacingAction = GTK_ACTION( g_object_get_data( tbl, "TextLetterSpacingAction" ) ); - GtkAdjustment *letterSpacingAdjustment = - ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( letterSpacingAction )); - gtk_adjustment_set_value( letterSpacingAdjustment, letterSpacing ); - - - // Orientation - int activeButton2 = (query->writing_mode.computed == SP_CSS_WRITING_MODE_LR_TB ? 0 : 1); - - EgeSelectOneAction* textOrientationAction = - EGE_SELECT_ONE_ACTION( g_object_get_data( tbl, "TextOrientationAction" ) ); - ege_select_one_action_set_active( textOrientationAction, activeButton2 ); - - - } // if( query->text ) - -#ifdef DEBUG_TEXT - std::cout << " GUI: fontfamily.value: " - << (query->text->font_family.value ? query->text->font_family.value : "No value") - << std::endl; - std::cout << " GUI: font_size.computed: " << query->font_size.computed << std::endl; - std::cout << " GUI: font_weight.computed: " << query->font_weight.computed << std::endl; - std::cout << " GUI: font_style.computed: " << query->font_style.computed << std::endl; - std::cout << " GUI: text_anchor.computed: " << query->text_anchor.computed << std::endl; - std::cout << " GUI: text_align.computed: " << query->text_align.computed << std::endl; - std::cout << " GUI: line_height.computed: " << query->line_height.computed - << " line_height.value: " << query->line_height.value - << " line_height.unit: " << query->line_height.unit << std::endl; - std::cout << " GUI: word_spacing.computed: " << query->word_spacing.computed - << " word_spacing.value: " << query->word_spacing.value - << " word_spacing.unit: " << query->word_spacing.unit << std::endl; - std::cout << " GUI: letter_spacing.computed: " << query->letter_spacing.computed - << " letter_spacing.value: " << query->letter_spacing.value - << " letter_spacing.unit: " << query->letter_spacing.unit << std::endl; - std::cout << " GUI: writing_mode.computed: " << query->writing_mode.computed << std::endl; -#endif - - sp_style_unref(query); - - // Kerning (xshift), yshift, rotation. NB: These are not CSS attributes. - if( SP_IS_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context) ) { - SPTextContext *const tc = SP_TEXT_CONTEXT((SP_ACTIVE_DESKTOP)->event_context); - if( tc ) { - unsigned char_index = -1; - TextTagAttributes *attributes = - text_tag_attributes_at_position( tc->text, std::min(tc->text_sel_start, tc->text_sel_end), &char_index ); - if( attributes ) { - - // Dx - double dx = attributes->getDx( char_index ); - GtkAction* dxAction = GTK_ACTION( g_object_get_data( tbl, "TextDxAction" )); - GtkAdjustment *dxAdjustment = - ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( dxAction )); - gtk_adjustment_set_value( dxAdjustment, dx ); - - // Dy - double dy = attributes->getDy( char_index ); - GtkAction* dyAction = GTK_ACTION( g_object_get_data( tbl, "TextDyAction" )); - GtkAdjustment *dyAdjustment = - ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( dyAction )); - gtk_adjustment_set_value( dyAdjustment, dy ); - - // Rotation - double rotation = attributes->getRotate( char_index ); - /* SVG value is between 0 and 360 but we're using -180 to 180 in widget */ - if( rotation > 180.0 ) rotation -= 360.0; - GtkAction* rotationAction = GTK_ACTION( g_object_get_data( tbl, "TextRotationAction" )); - GtkAdjustment *rotationAdjustment = - ege_adjustment_action_get_adjustment(EGE_ADJUSTMENT_ACTION( rotationAction )); - gtk_adjustment_set_value( rotationAdjustment, rotation ); - -#ifdef DEBUG_TEXT - std::cout << " GUI: Dx: " << dx << std::endl; - std::cout << " GUI: Dy: " << dy << std::endl; - std::cout << " GUI: Rotation: " << rotation << std::endl; -#endif - } - } - } - - { - // Set these here as we don't always have kerning/rotating attributes - GtkAction* dxAction = GTK_ACTION( g_object_get_data( tbl, "TextDxAction" )); - gtk_action_set_sensitive( GTK_ACTION(dxAction), !isFlow ); - - GtkAction* dyAction = GTK_ACTION( g_object_get_data( tbl, "TextDyAction" )); - gtk_action_set_sensitive( GTK_ACTION(dyAction), !isFlow ); - - GtkAction* rotationAction = GTK_ACTION( g_object_get_data( tbl, "TextRotationAction" )); - gtk_action_set_sensitive( GTK_ACTION(rotationAction), !isFlow ); - } - -#ifdef DEBUG_TEXT - std::cout << "&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&" << std::endl; - std::cout << std::endl; -#endif - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); - -} - -static void sp_text_toolbox_selection_modified(Inkscape::Selection *selection, guint /*flags*/, GObject *tbl) -{ - sp_text_toolbox_selection_changed (selection, tbl); -} - -void -sp_text_toolbox_subselection_changed (gpointer /*tc*/, GObject *tbl) -{ - sp_text_toolbox_selection_changed (NULL, tbl); -} - -// Define all the "widgets" in the toolbar. -static void sp_text_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - // Is this used? - UnitTracker* tracker = new UnitTracker( SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE ); - tracker->setActiveUnit( sp_desktop_namedview(desktop)->doc_units ); - g_object_set_data( holder, "tracker", tracker ); - - /* Font family */ - { - // Font list - Glib::RefPtr<Gtk::ListStore> store = Inkscape::FontLister::get_instance()->get_font_list(); - GtkListStore* model = store->gobj(); - - Ink_ComboBoxEntry_Action* act = ink_comboboxentry_action_new( "TextFontFamilyAction", - _("Font Family"), - _("Select Font Family (Alt-X to access)"), - NULL, - GTK_TREE_MODEL(model), - -1, // Entry width - 50, // Extra list width - (gpointer)cell_data_func ); // Cell layout - ink_comboboxentry_action_popup_enable( act ); // Enable entry completion - gchar *const warning = _("Font not found on system"); - ink_comboboxentry_action_set_warning( act, warning ); // Show icon with tooltip if missing font - ink_comboboxentry_action_set_altx_name( act, "altx-text" ); // Set Alt-X keyboard shortcut - g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(sp_text_fontfamily_value_changed), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - g_object_set_data( holder, "TextFontFamilyAction", act ); - - // Change style of drop-down from menu to list - gtk_rc_parse_string ( - "style \"dropdown-as-list-style\"\n" - "{\n" - " GtkComboBox::appears-as-list = 1\n" - "}\n" - "widget \"*.TextFontFamilyAction_combobox\" style \"dropdown-as-list-style\""); - } - - /* Font size */ - { - // List of font sizes for drop-down menu - GtkListStore* model_size = gtk_list_store_new( 1, G_TYPE_STRING ); - gchar const *const sizes[] = { - "4", "6", "8", "9", "10", "11", "12", "13", "14", "16", - "18", "20", "22", "24", "28", "32", "36", "40", "48", "56", - "64", "72", "144" - }; - for( unsigned int i = 0; i < G_N_ELEMENTS(sizes); ++i ) { - GtkTreeIter iter; - gtk_list_store_append( model_size, &iter ); - gtk_list_store_set( model_size, &iter, 0, sizes[i], -1 ); - } - - Ink_ComboBoxEntry_Action* act = ink_comboboxentry_action_new( "TextFontSizeAction", - _("Font Size"), - _("Font size (px)"), - NULL, - GTK_TREE_MODEL(model_size), - 4 ); // Width in characters - g_signal_connect( G_OBJECT(act), "changed", G_CALLBACK(sp_text_fontsize_value_changed), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - g_object_set_data( holder, "TextFontSizeAction", act ); - } - - /* Style - Bold */ - { - InkToggleAction* act = ink_toggle_action_new( "TextBoldAction", // Name - _("Toggle Bold"), // Label - _("Toggle bold or normal weight"), // Tooltip - GTK_STOCK_BOLD, // Icon (inkId) - secondarySize ); // Icon size - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_style_changed), holder ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/bold", false) ); - g_object_set_data( holder, "TextBoldAction", act ); - } - - /* Style - Italic/Oblique */ - { - InkToggleAction* act = ink_toggle_action_new( "TextItalicAction", // Name - _("Toggle Italic/Oblique"), // Label - _("Toggle italic/oblique style"),// Tooltip - GTK_STOCK_ITALIC, // Icon (inkId) - secondarySize ); // Icon size - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_style_changed), holder ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/italic", false) ); - g_object_set_data( holder, "TextItalicAction", act ); - } - - /* Style - Superscript */ - { - InkToggleAction* act = ink_toggle_action_new( "TextSuperscriptAction", // Name - _("Toggle Superscript"), // Label - _("Toggle superscript"), // Tooltip - "text_superscript", // Icon (inkId) - secondarySize ); // Icon size - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_script_changed), holder ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/super", false) ); - g_object_set_data( holder, "TextSuperscriptAction", act ); - } - - /* Style - Subscript */ - { - InkToggleAction* act = ink_toggle_action_new( "TextSubscriptAction", // Name - _("Toggle Subscript"), // Label - _("Toggle subscript"), // Tooltip - "text_subscript", // Icon (inkId) - secondarySize ); // Icon size - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_text_script_changed), holder ); - gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), prefs->getBool("/tools/text/sub", false) ); - g_object_set_data( holder, "TextSubscriptAction", act ); - } - - /* Alignment */ - { - GtkListStore* model = gtk_list_store_new( 4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN ); - - GtkTreeIter iter; - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Align left"), - 1, _("Align left"), - 2, GTK_STOCK_JUSTIFY_LEFT, - 3, true, - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Align center"), - 1, _("Align center"), - 2, GTK_STOCK_JUSTIFY_CENTER, - 3, true, - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Align right"), - 1, _("Align right"), - 2, GTK_STOCK_JUSTIFY_RIGHT, - 3, true, - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Justify"), - 1, _("Justify (only flowed text)"), - 2, GTK_STOCK_JUSTIFY_FILL, - 3, false, - -1 ); - - EgeSelectOneAction* act = ege_select_one_action_new( "TextAlignAction", // Name - _("Alignment"), // Label - _("Text alignment"), // Tooltip - NULL, // StockID - GTK_TREE_MODEL(model) ); // Model - g_object_set( act, "short_label", "NotUsed", NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - g_object_set_data( holder, "TextAlignAction", act ); - - ege_select_one_action_set_appearance( act, "full" ); - ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE ); - g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL ); - ege_select_one_action_set_icon_column( act, 2 ); - ege_select_one_action_set_icon_size( act, secondarySize ); - ege_select_one_action_set_tooltip_column( act, 1 ); - ege_select_one_action_set_sensitive_column( act, 3 ); - gint mode = prefs->getInt("/tools/text/align_mode", 0); - ege_select_one_action_set_active( act, mode ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_text_align_mode_changed), holder ); - } - - /* Orientation (Left to Right, Top to Bottom */ - { - GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING ); - - GtkTreeIter iter; - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Horizontal"), - 1, _("Horizontal text"), - 2, INKSCAPE_ICON("format-text-direction-horizontal"), - -1 ); - - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, - 0, _("Vertical"), - 1, _("Vertical text"), - 2, INKSCAPE_ICON("format-text-direction-vertical"), - -1 ); - - EgeSelectOneAction* act = ege_select_one_action_new( "TextOrientationAction", // Name - _("Orientation"), // Label - _("Text orientation"), // Tooltip - NULL, // StockID - GTK_TREE_MODEL(model) ); // Model - - g_object_set( act, "short_label", "NotUsed", NULL ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act) ); - g_object_set_data( holder, "TextOrientationAction", act ); - - ege_select_one_action_set_appearance( act, "full" ); - ege_select_one_action_set_radio_action_type( act, INK_RADIO_ACTION_TYPE ); - g_object_set( G_OBJECT(act), "icon-property", "iconId", NULL ); - ege_select_one_action_set_icon_column( act, 2 ); - ege_select_one_action_set_icon_size( act, secondarySize ); - ege_select_one_action_set_tooltip_column( act, 1 ); - - gint mode = prefs->getInt("/tools/text/orientation", 0); - ege_select_one_action_set_active( act, mode ); - g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_text_orientation_mode_changed), holder ); - } - - /* Line height */ - { - // Drop down menu - gchar const* labels[] = {_("Smaller spacing"), 0, 0, 0, 0, C_("Text tool", "Normal"), 0, 0, 0, 0, 0, _("Larger spacing")}; - gdouble values[] = { 0.5, 0.6, 0.7, 0.8, 0.9, 1.0, 1.1, 1,2, 1.3, 1.4, 1.5, 2.0}; - - EgeAdjustmentAction *eact = create_adjustment_action( - "TextLineHeightAction", /* name */ - _("Line Height"), /* label */ - _("Line:"), /* short label */ - _("Spacing between lines (times font size)"), /* tooltip */ - "/tools/text/lineheight", /* preferences path */ - 0.0, /* default */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - NULL, /* unit selector */ - holder, /* dataKludge */ - FALSE, /* set alt-x keyboard shortcut? */ - NULL, /* altx_mark */ - 0.0, 10.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */ - labels, values, G_N_ELEMENTS(labels), /* drop down menu */ - sp_text_lineheight_value_changed, /* callback */ - 0.1, /* step (used?) */ - 2, /* digits to show */ - 1.0 /* factor (multiplies default) */ - ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - g_object_set_data( holder, "TextLineHeightAction", eact ); - g_object_set( G_OBJECT(eact), "iconId", "text_line_spacing", NULL ); - } - - /* Word spacing */ - { - // Drop down menu - gchar const* labels[] = {_("Negative spacing"), 0, 0, 0, C_("Text tool", "Normal"), 0, 0, 0, 0, 0, 0, 0, _("Positive spacing")}; - gdouble values[] = {-2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0}; - - EgeAdjustmentAction *eact = create_adjustment_action( - "TextWordSpacingAction", /* name */ - _("Word spacing"), /* label */ - _("Word:"), /* short label */ - _("Spacing between words (px)"), /* tooltip */ - "/tools/text/wordspacing", /* preferences path */ - 0.0, /* default */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - NULL, /* unit selector */ - holder, /* dataKludge */ - FALSE, /* set alt-x keyboard shortcut? */ - NULL, /* altx_mark */ - -100.0, 100.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */ - labels, values, G_N_ELEMENTS(labels), /* drop down menu */ - sp_text_wordspacing_value_changed, /* callback */ - 0.1, /* step (used?) */ - 2, /* digits to show */ - 1.0 /* factor (multiplies default) */ - ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - g_object_set_data( holder, "TextWordSpacingAction", eact ); - g_object_set( G_OBJECT(eact), "iconId", "text_word_spacing", NULL ); - } - - /* Letter spacing */ - { - // Drop down menu - gchar const* labels[] = {_("Negative spacing"), 0, 0, 0, C_("Text tool", "Normal"), 0, 0, 0, 0, 0, 0, 0, _("Positive spacing")}; - gdouble values[] = {-2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5, 3.0, 4.0, 5.0}; - - EgeAdjustmentAction *eact = create_adjustment_action( - "TextLetterSpacingAction", /* name */ - _("Letter spacing"), /* label */ - _("Letter:"), /* short label */ - _("Spacing between letters (px)"), /* tooltip */ - "/tools/text/letterspacing", /* preferences path */ - 0.0, /* default */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - NULL, /* unit selector */ - holder, /* dataKludge */ - FALSE, /* set alt-x keyboard shortcut? */ - NULL, /* altx_mark */ - -100.0, 100.0, 0.01, 0.10, /* lower, upper, step (arrow up/down), page up/down */ - labels, values, G_N_ELEMENTS(labels), /* drop down menu */ - sp_text_letterspacing_value_changed, /* callback */ - 0.1, /* step (used?) */ - 2, /* digits to show */ - 1.0 /* factor (multiplies default) */ - ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - g_object_set_data( holder, "TextLetterSpacingAction", eact ); - g_object_set( G_OBJECT(eact), "iconId", "text_letter_spacing", NULL ); - } - - /* Character kerning (horizontal shift) */ - { - // Drop down menu - gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - gdouble values[] = { -2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5 }; - - EgeAdjustmentAction *eact = create_adjustment_action( - "TextDxAction", /* name */ - _("Kerning"), /* label */ - _("Kern:"), /* short label */ - _("Horizontal kerning (px)"), /* tooltip */ - "/tools/text/dx", /* preferences path */ - 0.0, /* default */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - NULL, /* unit selector */ - holder, /* dataKludge */ - FALSE, /* set alt-x keyboard shortcut? */ - NULL, /* altx_mark */ - -100.0, 100.0, 0.01, 0.1, /* lower, upper, step (arrow up/down), page up/down */ - labels, values, G_N_ELEMENTS(labels), /* drop down menu */ - sp_text_dx_value_changed, /* callback */ - 0.1, /* step (used?) */ - 2, /* digits to show */ - 1.0 /* factor (multiplies default) */ - ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - g_object_set_data( holder, "TextDxAction", eact ); - g_object_set( G_OBJECT(eact), "iconId", "text_horz_kern", NULL ); - } - - /* Character vertical shift */ - { - // Drop down menu - gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - gdouble values[] = { -2.0, -1.5, -1.0, -0.5, 0, 0.5, 1.0, 1.5, 2.0, 2.5 }; - - EgeAdjustmentAction *eact = create_adjustment_action( - "TextDyAction", /* name */ - _("Vertical Shift"), /* label */ - _("Vert:"), /* short label */ - _("Vertical shift (px)"), /* tooltip */ - "/tools/text/dy", /* preferences path */ - 0.0, /* default */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - NULL, /* unit selector */ - holder, /* dataKludge */ - FALSE, /* set alt-x keyboard shortcut? */ - NULL, /* altx_mark */ - -100.0, 100.0, 0.01, 0.1, /* lower, upper, step (arrow up/down), page up/down */ - labels, values, G_N_ELEMENTS(labels), /* drop down menu */ - sp_text_dy_value_changed, /* callback */ - 0.1, /* step (used?) */ - 2, /* digits to show */ - 1.0 /* factor (multiplies default) */ - ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - g_object_set_data( holder, "TextDyAction", eact ); - g_object_set( G_OBJECT(eact), "iconId", "text_vert_kern", NULL ); - } - - /* Character rotation */ - { - // Drop down menu - gchar const* labels[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - gdouble values[] = { -90, -45, -30, -15, 0, 15, 30, 45, 90, 180 }; - - EgeAdjustmentAction *eact = create_adjustment_action( - "TextRotationAction", /* name */ - _("Letter rotation"), /* label */ - _("Rot:"), /* short label */ - _("Character rotation (degrees)"),/* tooltip */ - "/tools/text/rotation", /* preferences path */ - 0.0, /* default */ - GTK_WIDGET(desktop->canvas), /* focusTarget */ - NULL, /* unit selector */ - holder, /* dataKludge */ - FALSE, /* set alt-x keyboard shortcut? */ - NULL, /* altx_mark */ - -180.0, 180.0, 0.1, 1.0, /* lower, upper, step (arrow up/down), page up/down */ - labels, values, G_N_ELEMENTS(labels), /* drop down menu */ - sp_text_rotation_value_changed, /* callback */ - 0.1, /* step (used?) */ - 2, /* digits to show */ - 1.0 /* factor (multiplies default) */ - ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - gtk_action_set_sensitive( GTK_ACTION(eact), TRUE ); - g_object_set_data( holder, "TextRotationAction", eact ); - g_object_set( G_OBJECT(eact), "iconId", "text_rotation", NULL ); - } - - // Is this necessary to call? Shouldn't hurt. - sp_text_toolbox_selection_changed(sp_desktop_selection(desktop), holder); - - // Watch selection - Inkscape::ConnectionPool* pool = Inkscape::ConnectionPool::new_connection_pool ("ISTextToolboxGTK"); - - sigc::connection *c_selection_changed = - new sigc::connection (sp_desktop_selection (desktop)->connectChanged - (sigc::bind (sigc::ptr_fun (sp_text_toolbox_selection_changed), (GObject*)holder))); - pool->add_connection ("selection-changed", c_selection_changed); - - sigc::connection *c_selection_modified = - new sigc::connection (sp_desktop_selection (desktop)->connectModified - (sigc::bind (sigc::ptr_fun (sp_text_toolbox_selection_modified), (GObject*)holder))); - pool->add_connection ("selection-modified", c_selection_modified); - - sigc::connection *c_subselection_changed = - new sigc::connection (desktop->connectToolSubselectionChanged - (sigc::bind (sigc::ptr_fun (sp_text_toolbox_subselection_changed), (GObject*)holder))); - pool->add_connection ("tool-subselection-changed", c_subselection_changed); - - Inkscape::ConnectionPool::connect_destroy (G_OBJECT (holder), pool); - - g_signal_connect( holder, "destroy", G_CALLBACK(purge_repr_listener), holder ); - -} - - -//######################### -//## Connector ## -//######################### - -static void sp_connector_mode_toggled( GtkToggleAction* act, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/connector/mode", - gtk_toggle_action_get_active( act )); -} - -static void sp_connector_path_set_avoid(void) -{ - cc_selection_set_avoid(true); -} - - -static void sp_connector_path_set_ignore(void) -{ - cc_selection_set_avoid(false); -} - -static void sp_connector_orthogonal_toggled( GtkToggleAction* act, GObject *tbl ) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); - Inkscape::Selection * selection = sp_desktop_selection(desktop); - SPDocument *doc = sp_desktop_document(desktop); - - if (!DocumentUndo::getUndoSensitive(doc)) { - return; - } - - - // quit if run by the _changed callbacks - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent callbacks from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - bool is_orthog = gtk_toggle_action_get_active( act ); - gchar orthog_str[] = "orthogonal"; - gchar polyline_str[] = "polyline"; - gchar *value = is_orthog ? orthog_str : polyline_str ; - - bool modmade = false; - GSList *l = (GSList *) selection->itemList(); - while (l) { - SPItem *item = (SPItem *) l->data; - - if (cc_item_is_connector(item)) { - item->setAttribute( "inkscape:connector-type", - value, NULL); - item->avoidRef->handleSettingChange(); - modmade = true; - } - l = l->next; - } - - if (!modmade) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/connector/orthogonal", is_orthog); - } else { - - DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, - is_orthog ? _("Set connector type: orthogonal"): _("Set connector type: polyline")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void connector_curvature_changed(GtkAdjustment *adj, GObject* tbl) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); - Inkscape::Selection * selection = sp_desktop_selection(desktop); - SPDocument *doc = sp_desktop_document(desktop); - - if (!DocumentUndo::getUndoSensitive(doc)) { - return; - } - - - // quit if run by the _changed callbacks - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent callbacks from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) ); - - gdouble newValue = gtk_adjustment_get_value(adj); - gchar value[G_ASCII_DTOSTR_BUF_SIZE]; - g_ascii_dtostr(value, G_ASCII_DTOSTR_BUF_SIZE, newValue); - - bool modmade = false; - GSList *l = (GSList *) selection->itemList(); - while (l) { - SPItem *item = (SPItem *) l->data; - - if (cc_item_is_connector(item)) { - item->setAttribute( "inkscape:connector-curvature", - value, NULL); - item->avoidRef->handleSettingChange(); - modmade = true; - } - l = l->next; - } - - if (!modmade) { - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble(Glib::ustring("/tools/connector/curvature"), newValue); - } - else { - DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, - _("Change connector curvature")); - } - - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - - -static void connector_spacing_changed(GtkAdjustment *adj, GObject* tbl) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); - SPDocument *doc = sp_desktop_document(desktop); - - if (!DocumentUndo::getUndoSensitive(doc)) { - return; - } - - Inkscape::XML::Node *repr = desktop->namedview->getRepr(); - - if ( !repr->attribute("inkscape:connector-spacing") && - ( gtk_adjustment_get_value(adj) == defaultConnSpacing )) { - // Don't need to update the repr if the attribute doesn't - // exist and it is being set to the default value -- as will - // happen at startup. - return; - } - - // quit if run by the attr_changed listener - if (g_object_get_data( tbl, "freeze" )) { - return; - } - - // in turn, prevent listener from responding - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE)); - - sp_repr_set_css_double(repr, "inkscape:connector-spacing", gtk_adjustment_get_value(adj)); - desktop->namedview->updateRepr(); - bool modmade = false; - - GSList *items = get_avoided_items(NULL, desktop->currentRoot(), desktop); - for ( GSList const *iter = items ; iter != NULL ; iter = iter->next ) { - SPItem *item = reinterpret_cast<SPItem *>(iter->data); - Geom::Affine m = Geom::identity(); - avoid_item_move(&m, item); - modmade = true; - } - - if (items) { - g_slist_free(items); - } - if(modmade) { - DocumentUndo::done(doc, SP_VERB_CONTEXT_CONNECTOR, - _("Change connector spacing")); - } - g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) ); -} - -static void sp_connector_graph_layout(void) -{ - if (!SP_ACTIVE_DESKTOP) { - return; - } - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - // hack for clones, see comment in align-and-distribute.cpp - int saved_compensation = prefs->getInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); - - graphlayout(sp_desktop_selection(SP_ACTIVE_DESKTOP)->itemList()); - - prefs->setInt("/options/clonecompensation/value", saved_compensation); - - DocumentUndo::done(sp_desktop_document(SP_ACTIVE_DESKTOP), SP_VERB_DIALOG_ALIGN_DISTRIBUTE, _("Arrange connector network")); -} - -static void sp_directed_graph_layout_toggled( GtkToggleAction* act, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/connector/directedlayout", - gtk_toggle_action_get_active( act )); -} - -static void sp_nooverlaps_graph_layout_toggled( GtkToggleAction* act, GObject * /*tbl*/ ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/connector/avoidoverlaplayout", - gtk_toggle_action_get_active( act )); -} - - -static void connector_length_changed(GtkAdjustment *adj, GObject* /*tbl*/) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble("/tools/connector/length", gtk_adjustment_get_value(adj)); -} - -static void connector_tb_event_attr_changed(Inkscape::XML::Node *repr, - gchar const *name, gchar const * /*old_value*/, gchar const * /*new_value*/, - bool /*is_interactive*/, gpointer data) -{ - GtkWidget *tbl = GTK_WIDGET(data); - - if ( !g_object_get_data(G_OBJECT(tbl), "freeze") - && (strcmp(name, "inkscape:connector-spacing") == 0) ) { - GtkAdjustment *adj = static_cast<GtkAdjustment*>(g_object_get_data(G_OBJECT(tbl), "spacing")); - gdouble spacing = defaultConnSpacing; - sp_repr_get_double(repr, "inkscape:connector-spacing", &spacing); - - gtk_adjustment_set_value(adj, spacing); - gtk_adjustment_value_changed(adj); - - spinbutton_defocus(tbl); - } -} - -static void sp_connector_new_connection_point(GtkWidget *, GObject *tbl) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); - SPConnectorContext* cc = SP_CONNECTOR_CONTEXT(desktop->event_context); - - if (cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE) { - cc_create_connection_point(cc); - } -} - -static void sp_connector_remove_connection_point(GtkWidget *, GObject *tbl) -{ - SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" ); - SPConnectorContext* cc = SP_CONNECTOR_CONTEXT(desktop->event_context); - - if (cc->mode == SP_CONNECTOR_CONTEXT_EDITING_MODE) { - cc_remove_connection_point(cc); - } -} - -static Inkscape::XML::NodeEventVector connector_tb_repr_events = { - NULL, /* child_added */ - NULL, /* child_removed */ - connector_tb_event_attr_changed, - NULL, /* content_changed */ - NULL /* order_changed */ -}; - -static void sp_connector_toolbox_selection_changed(Inkscape::Selection *selection, GObject *tbl) -{ - GtkAdjustment *adj = GTK_ADJUSTMENT( g_object_get_data( tbl, "curvature" ) ); - GtkToggleAction *act = GTK_TOGGLE_ACTION( g_object_get_data( tbl, "orthogonal" ) ); - SPItem *item = selection->singleItem(); - if (SP_IS_PATH(item)) - { - gdouble curvature = SP_PATH(item)->connEndPair.getCurvature(); - bool is_orthog = SP_PATH(item)->connEndPair.isOrthogonal(); - gtk_toggle_action_set_active(act, is_orthog); - gtk_adjustment_set_value(adj, curvature); - } - -} - -static void sp_connector_toolbox_prep( SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder ) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Inkscape::IconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1); - - // Editing mode toggle button - { - InkToggleAction* act = ink_toggle_action_new( "ConnectorEditModeAction", - _("EditMode"), - _("Switch between connection point editing and connector drawing mode"), - INKSCAPE_ICON("connector-edit"), - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - - bool tbuttonstate = prefs->getBool("/tools/connector/mode"); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE )); - g_object_set_data( holder, "mode", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_connector_mode_toggled), holder ); - } - - - { - InkAction* inky = ink_action_new( "ConnectorAvoidAction", - _("Avoid"), - _("Make connectors avoid selected objects"), - INKSCAPE_ICON("connector-avoid"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_path_set_avoid), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - { - InkAction* inky = ink_action_new( "ConnectorIgnoreAction", - _("Ignore"), - _("Make connectors ignore selected objects"), - INKSCAPE_ICON("connector-ignore"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_path_set_ignore), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - // Orthogonal connectors toggle button - { - InkToggleAction* act = ink_toggle_action_new( "ConnectorOrthogonalAction", - _("Orthogonal"), - _("Make connector orthogonal or polyline"), - INKSCAPE_ICON("connector-orthogonal"), - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - - bool tbuttonstate = prefs->getBool("/tools/connector/orthogonal"); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE )); - g_object_set_data( holder, "orthogonal", act ); - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_connector_orthogonal_toggled), holder ); - } - - EgeAdjustmentAction* eact = 0; - // Curvature spinbox - eact = create_adjustment_action( "ConnectorCurvatureAction", - _("Connector Curvature"), _("Curvature:"), - _("The amount of connectors curvature"), - "/tools/connector/curvature", defaultConnCurvature, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "inkscape:connector-curvature", - 0, 100, 1.0, 10.0, - 0, 0, 0, - connector_curvature_changed, 1, 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - - // Spacing spinbox - eact = create_adjustment_action( "ConnectorSpacingAction", - _("Connector Spacing"), _("Spacing:"), - _("The amount of space left around objects by auto-routing connectors"), - "/tools/connector/spacing", defaultConnSpacing, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "inkscape:connector-spacing", - 0, 100, 1.0, 10.0, - 0, 0, 0, - connector_spacing_changed, 1, 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - - // Graph (connector network) layout - { - InkAction* inky = ink_action_new( "ConnectorGraphAction", - _("Graph"), - _("Nicely arrange selected connector network"), - INKSCAPE_ICON("distribute-graph"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_graph_layout), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - // Default connector length spinbox - eact = create_adjustment_action( "ConnectorLengthAction", - _("Connector Length"), _("Length:"), - _("Ideal length for connectors when layout is applied"), - "/tools/connector/length", 100, - GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, "inkscape:connector-length", - 10, 1000, 10.0, 100.0, - 0, 0, 0, - connector_length_changed, 1, 0 ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - - - // Directed edges toggle button - { - InkToggleAction* act = ink_toggle_action_new( "ConnectorDirectedAction", - _("Downwards"), - _("Make connectors with end-markers (arrows) point downwards"), - INKSCAPE_ICON("distribute-graph-directed"), - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - - bool tbuttonstate = prefs->getBool("/tools/connector/directedlayout"); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), ( tbuttonstate ? TRUE : FALSE )); - - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_directed_graph_layout_toggled), holder ); - sp_desktop_selection(desktop)->connectChanged(sigc::bind(sigc::ptr_fun(sp_connector_toolbox_selection_changed), (GObject *)holder)); - } - - // Avoid overlaps toggle button - { - InkToggleAction* act = ink_toggle_action_new( "ConnectorOverlapAction", - _("Remove overlaps"), - _("Do not allow overlapping shapes"), - INKSCAPE_ICON("distribute-remove-overlaps"), - Inkscape::ICON_SIZE_DECORATION ); - gtk_action_group_add_action( mainActions, GTK_ACTION( act ) ); - - bool tbuttonstate = prefs->getBool("/tools/connector/avoidoverlaplayout"); - gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(act), (tbuttonstate ? TRUE : FALSE )); - - g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_nooverlaps_graph_layout_toggled), holder ); - } - - - // New connection point button - { - InkAction* inky = ink_action_new( "ConnectorNewConnPointAction", - _("New connection point"), - _("Add a new connection point to the currently selected item"), - INKSCAPE_ICON("connector-new-connpoint"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_new_connection_point), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - // Remove selected connection point button - - { - InkAction* inky = ink_action_new( "ConnectorRemoveConnPointAction", - _("Remove connection point"), - _("Remove the currently selected connection point"), - INKSCAPE_ICON("connector-remove-connpoint"), - secondarySize ); - g_signal_connect_after( G_OBJECT(inky), "activate", G_CALLBACK(sp_connector_remove_connection_point), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(inky) ); - } - - - // Code to watch for changes to the connector-spacing attribute in - // the XML. - Inkscape::XML::Node *repr = desktop->namedview->getRepr(); - g_assert(repr != NULL); - - purge_repr_listener( holder, holder ); - - if (repr) { - g_object_set_data( holder, "repr", repr ); - Inkscape::GC::anchor(repr); - sp_repr_add_listener( repr, &connector_tb_repr_events, holder ); - sp_repr_synthesize_events( repr, &connector_tb_repr_events, holder ); - } -} // end of sp_connector_toolbox_prep() - - -//######################### -//## Paintbucket ## -//######################### - -static void paintbucket_channels_changed(EgeSelectOneAction* act, GObject* /*tbl*/) -{ - gint channels = ege_select_one_action_get_active( act ); - flood_channels_set_channels( channels ); -} - -static void paintbucket_threshold_changed(GtkAdjustment *adj, GObject * /*tbl*/) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt("/tools/paintbucket/threshold", (gint)gtk_adjustment_get_value(adj)); -} - -static void paintbucket_autogap_changed(EgeSelectOneAction* act, GObject * /*tbl*/) -{ - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool("/tools/paintbucket/autogap", ege_select_one_action_get_active( act )); -} - -static void paintbucket_offset_changed(GtkAdjustment *adj, GObject *tbl) -{ - UnitTracker* tracker = static_cast<UnitTracker*>(g_object_get_data( tbl, "tracker" )); - SPUnit const *unit = tracker->getActiveUnit(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - // Don't adjust the offset value because we're saving the - // unit and it'll be correctly handled on load. - prefs->setDouble("/tools/paintbucket/offset", (gdouble)gtk_adjustment_get_value(adj)); - prefs->setString("/tools/paintbucket/offsetunits", sp_unit_get_abbreviation(unit)); -} - -static void paintbucket_defaults(GtkWidget *, GObject *tbl) -{ - // FIXME: make defaults settable via Inkscape Options - struct KeyValue { - char const *key; - double value; - } const key_values[] = { - {"threshold", 15}, - {"offset", 0.0} - }; - - for (unsigned i = 0; i < G_N_ELEMENTS(key_values); ++i) { - KeyValue const &kv = key_values[i]; - GtkAdjustment* adj = static_cast<GtkAdjustment *>(g_object_get_data(tbl, kv.key)); - if ( adj ) { - gtk_adjustment_set_value(adj, kv.value); - } - } - - EgeSelectOneAction* channels_action = EGE_SELECT_ONE_ACTION( g_object_get_data (tbl, "channels_action" ) ); - ege_select_one_action_set_active( channels_action, FLOOD_CHANNELS_RGB ); - EgeSelectOneAction* autogap_action = EGE_SELECT_ONE_ACTION( g_object_get_data (tbl, "autogap_action" ) ); - ege_select_one_action_set_active( autogap_action, 0 ); -} - -static void sp_paintbucket_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder) -{ - EgeAdjustmentAction* eact = 0; - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - - { - GtkListStore* model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT ); - - GList* items = 0; - gint count = 0; - for ( items = flood_channels_dropdown_items_list(); items ; items = g_list_next(items) ) - { - GtkTreeIter iter; - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, reinterpret_cast<gchar*>(items->data), 1, count, -1 ); - count++; - } - g_list_free( items ); - items = 0; - EgeSelectOneAction* act1 = ege_select_one_action_new( "ChannelsAction", _("Fill by"), (""), NULL, GTK_TREE_MODEL(model) ); - g_object_set( act1, "short_label", _("Fill by:"), NULL ); - ege_select_one_action_set_appearance( act1, "compact" ); - ege_select_one_action_set_active( act1, prefs->getInt("/tools/paintbucket/channels", 0) ); - g_signal_connect( G_OBJECT(act1), "changed", G_CALLBACK(paintbucket_channels_changed), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act1) ); - g_object_set_data( holder, "channels_action", act1 ); - } - - // Spacing spinbox - { - eact = create_adjustment_action( - "ThresholdAction", - _("Fill Threshold"), _("Threshold:"), - _("The maximum allowed difference between the clicked pixel and the neighboring pixels to be counted in the fill"), - "/tools/paintbucket/threshold", 5, GTK_WIDGET(desktop->canvas), NULL, holder, TRUE, - "inkscape:paintbucket-threshold", 0, 100.0, 1.0, 10.0, - 0, 0, 0, - paintbucket_threshold_changed, 1, 0 ); - - ege_adjustment_action_set_appearance( eact, TOOLBAR_SLIDER_HINT ); - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - // Create the units menu. - UnitTracker* tracker = new UnitTracker( SP_UNIT_ABSOLUTE | SP_UNIT_DEVICE ); - Glib::ustring stored_unit = prefs->getString("/tools/paintbucket/offsetunits"); - if (!stored_unit.empty()) { - tracker->setActiveUnit(sp_unit_get_by_abbreviation(stored_unit.data())); - } - g_object_set_data( holder, "tracker", tracker ); - { - GtkAction* act = tracker->createAction( "PaintbucketUnitsAction", _("Units"), ("") ); - gtk_action_group_add_action( mainActions, act ); - } - - // Offset spinbox - { - eact = create_adjustment_action( - "OffsetAction", - _("Grow/shrink by"), _("Grow/shrink by:"), - _("The amount to grow (positive) or shrink (negative) the created fill path"), - "/tools/paintbucket/offset", 0, GTK_WIDGET(desktop->canvas), NULL/*us*/, holder, TRUE, - "inkscape:paintbucket-offset", -1e4, 1e4, 0.1, 0.5, - 0, 0, 0, - paintbucket_offset_changed, 1, 2); - tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) ); - - gtk_action_group_add_action( mainActions, GTK_ACTION(eact) ); - } - - /* Auto Gap */ - { - GtkListStore* model = gtk_list_store_new( 2, G_TYPE_STRING, G_TYPE_INT ); - - GList* items = 0; - gint count = 0; - for ( items = flood_autogap_dropdown_items_list(); items ; items = g_list_next(items) ) - { - GtkTreeIter iter; - gtk_list_store_append( model, &iter ); - gtk_list_store_set( model, &iter, 0, reinterpret_cast<gchar*>(items->data), 1, count, -1 ); - count++; - } - g_list_free( items ); - items = 0; - EgeSelectOneAction* act2 = ege_select_one_action_new( "AutoGapAction", _("Close gaps"), (""), NULL, GTK_TREE_MODEL(model) ); - g_object_set( act2, "short_label", _("Close gaps:"), NULL ); - ege_select_one_action_set_appearance( act2, "compact" ); - ege_select_one_action_set_active( act2, prefs->getBool("/tools/paintbucket/autogap") ); - g_signal_connect( G_OBJECT(act2), "changed", G_CALLBACK(paintbucket_autogap_changed), holder ); - gtk_action_group_add_action( mainActions, GTK_ACTION(act2) ); - g_object_set_data( holder, "autogap_action", act2 ); - } - - /* Reset */ - { - GtkAction* act = gtk_action_new( "PaintbucketResetAction", - _("Defaults"), - _("Reset paint bucket parameters to defaults (use Inkscape Preferences > Tools to change defaults)"), - GTK_STOCK_CLEAR ); - g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(paintbucket_defaults), holder ); - gtk_action_group_add_action( mainActions, act ); - gtk_action_set_sensitive( act, TRUE ); - } - -} /* Local Variables: |
