From 29f9623ba77fc735b89765ae3a13e0c06aabafce Mon Sep 17 00:00:00 2001 From: cilix42 Date: Tue, 15 Jul 2008 12:41:43 +0000 Subject: [PATCH] New LPE FreehandShape derived from PatternAlongPath (for the shapes in pen/pencil context); don't apply shapes each time the selection changes; new functions to test for specific LPE type and if a path can accept a new shape --- src/draw-context.cpp | 21 ++++++++++---------- src/live_effects/effect.cpp | 4 ++++ src/live_effects/effect.h | 1 + src/live_effects/lpe-patternalongpath.cpp | 4 ++++ src/live_effects/lpe-patternalongpath.h | 17 ++++++++++++++++ src/sp-lpe-item.cpp | 24 +++++++++++++++++++++++ src/sp-lpe-item.h | 2 ++ 7 files changed, 63 insertions(+), 10 deletions(-) diff --git a/src/draw-context.cpp b/src/draw-context.cpp index 6831654ea..51938dc9e 100644 --- a/src/draw-context.cpp +++ b/src/draw-context.cpp @@ -248,13 +248,13 @@ sp_draw_context_root_handler(SPEventContext *ec, GdkEvent *event) } static void -spdc_paste_curve_as_param_path(const SPCurve *c, SPDrawContext *dc, SPItem *item) +spdc_paste_curve_as_freehand_shape(const SPCurve *c, SPDrawContext *dc, SPItem *item) { using namespace Inkscape::LivePathEffect; // TODO: Don't paste path if nothing is on the clipboard - Effect::createAndApply(Inkscape::LivePathEffect::PATTERN_ALONG_PATH, dc->desktop->doc(), item); + Effect::createAndApply(Inkscape::LivePathEffect::FREEHAND_SHAPE, dc->desktop->doc(), item); Effect* lpe = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)); gchar *svgd = sp_svg_write_path(c->get_pathvector()); static_cast(lpe)->pattern.paste_param_path(svgd); @@ -269,7 +269,7 @@ spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item) { using namespace Inkscape::LivePathEffect; - if (item) { + if (item && SP_IS_LPE_ITEM(item)) { if (prefs_get_int_attribute("tools.freehand", "spiro-spline-mode", 0)) { Effect::createAndApply(SPIRO, dc->desktop->doc(), item); } @@ -286,7 +286,7 @@ spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item) case 1: { // take shape from clipboard; TODO: catch the case where clipboard is empty - Effect::createAndApply(PATTERN_ALONG_PATH, dc->desktop->doc(), item); + Effect::createAndApply(FREEHAND_SHAPE, dc->desktop->doc(), item); Effect* lpe = sp_lpe_item_get_current_lpe(SP_LPE_ITEM(item)); static_cast(lpe)->pattern.on_paste_button_click(); @@ -303,7 +303,7 @@ spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item) c->lineto(200,10); c->lineto(200,0); c->closepath(); - spdc_paste_curve_as_param_path(c, dc, item); + spdc_paste_curve_as_freehand_shape(c, dc, item); c->unref(); shape_applied = true; @@ -319,7 +319,7 @@ spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item) c->lineto(0,10); c->lineto(200,5); c->closepath(); - spdc_paste_curve_as_param_path(c, dc, item); + spdc_paste_curve_as_freehand_shape(c, dc, item); c->unref(); shape_applied = true; @@ -355,10 +355,6 @@ spdc_check_for_and_apply_waiting_LPE(SPDrawContext *dc, SPItem *item) static void spdc_selection_changed(Inkscape::Selection *sel, SPDrawContext *dc) { - // note: in draw context, selection_changed() is only called with a valid item as argument when - // a new item was created; otherwise the following function call would yield wrong results - spdc_check_for_and_apply_waiting_LPE(dc, sel->singleItem()); - if (dc->attach) { spdc_attach_selection(dc, sel); } @@ -652,6 +648,11 @@ spdc_flush_white(SPDrawContext *dc, SPCurve *gc) item->updateRepr(); } + + // we finished the path; now apply any waiting LPEs or freehand shapes + // FIXME: placing this here seems to cause issues with undo! + spdc_check_for_and_apply_waiting_LPE(dc, dc->selection->singleItem()); + sp_document_done(doc, SP_IS_PEN_CONTEXT(dc)? SP_VERB_CONTEXT_PEN : SP_VERB_CONTEXT_PENCIL, _("Draw path")); diff --git a/src/live_effects/effect.cpp b/src/live_effects/effect.cpp index d5ac6dc74..4c74d56a6 100644 --- a/src/live_effects/effect.cpp +++ b/src/live_effects/effect.cpp @@ -72,6 +72,7 @@ const Util::EnumData LPETypeData[INVALID_LPE] = { // {constant defined in effect.h, N_("name of your effect"), "name of your effect in SVG"} {BEND_PATH, N_("Bend"), "bend_path"}, {PATTERN_ALONG_PATH, N_("Pattern Along Path"), "skeletal"}, // for historic reasons, this effect is called skeletal(strokes) in Inkscape:SVG + {FREEHAND_SHAPE, N_("Freehand Shape"), "freehand_shape"}, // this is actually a special type of PatternAlongPath, used to paste shapes in pen/pencil tool {SKETCH, N_("Sketch"), "sketch"}, {VONKOCH, N_("VonKoch"), "vonkoch"}, {KNOT, N_("Knot"), "knot"}, @@ -106,6 +107,9 @@ Effect::New(EffectType lpenr, LivePathEffectObject *lpeobj) case PATTERN_ALONG_PATH: neweffect = static_cast ( new LPEPatternAlongPath(lpeobj) ); break; + case FREEHAND_SHAPE: + neweffect = static_cast ( new LPEFreehandShape(lpeobj) ); + break; case BEND_PATH: neweffect = static_cast ( new LPEBendPath(lpeobj) ); break; diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h index eced0a194..fbaf8f867 100644 --- a/src/live_effects/effect.h +++ b/src/live_effects/effect.h @@ -53,6 +53,7 @@ namespace LivePathEffect { enum EffectType { BEND_PATH = 0, PATTERN_ALONG_PATH, + FREEHAND_SHAPE, SKETCH, VONKOCH, KNOT, diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp index 2e10efe7a..30ec589af 100644 --- a/src/live_effects/lpe-patternalongpath.cpp +++ b/src/live_effects/lpe-patternalongpath.cpp @@ -7,6 +7,7 @@ */ #include "live_effects/lpe-patternalongpath.h" +#include "live_effects/lpeobject.h" #include "sp-shape.h" #include "display/curve.h" #include @@ -203,6 +204,9 @@ LPEPatternAlongPath::transform_multiply(Geom::Matrix const& postmul, bool set) Effect::transform_multiply(postmul, set); } +LPEFreehandShape::LPEFreehandShape(LivePathEffectObject *lpeobject) : LPEPatternAlongPath(lpeobject) +{ +} } // namespace LivePathEffect } /* namespace Inkscape */ diff --git a/src/live_effects/lpe-patternalongpath.h b/src/live_effects/lpe-patternalongpath.h index 341f99454..10b9e8bc2 100644 --- a/src/live_effects/lpe-patternalongpath.h +++ b/src/live_effects/lpe-patternalongpath.h @@ -51,7 +51,24 @@ private: LPEPatternAlongPath& operator=(const LPEPatternAlongPath&); }; +class LPEFreehandShape : public LPEPatternAlongPath { +public: + LPEFreehandShape(LivePathEffectObject *lpeobject); + virtual ~LPEFreehandShape() {} +}; + }; //namespace LivePathEffect }; //namespace Inkscape #endif + +/* + Local Variables: + mode:c++ + c-file-style:"stroustrup" + c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) + indent-tabs-mode:nil + fill-column:99 + End: +*/ +// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 : diff --git a/src/sp-lpe-item.cpp b/src/sp-lpe-item.cpp index 3cb022f5b..229ae326e 100644 --- a/src/sp-lpe-item.cpp +++ b/src/sp-lpe-item.cpp @@ -574,6 +574,30 @@ bool sp_lpe_item_has_path_effect_recursive(SPLPEItem *lpeitem) } } +Inkscape::LivePathEffect::Effect* +sp_lpe_item_has_path_effect_of_type(SPLPEItem *lpeitem, int type) +{ + std::list::iterator i; + for (i = lpeitem->path_effect_list->begin(); i != lpeitem->path_effect_list->end(); ++i) { + if ((*i)->lpeobject->lpe->effectType() == type) { + return (*i)->lpeobject->lpe; + } + } + return NULL; +} + +/* Return false if the item is not a path or already has a shape applied */ +bool sp_lpe_item_can_accept_freehand_shape(SPLPEItem *lpeitem) +{ + if (!SP_IS_PATH(lpeitem)) + return false; + + if (sp_lpe_item_has_path_effect_of_type(lpeitem, Inkscape::LivePathEffect::FREEHAND_SHAPE)) + return false; + + return true; +} + void sp_lpe_item_edit_next_param_oncanvas(SPLPEItem *lpeitem, SPDesktop *dt) { Inkscape::LivePathEffect::LPEObjectReference *lperef = sp_lpe_item_get_current_lpereference(lpeitem); diff --git a/src/sp-lpe-item.h b/src/sp-lpe-item.h index 54642f27b..c92616cca 100644 --- a/src/sp-lpe-item.h +++ b/src/sp-lpe-item.h @@ -68,6 +68,8 @@ void sp_lpe_item_down_current_path_effect(SPLPEItem *lpeitem); void sp_lpe_item_up_current_path_effect(SPLPEItem *lpeitem); bool sp_lpe_item_has_path_effect(SPLPEItem *lpeitem); bool sp_lpe_item_has_path_effect_recursive(SPLPEItem *lpeitem); +Inkscape::LivePathEffect::Effect* sp_lpe_item_has_path_effect_of_type(SPLPEItem *lpeitem, int type); +bool sp_lpe_item_can_accept_freehand_shape(SPLPEItem *lpeitem); void sp_lpe_item_edit_next_param_oncanvas(SPLPEItem *lpeitem, SPDesktop *dt); PathEffectList sp_lpe_item_get_effect_list(SPLPEItem *lpeitem); Inkscape::LivePathEffect::LPEObjectReference* sp_lpe_item_get_current_lpereference(SPLPEItem *lpeitem); -- 2.30.2