Code

Reword transform toggle tooltips based on user feedback regarding the
[inkscape.git] / src / widgets / toolbox.cpp
index 95e893a349dac126515b48cc6ebb8e06b697f8fb..9801c9f48876c056fe53b0370b611d9275d45c09 100644 (file)
 #include "ege-select-one-action.h"
 #include "helper/unit-tracker.h"
 
-// FIXME: The next two lines are only temporarily added until
-//        the final resizing behaviour of 3D boxes is sorted out.
-#include "knotholder.h"
-SPKnotHolder *sp_3dbox_knot_holder(SPItem *item, SPDesktop *desktop, guint number_of_handles);
-
 using Inkscape::UnitTracker;
 
 typedef void (*SetupFunction)(GtkWidget *toolbox, SPDesktop *desktop);
 typedef void (*UpdateFunction)(SPDesktop *desktop, SPEventContext *eventcontext, GtkWidget *toolbox);
 
 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_zoom_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);
@@ -130,8 +126,10 @@ static struct {
 } const tools[] = {
     { "SPSelectContext",   "select_tool",    SP_VERB_CONTEXT_SELECT,  SP_VERB_CONTEXT_SELECT_PREFS},
     { "SPNodeContext",     "node_tool",      SP_VERB_CONTEXT_NODE, SP_VERB_CONTEXT_NODE_PREFS },
+    { "SPTweakContext",    "tweak_tool",     SP_VERB_CONTEXT_TWEAK, SP_VERB_CONTEXT_TWEAK_PREFS },
     { "SPZoomContext",     "zoom_tool",      SP_VERB_CONTEXT_ZOOM, SP_VERB_CONTEXT_ZOOM_PREFS },
     { "SPRectContext",     "rect_tool",      SP_VERB_CONTEXT_RECT, SP_VERB_CONTEXT_RECT_PREFS },
+//    { "SP3DBoxContext",    "3dbox_tool",     SP_VERB_CONTEXT_3DBOX, SP_VERB_CONTEXT_3DBOX_PREFS },
     { "SPArcContext",      "arc_tool",       SP_VERB_CONTEXT_ARC, SP_VERB_CONTEXT_ARC_PREFS },
     { "SPStarContext",     "star_tool",      SP_VERB_CONTEXT_STAR, SP_VERB_CONTEXT_STAR_PREFS },
     { "SPSpiralContext",   "spiral_tool",    SP_VERB_CONTEXT_SPIRAL, SP_VERB_CONTEXT_SPIRAL_PREFS },
@@ -140,7 +138,6 @@ static struct {
     { "SPDynaDrawContext", "dyna_draw_tool", SP_VERB_CONTEXT_CALLIGRAPHIC, SP_VERB_CONTEXT_CALLIGRAPHIC_PREFS },
     { "SPFloodContext",    "paintbucket_tool",     SP_VERB_CONTEXT_PAINTBUCKET, SP_VERB_CONTEXT_PAINTBUCKET_PREFS },
     { "SPTextContext",     "text_tool",      SP_VERB_CONTEXT_TEXT, SP_VERB_CONTEXT_TEXT_PREFS },
-//    { "SP3DBoxContext",    "3dbox_tool",     SP_VERB_CONTEXT_3DBOX, SP_VERB_CONTEXT_3DBOX_PREFS },
     { "SPConnectorContext","connector_tool", SP_VERB_CONTEXT_CONNECTOR, SP_VERB_CONTEXT_CONNECTOR_PREFS },
     { "SPGradientContext", "gradient_tool",  SP_VERB_CONTEXT_GRADIENT, SP_VERB_CONTEXT_GRADIENT_PREFS },
     { "SPDropperContext",  "dropper_tool",   SP_VERB_CONTEXT_DROPPER, SP_VERB_CONTEXT_DROPPER_PREFS },
@@ -161,6 +158,8 @@ static struct {
       SP_VERB_INVALID, 0, 0},
     { "SPNodeContext",   "node_toolbox",   0, sp_node_toolbox_prep,              "NodeToolbar",
       SP_VERB_INVALID, 0, 0},
+    { "SPTweakContext",   "tweak_toolbox",   0, sp_tweak_toolbox_prep,              "TweakToolbar",
+      SP_VERB_INVALID, 0, 0},
     { "SPZoomContext",   "zoom_toolbox",   0, sp_zoom_toolbox_prep,              "ZoomToolbar",
       SP_VERB_INVALID, 0, 0},
     { "SPStarContext",   "star_toolbox",   0, sp_star_toolbox_prep,              "StarToolbar",
@@ -241,6 +240,16 @@ static gchar const * ui_descr =
         "    <toolitem action='NodesShowHandlesAction' />"
         "  </toolbar>"
 
+        "  <toolbar name='TweakToolbar'>"
+        "    <toolitem action='TweakWidthAction' />"
+        "    <toolitem action='TweakForceAction' />"
+        "    <separator />"
+        "    <toolitem action='TweakModeAction' />"
+        "    <separator />"
+        "    <toolitem action='TweakFidelityAction' />"
+        "    <toolitem action='TweakPressureAction' />"
+        "  </toolbar>"
+
         "  <toolbar name='ZoomToolbar'>"
         "    <toolitem action='ZoomIn' />"
         "    <toolitem action='ZoomOut' />"
@@ -288,8 +297,6 @@ static gchar const * ui_descr =
         "    <toolitem action='3DBoxVPYAction' />"
         "    <toolitem action='3DBoxVPZAction' />"
         "    <separator />"
-        "    <toolitem action='3DBoxHandlesAction' />"
-        "    <separator />"
         "  </toolbar>"
 
         "  <toolbar name='SpiralToolbar'>"
@@ -2115,89 +2122,18 @@ static void sp_rect_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions
 
 static void sp_3dbox_toggle_vp_changed( GtkToggleAction *act, gpointer data )
 {
+    SPDocument *document = sp_desktop_document (inkscape_active_desktop ());
     Box3D::Axis axis = (Box3D::Axis) GPOINTER_TO_INT(data);
 
-    GString *pstring;
-    switch (axis) {
-        case Box3D::X:
-            pstring = g_string_new("togglevpx");
-            break;
-        case Box3D::Y:
-            pstring = g_string_new("togglevpy");
-            break;
-        case Box3D::Z:
-            pstring = g_string_new("togglevpz");
-            break;
-        default:
-            g_warning ("Only single axis directions may be used to toggle VPs!\n");
-            break;
-    }
-    
-    if (SP3DBoxContext::current_perspective) {
-        Box3D::VanishingPoint *vp = SP3DBoxContext::current_perspective->get_vanishing_point(axis);
-        vp->toggle_parallel();
-        vp->draw(axis);
-        prefs_set_int_attribute( "tools.shapes.3dbox", pstring->str, vp->is_finite() ? 0 : 1);
+    if (document->current_perspective) {
+        document->current_perspective->toggle_boxes (axis);
     }
     
 }
 
-static void sp_3dboxtb_handles_state_changed( EgeSelectOneAction *act, GObject *tbl )
-{
-    SPDesktop *desktop = (SPDesktop *) g_object_get_data( tbl, "desktop" );
-    if (sp_document_get_undo_sensitive(sp_desktop_document(desktop))) {
-        if ( ege_select_one_action_get_active( act ) != 0 ) {
-            prefs_set_string_attribute("tools.shapes.3dbox", "constrainedXYmoving", "true");
-        } else {
-            prefs_set_string_attribute("tools.shapes.3dbox", "constrainedXYmoving", NULL);
-        }
-    }
-
-    // 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;
-
-    SPEventContext *ec = SP_EVENT_CONTEXT(inkscape_active_event_context());
-    if (!SP_IS_3DBOX_CONTEXT(ec)) return;
-    SP3DBoxContext *bc = SP_3DBOX_CONTEXT(ec);
-    for (GSList const *items = sp_desktop_selection(desktop)->itemList();
-         items != NULL;
-         items = items->next)
-    {
-        if (SP_IS_3DBOX((SPItem *) items->data)) {
-            if (ec->shape_knot_holder) {
-                sp_knot_holder_destroy(ec->shape_knot_holder);
-                if ( ege_select_one_action_get_active(act) != 0 ) {
-                    bc->number_of_handles = 4;
-                    ec->shape_knot_holder = sp_3dbox_knot_holder((SPItem *) items->data, SP_ACTIVE_DESKTOP, 4);;
-                } else {
-                    bc->number_of_handles = 3;
-                    ec->shape_knot_holder = sp_3dbox_knot_holder((SPItem *) items->data, SP_ACTIVE_DESKTOP, 3);;
-                }
-            } else {
-                g_print ("Warning: No KnotHolder detected!!!\n");
-            }
-            modmade = true;
-        }
-    }
-
-    if (modmade) {
-        sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_3DBOX,
-                                   _("3D Box: Change number of handles"));
-    }
-
-    g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
-}
-
-
 static void sp_3dbox_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
 {
+    SPDocument *document = sp_desktop_document (desktop);
     bool toggled = false;
     /* toggle VP in X direction */
     {
@@ -2207,11 +2143,12 @@ static void sp_3dbox_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
                                                   "toggle_vp_x",
                                                   Inkscape::ICON_SIZE_DECORATION );
     gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
-    g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_changed), GINT_TO_POINTER(Box3D::X));
-    if (SP3DBoxContext::current_perspective) {
-        toggled = SP3DBoxContext::current_perspective->get_vanishing_point(Box3D::X)->is_finite();
+    if (document->current_perspective) {
+        toggled = !document->current_perspective->get_vanishing_point(Box3D::X)->is_finite();
     }
     gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), toggled );
+    /* we connect the signal after setting the state to avoid switching the state again */
+    g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_changed), GINT_TO_POINTER(Box3D::X));
     }
 
     /* toggle VP in Y direction */
@@ -2222,11 +2159,12 @@ static void sp_3dbox_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
                                                   "toggle_vp_y",
                                                   Inkscape::ICON_SIZE_DECORATION );
     gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
-    g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_changed), GINT_TO_POINTER(Box3D::Y));
-    if (SP3DBoxContext::current_perspective) {
-        toggled = SP3DBoxContext::current_perspective->get_vanishing_point(Box3D::Y)->is_finite();
+    if (document->current_perspective) {
+        toggled = !document->current_perspective->get_vanishing_point(Box3D::Y)->is_finite();
     }
     gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), toggled );
+    /* we connect the signal after setting the state to avoid switching the state again */
+    g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_changed), GINT_TO_POINTER(Box3D::Y));
     }
 
     /* toggle VP in Z direction */
@@ -2237,47 +2175,12 @@ static void sp_3dbox_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
                                                   "toggle_vp_z",
                                                   Inkscape::ICON_SIZE_DECORATION );
     gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
-    g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_changed), GINT_TO_POINTER(Box3D::Z));
-    if (SP3DBoxContext::current_perspective) {
-        toggled = SP3DBoxContext::current_perspective->get_vanishing_point(Box3D::Z)->is_finite();
+    if (document->current_perspective) {
+        toggled = !document->current_perspective->get_vanishing_point(Box3D::Z)->is_finite();
     }
+    /* we connect the signal after setting the state to avoid switching the state again */
     gtk_toggle_action_set_active( GTK_TOGGLE_ACTION(act), toggled );
-    }
-
-
-    /* Number of handles and resizing behaviour */
-    {
-        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, _("Three Handles"),
-                            1, _("Switch to three handles (arbitrary resizing in XY-direction)"),
-                            2, "3dbox_three_handles",
-                            -1 );
-
-        gtk_list_store_append( model, &iter );
-        gtk_list_store_set( model, &iter,
-                            0, _("Four Handles"),
-                            1, _("Switch to four handles (constrained resizing in XY-direction)"),
-                            2, "3dbox_four_handles",
-                            -1 );
-
-        EgeSelectOneAction* act = ege_select_one_action_new( "3DBoxHandlesAction", _(""), _(""), NULL, GTK_TREE_MODEL(model) );
-        gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
-        g_object_set_data( holder, "handles_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  );
-
-        gchar const *handlestr = prefs_get_string_attribute("tools.shapes.3dbox", "constrainedXYmoving");
-        bool isConstrained = (!handlestr || (handlestr && !strcmp(handlestr, "true")));
-        ege_select_one_action_set_active( act, isConstrained ? 0 : 1 );
-        g_signal_connect_after( G_OBJECT(act), "changed", G_CALLBACK(sp_3dboxtb_handles_state_changed), holder );
+    g_signal_connect_after( G_OBJECT(act), "toggled", G_CALLBACK(sp_3dbox_toggle_vp_changed), GINT_TO_POINTER(Box3D::Z));
     }
 }
 
@@ -2529,6 +2432,148 @@ static void sp_pencil_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActio
     // Put stuff here
 }
 
+//########################
+//##       Tweak        ##
+//########################
+
+static void sp_tweak_width_value_changed( GtkAdjustment *adj, GObject *tbl )
+{
+    prefs_set_double_attribute( "tools.tweak", "width", adj->value * 0.01 );
+}
+
+static void sp_tweak_force_value_changed( GtkAdjustment *adj, GObject *tbl )
+{
+    prefs_set_double_attribute( "tools.tweak", "force", adj->value * 0.01 );
+}
+
+static void sp_tweak_pressure_state_changed( GtkToggleAction *act, gpointer data )
+{
+    prefs_set_int_attribute( "tools.tweak", "usepressure", gtk_toggle_action_get_active( act ) ? 1 : 0);
+}
+
+static void sp_tweak_mode_changed( EgeSelectOneAction *act, GObject *tbl )
+{
+    prefs_set_int_attribute("tools.tweak", "mode", ege_select_one_action_get_active( act ));
+}
+
+static void sp_tweak_fidelity_value_changed( GtkAdjustment *adj, GObject *tbl )
+{
+    prefs_set_double_attribute( "tools.tweak", "fidelity", adj->value * 0.01 );
+}
+
+
+static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
+{
+    {
+        /* 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:"), _("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 );
+        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:"), _("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 );
+        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, _("Push mode"),
+                            1, _("Switch to Push mode"),
+                            2, "tweak_push_mode",
+                            -1 );
+
+        gtk_list_store_append( model, &iter );
+        gtk_list_store_set( model, &iter,
+                            0, _("Melt mode"),
+                            1, _("Switch to Melt mode"),
+                            2, "tweak_suck_mode",
+                            -1 );
+
+        gtk_list_store_append( model, &iter );
+        gtk_list_store_set( model, &iter,
+                            0, _("Blow mode"),
+                            1, _("Switch to Blow mode"),
+                            2, "tweak_blow_mode",
+                            -1 );
+
+        gtk_list_store_append( model, &iter );
+        gtk_list_store_set( model, &iter,
+                            0, _("Roughen mode"),
+                            1, _("Switch to Roughen mode"),
+                            2, "tweak_roughen_mode",
+                            -1 );
+
+        EgeSelectOneAction* act = ege_select_one_action_new( "TweakModeAction", _(""), _(""), NULL, GTK_TREE_MODEL(model) );
+        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_tooltip_column( act, 1  );
+
+        gint mode = prefs_get_int_attribute("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);
+    }
+
+    {   /* 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:"), _("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 );
+    }
+
+
+    /* Use Pressure button */
+    {
+        InkToggleAction* act = ink_toggle_action_new( "TweakPressureAction",
+                                                      _("Pressure"),
+                                                      _("Use the pressure of the input device to alter the width of the area"),
+                                                      "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_get_int_attribute( "tools.tweak", "usepressure", 1 ) );
+    }
+
+}
+
 
 //########################
 //##     Calligraphy    ##
@@ -2788,7 +2833,7 @@ static void sp_calligraphy_toolbox_prep(SPDesktop *desktop, GtkActionGroup* main
         {
             GtkAction* act = gtk_action_new( "CalligraphyResetAction",
                                              _("Defaults"),
-                                             _("Reset shape parameters to defaults (use Inkscape Preferences > Tools to change defaults)"),
+                                             _("Reset all parameters to defaults"),
                                              GTK_STOCK_CLEAR );
             g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_ddc_defaults), holder );
             gtk_action_group_add_action( mainActions, act );