From: cilix42 Date: Sat, 19 Jan 2008 23:31:25 +0000 (+0000) Subject: Make creation of dots via Ctrl+click also possible in pen context; fill dots with... X-Git-Url: https://git.tokkee.org/?a=commitdiff_plain;h=32d45022bee1aac3efef2614be44ea1faf944227;p=inkscape.git Make creation of dots via Ctrl+click also possible in pen context; fill dots with current stroke color (and unset stroke); add preferences settings for dot radius and status bar messages; Shift+Ctrl+click varies the radius slightly --- diff --git a/src/pen-context.cpp b/src/pen-context.cpp index f56714eb7..6eb534e54 100644 --- a/src/pen-context.cpp +++ b/src/pen-context.cpp @@ -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; diff --git a/src/pencil-context.cpp b/src/pencil-context.cpp index f17337183..691dcb098 100644 --- a/src/pencil-context.cpp +++ b/src/pencil-context.cpp @@ -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; diff --git a/src/sp-path.cpp b/src/sp-path.cpp index 4b897158b..29a5910b9 100644 --- a/src/sp-path.cpp +++ b/src/sp-path.cpp @@ -33,6 +33,14 @@ #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++ diff --git a/src/sp-path.h b/src/sp-path.h index bf294c37c..ce701d251 100644 --- a/src/sp-path.h +++ b/src/sp-path.h @@ -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 /* diff --git a/src/tools-switch.cpp b/src/tools-switch.cpp index e4692d91b..c6251fe5b 100644 --- a/src/tools-switch.cpp +++ b/src/tools-switch.cpp @@ -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, _("Drag to create a freehand line. Start drawing with Shift to append to selected path.")); + dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Drag to create a freehand line. Start drawing with Shift to append to selected path. Ctrl+click 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, _("Click or click and drag to start a path; with Shift to append to selected path.")); + dt->tipsMessageContext()->set(Inkscape::NORMAL_MESSAGE, _("Click or click and drag to start a path; with Shift to append to selected path. Ctrl+click to create single dots.")); break; case TOOLS_CALLIGRAPHIC: dt->set_event_context(SP_TYPE_DYNA_DRAW_CONTEXT, tool_names[num]); diff --git a/src/ui/dialog/inkscape-preferences.cpp b/src/ui/dialog/inkscape-preferences.cpp index b0c8bcb85..2f3119108 100644 --- a/src/ui/dialog/inkscape-preferences.cpp +++ b/src/ui/dialog/inkscape-preferences.cpp @@ -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); diff --git a/src/ui/dialog/inkscape-preferences.h b/src/ui/dialog/inkscape-preferences.h index 15d6ee54e..c6c17476d 100644 --- a/src/ui/dialog/inkscape-preferences.h +++ b/src/ui/dialog/inkscape-preferences.h @@ -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();