summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabiertxof <jtx@jtx>2016-12-05 14:04:19 +0000
committerJabiertxof <jtx@jtx>2016-12-05 14:04:19 +0000
commit4839ba469180e32f7bff635c3f0a4b436511bf3b (patch)
treeaa38b7ab01a4992bdee2476c0a7103de0b42d227 /src
parentUpdate to trunk (diff)
downloadinkscape-4839ba469180e32f7bff635c3f0a4b436511bf3b.tar.gz
inkscape-4839ba469180e32f7bff635c3f0a4b436511bf3b.zip
Added rough mirror improvements, things to fix
(bzr r15295.1.3)
Diffstat (limited to 'src')
-rw-r--r--src/live_effects/effect.h8
-rw-r--r--src/live_effects/lpe-measure-line.h6
-rw-r--r--src/live_effects/lpe-mirror_symmetry.cpp230
-rw-r--r--src/live_effects/lpe-mirror_symmetry.h18
4 files changed, 158 insertions, 104 deletions
diff --git a/src/live_effects/effect.h b/src/live_effects/effect.h
index 06aa075eb..28a1a4e8e 100644
--- a/src/live_effects/effect.h
+++ b/src/live_effects/effect.h
@@ -44,6 +44,12 @@ enum LPEPathFlashType {
DEFAULT
};
+enum LpeAction {
+ LPE_ERASE = 0,
+ LPE_TO_OBJECTS,
+ LPE_VISIBILITY
+};
+
class Effect {
public:
static Effect* New(EffectType lpenr, LivePathEffectObject *lpeobj);
@@ -125,6 +131,7 @@ public:
bool apply_to_clippath_and_mask;
bool erase_extra_objects; // set this to false allow retain extra generated objects, see measure line LPE
bool upd_params;
+ BoolParam is_visible;
protected:
Effect(LivePathEffectObject *lpeobject);
@@ -150,7 +157,6 @@ protected:
bool _provides_knotholder_entities;
int oncanvasedit_it;
- BoolParam is_visible;
bool show_orig_path; // set this to true in derived effects to automatically have the original
// path displayed as helperpath
diff --git a/src/live_effects/lpe-measure-line.h b/src/live_effects/lpe-measure-line.h
index a05189039..d668fbd30 100644
--- a/src/live_effects/lpe-measure-line.h
+++ b/src/live_effects/lpe-measure-line.h
@@ -32,12 +32,6 @@ enum OrientationMethod {
OM_END
};
-enum LpeAction {
- LPE_ERASE = 0,
- LPE_TO_OBJECTS,
- LPE_VISIBILITY
-};
-
class LPEMeasureLine : public Effect {
public:
LPEMeasureLine(LivePathEffectObject *lpeobject);
diff --git a/src/live_effects/lpe-mirror_symmetry.cpp b/src/live_effects/lpe-mirror_symmetry.cpp
index e62dbbca9..f420c7e69 100644
--- a/src/live_effects/lpe-mirror_symmetry.cpp
+++ b/src/live_effects/lpe-mirror_symmetry.cpp
@@ -40,7 +40,7 @@ static const Util::EnumData<ModeType> ModeTypeData[MT_END] = {
static const Util::EnumDataConverter<ModeType>
MTConverter(ModeTypeData, MT_END);
-std::vector<Glib::ustring> ms_elements;
+std::vector<gchar *> ms_elements;
SPObject * ms_container;
namespace MS {
@@ -52,45 +52,38 @@ public:
virtual Geom::Point knot_get() const;
};
-class KnotHolderEntityStartMirrorSymmetry : public LPEKnotHolderEntity {
-public:
- KnotHolderEntityStartMirrorSymmetry(LPEMirrorSymmetry *effect) : LPEKnotHolderEntity(effect){};
- virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
- virtual Geom::Point knot_get() const;
-};
-
-class KnotHolderEntityEndMirrorSymmetry : public LPEKnotHolderEntity {
-public:
- KnotHolderEntityEndMirrorSymmetry(LPEMirrorSymmetry *effect) : LPEKnotHolderEntity(effect){};
- virtual void knot_set(Geom::Point const &p, Geom::Point const &origin, guint state);
- virtual Geom::Point knot_get() const;
-};
-
} // namespace MS
LPEMirrorSymmetry::LPEMirrorSymmetry(LivePathEffectObject *lpeobject) :
Effect(lpeobject),
mode(_("Mode"), _("Symmetry move mode"), "mode", MTConverter, &wr, this, MT_FREE),
+ split_gap(_("Gap on split"), _("Gap on split"), "split_gap", &wr, this, 0),
discard_orig_path(_("Discard original path?"), _("Check this to only keep the mirrored part of the path"), "discard_orig_path", &wr, this, false),
fuse_paths(_("Fuse paths"), _("Fuse original and the reflection into a single path"), "fuse_paths", &wr, this, false),
oposite_fuse(_("Opposite fuse"), _("Picks the other side of the mirror as the original"), "oposite_fuse", &wr, this, false),
- split(_("Split elements"), _("Split elements, this allow gradients and other paints"), "split", &wr, this, false),
- split_sensitive(_("Make split selectable"), _("Allow select splited elements"), "split", &wr, this, false),
- split_style(_("Make splits with style"), _("Allow Change colors to split"), "split", &wr, this, false),
+ split_elements(_("Split elements"), _("Split elements, this allow gradients and other paints"), "split_elements", &wr, this, false),
+ split_sensitive(_("Make split selectable"), _("Allow select splited elements"), "split_sensitive", &wr, this, false),
start_point(_("Start mirror line"), _("Start mirror line"), "start_point", &wr, this, "Adjust the start of mirroring"),
- end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, "Adjust end of mirroring")
+ end_point(_("End mirror line"), _("End mirror line"), "end_point", &wr, this, "Adjust end of mirroring"),
+ id_origin("id_origin", "id_origin", "id_origin", &wr, this,"")
{
show_orig_path = true;
registerParameter(&mode);
+ registerParameter( &split_gap);
registerParameter( &discard_orig_path);
registerParameter( &fuse_paths);
registerParameter( &oposite_fuse);
- registerParameter( &split);
- registerParameter( &split_sensitive);
- registerParameter( &split_style);
+ registerParameter( &split_elements);
+ //registerParameter( &split_sensitive);
registerParameter( &start_point);
registerParameter( &end_point);
+ registerParameter( &id_origin);
+ id_origin.param_hide_canvas_text();
+ split_gap.param_set_range(-999999.0, 999999.0);
+ split_gap.param_set_increments(0.1, 0.1);
+ split_gap.param_set_digits(2);
apply_to_clippath_and_mask = true;
+ actual = true;
}
LPEMirrorSymmetry::~LPEMirrorSymmetry()
@@ -98,14 +91,30 @@ LPEMirrorSymmetry::~LPEMirrorSymmetry()
}
void
-
LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem)
{
+ SPLPEItem * splpeitem = const_cast<SPLPEItem *>(lpeitem);
+ if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) {
+ Inkscape::Selection *sel = desktop->getSelection();
+ if ( sel && !sel->isEmpty() ) {
+ SPItem *item = sel->singleItem();
+ if (item) {
+ if(std::strcmp(splpeitem->getId(),item->getId()) != 0) {
+ actual = false;
+ return;
+ }
+ } else {
+
+ }
+ }
+ }
+
using namespace Geom;
original_bbox(lpeitem);
+ Geom::Affine m = Geom::identity();//lpeitem->transform;
Point point_a(boundingbox_X.max(), boundingbox_Y.min());
Point point_b(boundingbox_X.max(), boundingbox_Y.max());
- Point point_c(boundingbox_X.max(), boundingbox_Y.middle());
+ gchar * id = g_strdup(((Glib::ustring)"mirror-" + (Glib::ustring)id_origin.param_getSVGValue() + (Glib::ustring)"-" + (Glib::ustring)this->getRepr()->attribute("id")).c_str());
if (mode == MT_Y) {
point_a = Geom::Point(boundingbox_X.min(),center_point[Y]);
point_b = Geom::Point(boundingbox_X.max(),center_point[Y]);
@@ -157,8 +166,7 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem)
}
}
previous_center = center_point;
- if (split) {
- SPLPEItem * splpeitem = const_cast<SPLPEItem *>(lpeitem);
+ if (split_elements) {
ms_container = dynamic_cast<SPObject *>(splpeitem->parent);
SPDocument * doc = SP_ACTIVE_DOCUMENT;
Inkscape::XML::Node *root = splpeitem->document->getReprRoot();
@@ -166,9 +174,16 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem)
if (root_origin != root) {
return;
}
+// if (std::strcmp(splpeitem->getId(), id) == 0) {
+// Geom::Affine affine = Geom::identity();
+// affine *= Geom::Translate(center_point).inverse();
+// affine *= Geom::Rotate(Geom::rad_from_deg(180));
+// affine *= Geom::Translate(center_point);
+// line_separation *= affine;
+// }
Geom::Point point_a(line_separation.initialPoint());
Geom::Point point_b(line_separation.finalPoint());
-
+ Geom::Point gap = Geom::Point(split_gap,0);
Geom::Translate m1(point_a[0], point_a[1]);
double hyp = Geom::distance(point_a, point_b);
double cos = 0;
@@ -178,76 +193,80 @@ LPEMirrorSymmetry::doBeforeEffect (SPLPEItem const* lpeitem)
sin = (point_b[1] - point_a[1]) / hyp;
}
Geom::Affine m2(cos, -sin, sin, cos, 0.0, 0.0);
+ gap *= m2;
Geom::Scale sca(1.0, -1.0);
-
- Geom::Affine m = m1.inverse() * m2;
+ if (std::strcmp(splpeitem->getId(), id) == 0) {
+ id = id_origin.param_getSVGValue();
+ }
+ m = m1.inverse() * m2;
m = m * sca;
m = m * m2.inverse();
m = m * m1;
- createPhantom(splpeitem , (Glib::ustring) "origin-clon-", split_style);
- createClone(splpeitem , m, (Glib::ustring) "clon-");
+ m = m * gap;
+ m = m * lpeitem->transform;
+ ms_elements.clear();
+ createMirror(splpeitem, m, id);
+ } else {
+ processObjects(LPE_ERASE);
}
}
void
-LPEMirrorSymmetry::createPhantom(SPLPEItem *origin, Glib::ustring id, bool styling)
+LPEMirrorSymmetry::cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, char const * first_attribute, ...)
{
- if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) {
- Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc();
- id = id + (Glib::ustring)this->getRepr()->attribute("id");
- Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str());
- Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc());
- SVGElemRef->attach(SVGElem_uri);
- SPObject *elemref = NULL;
- Inkscape::XML::Node *phantom = origin->getRepr()->duplicate(xml_doc);
- if (elemref = SVGElemRef->getObject()) {
- elemref->deleteObject();
- }
- if (styling) {
- SPCSSAttr *css = sp_repr_css_attr_new();
- sp_repr_css_set_property (css, "fill", NULL);
- sp_repr_css_set_property (css, "stroke",NULL);
- Glib::ustring css_str;
- sp_repr_css_write_string(css,css_str);
- sp_repr_css_change_recursive (phantom, css, css_str.c_str());
+ va_list args;
+ va_start(args, first_attribute);
+
+ if ( origin->name() == "svg:g" && origin->childCount() == dest->childCount() ) {
+ Inkscape::XML::Node * node_it = origin->firstChild();
+ size_t index = 0;
+ while (node_it != origin->lastChild()) {
+ cloneAttrbutes(node_it, dest->nthChild(index), first_attribute, args);
+ node_it = node_it->next();
+ index++;
}
- phantom->setAttribute("id", id);
- phantom->setAttribute("inkscape:path-effect", NULL);
- SP_OBJECT(desktop->getDocument()->getDefs()->appendChildRepr(phantom));
- Inkscape::GC::release(phantom);
- ms_elements.push_back(id);
}
+ while(char const * att = va_arg(args, char const *)) {
+ dest->setAttribute(att,origin->attribute(att));
+ }
+ va_end(args);
}
void
-LPEMirrorSymmetry::createClone(SPLPEItem *origin, Geom::Affine transform, Glib::ustring id)
+LPEMirrorSymmetry::createMirror(SPLPEItem *origin, Geom::Affine transform, gchar * id)
{
if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) {
Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc();
- id = id + (Glib::ustring)this->getRepr()->attribute("id");
Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str());
Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc());
SVGElemRef->attach(SVGElem_uri);
- SPObject *elemref = NULL;
- Inkscape::XML::Node *use = NULL;
- use = xml_doc->createElement("svg:use");
- use->setAttribute("transform" , sp_svg_transform_write(transform));
- use->setAttribute("xlink:href", ((Glib::ustring)"#origin-" + id).c_str());
- use->setAttribute("width", "100%");
- use->setAttribute("height", "100%");
- use->setAttribute("id", id);
- use->setAttribute("x", "0");
- use->setAttribute("y", "0");
- if (split_sensitive) {
- use->setAttribute("sodipodi:insensitive" , "false");
+ SPObject *elemref= NULL;
+ Inkscape::XML::Node *phantom = NULL;
+ if (elemref = SVGElemRef->getObject()) {
+ phantom = elemref->getRepr();
} else {
- use->setAttribute("sodipodi:insensitive" , "true");
+ phantom = origin->getRepr()->duplicate(xml_doc);
}
- if (elemref) {
+ cloneAttrbutes(origin->getRepr(), phantom, "inkscape:original-d");
+ phantom->setAttribute("id", id);
+ // if (std::strcmp(id, id_origin.param_getSVGValue()) != 0) {
+ phantom->setAttribute("transform" , sp_svg_transform_write(transform));
+
+// if (split_sensitive) {
+// phantom->setAttribute("sodipodi:insensitive" , NULL);
+// } else {
+// phantom->setAttribute("sodipodi:insensitive" , "true");
+// }
+ if (!elemref) {
+ elemref = ms_container->appendChildRepr(phantom);
+ Inkscape::GC::release(phantom);
+ } else if (elemref->parent != ms_container) {
+ Inkscape::XML::Node *copy = phantom->duplicate(xml_doc);
+ ms_container->appendChildRepr(copy);
+ Inkscape::GC::release(copy);
elemref->deleteObject();
+ copy->setAttribute("id", id);
}
- elemref = ms_container->appendChildRepr(use);
- Inkscape::GC::release(use);
ms_elements.push_back(id);
}
}
@@ -274,9 +293,9 @@ void
LPEMirrorSymmetry::processObjects(LpeAction lpe_action)
{
if (SPDesktop *desktop = SP_ACTIVE_DESKTOP) {
- for (std::vector<Glib::ustring>::iterator el_it = ms_elements.begin();
+ for (std::vector<gchar *>::iterator el_it = ms_elements.begin();
el_it != ms_elements.end();++el_it) {
- Glib::ustring id = *el_it;
+ gchar * id = *el_it;
Inkscape::URI SVGElem_uri(((Glib::ustring)"#" + id).c_str());
Inkscape::URIReference* SVGElemRef = new Inkscape::URIReference(desktop->doc());
SVGElemRef->attach(SVGElem_uri);
@@ -285,6 +304,7 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action)
switch (lpe_action){
case LPE_TO_OBJECTS:
elemref->getRepr()->setAttribute("sodipodi:insensitive", NULL);
+ SP_LPE_ITEM(elemref)->removeAllPathEffects(true);
break;
case LPE_ERASE:
elemref->deleteObject();
@@ -309,12 +329,14 @@ LPEMirrorSymmetry::processObjects(LpeAction lpe_action)
void
LPEMirrorSymmetry::transform_multiply(Geom::Affine const& postmul, bool set)
{
- center_point *= postmul;
- previous_center = center_point;
- // cycle through all parameters. Most parameters will not need transformation, but path and point params do.
- for (std::vector<Parameter *>::iterator it = param_vector.begin(); it != param_vector.end(); ++it) {
- Parameter * param = *it;
- param->param_transform_multiply(postmul, set);
+ if( !split_elements) {
+ center_point *= postmul;
+ previous_center = center_point;
+ // cycle through all parameters. Most parameters will not need transformation, but path and point params do.
+ for (std::vector<Parameter *>::iterator it = param_vector.begin(); it != param_vector.end(); ++it) {
+ Parameter * param = *it;
+ param->param_transform_multiply(postmul, set);
+ }
}
}
@@ -334,13 +356,14 @@ LPEMirrorSymmetry::doOnApply (SPLPEItem const* lpeitem)
end_point.param_update_default(point_b);
center_point = point_c;
previous_center = center_point;
+ id_origin.param_setValue((Glib::ustring)lpeitem->getId());
}
Geom::PathVector
LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in)
{
- if (split && !fuse_paths) {
+ if (split_elements && !fuse_paths) {
return path_in;
}
Geom::PathVector const original_pathv = pathv_to_linear_and_cubic_beziers(path_in);
@@ -369,7 +392,7 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in)
m = m * m2.inverse();
m = m * m1;
- if (fuse_paths && (!discard_orig_path || split )) {
+ if (fuse_paths && (!discard_orig_path || split_elements )) {
for (Geom::PathVector::const_iterator path_it = original_pathv.begin();
path_it != original_pathv.end(); ++path_it)
{
@@ -420,7 +443,7 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in)
}
if (position == 1) {
Geom::Path mirror = portion.reversed() * m;
- if (split) {
+ if (split_elements) {
portion.close();
} else {
mirror.setInitial(portion.finalPoint());
@@ -446,9 +469,7 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in)
Geom::Path portion = original.portion(time_start, original.size());
if (!portion.empty()) {
portion = portion.reversed();
- if (split) {
-
- } else {
+ if (!split_elements) {
Geom::Path mirror = portion.reversed() * m;
mirror.setInitial(portion.finalPoint());
portion.append(mirror);
@@ -486,6 +507,41 @@ LPEMirrorSymmetry::doEffect_path (Geom::PathVector const & path_in)
return path_out;
}
+
+Gtk::Widget *LPEMirrorSymmetry::newWidget()
+{
+ // use manage here, because after deletion of Effect object, others might
+ // still be pointing to this widget.
+ Gtk::VBox *vbox = Gtk::manage(new Gtk::VBox(Effect::newWidget()));
+
+ vbox->set_border_width(5);
+ vbox->set_homogeneous(false);
+ vbox->set_spacing(2);
+
+ std::vector<Parameter *>::iterator it = param_vector.begin();
+ while (it != param_vector.end()) {
+ if ((*it)->widget_is_visible) {
+ Parameter *param = *it;
+ Gtk::Widget *widg = dynamic_cast<Gtk::Widget *>(param->param_newWidget());
+ Glib::ustring *tip = param->param_getTooltip();
+ if (widg) {
+ if (param->param_key != "id_origin") {
+ vbox->pack_start(*widg, true, true, 2);
+ if (tip) {
+ widg->set_tooltip_text(*tip);
+ } else {
+ widg->set_tooltip_text("");
+ widg->set_has_tooltip(false);
+ }
+ }
+ }
+ }
+
+ ++it;
+ }
+ return dynamic_cast<Gtk::Widget *>(vbox);
+}
+
void
LPEMirrorSymmetry::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec)
{
diff --git a/src/live_effects/lpe-mirror_symmetry.h b/src/live_effects/lpe-mirror_symmetry.h
index 70c82e330..00bc45488 100644
--- a/src/live_effects/lpe-mirror_symmetry.h
+++ b/src/live_effects/lpe-mirror_symmetry.h
@@ -17,6 +17,7 @@
*/
#include <gtkmm.h>
#include "live_effects/effect.h"
+#include "live_effects/parameter/text.h"
#include "live_effects/parameter/parameter.h"
#include "live_effects/parameter/point.h"
#include "live_effects/parameter/path.h"
@@ -31,12 +32,6 @@ namespace MS {
class KnotHolderEntityCenterMirrorSymmetry;
}
-enum LpeAction {
- LPE_ERASE = 0,
- LPE_TO_OBJECTS,
- LPE_VISIBILITY
-};
-
enum ModeType {
MT_V,
MT_H,
@@ -56,11 +51,12 @@ public:
virtual Geom::PathVector doEffect_path (Geom::PathVector const & path_in);
virtual void doOnRemove (SPLPEItem const* /*lpeitem*/);
virtual void doOnVisibilityToggled(SPLPEItem const* /*lpeitem*/);
+ virtual Gtk::Widget *newWidget();
void processObjects(LpeAction lpe_action);
/* the knotholder entity classes must be declared friends */
friend class MS::KnotHolderEntityCenterMirrorSymmetry;
- void createPhantom(SPLPEItem *origin, Glib::ustring id, bool styling);
- void createClone(SPLPEItem *origin, Geom::Affine transform, Glib::ustring id);
+ void createMirror(SPLPEItem *origin, Geom::Affine transform, gchar * id);
+ void cloneAttrbutes(Inkscape::XML::Node * origin, Inkscape::XML::Node * dest, char const * first_attribute, ...);
void addKnotHolderEntities(KnotHolder *knotholder, SPDesktop *desktop, SPItem *item);
protected:
@@ -68,17 +64,19 @@ protected:
private:
EnumParam<ModeType> mode;
+ ScalarParam split_gap;
BoolParam discard_orig_path;
BoolParam fuse_paths;
BoolParam oposite_fuse;
- BoolParam split;
+ BoolParam split_elements;
BoolParam split_sensitive;
- BoolParam split_style;
PointParam start_point;
PointParam end_point;
+ TextParam id_origin;
Geom::Line line_separation;
Geom::Point previous_center;
Geom::Point center_point;
+ bool actual;
LPEMirrorSymmetry(const LPEMirrorSymmetry&);
LPEMirrorSymmetry& operator=(const LPEMirrorSymmetry&);