Code

Make creation of dots via Ctrl+click also possible in pen context; fill dots with...
authorcilix42 <cilix42@users.sourceforge.net>
Sat, 19 Jan 2008 23:31:25 +0000 (23:31 +0000)
committercilix42 <cilix42@users.sourceforge.net>
Sat, 19 Jan 2008 23:31:25 +0000 (23:31 +0000)
src/pen-context.cpp
src/pencil-context.cpp
src/sp-path.cpp
src/sp-path.h
src/tools-switch.cpp
src/ui/dialog/inkscape-preferences.cpp
src/ui/dialog/inkscape-preferences.h

index f56714eb79fc6ec9bfb8b453e68d606b96c26661..6eb534e54aa9b7423079b8632a78416222eff8ff 100644 (file)
@@ -408,6 +408,12 @@ static gint pen_handle_button_press(SPPenContext *const pc, GdkEventButton const
                     case SP_PEN_CONTEXT_POINT:
                         if (pc->npoints == 0) {
 
+                            if (bevent.state & GDK_CONTROL_MASK) {
+                                freehand_create_single_dot(event_context, event_dt, "tools.freehand.pen", bevent.state & GDK_SHIFT_MASK);
+                                ret = TRUE;
+                                break;
+                            }
+
                             /* Set start anchor */
                             pc->sa = anchor;
                             NR::Point p;
index f173371838c0c680d1cfa5310f0bf35eae0cd839..691dcb0986c7e3917a5901cb8b6a2a89ed9b59ac 100644 (file)
@@ -229,28 +229,9 @@ pencil_handle_button_press(SPPencilContext *const pc, GdkEventButton const &beve
             default:
                 /* Set first point of sequence */
                 if (bevent.state & GDK_CONTROL_MASK) {
-                    /* Create object */
-                    Inkscape::XML::Document *xml_doc = sp_document_repr_doc(desktop->doc());
-                    Inkscape::XML::Node *repr = xml_doc->createElement("svg:path");
-                    repr->setAttribute("sodipodi:type", "arc");
-                    SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr));
-                    Inkscape::GC::release(repr);
-                    NR::Matrix const i2d (sp_item_i2d_affine (item));
-                    NR::Point pp = p * i2d;
-                    sp_repr_set_svg_double (repr, "sodipodi:cx", pp[NR::X]);
-                    sp_repr_set_svg_double (repr, "sodipodi:cy", pp[NR::Y]);
-                    sp_repr_set_int (repr, "sodipodi:rx", 10);
-                    sp_repr_set_int (repr, "sodipodi:ry", 10);
-
-                    /* Set style */
-                    sp_desktop_apply_style_tool(desktop, repr, "tools.shapes.arc", false);
-
-                    item->updateRepr();
-                    desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating single point"));
-                    sp_document_done(sp_desktop_document(desktop), SP_VERB_CONTEXT_PENCIL, _("Create single point"));
+                    freehand_create_single_dot(event_context, p, "tools.freehand.pencil", bevent.state & GDK_SHIFT_MASK);
                     ret = true;
                     break;
-                    
                 }
                 if (anchor) {
                     p = anchor->dp;
index 4b897158b3074f36d0306fd08622e19a94fb5ab1..29a5910b94184f23759470fc20433af942f6baaa 100644 (file)
 #include "sp-guide.h"
 
 #include "document.h"
+#include "desktop.h"
+#include "desktop-handles.h"
+#include "desktop-style.h"
+#include "event-context.h"
+#include "inkscape.h"
+#include "style.h"
+#include "message-stack.h"
+#include "prefs-utils.h"
 
 #define noPATH_VERBOSE
 
@@ -503,6 +511,62 @@ sp_path_get_curve_reference (SPPath *path)
     }
 }
 
+/* Create a single dot represented by a circle */
+void freehand_create_single_dot(SPEventContext *ec, NR::Point const &pt, char const *tool, bool randomize) {
+    g_return_if_fail(!strcmp(tool, "tools.freehand.pen") || !strcmp(tool, "tools.freehand.pencil"));
+
+    SPDesktop *desktop = SP_EVENT_CONTEXT_DESKTOP(ec);
+    Inkscape::XML::Document *xml_doc = sp_document_repr_doc(desktop->doc());
+    Inkscape::XML::Node *repr = xml_doc->createElement("svg:path");
+    repr->setAttribute("sodipodi:type", "arc");
+    SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr));
+    Inkscape::GC::release(repr);
+
+    /* apply the tool's current style */
+    sp_desktop_apply_style_tool(desktop, repr, tool, false);
+
+    /* find out stroke width (TODO: is there an easier way??) */
+    double stroke_width = 3.0;
+    gchar const *style_str = NULL;
+    style_str = repr->attribute("style");
+    if (style_str) {
+        SPStyle *style = sp_style_new(SP_ACTIVE_DOCUMENT);
+        sp_style_merge_from_style_string(style, style_str);
+        stroke_width = style->stroke_width.computed;
+        style->stroke_width.computed = 0;
+        sp_style_unref(style);
+    }
+    /* unset stroke and set fill color to former stroke color */
+    gchar * str;
+    str = g_strdup_printf("fill:#%06x;stroke:none;", sp_desktop_get_color_tool(desktop, tool, false) >> 8);
+    repr->setAttribute("style", str);
+    g_free(str);
+
+    /* put the circle where the mouse click occurred and set the diameter to the
+       current stroke width, multiplied by the amount specified in the preferences */
+    NR::Matrix const i2d (sp_item_i2d_affine (item));
+    NR::Point pp = pt * i2d;
+    double rad = 0.5 * prefs_get_double_attribute(tool, "dot-size", 3.0);
+    if (randomize) {
+        /* TODO: We vary the dot size between 0.5*rad and 1.5*rad, where rad is the dot size
+           as specified in prefs. Very simple, but it might be sufficient in practice. If not,
+           we need to devise something more sophisticated. */
+        double s = g_random_double_range(-0.5, 0.5);
+        rad *= (1 + s);
+    }
+
+    sp_repr_set_svg_double (repr, "sodipodi:cx", pp[NR::X]);
+    sp_repr_set_svg_double (repr, "sodipodi:cy", pp[NR::Y]);
+    sp_repr_set_svg_double (repr, "sodipodi:rx", rad * stroke_width);
+    sp_repr_set_svg_double (repr, "sodipodi:ry", rad * stroke_width);
+    item->updateRepr();
+
+    unsigned int tool_code = !strcmp(tool, "tools.freehand.pencil") ? SP_VERB_CONTEXT_PENCIL : SP_VERB_CONTEXT_PEN;
+
+    desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Creating single dot"));
+    sp_document_done(sp_desktop_document(desktop), tool_code, _("Create single dot"));
+}
+
 /*
   Local Variables:
   mode:c++
index bf294c37ceebedf980d5af97eae31be309292e27..ce701d251a60e4627f42578a722d86318c09bcf4 100644 (file)
@@ -39,6 +39,8 @@ SPCurve* sp_path_get_original_curve (SPPath *path);
 SPCurve* sp_path_get_curve_for_edit (SPPath *path);
 const SPCurve* sp_path_get_curve_reference (SPPath *path);
 
+void freehand_create_single_dot(SPEventContext *ec, NR::Point const &pt, char const *tool, bool randomize = false);
+
 #endif
 
 /*
index e4692d91b85e878242d2b51f0e4117816f36a5b2..c6251fe5bd77595ddb711b41cc1a6a1d70deaadd 100644 (file)
@@ -184,13 +184,13 @@ tools_switch(SPDesktop *dt, int num)
             dt->set_event_context(SP_TYPE_PENCIL_CONTEXT, tool_names[num]);
             dt->activate_guides(false);
             inkscape_eventcontext_set(sp_desktop_event_context(dt));
-            dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag</b> to create a freehand line. Start drawing with <b>Shift</b> to append to selected path."));
+            dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Drag</b> to create a freehand line. Start drawing with <b>Shift</b> to append to selected path. <b>Ctrl+click</b> to create single dots."));
             break;
         case TOOLS_FREEHAND_PEN:
             dt->set_event_context(SP_TYPE_PEN_CONTEXT, tool_names[num]);
             dt->activate_guides(false);
             inkscape_eventcontext_set(sp_desktop_event_context(dt));
-            dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Click</b> or <b>click and drag</b> to start a path; with <b>Shift</b> to append to selected path."));
+            dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("<b>Click</b> or <b>click and drag</b> to start a path; with <b>Shift</b> to append to selected path. <b>Ctrl+click</b> to create single dots."));
             break;
         case TOOLS_CALLIGRAPHIC:
             dt->set_event_context(SP_TYPE_DYNA_DRAW_CONTEXT, tool_names[num]);
index b0c8bcb85fedda751d74d478977b364eef534472..2f31191081e5e92bc75aeed20b0c7a24c9b6210d 100644 (file)
@@ -235,6 +235,16 @@ void InkscapePreferences::AddConvertGuidesCheckbox(DialogPage& p, const std::str
     p.add_line( false, "", *cb, "", _("Converting an object to guides places these along the object's true edges (imitating the object's shape), not along the bounding box."));
 }
 
+void InkscapePreferences::AddDotSizeSpinbutton(DialogPage& p, const std::string& prefs_path, double def_value)
+{
+    PrefSpinButton* sb = Gtk::manage( new PrefSpinButton);
+    sb->init ( prefs_path, "dot-size", 0.0, 1000.0, 0.1, 10.0, def_value, false, false);
+    p.add_line( false, _("Dot size:"), *sb, "times current stroke width", 
+                       _("Size of dots created with Ctrl+click (relative to current stroke width)"),
+                       false );
+}
+
+
 void StyleFromSelectionToTool(gchar const *prefs_path, StyleSwatch *swatch)
 {
     SPDesktop *desktop = SP_ACTIVE_DESKTOP;
@@ -406,10 +416,12 @@ void InkscapePreferences::initPageTools()
     _page_pencil.add_line( false, _("Tolerance:"), _t_pencil_tolerance, "", 
                            _("This value affects the amount of smoothing applied to freehand lines; lower values produce more uneven paths with more nodes"),
                            false );
+    this->AddDotSizeSpinbutton(_page_pencil, "tools.freehand.pencil", 3.0);
     this->AddNewObjectsStyle(_page_pencil, "tools.freehand.pencil");
     //Pen
     this->AddPage(_page_pen, _("Pen"), iter_tools, PREFS_PAGE_TOOLS_PEN);
     this->AddSelcueCheckbox(_page_pen, "tools.freehand.pen", true);
+    this->AddDotSizeSpinbutton(_page_pen, "tools.freehand.pen", 3.0);
     this->AddNewObjectsStyle(_page_pen, "tools.freehand.pen");
     //Calligraphy
     this->AddPage(_page_calligraphy, _("Calligraphy"), iter_tools, PREFS_PAGE_TOOLS_CALLIGRAPHY);
index 15d6ee54e7eb661276337835b027ed94a81dab6d..c6c17476d9166cc58211db00307ba5d3feb796c6 100644 (file)
@@ -218,6 +218,7 @@ protected:
     static void AddSelcueCheckbox(DialogPage& p, const std::string& prefs_path, bool def_value);
     static void AddGradientCheckbox(DialogPage& p, const std::string& prefs_path, bool def_value);
     static void AddConvertGuidesCheckbox(DialogPage& p, const std::string& prefs_path, bool def_value);
+    static void AddDotSizeSpinbutton(DialogPage& p, const std::string& prefs_path, double def_value);
     static void AddNewObjectsStyle(DialogPage& p, const std::string& prefs_path);
 
     void on_pagelist_selection_changed();