Code

four more modes
authorbuliabyak <buliabyak@users.sourceforge.net>
Mon, 27 Aug 2007 00:38:40 +0000 (00:38 +0000)
committerbuliabyak <buliabyak@users.sourceforge.net>
Mon, 27 Aug 2007 00:38:40 +0000 (00:38 +0000)
src/preferences-skeleton.h
src/tweak-context.cpp
src/tweak-context.h
src/widgets/toolbox.cpp

index 6650de925c293e76e0ea45dee3c5d1f4a9cc4c1a..eb83a2b95c570a6046456d8fd67b07ff0ac687e4 100644 (file)
@@ -75,7 +75,7 @@ static char const preferences_skeleton[] =
 "                       font_sample=\"AaBbCcIiPpQq12369$\342\202\254\302\242?.;/()\"\n"
 "                  style=\"fill:black;fill-opacity:1;stroke:none;font-family:Bitstream Vera Sans;font-style:normal;font-weight:normal;font-size:12px;\" selcue=\"1\"/>\n"
 "    <eventcontext id=\"nodes\" selcue=\"1\" gradientdrag=\"1\" show_handles=\"1\" sculpting_profile=\"1\" />\n"
-"    <eventcontext id=\"tweak\" selcue=\"0\" gradientdrag=\"0\" show_handles=\"0\" width=\"0.2\" force=\"0.2\" fidelity=\"0.5\" usepressure=\"1\" />\n"
+"    <eventcontext id=\"tweak\" selcue=\"0\" gradientdrag=\"0\" show_handles=\"0\" width=\"0.2\" force=\"0.2\" fidelity=\"0.5\" usepressure=\"1\" style=\"fill:red;stroke:none;\" usecurrent=\"0\"/>\n"
 "    <eventcontext id=\"gradient\" selcue=\"1\"/>\n"
 "    <eventcontext id=\"zoom\" selcue=\"1\" gradientdrag=\"0\"/>\n"
 "    <eventcontext id=\"dropper\" selcue=\"1\" gradientdrag=\"1\" pick=\"1\" setalpha=\"1\"/>\n"
index a7520d22968ea8cad9fd99d41029e19aaf90c685..201af0fc57161863c820f14ad38df04ced7ec2b1 100644 (file)
@@ -11,8 +11,6 @@
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 
-#define noTWEAK_VERBOSE
-
 #include "config.h"
 
 #include <gtk/gtk.h>
 #include "message-context.h"
 #include "pixmaps/cursor-thin.xpm"
 #include "pixmaps/cursor-thicken.xpm"
+#include "pixmaps/cursor-attract.xpm"
+#include "pixmaps/cursor-repel.xpm"
 #include "pixmaps/cursor-push.xpm"
 #include "pixmaps/cursor-roughen.xpm"
+#include "pixmaps/cursor-color.xpm"
 #include "libnr/n-art-bpath.h"
 #include "libnr/nr-path.h"
+#include "libnr/nr-maybe.h"
 #include "libnr/nr-matrix-ops.h"
 #include "libnr/nr-scale-translate-ops.h"
 #include "xml/repr.h"
 #include "sp-item.h"
 #include "inkscape.h"
 #include "color.h"
+#include "svg/svg-color.h"
 #include "splivarot.h"
 #include "sp-item-group.h"
 #include "sp-shape.h"
 #include "sp-path.h"
 #include "path-chemistry.h"
+#include "sp-gradient.h"
+#include "sp-stop.h"
+#include "sp-stop-fns.h"
+#include "sp-gradient-reference.h"
+#include "sp-linear-gradient.h"
+#include "sp-radial-gradient.h"
+#include "gradient-chemistry.h"
 #include "sp-text.h"
 #include "sp-flowtext.h"
 #include "display/canvas-bpath.h"
@@ -60,6 +70,7 @@
 #include "livarot/Shape.h"
 #include "isnan.h"
 #include "prefs-utils.h"
+#include "style.h"
 
 #include "tweak-context.h"
 
@@ -143,6 +154,13 @@ sp_tweak_context_init(SPTweakContext *tc)
 
     tc->is_dilating = false;
     tc->has_dilated = false;
+
+    tc->do_h = true;
+    tc->do_s = true;
+    tc->do_l = true;
+    tc->do_o = false;
+
+    new (&tc->style_set_connection) sigc::connection();
 }
 
 static void
@@ -150,6 +168,9 @@ sp_tweak_context_dispose(GObject *object)
 {
     SPTweakContext *tc = SP_TWEAK_CONTEXT(object);
 
+    tc->style_set_connection.disconnect();
+    tc->style_set_connection.~connection();
+
     if (tc->dilate_area) {
         gtk_object_destroy(GTK_OBJECT(tc->dilate_area));
         tc->dilate_area = NULL;
@@ -170,19 +191,44 @@ sp_tweak_update_cursor (SPTweakContext *tc, gint mode)
        case TWEAK_MODE_PUSH:
            event_context->cursor_shape = cursor_push_xpm;
            break;
-       case TWEAK_MODE_MELT:
+       case TWEAK_MODE_SHRINK:
            event_context->cursor_shape = cursor_thin_xpm;
            break;
-       case TWEAK_MODE_INFLATE:
+       case TWEAK_MODE_GROW:
            event_context->cursor_shape = cursor_thicken_xpm;
            break;
+       case TWEAK_MODE_ATTRACT:
+           event_context->cursor_shape = cursor_attract_xpm;
+           break;
+       case TWEAK_MODE_REPEL:
+           event_context->cursor_shape = cursor_repel_xpm;
+           break;
        case TWEAK_MODE_ROUGHEN:
            event_context->cursor_shape = cursor_roughen_xpm;
            break;
+       case TWEAK_MODE_COLORPAINT:
+       case TWEAK_MODE_COLORJITTER:
+           event_context->cursor_shape = cursor_color_xpm;
+           break;
    }
    sp_event_context_update_cursor(event_context);
 }
 
+static bool
+sp_tweak_context_style_set(SPCSSAttr const *css, SPTweakContext *tc)
+{
+    if (tc->mode == TWEAK_MODE_COLORPAINT) { // intercept color setting only in this mode
+        // we cannot store properties with uris
+        css = sp_css_attr_unset_uris ((SPCSSAttr *) css);
+
+        sp_repr_css_change (inkscape_get_repr (INKSCAPE, "tools.tweak"), (SPCSSAttr *) css, "style");
+
+        return true;
+    }
+    return false;
+}
+
+
 static void
 sp_tweak_context_setup(SPEventContext *ec)
 {
@@ -205,10 +251,18 @@ sp_tweak_context_setup(SPEventContext *ec)
     sp_event_context_read(ec, "fidelity");
     sp_event_context_read(ec, "force");
     sp_event_context_read(ec, "usepressure");
+    sp_event_context_read(ec, "doh");
+    sp_event_context_read(ec, "dol");
+    sp_event_context_read(ec, "dos");
+    sp_event_context_read(ec, "doo");
 
     tc->is_drawing = false;
 
     tc->_message_context = new Inkscape::MessageContext((ec->desktop)->messageStack());
+
+    tc->style_set_connection = ec->desktop->connectSetStyle( // catch style-setting signal in this tool
+        sigc::bind(sigc::ptr_fun(&sp_tweak_context_style_set), tc)
+    );
 }
 
 static void
@@ -231,6 +285,14 @@ sp_tweak_context_set(SPEventContext *ec, gchar const *key, gchar const *val)
         tc->force = CLAMP(dval, 0, 1.0);
     } else if (!strcmp(key, "usepressure")) {
         tc->usepressure = (val && strcmp(val, "0"));
+    } else if (!strcmp(key, "doh")) {
+        tc->do_h = (val && strcmp(val, "0"));
+    } else if (!strcmp(key, "dos")) {
+        tc->do_s = (val && strcmp(val, "0"));
+    } else if (!strcmp(key, "dol")) {
+        tc->do_l = (val && strcmp(val, "0"));
+    } else if (!strcmp(key, "doo")) {
+        tc->do_o = (val && strcmp(val, "0"));
     } 
 }
 
@@ -336,12 +398,18 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Poi
 
         bool did_this = false;
         NR::Matrix i2doc(sp_item_i2doc_affine(item));
-        if (mode == TWEAK_MODE_MELT || mode == TWEAK_MODE_INFLATE) {
+        if (mode == TWEAK_MODE_SHRINK || mode == TWEAK_MODE_GROW) {
             if (theShape->MakeOffset(theRes, 
-                                 mode == TWEAK_MODE_INFLATE? force : -force,
+                                 mode == TWEAK_MODE_GROW? force : -force,
                                  join_straight, 4.0,
                                  true, p[NR::X], p[NR::Y], radius, &i2doc) == 0) // 0 means the shape was actually changed
               did_this = true;
+        } else if (mode == TWEAK_MODE_ATTRACT || mode == TWEAK_MODE_REPEL) {
+            if (theShape->MakeRepel(theRes, 
+                                 mode == TWEAK_MODE_REPEL? force : -force,
+                                 join_straight, 4.0,
+                                 true, p[NR::X], p[NR::Y], radius, &i2doc) == 0) 
+              did_this = true;
         } else if (mode == TWEAK_MODE_PUSH) {
             if (theShape->MakePush(theRes, 
                                  join_straight, 4.0,
@@ -414,9 +482,306 @@ sp_tweak_dilate_recursive (Inkscape::Selection *selection, SPItem *item, NR::Poi
     return did;
 }
 
+void 
+tweak_colorpaint (float *color, guint32 goal, double force, bool do_h, bool do_s, bool do_l) 
+{
+    float rgb_g[3];
+
+    if (!do_h || !do_s || !do_l) {
+        float hsl_g[3];
+        sp_color_rgb_to_hsl_floatv (hsl_g, SP_RGBA32_R_F(goal), SP_RGBA32_G_F(goal), SP_RGBA32_B_F(goal));
+        float hsl_c[3];
+        sp_color_rgb_to_hsl_floatv (hsl_c, color[0], color[1], color[2]);
+        if (!do_h) 
+            hsl_g[0] = hsl_c[0];
+        if (!do_s) 
+            hsl_g[1] = hsl_c[1];
+        if (!do_l) 
+            hsl_g[2] = hsl_c[2];
+        sp_color_hsl_to_rgb_floatv (rgb_g, hsl_g[0], hsl_g[1], hsl_g[2]);
+    } else {
+        rgb_g[0] = SP_RGBA32_R_F(goal);
+        rgb_g[1] = SP_RGBA32_G_F(goal);
+        rgb_g[2] = SP_RGBA32_B_F(goal);
+    }
+
+    for (int i = 0; i < 3; i++) {
+        double d = rgb_g[i] - color[i];
+        color[i] += d * force;
+    }
+}
+
+void 
+tweak_colorjitter (float *color, double force, bool do_h, bool do_s, bool do_l) 
+{
+    force = force*force; // in [0..1], this makes finer adjustments easier
+
+    float hsl_c[3];
+    sp_color_rgb_to_hsl_floatv (hsl_c, color[0], color[1], color[2]);
+
+    if (do_h) {
+        hsl_c[0] += g_random_double_range(-0.5, 0.5) * force;
+        if (hsl_c[0] > 1)
+            hsl_c[0] -= 1;
+        if (hsl_c[0] < 0)
+            hsl_c[0] += 1;
+    }
+    if (do_s) {
+        hsl_c[1] += g_random_double_range(-hsl_c[1], 1 - hsl_c[1]) * force;
+    }
+    if (do_l) {
+        hsl_c[2] += g_random_double_range(-hsl_c[2], 1 - hsl_c[2]) * force;
+    }
+
+    sp_color_hsl_to_rgb_floatv (color, hsl_c[0], hsl_c[1], hsl_c[2]);
+}
+
+void 
+tweak_color (guint mode, float *color, guint32 goal, double force, bool do_h, bool do_s, bool do_l) 
+{
+    if (mode == TWEAK_MODE_COLORPAINT) {
+        tweak_colorpaint (color, goal, force, do_h, do_s, do_l);
+    } else if (mode == TWEAK_MODE_COLORJITTER) {
+        tweak_colorjitter (color, force, do_h, do_s, do_l);
+    }
+}
+
+void
+tweak_opacity (guint mode, SPIScale24 *style_opacity, double opacity_goal, double force)
+{
+    double opacity = SP_SCALE24_TO_FLOAT (style_opacity->value);
+
+    if (mode == TWEAK_MODE_COLORPAINT) {
+        double d = opacity_goal - opacity;
+        opacity += d * force;
+    } else if (mode == TWEAK_MODE_COLORJITTER) {
+        opacity += g_random_double_range(-opacity, 1 - opacity) * force;
+    }
+
+    style_opacity->value = SP_SCALE24_FROM_FLOAT(opacity);
+}
+
+
+double
+tweak_profile (double dist, double radius) 
+{
+    if (radius == 0)
+        return 0;
+    double x = dist / radius;
+    double alpha = 1;
+    if (x >= 1) {
+        return 0;
+    } else if (x <= 0) {
+        return 1;
+    } else {
+        return (0.5 * cos (M_PI * (pow(x, alpha))) + 0.5);
+    }
+}
+
+void
+tweak_colors_in_gradient (SPItem *item, bool fill_or_stroke, 
+    guint32 const rgb_goal, NR::Point p_w, double radius, double force, guint mode, 
+    bool do_h, bool do_s, bool do_l, bool do_o)
+{
+    SPGradient *gradient = sp_item_gradient (item, fill_or_stroke);
+
+    if (!gradient || !SP_IS_GRADIENT(gradient))
+        return;
+
+    NR::Matrix i2d = sp_item_i2doc_affine (item);
+    NR::Point p = p_w * i2d.inverse();
+    p *= (gradient->gradientTransform).inverse();
+    // now p is in gradient's original coordinates
+
+    double pos = 0;
+    double r = 0;
+    if (SP_IS_LINEARGRADIENT(gradient)) {
+        SPLinearGradient *lg = SP_LINEARGRADIENT(gradient);
+
+        NR::Point p1(lg->x1.computed, lg->y1.computed);
+        NR::Point p2(lg->x2.computed, lg->y2.computed);
+        NR::Point pdiff(p2 - p1);
+        double vl = NR::L2(pdiff);
+
+        // This is the matrix which moves and rotates the gradient line
+        // so it's oriented along the X axis:
+        NR::Matrix norm = NR::Matrix(NR::translate(-p1)) * NR::Matrix(NR::rotate(-atan2(pdiff[NR::Y], pdiff[NR::X])));
+
+        // Transform the mouse point by it to find out its projection onto the gradient line:
+        NR::Point pnorm = p * norm;
+
+        // Scale its X coordinate to match the length of the gradient line:
+        pos = pnorm[NR::X] / vl;
+        // Calculate radius in lenfth-of-gradient-line units
+        r = radius / vl;
+
+    } else if (SP_IS_RADIALGRADIENT(gradient)) {
+        SPRadialGradient *rg = SP_RADIALGRADIENT(gradient);
+        NR::Point c (rg->cx.computed, rg->cy.computed);
+        pos = NR::L2(p - c) / rg->r.computed;
+        r = radius / rg->r.computed;
+    }
+
+    // Normalize pos to 0..1, taking into accound gradient spread:
+    double pos_e = pos;
+    if (gradient->spread == SP_GRADIENT_SPREAD_PAD) {
+        if (pos > 1)
+            pos_e = 1;
+        if (pos < 0)
+            pos_e = 0;
+    } else if (gradient->spread == SP_GRADIENT_SPREAD_REPEAT) {
+        if (pos > 1 || pos < 0)
+            pos_e = pos - floor(pos);
+    } else if (gradient->spread == SP_GRADIENT_SPREAD_REFLECT) {
+        if (pos > 1 || pos < 0) {
+            bool odd = ((int)(floor(pos)) % 2 == 1);
+            pos_e = pos - floor(pos);
+            if (odd) 
+                pos_e = 1 - pos_e;
+        }
+    }
+
+    SPGradient *vector = sp_gradient_get_forked_vector_if_necessary(gradient, false);
+
+    double offset_l = 0;
+    double offset_h = 0;
+    SPObject *child_prev = NULL;
+    for (SPObject *child = sp_object_first_child(vector);
+         child != NULL; child = SP_OBJECT_NEXT(child)) {
+        if (!SP_IS_STOP(child))
+            continue;
+        SPStop *stop = SP_STOP (child);
+
+        offset_h = stop->offset;
+
+        if (child_prev) {
+
+            if (offset_h - offset_l > r && pos_e >= offset_l && pos_e <= offset_h) {
+                // the summit falls in this interstop, and the radius is small,
+                // so it only affects the ends of this interstop;
+                // distribute the force between the two endstops so that they
+                // get all the painting even if they are not touched by the brush
+                tweak_color (mode, stop->specified_color.v.c, rgb_goal, 
+                                  force * (pos_e - offset_l) / (offset_h - offset_l), 
+                                  do_h, do_s, do_l);
+                tweak_color (mode, SP_STOP(child_prev)->specified_color.v.c, rgb_goal, 
+                                  force * (offset_h - pos_e) / (offset_h - offset_l), 
+                                  do_h, do_s, do_l);
+                SP_OBJECT(stop)->updateRepr();
+                child_prev->updateRepr();
+                break;
+            } else {
+                // wide brush, may affect more than 2 stops, 
+                // paint each stop by the force from the profile curve
+                if (offset_l <= pos_e && offset_l > pos_e - r) { 
+                    tweak_color (mode, SP_STOP(child_prev)->specified_color.v.c, rgb_goal, 
+                                 force * tweak_profile (fabs (pos_e - offset_l), r),
+                                 do_h, do_s, do_l);
+                    child_prev->updateRepr();
+                } 
+
+                if (offset_h >= pos_e && offset_h < pos_e + r) { 
+                    tweak_color (mode, stop->specified_color.v.c, rgb_goal, 
+                                 force * tweak_profile (fabs (pos_e - offset_h), r),
+                                 do_h, do_s, do_l);
+                    SP_OBJECT(stop)->updateRepr();
+                }
+            }
+        }
+
+        offset_l = offset_h;
+        child_prev = child;
+    }
+}
+
+bool
+sp_tweak_color_recursive (guint mode, SPItem *item, SPItem *item_at_point, 
+                          guint32 fill_goal, bool do_fill,
+                          guint32 stroke_goal, bool do_stroke,
+                          float opacity_goal, bool do_opacity,
+                          NR::Point p, double radius, double force, 
+                          bool do_h, bool do_s, bool do_l, bool do_o)
+{
+    bool did = false;
+
+    if (SP_IS_GROUP(item)) {
+        for (SPObject *child = sp_object_first_child(SP_OBJECT(item)) ; child != NULL; child = SP_OBJECT_NEXT(child) ) {
+            if (SP_IS_ITEM(child)) {
+                if (sp_tweak_color_recursive (mode, SP_ITEM(child), item_at_point, 
+                                          fill_goal, do_fill,
+                                          stroke_goal, do_stroke,
+                                          opacity_goal, do_opacity,
+                                          p, radius, force, do_h, do_s, do_l, do_o));
+                    did = true;
+            }
+        }
+
+    } else {
+        SPStyle *style = SP_OBJECT_STYLE(item);
+        if (!style) {
+            return false;
+        }
+        NR::Maybe<NR::Rect> bbox = item->getBounds(sp_item_i2doc_affine(item),
+                                                        SPItem::GEOMETRIC_BBOX);
+        if (!bbox) {
+            return false;
+        }
+
+        NR::Rect brush(p - NR::Point(radius, radius), p + NR::Point(radius, radius));
+
+        NR::Point center = bbox->midpoint();
+        double this_force;
+
+// if item == item_at_point, use max force
+        if (item == item_at_point) {
+            this_force = force;
+// else if no overlap of bbox and brush box, skip:
+        } else if (!bbox->intersects(brush)) {
+            return false;
+//TODO:
+// else if object > 1.5 brush: test 4/8/16 points in the brush on hitting the object, choose max
+        //} else if (bbox->maxExtent() > 3 * radius) {
+        //}
+// else if object > 0.5 brush: test 4 corners of bbox and center on being in the brush, choose max
+// else if still smaller, then check only the object center:
+        } else {
+            this_force = force * tweak_profile (NR::L2 (p - center), radius);
+        }
+        
+        if (this_force > 0.002) {
+
+            if (do_fill) {
+                if (style->fill.type == SP_PAINT_TYPE_COLOR) {
+                    tweak_color (mode, style->fill.value.color.v.c, fill_goal, this_force, do_h, do_s, do_l);
+                    item->updateRepr();
+                    did = true;
+                } else if (style->fill.type == SP_PAINT_TYPE_PAINTSERVER) {
+                    tweak_colors_in_gradient (item, true, fill_goal, p, radius, this_force, mode, do_h, do_s, do_l, do_o);
+                    did = true;
+                }
+            }
+            if (do_stroke) {
+                if (style->stroke.type == SP_PAINT_TYPE_COLOR) {
+                    tweak_color (mode, style->stroke.value.color.v.c, stroke_goal, this_force, do_h, do_s, do_l);
+                    item->updateRepr();
+                    did = true;
+                } else if (style->stroke.type == SP_PAINT_TYPE_PAINTSERVER) {
+                    tweak_colors_in_gradient (item, false, stroke_goal, p, radius, this_force, mode, do_h, do_s, do_l, do_o);
+                    did = true;
+                }
+            }
+            if (do_opacity && do_o) {
+                tweak_opacity (mode, &style->opacity, opacity_goal, this_force);
+            }
+        }
+    }
+
+    return did;
+}
+
 
 bool
-sp_tweak_dilate (SPTweakContext *tc, NR::Point p, NR::Point vector)
+sp_tweak_dilate (SPTweakContext *tc, NR::Point event_p, NR::Point p, NR::Point vector)
 {
     Inkscape::Selection *selection = sp_desktop_selection(SP_EVENT_CONTEXT(tc)->desktop);
 
@@ -430,6 +795,33 @@ sp_tweak_dilate (SPTweakContext *tc, NR::Point p, NR::Point vector)
     if (radius == 0 || force == 0) {
         return false;
     }
+    double color_force = MIN(sqrt(force)/4.0, 1);
+
+    SPItem *item_at_point = SP_EVENT_CONTEXT(tc)->desktop->item_at_point(event_p, TRUE);
+    Inkscape::XML::Node *tool_repr = inkscape_get_repr(INKSCAPE, "tools.tweak");
+    SPCSSAttr *css = sp_repr_css_attr_inherited(tool_repr, "style");
+    if (tc->mode == TWEAK_MODE_COLORPAINT && !css) 
+        return false;
+
+    bool do_fill = false, do_stroke = false, do_opacity = false;
+    guint32 fill_goal = 0, stroke_goal = 0;
+    float opacity_goal = 1;
+
+    const gchar *fill_prop = sp_repr_css_property(css, "fill", NULL);
+    if (fill_prop && strcmp(fill_prop, "none")) {
+        do_fill = true;
+        fill_goal = sp_svg_read_color(fill_prop, 0);
+    }
+    const gchar *stroke_prop = sp_repr_css_property(css, "stroke", NULL);
+    if (stroke_prop && strcmp(stroke_prop, "none")) {
+        do_stroke = true;
+        stroke_goal = sp_svg_read_color(stroke_prop, 0);
+    }
+    const gchar *opacity_prop = sp_repr_css_property(css, "opacity", NULL);
+    if (opacity_prop) {
+        do_opacity = true;
+        sp_svg_number_read_f(opacity_prop, &opacity_goal);
+    }
 
     for (GSList *items = g_slist_copy((GSList *) selection->itemList());
          items != NULL;
@@ -437,9 +829,19 @@ sp_tweak_dilate (SPTweakContext *tc, NR::Point p, NR::Point vector)
 
         SPItem *item = (SPItem *) items->data;
 
-        if (sp_tweak_dilate_recursive (selection, item, p, vector, tc->mode, radius, force, tc->fidelity))
-            did = true;
-
+        if (tc->mode == TWEAK_MODE_COLORPAINT || tc->mode == TWEAK_MODE_COLORJITTER) {
+            if (do_fill || do_stroke || do_opacity) {
+                if (sp_tweak_color_recursive (tc->mode, item, item_at_point, 
+                                          fill_goal, do_fill,
+                                          stroke_goal, do_stroke,
+                                          opacity_goal, do_opacity,
+                                          p, radius, color_force, tc->do_h, tc->do_s, tc->do_l, tc->do_o))
+                did = true;
+            }
+        } else {
+            if (sp_tweak_dilate_recursive (selection, item, p, vector, tc->mode, radius, force, tc->fidelity))
+                did = true;
+        }
     }
 
     return did;
@@ -469,11 +871,11 @@ sp_tweak_switch_mode_temporarily (SPTweakContext *tc, gint mode)
    // Juggling about so that prefs have the old value but tc->mode and the button show new mode:
    gint now_mode = prefs_get_int_attribute("tools.tweak", "mode", 0);
    SP_EVENT_CONTEXT(tc)->desktop->setToolboxSelectOneValue ("tweak_tool_mode", mode);
-   sp_tweak_update_cursor (tc, mode);
    // button has changed prefs, restore
    prefs_set_int_attribute("tools.tweak", "mode", now_mode);
    // changing prefs changed tc->mode, restore back :)
    tc->mode = mode;
+   sp_tweak_update_cursor (tc, mode);
 }
 
 gint
@@ -486,6 +888,12 @@ sp_tweak_context_root_handler(SPEventContext *event_context,
     gint ret = FALSE;
 
     switch (event->type) {
+        case GDK_ENTER_NOTIFY:
+            sp_canvas_item_show(tc->dilate_area);
+            break;
+        case GDK_LEAVE_NOTIFY:
+            sp_canvas_item_hide(tc->dilate_area);
+            break;
         case GDK_BUTTON_PRESS:
             if (event->button.button == 1 && !event_context->space_panning) {
 
@@ -534,17 +942,32 @@ sp_tweak_context_root_handler(SPEventContext *event_context,
                            tc->_message_context->setF(Inkscape::NORMAL_MESSAGE,
                                                       _("<b>Pushing %d</b> selected object(s)"), num);  
                            break;
-                        case TWEAK_MODE_MELT:
+                        case TWEAK_MODE_SHRINK:
+                           tc->_message_context->setF(Inkscape::NORMAL_MESSAGE,
+                                                      _("<b>Shrinking %d</b> selected object(s)"), num);
+                           break;
+                        case TWEAK_MODE_GROW:
+                           tc->_message_context->setF(Inkscape::NORMAL_MESSAGE,
+                                                      _("<b>Growing %d</b> selected object(s)"), num);
+                           break;
+                        case TWEAK_MODE_ATTRACT:
                            tc->_message_context->setF(Inkscape::NORMAL_MESSAGE,
-                                                      _("<b>Melting %d</b> selected object(s)"), num);
+                                                      _("<b>Attracting %d</b> selected object(s)"), num);
                            break;
-                        case TWEAK_MODE_INFLATE:
+                        case TWEAK_MODE_REPEL:
                            tc->_message_context->setF(Inkscape::NORMAL_MESSAGE,
-                                                      _("<b>Inflating %d</b> selected object(s)"), num);
+                                                      _("<b>Repelling %d</b> selected object(s)"), num);
                            break;
                         case TWEAK_MODE_ROUGHEN:
                            tc->_message_context->setF(Inkscape::NORMAL_MESSAGE,
                                                       _("<b>Roughening %d</b> selected object(s)"), num);
+                        case TWEAK_MODE_COLORPAINT:
+                           tc->_message_context->setF(Inkscape::NORMAL_MESSAGE,
+                                                      _("<b>Painting %d</b> selected object(s)"), num);
+                           break;
+                        case TWEAK_MODE_COLORJITTER:
+                           tc->_message_context->setF(Inkscape::NORMAL_MESSAGE,
+                                                      _("<b>Jittering colors in %d</b> selected object(s)"), num);
                            break;
                     }
                 }
@@ -552,7 +975,7 @@ sp_tweak_context_root_handler(SPEventContext *event_context,
 
             // dilating:
             if (tc->is_drawing && ( event->motion.state & GDK_BUTTON1_MASK )) {  
-                sp_tweak_dilate (tc, motion_doc, motion_doc - tc->last_push);
+                sp_tweak_dilate (tc, motion_w, motion_doc, motion_doc - tc->last_push);
                 //tc->last_push = motion_doc;
                 tc->has_dilated = true;
                 // it's slow, so prevent clogging up with events
@@ -576,15 +999,43 @@ sp_tweak_context_root_handler(SPEventContext *event_context,
             if (!tc->has_dilated) {
                 // if we did not rub, do a light tap
                 tc->pressure = 0.03;
-                sp_tweak_dilate (tc, desktop->dt2doc(motion_dt), NR::Point(0,0));
+                sp_tweak_dilate (tc, motion_w, desktop->dt2doc(motion_dt), NR::Point(0,0));
             }
             tc->is_dilating = false;
             tc->has_dilated = false;
-            sp_document_done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop), 
-                         SP_VERB_CONTEXT_TWEAK,
-                             (tc->mode==TWEAK_MODE_INFLATE ? _("Inflate tweak") : (tc->mode==TWEAK_MODE_MELT ? _("Melt tweak") : (tc->mode==TWEAK_MODE_PUSH ? _("Push tweak") : _("Roughen tweak")))));
-            ret = TRUE;
-
+            switch (tc->mode) {
+                case TWEAK_MODE_PUSH:
+                    sp_document_done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop), 
+                                     SP_VERB_CONTEXT_TWEAK, _("Push tweak"));
+                    break;
+                case TWEAK_MODE_SHRINK:
+                    sp_document_done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop), 
+                                     SP_VERB_CONTEXT_TWEAK, _("Shrink tweak"));
+                    break;
+                case TWEAK_MODE_GROW:
+                    sp_document_done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop), 
+                                     SP_VERB_CONTEXT_TWEAK, _("Grow tweak"));
+                    break;
+                case TWEAK_MODE_ATTRACT:
+                    sp_document_done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop), 
+                                     SP_VERB_CONTEXT_TWEAK, _("Attract tweak"));
+                    break;
+                case TWEAK_MODE_REPEL:
+                    sp_document_done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop), 
+                                     SP_VERB_CONTEXT_TWEAK, _("Repel tweak"));
+                    break;
+                case TWEAK_MODE_ROUGHEN:
+                    sp_document_done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop), 
+                                     SP_VERB_CONTEXT_TWEAK, _("Roughen tweak"));
+                    break;
+                case TWEAK_MODE_COLORPAINT:
+                    sp_document_done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop), 
+                                     SP_VERB_CONTEXT_TWEAK, _("Color paint tweak"));
+                case TWEAK_MODE_COLORJITTER:
+                    sp_document_done(sp_desktop_document(SP_EVENT_CONTEXT(tc)->desktop), 
+                                     SP_VERB_CONTEXT_TWEAK, _("Color jitter tweak"));
+                    break;
+            }
         } 
         break;
     }
@@ -599,30 +1050,62 @@ sp_tweak_context_root_handler(SPEventContext *event_context,
                 ret = TRUE;
             }
             break;
-        case GDK_m:
-        case GDK_M:
+        case GDK_s:
+        case GDK_S:
         case GDK_2:
             if (MOD__SHIFT_ONLY) {
-                sp_tweak_switch_mode(tc, TWEAK_MODE_MELT);
+                sp_tweak_switch_mode(tc, TWEAK_MODE_SHRINK);
                 ret = TRUE;
             }
             break;
-        case GDK_i:
-        case GDK_I:
+        case GDK_g:
+        case GDK_G:
         case GDK_3:
             if (MOD__SHIFT_ONLY) {
-                sp_tweak_switch_mode(tc, TWEAK_MODE_INFLATE);
+                sp_tweak_switch_mode(tc, TWEAK_MODE_GROW);
+                ret = TRUE;
+            }
+            break;
+        case GDK_a:
+        case GDK_A:
+        case GDK_4:
+            if (MOD__SHIFT_ONLY) {
+                sp_tweak_switch_mode(tc, TWEAK_MODE_ATTRACT);
+                ret = TRUE;
+            }
+            break;
+        case GDK_e:
+        case GDK_E:
+        case GDK_5:
+            if (MOD__SHIFT_ONLY) {
+                sp_tweak_switch_mode(tc, TWEAK_MODE_REPEL);
                 ret = TRUE;
             }
             break;
         case GDK_r:
         case GDK_R:
-        case GDK_4:
+        case GDK_6:
             if (MOD__SHIFT_ONLY) {
                 sp_tweak_switch_mode(tc, TWEAK_MODE_ROUGHEN);
                 ret = TRUE;
             }
             break;
+        case GDK_c:
+        case GDK_C:
+        case GDK_7:
+            if (MOD__SHIFT_ONLY) {
+                sp_tweak_switch_mode(tc, TWEAK_MODE_COLORPAINT);
+                ret = TRUE;
+            }
+            break;
+        case GDK_j:
+        case GDK_J:
+        case GDK_8:
+            if (MOD__SHIFT_ONLY) {
+                sp_tweak_switch_mode(tc, TWEAK_MODE_COLORJITTER);
+                ret = TRUE;
+            }
+            break;
 
         case GDK_Up:
         case GDK_KP_Up:
@@ -691,15 +1174,15 @@ sp_tweak_context_root_handler(SPEventContext *event_context,
         case GDK_Control_L:
         case GDK_Control_R:
             if (MOD__SHIFT) {
-                sp_tweak_switch_mode_temporarily(tc, TWEAK_MODE_INFLATE);
+                sp_tweak_switch_mode_temporarily(tc, TWEAK_MODE_GROW);
             } else {
-                sp_tweak_switch_mode_temporarily(tc, TWEAK_MODE_MELT);
+                sp_tweak_switch_mode_temporarily(tc, TWEAK_MODE_SHRINK);
             }
             break;
         case GDK_Shift_L:
         case GDK_Shift_R:
             if (MOD__CTRL) {
-                sp_tweak_switch_mode_temporarily(tc, TWEAK_MODE_INFLATE);
+                sp_tweak_switch_mode_temporarily(tc, TWEAK_MODE_GROW);
             }
             break;
         default:
@@ -717,7 +1200,7 @@ sp_tweak_context_root_handler(SPEventContext *event_context,
             case GDK_Shift_L:
             case GDK_Shift_R:
                 if (MOD__CTRL) {
-                    sp_tweak_switch_mode_temporarily(tc, TWEAK_MODE_MELT);
+                    sp_tweak_switch_mode_temporarily(tc, TWEAK_MODE_SHRINK);
                 }
                 break;
             break;
index 478fe223f7b17a1a7a3617146f69652e47897ab9..8fccaf97000ed9faf6e3a68b3c584658dda63770 100644 (file)
@@ -34,9 +34,13 @@ class SPTweakContextClass;
 
 enum {
     TWEAK_MODE_PUSH,
-    TWEAK_MODE_MELT,
-    TWEAK_MODE_INFLATE,
-    TWEAK_MODE_ROUGHEN
+    TWEAK_MODE_SHRINK,
+    TWEAK_MODE_GROW,
+    TWEAK_MODE_ATTRACT,
+    TWEAK_MODE_REPEL,
+    TWEAK_MODE_ROUGHEN,
+    TWEAK_MODE_COLORPAINT,
+    TWEAK_MODE_COLORJITTER
 };
 
 struct SPTweakContext
@@ -65,6 +69,13 @@ struct SPTweakContext
     bool has_dilated;
     NR::Point last_push;
     SPCanvasItem *dilate_area;
+
+    bool do_h;
+    bool do_s;
+    bool do_l;
+    bool do_o;
+
+       sigc::connection style_set_connection;
 };
 
 struct SPTweakContextClass
index cb2b714d8a3ab69442d12855fa64d6f093515862..7e5de6b512aa879530874802522f0aa6e3bc2913 100644 (file)
@@ -63,6 +63,7 @@
 #include "connector-context.h"
 #include "node-context.h"
 #include "shape-editor.h"
+#include "tweak-context.h"
 #include "sp-rect.h"
 #include "box3d.h"
 #include "box3d-context.h"
@@ -159,7 +160,7 @@ static struct {
     { "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},
+      SP_VERB_CONTEXT_TWEAK_PREFS, "tools.tweak", _("Color/opacity used for color tweaking")},
     { "SPZoomContext",   "zoom_toolbox",   0, sp_zoom_toolbox_prep,              "ZoomToolbar",
       SP_VERB_INVALID, 0, 0},
     { "SPStarContext",   "star_toolbox",   0, sp_star_toolbox_prep,              "StarToolbar",
@@ -245,9 +246,17 @@ static gchar const * ui_descr =
         "    <toolitem action='TweakWidthAction' />"
         "    <toolitem action='TweakForceAction' />"
         "    <separator />"
+        "    <toolitem action='TweakModeLabel' />"
         "    <toolitem action='TweakModeAction' />"
         "    <separator />"
+        "    <toolitem action='TweakChannelsLabel' />"
+        "    <toolitem action='TweakDoH' />"
+        "    <toolitem action='TweakDoS' />"
+        "    <toolitem action='TweakDoL' />"
+        "    <toolitem action='TweakDoO' />"
+        "    <separator />"
         "    <toolitem action='TweakFidelityAction' />"
+        "    <separator />"    
         "    <toolitem action='TweakPressureAction' />"
         "  </toolbar>"
 
@@ -2476,7 +2485,27 @@ static void sp_tweak_pressure_state_changed( GtkToggleAction *act, gpointer data
 
 static void sp_tweak_mode_changed( EgeSelectOneAction *act, GObject *tbl )
 {
-    prefs_set_int_attribute("tools.tweak", "mode", ege_select_one_action_get_active( act ));
+    int mode = ege_select_one_action_get_active( act );
+    prefs_set_int_attribute("tools.tweak", "mode", mode);
+
+    GtkAction *doh = GTK_ACTION(g_object_get_data( tbl, "tweak_doh"));
+    GtkAction *dos = GTK_ACTION(g_object_get_data( tbl, "tweak_dos"));
+    GtkAction *dol = GTK_ACTION(g_object_get_data( tbl, "tweak_dol"));
+    GtkAction *doo = GTK_ACTION(g_object_get_data( tbl, "tweak_doo"));
+    GtkAction *dolabel = GTK_ACTION(g_object_get_data( tbl, "tweak_channels_label"));
+    if (mode == TWEAK_MODE_COLORPAINT || mode == TWEAK_MODE_COLORJITTER) {
+        if (doh) gtk_action_set_sensitive (doh, TRUE);
+        if (dos) gtk_action_set_sensitive (dos, TRUE);
+        if (dol) gtk_action_set_sensitive (dol, TRUE);
+        if (doo) gtk_action_set_sensitive (doo, TRUE);
+        if (dolabel) gtk_action_set_sensitive (dolabel, TRUE);
+    } else {
+        if (doh) gtk_action_set_sensitive (doh, FALSE);
+        if (dos) gtk_action_set_sensitive (dos, FALSE);
+        if (dol) gtk_action_set_sensitive (dol, FALSE);
+        if (doo) gtk_action_set_sensitive (doo, FALSE);
+        if (dolabel) gtk_action_set_sensitive (dolabel, FALSE);
+    }
 }
 
 static void sp_tweak_fidelity_value_changed( GtkAdjustment *adj, GObject *tbl )
@@ -2484,6 +2513,22 @@ static void sp_tweak_fidelity_value_changed( GtkAdjustment *adj, GObject *tbl )
     prefs_set_double_attribute( "tools.tweak", "fidelity", adj->value * 0.01 );
 }
 
+static void tweak_toggle_doh (GtkToggleAction *act, gpointer data) {
+    bool show = gtk_toggle_action_get_active( act );
+    prefs_set_int_attribute ("tools.tweak", "doh",  show ? 1 : 0);
+}
+static void tweak_toggle_dos (GtkToggleAction *act, gpointer data) {
+    bool show = gtk_toggle_action_get_active( act );
+    prefs_set_int_attribute ("tools.tweak", "dos",  show ? 1 : 0);
+}
+static void tweak_toggle_dol (GtkToggleAction *act, gpointer data) {
+    bool show = gtk_toggle_action_get_active( act );
+    prefs_set_int_attribute ("tools.tweak", "dol",  show ? 1 : 0);
+}
+static void tweak_toggle_doo (GtkToggleAction *act, gpointer data) {
+    bool show = gtk_toggle_action_get_active( act );
+    prefs_set_int_attribute ("tools.tweak", "doo",  show ? 1 : 0);
+}
 
 static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObject* holder)
 {
@@ -2518,6 +2563,12 @@ static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
         gtk_action_set_sensitive( GTK_ACTION(eact), TRUE );
     }
 
+    {
+        EgeOutputAction* act = ege_output_action_new( "TweakModeLabel", _("<b>Mode:</b>"), "", 0 );
+        ege_output_action_set_use_markup( act, TRUE );
+        gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );
+    }
+
     /* Mode */
     {
         GtkListStore* model = gtk_list_store_new( 3, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING );
@@ -2526,31 +2577,59 @@ static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
         gtk_list_store_append( model, &iter );
         gtk_list_store_set( model, &iter,
                             0, _("Push mode"),
-                            1, _("Switch to Push mode"),
+                            1, _("Push parts of paths in any direction"),
                             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",
+                            0, _("Shrink mode"),
+                            1, _("Shrink (inset) parts of paths"),
+                            2, "tweak_shrink_mode",
+                            -1 );
+
+        gtk_list_store_append( model, &iter );
+        gtk_list_store_set( model, &iter,
+                            0, _("Grow mode"),
+                            1, _("Grow (outset) parts of paths"),
+                            2, "tweak_grow_mode",
                             -1 );
 
         gtk_list_store_append( model, &iter );
         gtk_list_store_set( model, &iter,
-                            0, _("Inflate mode"),
-                            1, _("Switch to Inflate mode"),
-                            2, "tweak_inflate_mode",
+                            0, _("Attract mode"),
+                            1, _("Attract parts of paths towards cursor"),
+                            2, "tweak_attract_mode",
+                            -1 );
+
+        gtk_list_store_append( model, &iter );
+        gtk_list_store_set( model, &iter,
+                            0, _("Repel mode"),
+                            1, _("Repel parts of paths from cursor"),
+                            2, "tweak_repel_mode",
                             -1 );
 
         gtk_list_store_append( model, &iter );
         gtk_list_store_set( model, &iter,
                             0, _("Roughen mode"),
-                            1, _("Switch to Roughen mode"),
+                            1, _("Roughen parts of paths"),
                             2, "tweak_roughen_mode",
                             -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, "tweak_colorpaint_mode",
+                            -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, "tweak_colorjitter_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 );
@@ -2568,6 +2647,70 @@ static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
         g_object_set_data( G_OBJECT(holder), "tweak_tool_mode", act);
     }
 
+    guint mode = prefs_get_int_attribute("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",
+                                                      _("H"),
+                                                      _("In color mode, act on objects' hue"),
+                                                      NULL,
+                                                      Inkscape::ICON_SIZE_DECORATION );
+        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_get_int_attribute( "tools.tweak", "doh", 1 ) );
+        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",
+                                                      _("S"),
+                                                      _("In color mode, act on objects' saturation"),
+                                                      NULL,
+                                                      Inkscape::ICON_SIZE_DECORATION );
+        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_get_int_attribute( "tools.tweak", "dos", 1 ) );
+        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",
+                                                      _("L"),
+                                                      _("In color mode, act on objects' lightness"),
+                                                      NULL,
+                                                      Inkscape::ICON_SIZE_DECORATION );
+        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_get_int_attribute( "tools.tweak", "dol", 1 ) );
+        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",
+                                                      _("O"),
+                                                      _("In color mode, act on objects' opacity"),
+                                                      NULL,
+                                                      Inkscape::ICON_SIZE_DECORATION );
+        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_get_int_attribute( "tools.tweak", "doo", 1 ) );
+        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};
@@ -2587,7 +2730,7 @@ static void sp_tweak_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainAction
     {
         InkToggleAction* act = ink_toggle_action_new( "TweakPressureAction",
                                                       _("Pressure"),
-                                                      _("Use the pressure of the input device to alter the width of the area"),
+                                                      _("Use the pressure of the input device to alter the force of tweak action"),
                                                       "use_pressure",
                                                       Inkscape::ICON_SIZE_DECORATION );
         gtk_action_group_add_action( mainActions, GTK_ACTION( act ) );