summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza <jabier.arraiza@marker.es>2017-12-07 20:47:44 +0000
committerJabier Arraiza <jabier.arraiza@marker.es>2017-12-07 20:47:44 +0000
commit075a88fc7edbec8682bcd672de325ec1bedf129f (patch)
tree33d64f8ddc366a96e2c480b672224d44fc0e6355 /src
parentUpdate to trunk (diff)
parentFix bug 1733422 - Bezier and pencil tool don't work form: from clipboard (diff)
downloadinkscape-075a88fc7edbec8682bcd672de325ec1bedf129f.tar.gz
inkscape-075a88fc7edbec8682bcd672de325ec1bedf129f.zip
Mege trunk into powerpencilII
Diffstat (limited to 'src')
-rw-r--r--src/extension/internal/latex-text-renderer.cpp101
-rw-r--r--src/file.cpp5
-rw-r--r--src/live_effects/lpe-bendpath.cpp47
-rw-r--r--src/live_effects/lpe-bendpath.h3
-rw-r--r--src/live_effects/lpe-knot.cpp8
-rw-r--r--src/live_effects/lpe-patternalongpath.cpp44
-rw-r--r--src/live_effects/lpe-patternalongpath.h3
-rw-r--r--src/live_effects/parameter/parameter.cpp11
-rw-r--r--src/live_effects/parameter/parameter.h2
-rw-r--r--src/live_effects/parameter/point.cpp6
-rw-r--r--src/live_effects/parameter/point.h1
-rw-r--r--src/live_effects/parameter/random.cpp7
-rw-r--r--src/live_effects/parameter/random.h1
-rw-r--r--src/sp-ellipse.cpp59
-rw-r--r--src/sp-ellipse.h13
-rw-r--r--src/sp-guide.cpp6
-rw-r--r--src/sp-namedview.cpp13
-rw-r--r--src/sp-namedview.h2
-rw-r--r--src/ui/dialog/guides.cpp2
-rw-r--r--src/ui/tools/freehand-base.cpp76
-rw-r--r--src/ui/tools/freehand-base.h7
-rw-r--r--src/ui/tools/pen-tool.cpp145
-rw-r--r--src/ui/tools/pencil-tool.cpp61
-rw-r--r--src/ui/widget/registered-widget.cpp24
-rw-r--r--src/ui/widget/registered-widget.h11
-rw-r--r--src/ui/widget/scalar.cpp6
-rw-r--r--src/ui/widget/scalar.h5
-rw-r--r--src/widgets/arc-toolbar.cpp156
-rw-r--r--src/widgets/desktop-widget.cpp6
29 files changed, 555 insertions, 276 deletions
diff --git a/src/extension/internal/latex-text-renderer.cpp b/src/extension/internal/latex-text-renderer.cpp
index d1cf7e484..7a1cacbf2 100644
--- a/src/extension/internal/latex-text-renderer.cpp
+++ b/src/extension/internal/latex-text-renderer.cpp
@@ -260,6 +260,11 @@ void LaTeXTextRenderer::sp_use_render(SPUse *use)
void LaTeXTextRenderer::sp_text_render(SPText *textobj)
{
+ // Nothing to do here... (so don't emit an empty box)
+ // Also avoids falling out of sync with the CairoRenderer (which won't render anything in this case either)
+ if (textobj->layout.getActualLength() == 0)
+ return;
+
// Only PDFLaTeX supports importing a single page of a graphics file,
// so only PDF backend gets interleaved text/graphics
if (_pdflatex && _omittext_state == GRAPHIC_ON_TOP)
@@ -271,16 +276,20 @@ void LaTeXTextRenderer::sp_text_render(SPText *textobj)
// Align vertically on the baseline of the font (retreived from the anchor point)
// Align horizontally on anchorpoint
gchar const *alignment = NULL;
+ gchar const *alignstack = NULL;
switch (style->text_anchor.computed) {
case SP_CSS_TEXT_ANCHOR_START:
- alignment = "[lb]";
+ alignment = "[lt]";
+ alignstack = "[l]";
break;
case SP_CSS_TEXT_ANCHOR_END:
- alignment = "[rb]";
+ alignment = "[rt]";
+ alignstack = "[r]";
break;
case SP_CSS_TEXT_ANCHOR_MIDDLE:
default:
- alignment = "[b]";
+ alignment = "[t]";
+ alignstack = "[c]";
break;
}
Geom::Point anchor = textobj->attributes.firstXY() * transform();
@@ -327,39 +336,16 @@ void LaTeXTextRenderer::sp_text_render(SPText *textobj)
os << "\\rotatebox{" << degrees << "}{";
}
os << "\\makebox(0,0)" << alignment << "{";
- os << "\\smash{"; // smash the text, to be able to put the makebox coordinates at the baseline
+ os << "\\shortstack" << alignstack << "{";
+ os << "\\smash{";
+ bool smash_closed = false;
// Walk through all spans in the text object.
// Write span strings to LaTeX, associated with font weight and style.
Inkscape::Text::Layout const &layout = *(te_get_layout (textobj));
- for (Inkscape::Text::Layout::iterator li = layout.begin(), le = layout.end();
+ for (Inkscape::Text::Layout::iterator li = layout.begin(), le = layout.end();
li != le; li.nextStartOfSpan())
{
- SPStyle const &spanstyle = *(sp_te_style_at_position (textobj, li));
- bool is_bold = false, is_italic = false, is_oblique = false;
-
- if (spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_500 ||
- spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_600 ||
- spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_700 ||
- spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_800 ||
- spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_900 ||
- spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLD ||
- spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLDER)
- {
- is_bold = true;
- os << "\\textbf{";
- }
- if (spanstyle.font_style.computed == SP_CSS_FONT_STYLE_ITALIC)
- {
- is_italic = true;
- os << "\\textit{";
- }
- if (spanstyle.font_style.computed == SP_CSS_FONT_STYLE_OBLIQUE)
- {
- is_oblique = true;
- os << "\\textsl{"; // this is an accurate choice if the LaTeX chosen font matches the font in Inkscape. Gives bad results when it is not so...
- }
-
Inkscape::Text::Layout::iterator ln = li;
ln.nextStartOfSpan();
Glib::ustring uspanstr = sp_te_get_string_multiline (textobj, li, ln);
@@ -367,22 +353,61 @@ void LaTeXTextRenderer::sp_text_render(SPText *textobj)
if (!spanstr) {
continue;
}
+
+ bool is_bold = false, is_italic = false, is_oblique = false;
+
+ // newline character only -> don't attempt to add style (will break compilation in LaTeX)
+ if (g_strcmp0(spanstr, "\n")) {
+ SPStyle const &spanstyle = *(sp_te_style_at_position (textobj, li));
+ if (spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_500 ||
+ spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_600 ||
+ spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_700 ||
+ spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_800 ||
+ spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_900 ||
+ spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLD ||
+ spanstyle.font_weight.computed == SP_CSS_FONT_WEIGHT_BOLDER)
+ {
+ is_bold = true;
+ os << "\\textbf{";
+ }
+ if (spanstyle.font_style.computed == SP_CSS_FONT_STYLE_ITALIC)
+ {
+ is_italic = true;
+ os << "\\textit{";
+ }
+ if (spanstyle.font_style.computed == SP_CSS_FONT_STYLE_OBLIQUE)
+ {
+ is_oblique = true;
+ os << "\\textsl{"; // this is an accurate choice if the LaTeX chosen font matches the font in Inkscape. Gives bad results when it is not so...
+ }
+ }
+
// replace carriage return with double slash
- gchar ** splitstr = g_strsplit(spanstr, "\n", -1);
- gchar *spanstr_new = g_strjoinv("\\\\ ", splitstr);
- os << spanstr_new;
+ gchar ** splitstr = g_strsplit(spanstr, "\n", 2);
+ os << splitstr[0];
+
+ // smash the first line of the text only, to be able to align the rest of the makebox top
+ // assuming that spans always end at the end of a line
+ if (g_strv_length(splitstr) > 1)
+ {
+ if (!smash_closed)
+ {
+ os << "}"; // smash end
+ smash_closed = true;
+ }
+ os << "\\\\";
+ }
+
g_strfreev(splitstr);
- g_free(spanstr_new);
if (is_oblique) { os << "}"; } // oblique end
if (is_italic) { os << "}"; } // italic end
if (is_bold) { os << "}"; } // bold end
}
- os << "}"; // smash end
- if (has_rotation) {
- os << "}"; // rotatebox end
- }
+ if (!smash_closed) { os << "}"; } // smash end
+ os << "}"; // shortstack end
+ if (has_rotation) { os << "}"; } // rotatebox end
os << "}"; //makebox end
os << "}%\n"; // put end
diff --git a/src/file.cpp b/src/file.cpp
index 320016a41..e5caaaca0 100644
--- a/src/file.cpp
+++ b/src/file.cpp
@@ -272,6 +272,11 @@ bool sp_file_open(const Glib::ustring &uri,
}
if ( INKSCAPE.use_gui() ) {
+
+ SPNamedView *nv = desktop->namedview;
+ if (nv->lockguides) {
+ desktop->toggleGuidesLock();
+ }
// Perform a fixup pass for hrefs.
if ( Inkscape::ResourceManager::getManager().fixupBrokenLinks(doc) ) {
Glib::ustring msg = _("Broken links have been changed to point to existing files.");
diff --git a/src/live_effects/lpe-bendpath.cpp b/src/live_effects/lpe-bendpath.cpp
index ff5f738eb..dcbf5efd0 100644
--- a/src/live_effects/lpe-bendpath.cpp
+++ b/src/live_effects/lpe-bendpath.cpp
@@ -9,6 +9,7 @@
#include "sp-item-group.h"
#include "knot-holder-entity.h"
#include "knotholder.h"
+#include "display/curve.h"
// TODO due to internal breakage in glibmm headers, this must be last:
#include <glibmm/i18n.h>
@@ -39,7 +40,6 @@ first) but I think we can first forget about them.
namespace Inkscape {
namespace LivePathEffect {
-Geom::PathVector bp_helper_path;
namespace BeP {
class KnotHolderEntityWidthBendPath : public LPEKnotHolderEntity {
public:
@@ -55,16 +55,19 @@ LPEBendPath::LPEBendPath(LivePathEffectObject *lpeobject) :
original_height(0.0),
prop_scale(_("_Width:"), _("Width of the path"), "prop_scale", &wr, this, 1.0),
scale_y_rel(_("W_idth in units of length"), _("Scale the width of the path in units of its length"), "scale_y_rel", &wr, this, false),
- vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false)
+ vertical_pattern(_("_Original path is vertical"), _("Rotates the original 90 degrees, before bending it along the bend path"), "vertical", &wr, this, false),
+ hide_knot(_("Hide width knot"), _("Hide width knot"),"hide_knot", &wr, this, false)
{
registerParameter( &bend_path );
registerParameter( &prop_scale);
registerParameter( &scale_y_rel);
registerParameter( &vertical_pattern);
+ registerParameter(&hide_knot);
prop_scale.param_set_digits(3);
prop_scale.param_set_increments(0.01, 0.10);
-
+
+ knot_entity = NULL;
_provides_knotholder_entities = true;
apply_to_clippath_and_mask = true;
concatenate_before_pwd2 = true;
@@ -81,6 +84,15 @@ LPEBendPath::doBeforeEffect (SPLPEItem const* lpeitem)
// get the item bounding box
original_bbox(lpeitem);
original_height = boundingbox_Y.max() - boundingbox_Y.min();
+ if (knot_entity) {
+ if (hide_knot) {
+ helper_path.clear();
+ knot_entity->knot->hide();
+ } else {
+ knot_entity->knot->show();
+ }
+ knot_entity->update_knot();
+ }
}
Geom::Piecewise<Geom::D2<Geom::SBasis> >
@@ -162,15 +174,19 @@ LPEBendPath::transform_multiply(Geom::Affine const& postmul, bool set)
void
LPEBendPath::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec)
{
- hp_vec.push_back(bp_helper_path);
+ hp_vec.push_back(helper_path);
}
void
LPEBendPath::addKnotHolderEntities(KnotHolder *knotholder, SPItem *item)
{
- KnotHolderEntity *e = new BeP::KnotHolderEntityWidthBendPath(this);
- e->create(NULL, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE);
- knotholder->add(e);
+ knot_entity = new BeP::KnotHolderEntityWidthBendPath(this);
+ knot_entity->create(NULL, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE);
+ knotholder->add(knot_entity);
+ if (hide_knot) {
+ knot_entity->knot->hide();
+ knot_entity->update_knot();
+ }
}
namespace BeP {
@@ -208,7 +224,6 @@ Geom::Point
KnotHolderEntityWidthBendPath::knot_get() const
{
LPEBendPath *lpe = dynamic_cast<LPEBendPath *> (_effect);
-
Geom::Path path_in = lpe->bend_path.get_pathvector().pathAt(Geom::PathVectorTime(0, 0, 0.0));
Geom::Point ptA = path_in.pointAt(Geom::PathTime(0, 0.0));
Geom::Point B = path_in.pointAt(Geom::PathTime(1, 0.0));
@@ -216,17 +231,17 @@ KnotHolderEntityWidthBendPath::knot_get() const
Geom::CubicBezier const *cubic = dynamic_cast<Geom::CubicBezier const *>(&*first_curve);
Geom::Ray ray(ptA, B);
if (cubic) {
- ray.setPoints(ptA,(*cubic)[1]);
+ ray.setPoints(ptA, (*cubic)[1]);
}
ray.setAngle(ray.angle() + Geom::rad_from_deg(90));
Geom::Point result_point = Geom::Point::polar(ray.angle(), (lpe->original_height/2.0) * lpe->prop_scale) + ptA;
-
- bp_helper_path.clear();
- Geom::Path hp(result_point);
- hp.appendNew<Geom::LineSegment>(ptA);
- bp_helper_path.push_back(hp);
- hp.clear();
-
+ lpe->helper_path.clear();
+ if (!lpe->hide_knot) {
+ Geom::Path hp(result_point);
+ hp.appendNew<Geom::LineSegment>(ptA);
+ lpe->helper_path.push_back(hp);
+ hp.clear();
+ }
return result_point;
}
} // namespace BeP
diff --git a/src/live_effects/lpe-bendpath.h b/src/live_effects/lpe-bendpath.h
index f232687ce..74892201d 100644
--- a/src/live_effects/lpe-bendpath.h
+++ b/src/live_effects/lpe-bendpath.h
@@ -58,6 +58,9 @@ protected:
private:
BoolParam scale_y_rel;
BoolParam vertical_pattern;
+ BoolParam hide_knot;
+ KnotHolderEntity *knot_entity;
+ Geom::PathVector helper_path;
Geom::Piecewise<Geom::D2<Geom::SBasis> > uskeleton;
Geom::Piecewise<Geom::D2<Geom::SBasis> > n;
diff --git a/src/live_effects/lpe-knot.cpp b/src/live_effects/lpe-knot.cpp
index b21181ffc..b3918b6ab 100644
--- a/src/live_effects/lpe-knot.cpp
+++ b/src/live_effects/lpe-knot.cpp
@@ -510,12 +510,7 @@ collectPathsAndWidths (SPLPEItem const *lpeitem, Geom::PathVector &paths, std::v
}
}
else if (SP_IS_SHAPE(lpeitem)) {
- SPCurve * c = NULL;
- if (SP_IS_PATH(lpeitem)) {
- c = SP_PATH(lpeitem)->get_curve_for_edit();
- } else {
- c = SP_SHAPE(lpeitem)->getCurve();
- }
+ SPCurve * c = SP_SHAPE(lpeitem)->getCurve();
if (c) {
Geom::PathVector subpaths = pathv_to_linear_and_cubic_beziers(c->get_pathvector());
for (unsigned i=0; i<subpaths.size(); i++){
@@ -524,6 +519,7 @@ collectPathsAndWidths (SPLPEItem const *lpeitem, Geom::PathVector &paths, std::v
stroke_widths.push_back(lpeitem->style->stroke_width.computed);
}
}
+ c->unref();
}
}
diff --git a/src/live_effects/lpe-patternalongpath.cpp b/src/live_effects/lpe-patternalongpath.cpp
index 4aa172161..5be88a2b7 100644
--- a/src/live_effects/lpe-patternalongpath.cpp
+++ b/src/live_effects/lpe-patternalongpath.cpp
@@ -42,7 +42,6 @@ first) but I think we can first forget about them.
namespace Inkscape {
namespace LivePathEffect {
-Geom::PathVector pap_helper_path;
namespace WPAP {
class KnotHolderEntityWidthPatternAlongPath : public LPEKnotHolderEntity {
@@ -82,6 +81,7 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) :
"prop_units", &wr, this, false),
vertical_pattern(_("Pattern is _vertical"), _("Rotate pattern 90 deg before applying"),
"vertical_pattern", &wr, this, false),
+ hide_knot(_("Hide width knot"), _("Hide width knot"),"hide_knot", &wr, this, false),
fuse_tolerance(_("_Fuse nearby ends:"), _("Fuse ends closer than this number. 0 means don't fuse."),
"fuse_tolerance", &wr, this, 0)
{
@@ -94,10 +94,11 @@ LPEPatternAlongPath::LPEPatternAlongPath(LivePathEffectObject *lpeobject) :
registerParameter(&tang_offset);
registerParameter(&prop_units);
registerParameter(&vertical_pattern);
+ registerParameter(&hide_knot);
registerParameter(&fuse_tolerance);
prop_scale.param_set_digits(3);
prop_scale.param_set_increments(0.01, 0.10);
-
+ knot_entity = NULL;
_provides_knotholder_entities = true;
}
@@ -115,6 +116,15 @@ LPEPatternAlongPath::doBeforeEffect (SPLPEItem const* lpeitem)
if (bbox) {
original_height = (*bbox)[Geom::Y].max() - (*bbox)[Geom::Y].min();
}
+ if (knot_entity) {
+ if (hide_knot) {
+ helper_path.clear();
+ knot_entity->knot->hide();
+ } else {
+ knot_entity->knot->show();
+ }
+ knot_entity->update_knot();
+ }
}
Geom::Piecewise<Geom::D2<Geom::SBasis> >
@@ -272,16 +282,20 @@ LPEPatternAlongPath::transform_multiply(Geom::Affine const& postmul, bool set)
void
LPEPatternAlongPath::addCanvasIndicators(SPLPEItem const */*lpeitem*/, std::vector<Geom::PathVector> &hp_vec)
{
- hp_vec.push_back(pap_helper_path);
+ hp_vec.push_back(helper_path);
}
void
LPEPatternAlongPath::addKnotHolderEntities(KnotHolder *knotholder, SPItem *item)
{
- KnotHolderEntity *e = new WPAP::KnotHolderEntityWidthPatternAlongPath(this);
- e->create(NULL, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE);
- knotholder->add(e);
+ knot_entity = new WPAP::KnotHolderEntityWidthPatternAlongPath(this);
+ knot_entity->create(NULL, item, knotholder, Inkscape::CTRL_TYPE_UNKNOWN, _("Change the width"), SP_KNOT_SHAPE_CIRCLE);
+ knotholder->add(knot_entity);
+ if (hide_knot) {
+ knot_entity->knot->hide();
+ knot_entity->update_knot();
+ }
}
namespace WPAP {
@@ -290,7 +304,7 @@ void
KnotHolderEntityWidthPatternAlongPath::knot_set(Geom::Point const &p, Geom::Point const& /*origin*/, guint state)
{
LPEPatternAlongPath *lpe = dynamic_cast<LPEPatternAlongPath *> (_effect);
-
+
Geom::Point const s = snap_knot_position(p, state);
SPShape const *sp_shape = dynamic_cast<SPShape const *>(SP_LPE_ITEM(item));
if (sp_shape) {
@@ -325,7 +339,6 @@ Geom::Point
KnotHolderEntityWidthPatternAlongPath::knot_get() const
{
LPEPatternAlongPath *lpe = dynamic_cast<LPEPatternAlongPath *> (_effect);
-
SPShape const *sp_shape = dynamic_cast<SPShape const *>(SP_LPE_ITEM(item));
if (sp_shape) {
SPCurve *curve_before = sp_shape->getCurveBeforeLPE();
@@ -341,13 +354,14 @@ KnotHolderEntityWidthPatternAlongPath::knot_get() const
}
ray.setAngle(ray.angle() + Geom::rad_from_deg(90));
Geom::Point result_point = Geom::Point::polar(ray.angle(), (lpe->original_height/2.0) * lpe->prop_scale) + ptA;
-
- pap_helper_path.clear();
- Geom::Path hp(result_point);
- hp.appendNew<Geom::LineSegment>(ptA);
- pap_helper_path.push_back(hp);
- hp.clear();
- curve_before->unref();
+ lpe->helper_path.clear();
+ if (!lpe->hide_knot) {
+ Geom::Path hp(result_point);
+ hp.appendNew<Geom::LineSegment>(ptA);
+ lpe->helper_path.push_back(hp);
+ hp.clear();
+ }
+ curve_before->unref();
return result_point;
}
}
diff --git a/src/live_effects/lpe-patternalongpath.h b/src/live_effects/lpe-patternalongpath.h
index c34a9a15d..ded875a8b 100644
--- a/src/live_effects/lpe-patternalongpath.h
+++ b/src/live_effects/lpe-patternalongpath.h
@@ -60,7 +60,10 @@ private:
ScalarParam tang_offset;
BoolParam prop_units;
BoolParam vertical_pattern;
+ BoolParam hide_knot;
ScalarParam fuse_tolerance;
+ KnotHolderEntity *knot_entity;
+ Geom::PathVector helper_path;
void on_pattern_pasted();
LPEPatternAlongPath(const LPEPatternAlongPath&);
diff --git a/src/live_effects/parameter/parameter.cpp b/src/live_effects/parameter/parameter.cpp
index 319ab3fe8..497113e03 100644
--- a/src/live_effects/parameter/parameter.cpp
+++ b/src/live_effects/parameter/parameter.cpp
@@ -129,9 +129,6 @@ ScalarParam::param_update_default(const gchar * default_value)
void
ScalarParam::param_set_value(gdouble val)
{
- if (value != val) {
- param_effect->upd_params = true;
- }
value = val;
if (integer)
value = round(value);
@@ -180,7 +177,7 @@ ScalarParam::param_set_undo(bool set_undo)
Gtk::Widget *
ScalarParam::param_newWidget()
{
- if(widget_is_visible){
+ if (widget_is_visible) {
Inkscape::UI::Widget::RegisteredScalar *rsu = Gtk::manage( new Inkscape::UI::Widget::RegisteredScalar(
param_label, param_tooltip, param_key, *param_wr, param_effect->getRepr(), param_effect->getSPDoc() ) );
@@ -192,6 +189,7 @@ ScalarParam::param_newWidget()
if (add_slider) {
rsu->addSlider();
}
+ rsu->signal_button_release_event().connect(sigc::mem_fun (*this, &ScalarParam::on_button_release));
if(_set_undo){
rsu->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change scalar parameter"));
}
@@ -201,6 +199,11 @@ ScalarParam::param_newWidget()
}
}
+bool ScalarParam::on_button_release(GdkEventButton* button_event) {
+ param_effect->upd_params = true;
+ return false;
+}
+
void
ScalarParam::param_set_digits(unsigned digits)
{
diff --git a/src/live_effects/parameter/parameter.h b/src/live_effects/parameter/parameter.h
index 1586ef346..aa4212f15 100644
--- a/src/live_effects/parameter/parameter.h
+++ b/src/live_effects/parameter/parameter.h
@@ -141,6 +141,8 @@ protected:
bool _set_undo;
private:
+ bool on_button_release(GdkEventButton* button_event);
+
ScalarParam(const ScalarParam&);
ScalarParam& operator=(const ScalarParam&);
};
diff --git a/src/live_effects/parameter/point.cpp b/src/live_effects/parameter/point.cpp
index da6edf812..ff5f59ce2 100644
--- a/src/live_effects/parameter/point.cpp
+++ b/src/live_effects/parameter/point.cpp
@@ -146,6 +146,7 @@ PointParam::param_newWidget()
pointwdg->setValue( *this );
pointwdg->clearProgrammatically();
pointwdg->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change point parameter"));
+ pointwdg->signal_button_release_event().connect(sigc::mem_fun (*this, &PointParam::on_button_release));
Gtk::HBox * hbox = Gtk::manage( new Gtk::HBox() );
static_cast<Gtk::HBox*>(hbox)->pack_start(*pointwdg, true, true);
@@ -153,6 +154,11 @@ PointParam::param_newWidget()
return dynamic_cast<Gtk::Widget *> (hbox);
}
+bool PointParam::on_button_release(GdkEventButton* button_event) {
+ param_effect->upd_params = true;
+ return false;
+}
+
void
PointParam::set_oncanvas_looks(SPKnotShapeType shape, SPKnotModeType mode, guint32 color)
{
diff --git a/src/live_effects/parameter/point.h b/src/live_effects/parameter/point.h
index 03256f6d0..6c5f8df65 100644
--- a/src/live_effects/parameter/point.h
+++ b/src/live_effects/parameter/point.h
@@ -57,6 +57,7 @@ public:
private:
PointParam(const PointParam&);
PointParam& operator=(const PointParam&);
+ bool on_button_release(GdkEventButton* button_event);
Geom::Point defvalue;
bool liveupdate;
KnotHolder *knoth;
diff --git a/src/live_effects/parameter/random.cpp b/src/live_effects/parameter/random.cpp
index c2c1b5440..4afa43c6e 100644
--- a/src/live_effects/parameter/random.cpp
+++ b/src/live_effects/parameter/random.cpp
@@ -103,7 +103,6 @@ RandomParam::param_update_default(const gchar * default_value){
void
RandomParam::param_set_value(gdouble val, long newseed)
{
- param_effect->upd_params = true;
value = val;
if (integer)
value = round(value);
@@ -154,12 +153,18 @@ RandomParam::param_newWidget()
}
regrandom->setRange(min, max);
regrandom->setProgrammatically = false;
+ regrandom->signal_button_release_event().connect(sigc::mem_fun (*this, &RandomParam::on_button_release));
regrandom->set_undo_parameters(SP_VERB_DIALOG_LIVE_PATH_EFFECT, _("Change random parameter"));
return dynamic_cast<Gtk::Widget *> (regrandom);
}
+bool RandomParam::on_button_release(GdkEventButton* button_event) {
+ param_effect->upd_params = true;
+ return false;
+}
+
RandomParam::operator gdouble()
{
return rand() * value;
diff --git a/src/live_effects/parameter/random.h b/src/live_effects/parameter/random.h
index c10473e85..a2c3712a1 100644
--- a/src/live_effects/parameter/random.h
+++ b/src/live_effects/parameter/random.h
@@ -57,6 +57,7 @@ protected:
gdouble defvalue;
private:
+ bool on_button_release(GdkEventButton* button_event);
long setup_seed(long);
gdouble rand();
diff --git a/src/sp-ellipse.cpp b/src/sp-ellipse.cpp
index 166237c8e..c32e3012c 100644
--- a/src/sp-ellipse.cpp
+++ b/src/sp-ellipse.cpp
@@ -721,6 +721,65 @@ bool SPGenericEllipse::_isSlice() const
return !(Geom::are_near(a.extent(), 0) || Geom::are_near(a.extent(), SP_2PI));
}
+/**
+Returns the ratio in which the vector from p0 to p1 is stretched by transform
+ */
+gdouble SPGenericEllipse::vectorStretch(Geom::Point p0, Geom::Point p1, Geom::Affine xform) {
+ if (p0 == p1) {
+ return 0;
+ }
+
+ return (Geom::distance(p0 * xform, p1 * xform) / Geom::distance(p0, p1));
+}
+
+void SPGenericEllipse::setVisibleRx(gdouble rx) {
+ if (rx == 0) {
+ this->rx.unset();
+ } else {
+ this->rx = rx / SPGenericEllipse::vectorStretch(
+ Geom::Point(this->cx.computed + 1, this->cy.computed),
+ Geom::Point(this->cx.computed, this->cy.computed),
+ this->i2doc_affine());
+ }
+
+ this->updateRepr();
+}
+
+void SPGenericEllipse::setVisibleRy(gdouble ry) {
+ if (ry == 0) {
+ this->ry.unset();
+ } else {
+ this->ry = ry / SPGenericEllipse::vectorStretch(
+ Geom::Point(this->cx.computed, this->cy.computed + 1),
+ Geom::Point(this->cx.computed, this->cy.computed),
+ this->i2doc_affine());
+ }
+
+ this->updateRepr();
+}
+
+gdouble SPGenericEllipse::getVisibleRx() const {
+ if (!this->rx._set) {
+ return 0;
+ }
+
+ return this->rx.computed * SPGenericEllipse::vectorStretch(
+ Geom::Point(this->cx.computed + 1, this->cy.computed),
+ Geom::Point(this->cx.computed, this->cy.computed),
+ this->i2doc_affine());
+}
+
+gdouble SPGenericEllipse::getVisibleRy() const {
+ if (!this->ry._set) {
+ return 0;
+ }
+
+ return this->ry.computed * SPGenericEllipse::vectorStretch(
+ Geom::Point(this->cx.computed, this->cy.computed + 1),
+ Geom::Point(this->cx.computed, this->cy.computed),
+ this->i2doc_affine());
+}
+
/*
Local Variables:
mode:c++
diff --git a/src/sp-ellipse.h b/src/sp-ellipse.h
index a879c596d..a31b571d8 100644
--- a/src/sp-ellipse.h
+++ b/src/sp-ellipse.h
@@ -20,8 +20,8 @@
#include "sp-shape.h"
/* Common parent class */
-#define SP_GENERICELLIPSE(obj) (dynamic_cast<SPGenericEllipse*>(obj))
-#define SP_IS_GENERICELLIPSE(obj) (dynamic_cast<const SPGenericEllipse*>((obj)) != NULL)
+#define SP_GENERICELLIPSE(obj) (dynamic_cast<SPGenericEllipse*>((SPObject*)obj))
+#define SP_IS_GENERICELLIPSE(obj) (dynamic_cast<const SPGenericEllipse*>((SPObject*)obj) != NULL)
enum GenericEllipseType {
SP_GENERIC_ELLIPSE_UNDEFINED, // FIXME shouldn't exist
@@ -83,11 +83,20 @@ public:
bool set_elliptical_path_attribute(Inkscape::XML::Node *repr);
void position_set(double x, double y, double rx, double ry);
+ double getVisibleRx() const;
+ void setVisibleRx(double rx);
+
+ double getVisibleRy() const;
+ void setVisibleRy(double ry);
+
protected:
/**
* @brief Determines whether the shape is a part of an ellipse.
*/
bool _isSlice() const;
+
+private:
+ static double vectorStretch(Geom::Point p0, Geom::Point p1, Geom::Affine xform);
};
#endif
diff --git a/src/sp-guide.cpp b/src/sp-guide.cpp
index 8b4bf121d..fe6d0b64a 100644
--- a/src/sp-guide.cpp
+++ b/src/sp-guide.cpp
@@ -112,9 +112,8 @@ void SPGuide::set(unsigned int key, const gchar *value) {
this->set_label(this->label, false);
break;
case SP_ATTR_INKSCAPE_LOCKED:
- this->locked = helperfns_read_bool(value, false);
if (value) {
- this->set_locked(this->locked, false);
+ this->set_locked(helperfns_read_bool(value, false), false);
}
break;
case SP_ATTR_ORIENTATION:
@@ -275,7 +274,8 @@ void SPGuide::showSPGuide(SPCanvasGroup *group, GCallback handler)
{
SPCanvasItem *item = sp_guideline_new(group, label, point_on_line, normal_to_line);
sp_guideline_set_color(SP_GUIDELINE(item), color);
-
+ sp_guideline_set_locked(SP_GUIDELINE(item), locked);
+
g_signal_connect(G_OBJECT(item), "event", G_CALLBACK(handler), this);
views.push_back(SP_GUIDELINE(item));
diff --git a/src/sp-namedview.cpp b/src/sp-namedview.cpp
index 2992b85d3..ef22eca2d 100644
--- a/src/sp-namedview.cpp
+++ b/src/sp-namedview.cpp
@@ -593,10 +593,9 @@ void SPNamedView::set(unsigned int key, const gchar* value) {
break;
}
case SP_ATTR_INKSCAPE_LOCKGUIDES:
- this->lockguides = value ? sp_str_to_bool(value) : FALSE;
- sp_namedview_lock_guides(this);
- this->requestModified(SP_OBJECT_MODIFIED_FLAG);
- break;
+ this->lockguides = value ? sp_str_to_bool(value) : FALSE;
+ this->requestModified(SP_OBJECT_MODIFIED_FLAG);
+ break;
default:
SPObjectGroup::set(key, value);
break;
@@ -671,7 +670,6 @@ void SPNamedView::child_added(Inkscape::XML::Node *child, Inkscape::XML::Node *r
}
sp_namedview_show_single_guide(SP_GUIDE(g), this->showguides);
- sp_namedview_lock_single_guide(SP_GUIDE(g), this->lockguides);
}
}
}
@@ -721,7 +719,6 @@ void SPNamedView::show(SPDesktop *desktop)
(*it)->sensitize(desktop->getCanvas(), TRUE);
}
sp_namedview_show_single_guide((*it), showguides);
- sp_namedview_lock_single_guide((*it), lockguides);
}
views.push_back(desktop);
@@ -1013,9 +1010,10 @@ void sp_namedview_toggle_guides(SPDocument *doc, Inkscape::XML::Node *repr)
doc->setModifiedSinceSave();
}
-void sp_namedview_guides_toggle_lock(SPDocument *doc, Inkscape::XML::Node *repr)
+void sp_namedview_guides_toggle_lock(SPDocument *doc, SPNamedView * namedview)
{
unsigned int v;
+ Inkscape::XML::Node *repr = namedview->getRepr();
unsigned int set = sp_repr_get_boolean(repr, "inkscape:lockguides", &v);
if (!set) { // hide guides if not specified, for backwards compatibility
v = true;
@@ -1026,6 +1024,7 @@ void sp_namedview_guides_toggle_lock(SPDocument *doc, Inkscape::XML::Node *repr)
bool saved = DocumentUndo::getUndoSensitive(doc);
DocumentUndo::setUndoSensitive(doc, false);
sp_repr_set_boolean(repr, "inkscape:lockguides", v);
+ sp_namedview_lock_guides(namedview);
DocumentUndo::setUndoSensitive(doc, saved);
doc->setModifiedSinceSave();
}
diff --git a/src/sp-namedview.h b/src/sp-namedview.h
index d8ac1a77e..20d762bc4 100644
--- a/src/sp-namedview.h
+++ b/src/sp-namedview.h
@@ -123,7 +123,7 @@ void sp_namedview_document_from_window(SPDesktop *desktop);
void sp_namedview_update_layers_from_document (SPDesktop *desktop);
void sp_namedview_toggle_guides(SPDocument *doc, Inkscape::XML::Node *repr);
-void sp_namedview_guides_toggle_lock(SPDocument *doc, Inkscape::XML::Node *repr);
+void sp_namedview_guides_toggle_lock(SPDocument *doc, SPNamedView *namedview);
void sp_namedview_show_grids(SPNamedView *namedview, bool show, bool dirty_document);
Inkscape::CanvasGrid * sp_namedview_get_first_enabled_grid(SPNamedView *namedview);
diff --git a/src/ui/dialog/guides.cpp b/src/ui/dialog/guides.cpp
index f0de5ad0d..5dc64bb24 100644
--- a/src/ui/dialog/guides.cpp
+++ b/src/ui/dialog/guides.cpp
@@ -96,7 +96,7 @@ void GuidelinePropertiesDialog::_onOK()
normal = Geom::rot90(Geom::Point::polar(rad_angle, 1.0));
}
//To allow reposition from dialog
- _guide->set_locked(false, true);
+ _guide->set_locked(false, false);
_guide->set_normal(normal, true);
diff --git a/src/ui/tools/freehand-base.cpp b/src/ui/tools/freehand-base.cpp
index 89d9074ba..b72eb84db 100644
--- a/src/ui/tools/freehand-base.cpp
+++ b/src/ui/tools/freehand-base.cpp
@@ -36,6 +36,7 @@
#include "ui/tools/lpe-tool.h"
#include "selection-chemistry.h"
#include "sp-item-group.h"
+#include "sp-rect.h"
#include "live_effects/lpe-powerstroke.h"
#include "style.h"
#include "ui/control-manager.h"
@@ -85,7 +86,7 @@ FreehandBase::FreehandBase(gchar const *const *cursor_shape)
, green_anchor(NULL)
, green_closed(false)
, white_item(NULL)
- , overwrite_curve(NULL)
+ , sa_overwrited(NULL)
, sa(NULL)
, ea(NULL)
, waiting_LPE_type(Inkscape::LivePathEffect::INVALID_LPE)
@@ -144,7 +145,7 @@ void FreehandBase::setup() {
this->green_closed = FALSE;
// Create start anchor alternative curve
- this->overwrite_curve = new SPCurve();
+ this->sa_overwrited = new SPCurve();
this->attach = TRUE;
spdc_attach_selection(this, this->selection);
@@ -464,6 +465,8 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item,
Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get();
if(cm->paste(SP_ACTIVE_DESKTOP,true)){
SPItem * pasted_clipboard = dc->selection->singleItem();
+ dc->selection->toCurves();
+ pasted_clipboard = dc->selection->singleItem();
if(pasted_clipboard){
Inkscape::XML::Node *pasted_clipboard_root = pasted_clipboard->getRepr();
Inkscape::XML::Node *path = sp_repr_lookup_name(pasted_clipboard_root, "svg:path", -1); // unlimited search depth
@@ -492,6 +495,19 @@ static void spdc_check_for_and_apply_waiting_LPE(FreehandBase *dc, SPItem *item,
{
gchar const *svgd = item->getRepr()->attribute("d");
if(bend_item && (SP_IS_SHAPE(bend_item) || SP_IS_GROUP(bend_item))){
+ // If item is a SPRect, convert it to path first:
+ if ( dynamic_cast<SPRect *>(bend_item) ) {
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if (desktop) {
+ Inkscape::Selection *sel = desktop->getSelection();
+ if ( sel && !sel->isEmpty() ) {
+ sel->clear();
+ sel->add(bend_item);
+ sel->toCurves();
+ bend_item = sel->singleItem();
+ }
+ }
+ }
bend_item->moveTo(item,false);
bend_item->transform.setTranslation(Geom::Point());
spdc_apply_bend_shape(svgd, dc, bend_item);
@@ -597,6 +613,9 @@ static void spdc_selection_modified(Inkscape::Selection *sel, guint /*flags*/, F
static void spdc_attach_selection(FreehandBase *dc, Inkscape::Selection */*sel*/)
{
+ if (SP_IS_PENCIL_CONTEXT(dc) && dc->sa && dc->input_has_pressure) {
+ return;
+ }
// We reset white and forget white/start/end anchors
spdc_reset_white(dc);
dc->sa = NULL;
@@ -742,38 +761,21 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed)
{
// We hit bot start and end of single curve, closing paths
dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Closing path."));
- if (dc->sa->start && !(dc->sa->curve->is_closed()) ) {
- c = reverse_then_unref(c);
- }
- if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 ||
- prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){
- dc->overwrite_curve->append_continuous(c, 0.0625);
- c->unref();
- dc->overwrite_curve->closepath_current();
- if(dc->sa){
- dc->white_curves.erase(std::find(dc->white_curves.begin(),dc->white_curves.end(), dc->sa->curve));
- dc->white_curves.push_back(dc->overwrite_curve);
- }
- }else{
- dc->sa->curve->append_continuous(c, 0.0625);
- c->unref();
- dc->sa->curve->closepath_current();
+ dc->sa_overwrited->append_continuous(c, 0.0625);
+ c->unref();
+ dc->sa_overwrited->closepath_current();
+ if(dc->sa){
+ dc->white_curves.erase(std::find(dc->white_curves.begin(),dc->white_curves.end(), dc->sa->curve));
+ dc->white_curves.push_back(dc->sa_overwrited);
}
+
spdc_flush_white(dc, NULL);
return;
}
-
// Step C - test start
if (dc->sa) {
- SPCurve *s = dc->sa->curve;
- dc->white_curves.erase(std::find(dc->white_curves.begin(),dc->white_curves.end(), s));
- if(prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 1 ||
- prefs->getInt(tool_name(dc) + "/freehand-mode", 0) == 2){
- s = dc->overwrite_curve;
- }
- if (dc->sa->start) {
- s = reverse_then_unref(s);
- }
+ dc->white_curves.erase(std::find(dc->white_curves.begin(),dc->white_curves.end(), dc->sa->curve));
+ SPCurve *s = dc->sa_overwrited;
s->append_continuous(c, 0.0625);
c->unref();
c = s;
@@ -805,7 +807,6 @@ void spdc_concat_colors_and_flush(FreehandBase *dc, gboolean forceclosed)
c->append_continuous(e, 0.0625);
e->unref();
}
-
if (forceclosed)
{
dc->desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Path is closed."));
@@ -880,8 +881,17 @@ static void spdc_flush_white(FreehandBase *dc, SPCurve *gc)
if(previous_shape_type == BEND_CLIPBOARD){
repr->parent()->removeChild(repr);
}
+ } else if (SP_IS_PENCIL_CONTEXT(dc)) {
+ if (dc->input_has_pressure) {
+ spdc_check_for_and_apply_waiting_LPE(dc, dc->white_item, c, false);
+// Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+// shapeType shape = (shapeType)prefs->getInt(tool_name(dc) + "/shape", 0);
+// if (shape == NONE) {
+// std::vector<Geom::Point> points;
+// spdc_apply_powerstroke_shape(points, dc, dc->white_item);
+// }
+ }
}
-
DocumentUndo::done(doc, SP_IS_PEN_CONTEXT(dc)? SP_VERB_CONTEXT_PEN : SP_VERB_CONTEXT_PENCIL,
_("Draw path"));
@@ -950,7 +960,11 @@ static void spdc_free_colors(FreehandBase *dc)
if (dc->blue_curve) {
dc->blue_curve = dc->blue_curve->unref();
}
-
+
+ // Overwrite start anchor curve
+ if (dc->sa_overwrited) {
+ dc->sa_overwrited = dc->sa_overwrited->unref();
+ }
// Green
for (auto i : dc->green_bpaths)
sp_canvas_item_destroy(i);
diff --git a/src/ui/tools/freehand-base.h b/src/ui/tools/freehand-base.h
index 02d0a9982..4a14cf8d3 100644
--- a/src/ui/tools/freehand-base.h
+++ b/src/ui/tools/freehand-base.h
@@ -76,11 +76,8 @@ public:
std::list<SPCurve *> white_curves;
std::vector<SPDrawAnchor*> white_anchors;
- // Alternative curve to use on continuing the exisiting curve in case of
- // bspline or spirolive, because using anchor curves gives random memory
- // bugs as reported by su_v when running this code on macOS (as well as
- // making the code hard to understand).
- SPCurve *overwrite_curve;
+ // Temporary modiffied curve when start anchor
+ SPCurve *sa_overwrited;
// Start anchor
SPDrawAnchor *sa;
diff --git a/src/ui/tools/pen-tool.cpp b/src/ui/tools/pen-tool.cpp
index 16cdf63b5..a42a3a07a 100644
--- a/src/ui/tools/pen-tool.cpp
+++ b/src/ui/tools/pen-tool.cpp
@@ -423,7 +423,7 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) {
// This is allowed, if we just canceled curve
case PenTool::POINT:
if (this->npoints == 0) {
- this->_bsplineSpiroColor();
+ this->setPolylineMode();
Geom::Point p;
if ((bevent.state & GDK_CONTROL_MASK) && (this->polylines_only || this->polylines_paraxial)) {
p = event_dt;
@@ -444,7 +444,13 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) {
// Set start anchor
this->sa = anchor;
- if(anchor){
+ if (anchor) {
+ //Put the start overwrite curve always on the same direction
+ if (anchor->start) {
+ this->sa_overwrited = this->sa->curve->create_reverse();
+ } else {
+ this->sa_overwrited = this->sa->curve->copy();
+ }
this->_bsplineSpiroStartAnchor(bevent.state & GDK_SHIFT_MASK);
}
if (anchor && (!this->hasWaitingLPE()|| this->bspline || this->spiro)) {
@@ -473,7 +479,6 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) {
}
this->_setInitialPoint(p);
} else {
-
// Set end anchor
this->ea = anchor;
Geom::Point p;
@@ -497,6 +502,7 @@ bool PenTool::_handleButtonPress(GdkEventButton const &bevent) {
this->_setSubsequentPoint(p, true);
}
}
+ this->_bsplineSpiroColor();
// avoid the creation of a control point so a node is created in the release event
this->state = (this->spiro || this->bspline || this->polylines_only) ? PenTool::POINT : PenTool::CONTROL;
ret = true;
@@ -734,26 +740,9 @@ bool PenTool::_handleButtonRelease(GdkEventButton const &revent) {
case PenTool::MODE_CLICK:
switch (this->state) {
case PenTool::POINT:
- if ( this->npoints == 0 ) {
- // Start new thread only with button release
- this->_bsplineSpiroColor();
- if (anchor) {
- p = anchor->dp;
- }
- this->sa = anchor;
- // continue the existing curve
- if (anchor) {
- if(this->bspline || this->spiro){
- this->_bsplineSpiroStartAnchor(revent.state & GDK_SHIFT_MASK);;
- }
- }
- this->_setInitialPoint(p);
- } else {
- // Set end anchor here
- this->ea = anchor;
- if (anchor) {
- p = anchor->dp;
- }
+ this->ea = anchor;
+ if (anchor) {
+ p = anchor->dp;
}
this->state = PenTool::CONTROL;
break;
@@ -1264,6 +1253,8 @@ void PenTool::_resetColors() {
}
this->sa = NULL;
this->ea = NULL;
+ this->sa_overwrited->reset();
+
this->npoints = 0;
this->red_curve_is_valid = false;
}
@@ -1415,11 +1406,7 @@ void PenTool::_bsplineSpiroStartAnchor(bool shift)
this->spiro = false;
}
if(!this->spiro && !this->bspline){
- SPCurve *tmp_curve = this->sa->curve->copy();
- if (this->sa->start) {
- tmp_curve = tmp_curve ->create_reverse();
- }
- this->overwrite_curve = tmp_curve ;
+ _bsplineSpiroColor();
return;
}
if(shift){
@@ -1433,14 +1420,10 @@ void PenTool::_bsplineSpiroStartAnchorOn()
{
using Geom::X;
using Geom::Y;
- SPCurve *tmp_curve = this->sa->curve->copy();
- if (this->sa->start) {
- tmp_curve = tmp_curve ->create_reverse();
- }
- Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*tmp_curve ->last_segment());
+ Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*this->sa_overwrited ->last_segment());
SPCurve *last_segment = new SPCurve();
- Geom::Point point_a = tmp_curve->last_segment()->initialPoint();
- Geom::Point point_d = *tmp_curve->last_point();
+ Geom::Point point_a = this->sa_overwrited->last_segment()->initialPoint();
+ Geom::Point point_d = *this->sa_overwrited->last_point();
Geom::Point point_c = point_d + (1./3)*(point_a - point_d);
point_c = Geom::Point(point_c[X] + HANDLE_CUBIC_GAP, point_c[Y] + HANDLE_CUBIC_GAP);
if(cubic){
@@ -1450,43 +1433,34 @@ void PenTool::_bsplineSpiroStartAnchorOn()
last_segment->moveto(point_a);
last_segment->curveto(point_a,point_c,point_d);
}
- if( tmp_curve ->get_segment_count() == 1){
- tmp_curve = last_segment;
+ if( this->sa_overwrited->get_segment_count() == 1){
+ this->sa_overwrited = last_segment->copy();
}else{
//we eliminate the last segment
- tmp_curve ->backspace();
+ this->sa_overwrited->backspace();
//and we add it again with the recreation
- tmp_curve ->append_continuous(last_segment, 0.0625);
+ this->sa_overwrited->append_continuous(last_segment, 0.0625);
}
- if (this->sa->start) {
- tmp_curve = tmp_curve ->create_reverse();
- }
- this->overwrite_curve = tmp_curve ;
+ last_segment->unref();
}
void PenTool::_bsplineSpiroStartAnchorOff()
{
- SPCurve *tmp_curve = this->sa->curve->copy();
- if(this->sa->start)
- tmp_curve = tmp_curve ->create_reverse();
- Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*tmp_curve ->last_segment());
+ Geom::CubicBezier const * cubic = dynamic_cast<Geom::CubicBezier const*>(&*this->sa_overwrited->last_segment());
if(cubic){
SPCurve *last_segment = new SPCurve();
last_segment->moveto((*cubic)[0]);
last_segment->curveto((*cubic)[1],(*cubic)[3],(*cubic)[3]);
- if( tmp_curve ->get_segment_count() == 1){
- tmp_curve = last_segment;
+ if( this->sa_overwrited->get_segment_count() == 1){
+ this->sa_overwrited = last_segment->copy();
}else{
//we eliminate the last segment
- tmp_curve ->backspace();
+ this->sa_overwrited->backspace();
//and we add it again with the recreation
- tmp_curve ->append_continuous(last_segment, 0.0625);
+ this->sa_overwrited->append_continuous(last_segment, 0.0625);
}
+ last_segment->unref();
}
- if (this->sa->start) {
- tmp_curve = tmp_curve ->create_reverse();
- }
- this->overwrite_curve = tmp_curve;
}
void PenTool::_bsplineSpiroMotion(guint const state){
@@ -1503,17 +1477,14 @@ void PenTool::_bsplineSpiroMotion(guint const state){
this->p[2] = Geom::Point(this->p[2][X] + HANDLE_CUBIC_GAP,this->p[2][Y] + HANDLE_CUBIC_GAP);
if (this->green_curve->is_unset() && !this->sa) {
this->p[1] = this->p[0] + (1./3)*(this->p[3] - this->p[0]);
- this->p[1] = Geom::Point(this->p[1][X] + HANDLE_CUBIC_GAP,this->p[1][Y] + HANDLE_CUBIC_GAP);
+ this->p[1] = Geom::Point(this->p[1][X] + HANDLE_CUBIC_GAP, this->p[1][Y] + HANDLE_CUBIC_GAP);
if(shift){
this->p[2] = this->p[3];
}
} else if (!this->green_curve->is_unset()){
tmp_curve = this->green_curve->copy();
} else {
- tmp_curve = this->overwrite_curve->copy();
- if(this->sa->start) {
- tmp_curve = tmp_curve ->create_reverse();
- }
+ tmp_curve = this->sa_overwrited->copy();
}
if ((state & GDK_MOD1_MASK ) && previous != Geom::Point(0,0)) { //ALT drag
this->p[0] = this->p[0] + (this->p[3] - previous);
@@ -1550,11 +1521,7 @@ void PenTool::_bsplineSpiroMotion(guint const state){
}
cubic = dynamic_cast<Geom::CubicBezier const*>(&*tmp_curve ->last_segment());
if (this->sa && this->green_curve->is_unset()) {
- if(this->sa->start) {
- this->overwrite_curve = tmp_curve->copy()->create_reverse();
- } else {
- this->overwrite_curve = tmp_curve->copy();
- }
+ this->sa_overwrited = tmp_curve->copy();
}
if (!this->green_bpaths.empty()) {
this->green_curve = tmp_curve->copy();
@@ -1588,6 +1555,9 @@ void PenTool::_bsplineSpiroMotion(guint const state){
if (shift) {
this->p[2] = this->p[3];
}
+ if(Geom::are_near((*cubic)[3], (*cubic)[2])) {
+ this->p[1] = this->p[0];
+ }
} else {
this->p[1] = (*cubic)[3] + ((*cubic)[3] - (*cubic)[2] );
}
@@ -1627,19 +1597,13 @@ void PenTool::_bsplineSpiroEndAnchorOn()
SPCurve *tmp_curve;
SPCurve *last_segment = new SPCurve();
Geom::Point point_c(0,0);
- bool reverse = false;
if( this->green_anchor && this->green_anchor->active ){
tmp_curve = this->green_curve->create_reverse();
if(this->green_curve->get_segment_count()==0){
return;
}
- reverse = true;
} else if(this->sa){
- tmp_curve = this->overwrite_curve->copy();
- if(!this->sa->start){
- tmp_curve = tmp_curve ->create_reverse();
- reverse = true;
- }
+ tmp_curve = this->sa_overwrited->copy()->create_reverse();
}else{
return;
}
@@ -1665,17 +1629,16 @@ void PenTool::_bsplineSpiroEndAnchorOn()
//and we add it again with the recreation
tmp_curve ->append_continuous(last_segment, 0.0625);
}
- if (reverse) {
- tmp_curve = tmp_curve ->create_reverse();
- }
+ tmp_curve = tmp_curve ->create_reverse();
if( this->green_anchor && this->green_anchor->active )
{
this->green_curve->reset();
- this->green_curve = tmp_curve ;
+ this->green_curve = tmp_curve->copy();
}else{
- this->overwrite_curve->reset();
- this->overwrite_curve = tmp_curve ;
+ this->sa_overwrited->reset();
+ this->sa_overwrited = tmp_curve->copy();
}
+ tmp_curve->unref();
}
void PenTool::_bsplineSpiroEndAnchorOff()
@@ -1683,20 +1646,14 @@ void PenTool::_bsplineSpiroEndAnchorOff()
SPCurve *tmp_curve;
SPCurve *last_segment = new SPCurve();
- bool reverse = false;
this->p[2] = this->p[3];
if( this->green_anchor && this->green_anchor->active ){
tmp_curve = this->green_curve->create_reverse();
if(this->green_curve->get_segment_count()==0){
return;
}
- reverse = true;
} else if(this->sa){
- tmp_curve = this->overwrite_curve->copy();
- if(!this->sa->start){
- tmp_curve = tmp_curve ->create_reverse();
- reverse = true;
- }
+ tmp_curve = this->sa_overwrited->copy()->create_reverse();
}else{
return;
}
@@ -1716,17 +1673,17 @@ void PenTool::_bsplineSpiroEndAnchorOff()
//and we add it again with the recreation
tmp_curve ->append_continuous(last_segment, 0.0625);
}
- if (reverse) {
- tmp_curve = tmp_curve ->create_reverse();
- }
+ tmp_curve = tmp_curve ->create_reverse();
+
if( this->green_anchor && this->green_anchor->active )
{
this->green_curve->reset();
- this->green_curve = tmp_curve ;
+ this->green_curve = tmp_curve->copy();
}else{
- this->overwrite_curve->reset();
- this->overwrite_curve = tmp_curve ;
+ this->sa_overwrited->reset();
+ this->sa_overwrited = tmp_curve->copy();
}
+ tmp_curve->unref();
}
//prepares the curves for its transformation into BSpline curve.
@@ -1740,10 +1697,7 @@ void PenTool::_bsplineSpiroBuild()
SPCurve *curve = new SPCurve();
//If we continuate the existing curve we add it at the start
if(this->sa && !this->sa->curve->is_unset()){
- curve = this->overwrite_curve->copy();
- if (this->sa->start) {
- curve = curve->create_reverse();
- }
+ curve = this->sa_overwrited->copy();
}
if (!this->green_curve->is_unset()){
@@ -2038,7 +1992,6 @@ void PenTool::_finish(gboolean const closed) {
// cancelate line without a created segment
this->red_curve->reset();
spdc_concat_colors_and_flush(this, closed);
- this->overwrite_curve = NULL;
this->sa = NULL;
this->ea = NULL;
diff --git a/src/ui/tools/pencil-tool.cpp b/src/ui/tools/pencil-tool.cpp
index 13d69b063..db1b975ef 100644
--- a/src/ui/tools/pencil-tool.cpp
+++ b/src/ui/tools/pencil-tool.cpp
@@ -211,7 +211,12 @@ bool PencilTool::_handleButtonPress(GdkEventButton const &bevent) {
}
if (anchor) {
p = anchor->dp;
- this->overwrite_curve = anchor->curve;
+ //Put the start overwrite curve always on the same direction
+ if (anchor->start) {
+ this->sa_overwrited = anchor->curve->create_reverse();
+ } else {
+ this->sa_overwrited = anchor->curve->copy();
+ }
desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Continuing selected path"));
} else {
m.setup(desktop, true);
@@ -277,6 +282,25 @@ bool PencilTool::_handleMotionNotify(GdkEventMotion const &mevent) {
return false; // Do not drag if we're within tolerance from origin.
}
}
+ // motion notify coordinates as given (no snapping back to origin)
+ if (input_has_pressure && pencil_within_tolerance) {
+ anchor = spdc_test_inside(this, pencil_drag_origin_w);
+ if (anchor) {
+ this->sa = anchor;
+ //Put the start overwrite curve always on the same direction
+ if (anchor->start) {
+ this->sa_overwrited = this->sa->curve->create_reverse();
+ } else {
+ this->sa_overwrited = this->sa->curve->copy();
+ }
+ p = anchor->dp;
+ this->_setStartpoint(p);
+ desktop->messageStack()->flash(Inkscape::NORMAL_MESSAGE, _("Continuing selected path"));
+ }
+ }
+ if (input_has_pressure) {
+ this->state = SP_PENCIL_CONTEXT_FREEHAND;
+ }
// Once the user has moved farther than tolerance from the original location
// (indicating they intend to move the object, not click), then always process the
@@ -760,7 +784,7 @@ PencilTool::addPowerStrokePencil(SPCurve * c)
min = max;
}
bool live = false;
- SPCurve * curve;
+ SPCurve * curve = new SPCurve();
if (sa) {
Effect* lpe = SP_LPE_ITEM(white_item)->getCurrentLPE();
LPEPowerStroke* ps = static_cast<LPEPowerStroke*>(lpe);
@@ -786,40 +810,27 @@ PencilTool::addPowerStrokePencil(SPCurve * c)
stroreps.clear();
strorewps.clear();
prefs->setDouble("/tools/freehand/pencil/tolerance", tol);
- if (sa) {
- curve = sa->curve;
- if(prefs->getInt("/tools/freehand/pencil/freehand-mode", 0) == 1 ||
- prefs->getInt("/tools/freehand/pencil/freehand-mode", 0) == 2)
- {
- curve = overwrite_curve;
- }
- if (sa->start) {
- SPCurve *ret = curve->create_reverse();
- curve->unref();
- curve = ret->copy();
- ret->unref();
- }
- if (!green_curve->is_empty()) {
- if (curve->is_empty()) {
- curve = green_curve->copy();
- } else {
- green_curve->move_endpoints(curve->first_path()->finalPoint(), green_curve->first_path()->finalPoint());
- curve->append_continuous( green_curve, 0.0625);
- }
- if (!red_curve->is_empty()) {
+ if (sa && sa->curve) {
+ curve = sa_overwrited->copy();
+ if (!green_curve->is_unset()) {
+ curve->append_continuous( green_curve, 0.0625);
+ if (!red_curve->is_unset()) {
curve->append_continuous( red_curve, 0.0625);
}
}
} else {
- if (!green_curve->is_empty()) {
+ if (!green_curve->is_unset()) {
curve = green_curve->copy();
- if (!red_curve->is_empty()) {
+ if (!red_curve->is_unset()) {
curve->append_continuous( red_curve, 0.0625);
}
} else {
curve = NULL;
}
}
+ if (curve->is_empty()) {
+ curve = NULL;
+ }
red_curve = previous_red->copy();
green_curve = previous_green->copy();
previous_red->unref();
diff --git a/src/ui/widget/registered-widget.cpp b/src/ui/widget/registered-widget.cpp
index a88413347..a3b87f89b 100644
--- a/src/ui/widget/registered-widget.cpp
+++ b/src/ui/widget/registered-widget.cpp
@@ -279,7 +279,6 @@ RegisteredScalar::RegisteredScalar ( const Glib::ustring& label, const Glib::ust
init_parent(key, wr, repr_in, doc_in);
setProgrammatically = false;
-
setRange (-1e6, 1e6);
setDigits (2);
setIncrements(0.1, 1.0);
@@ -299,12 +298,14 @@ RegisteredScalar::on_value_changed()
_wr->setUpdating (true);
Inkscape::SVGOStringStream os;
- os << getValue();
-
- set_sensitive(false);
+ //Force exact 0 if decimals over to 6
+ double val = getValue() < 1e-6 && getValue() > -1e-6?0.0:getValue();
+ os << val;
+ //TODO: Test is ok remove this sensitives
+ //also removed in registed text and in registered random
+ //set_sensitive(false);
write_to_xml(os.str().c_str());
- set_sensitive(true);
-
+ //set_sensitive(true);
_wr->setUpdating (false);
}
@@ -342,11 +343,9 @@ RegisteredText::on_activate()
}
_wr->setUpdating (true);
Glib::ustring str(getText());
- set_sensitive(false);
Inkscape::SVGOStringStream os;
os << str;
write_to_xml(os.str().c_str());
- set_sensitive(true);
_wr->setUpdating (false);
}
@@ -757,7 +756,6 @@ RegisteredRandom::RegisteredRandom ( const Glib::ustring& label, const Glib::ust
init_parent(key, wr, repr_in, doc_in);
setProgrammatically = false;
-
setRange (-1e6, 1e6);
setDigits (2);
setIncrements(0.1, 1.0);
@@ -786,12 +784,10 @@ RegisteredRandom::on_value_changed()
_wr->setUpdating (true);
Inkscape::SVGOStringStream os;
- os << getValue() << ';' << getStartSeed();
-
- set_sensitive(false);
+ //Force exact 0 if decimals over to 6
+ double val = getValue() < 1e-6 && getValue() > -1e-6?0.0:getValue();
+ os << val << ';' << getStartSeed();
write_to_xml(os.str().c_str());
- set_sensitive(true);
-
_wr->setUpdating (false);
}
diff --git a/src/ui/widget/registered-widget.h b/src/ui/widget/registered-widget.h
index f66d5cbf2..765fa77b6 100644
--- a/src/ui/widget/registered-widget.h
+++ b/src/ui/widget/registered-widget.h
@@ -12,11 +12,11 @@
#ifndef INKSCAPE_UI_WIDGET_REGISTERED_WIDGET__H_
#define INKSCAPE_UI_WIDGET_REGISTERED_WIDGET__H_
-#include "ui/widget/scalar.h"
#include <2geom/affine.h>
#include "xml/node.h"
#include "registry.h"
+#include "ui/widget/scalar.h"
#include "ui/widget/scalar-unit.h"
#include "ui/widget/point.h"
#include "ui/widget/text.h"
@@ -108,12 +108,14 @@ protected:
bool saved = DocumentUndo::getUndoSensitive(local_doc);
DocumentUndo::setUndoSensitive(local_doc, false);
+ const char * svgstr_old = local_repr->attribute(_key.c_str());
if (!write_undo) {
local_repr->setAttribute(_key.c_str(), svgstr);
}
DocumentUndo::setUndoSensitive(local_doc, saved);
-
- local_doc->setModifiedSinceSave();
+ if (svgstr_old && svgstr && strcmp(svgstr_old,svgstr)) {
+ local_doc->setModifiedSinceSave();
+ }
if (write_undo) {
local_repr->setAttribute(_key.c_str(), svgstr);
@@ -244,9 +246,8 @@ public:
Registry& wr,
Inkscape::XML::Node* repr_in = NULL,
SPDocument *doc_in = NULL );
-
protected:
- sigc::connection _value_changed_connection;
+ sigc::connection _value_changed_connection;
void on_value_changed();
};
diff --git a/src/ui/widget/scalar.cpp b/src/ui/widget/scalar.cpp
index f8543a371..937bea697 100644
--- a/src/ui/widget/scalar.cpp
+++ b/src/ui/widget/scalar.cpp
@@ -14,7 +14,6 @@
# include <config.h>
#endif
-
#include "scalar.h"
#include "spinbutton.h"
#include <gtkmm/scale.h>
@@ -149,6 +148,11 @@ Glib::SignalProxy0<void> Scalar::signal_value_changed()
return static_cast<SpinButton*>(_widget)->signal_value_changed();
}
+Glib::SignalProxy1<bool, GdkEventButton*> Scalar::signal_button_release_event()
+{
+ return static_cast<SpinButton*>(_widget)->signal_button_release_event();
+}
+
} // namespace Widget
} // namespace UI
diff --git a/src/ui/widget/scalar.h b/src/ui/widget/scalar.h
index f186f46ac..b2c923953 100644
--- a/src/ui/widget/scalar.h
+++ b/src/ui/widget/scalar.h
@@ -153,6 +153,11 @@ public:
Glib::SignalProxy0<void> signal_value_changed();
/**
+ * Signal raised when the spin button's pressed.
+ */
+ Glib::SignalProxy1<bool, GdkEventButton*> signal_button_release_event();
+
+ /**
* true if the value was set by setValue, not changed by the user;
* if a callback checks it, it must reset it back to false.
*/
diff --git a/src/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp
index 23e1eba1a..907285a60 100644
--- a/src/widgets/arc-toolbar.cpp
+++ b/src/widgets/arc-toolbar.cpp
@@ -45,15 +45,20 @@
#include "toolbox.h"
#include "ui/icon-names.h"
#include "ui/uxmanager.h"
+#include "ui/widget/unit-tracker.h"
#include "ui/tools/arc-tool.h"
#include "verbs.h"
#include "widgets/spinbutton-events.h"
+#include "widgets/widget-sizes.h"
#include "xml/node-event-vector.h"
+using Inkscape::UI::Widget::UnitTracker;
using Inkscape::UI::UXManager;
using Inkscape::DocumentUndo;
using Inkscape::UI::ToolboxFactory;
using Inkscape::UI::PrefPusher;
+using Inkscape::Util::Quantity;
+using Inkscape::Util::unit_table;
//########################
//## Circle / Arc ##
@@ -75,6 +80,79 @@ static void sp_arctb_sensitivize( GObject *tbl, double v1, double v2 )
}
}
+static void sp_arctb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name)
+{
+ // Per SVG spec "a [radius] value of zero disables rendering of the element".
+ // However our implementation does not allow a setting of zero in the UI (not even in the XML editor)
+ // and ugly things happen if it's forced here, so better leave the properties untouched.
+ if (!gtk_adjustment_get_value(adj)) {
+ return;
+ }
+
+ SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" ));
+
+ UnitTracker* tracker = reinterpret_cast<UnitTracker*>(g_object_get_data( tbl, "tracker" ));
+ Unit const *unit = tracker->getActiveUnit();
+ g_return_if_fail(unit != NULL);
+
+ SPDocument* document = desktop->getDocument();
+ Geom::Scale scale = document->getDocumentScale();
+
+ if (DocumentUndo::getUndoSensitive(document)) {
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ prefs->setDouble(Glib::ustring("/tools/shapes/arc/") + value_name,
+ Quantity::convert(gtk_adjustment_get_value(adj), unit, "px"));
+ }
+
+ // quit if run by the attr_changed listener
+ if (g_object_get_data( tbl, "freeze" ) || tracker->isUpdating()) {
+ return;
+ }
+
+ // in turn, prevent listener from responding
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE));
+
+ bool modmade = false;
+ Inkscape::Selection *selection = desktop->getSelection();
+ auto itemlist= selection->items();
+ for(auto i=itemlist.begin();i!=itemlist.end();++i){
+ SPItem *item = *i;
+ if (SP_IS_GENERICELLIPSE(item)) {
+
+ SPGenericEllipse *ge = SP_GENERICELLIPSE(item);
+
+ if (!strcmp(value_name, "rx")) {
+ ge->setVisibleRx(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px"));
+ } else {
+ ge->setVisibleRy(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px"));
+ }
+
+ ge->normalize();
+ (SP_OBJECT(ge))->updateRepr();
+ (SP_OBJECT(ge))->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG);
+
+ modmade = true;
+ }
+ }
+
+ if (modmade) {
+ DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_ARC,
+ _("Change arc"));
+ }
+
+ g_object_set_data( tbl, "freeze", GINT_TO_POINTER(FALSE) );
+}
+
+static void sp_arctb_rx_value_changed(GtkAdjustment *adj, GObject *tbl)
+{
+ sp_arctb_value_changed(adj, tbl, "rx");
+}
+
+static void sp_arctb_ry_value_changed(GtkAdjustment *adj, GObject *tbl)
+{
+ sp_arctb_value_changed(adj, tbl, "ry");
+}
+
static void
sp_arctb_startend_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const *value_name, gchar const *other_name)
{
@@ -204,6 +282,7 @@ static void sp_arctb_open_state_changed( EgeSelectOneAction *act, GObject *tbl )
static void sp_arctb_defaults(GtkWidget *, GObject *obj)
{
GtkAdjustment *adj;
+
adj = GTK_ADJUSTMENT( g_object_get_data(obj, "start") );
gtk_adjustment_set_value(adj, 0.0);
gtk_adjustment_value_changed(adj);
@@ -229,6 +308,26 @@ static void arc_tb_event_attr_changed(Inkscape::XML::Node *repr, gchar const * /
// in turn, prevent callbacks from responding
g_object_set_data( tbl, "freeze", GINT_TO_POINTER(TRUE) );
+ gpointer item = g_object_get_data( tbl, "item" );
+ if (item && SP_IS_GENERICELLIPSE(item)) {
+ SPGenericEllipse *ge = SP_GENERICELLIPSE(item);
+
+ UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) );
+ Unit const *unit = tracker->getActiveUnit();
+ g_return_if_fail(unit != NULL);
+
+ GtkAdjustment *adj;
+ adj = GTK_ADJUSTMENT( g_object_get_data(tbl, "rx") );
+ gdouble rx = ge->getVisibleRx();
+ gtk_adjustment_set_value(adj, Quantity::convert(rx, "px", unit));
+ gtk_adjustment_value_changed(adj);
+
+ adj = GTK_ADJUSTMENT( g_object_get_data(tbl, "ry") );
+ gdouble ry = ge->getVisibleRy();
+ gtk_adjustment_set_value(adj, Quantity::convert(ry, "px", unit));
+ gtk_adjustment_value_changed(adj);
+ }
+
gdouble start = 0.;
gdouble end = 0.;
sp_repr_get_double(repr, "sodipodi:start", &start);
@@ -276,14 +375,18 @@ static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GOb
{
int n_selected = 0;
Inkscape::XML::Node *repr = NULL;
+ SPItem *item = NULL;
+ if ( g_object_get_data( tbl, "repr" ) ) {
+ g_object_set_data( tbl, "item", NULL );
+ }
purge_repr_listener( tbl, tbl );
auto itemlist= selection->items();
for(auto i=itemlist.begin();i!=itemlist.end();++i){
- SPItem *item = *i;
- if (SP_IS_GENERICELLIPSE(item)) {
+ if (SP_IS_GENERICELLIPSE(*i)) {
n_selected++;
+ item = *i;
repr = item->getRepr();
}
}
@@ -297,8 +400,14 @@ static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GOb
g_object_set_data( tbl, "single", GINT_TO_POINTER(TRUE) );
g_object_set( G_OBJECT(act), "label", _("<b>Change:</b>"), NULL );
+ GtkAction* rx = GTK_ACTION( g_object_get_data( tbl, "rx_action" ) );
+ gtk_action_set_sensitive(rx, TRUE);
+ GtkAction* ry = GTK_ACTION( g_object_get_data( tbl, "ry_action" ) );
+ gtk_action_set_sensitive(ry, TRUE);
+
if (repr) {
g_object_set_data( tbl, "repr", repr );
+ g_object_set_data( tbl, "item", item );
Inkscape::GC::anchor(repr);
sp_repr_add_listener(repr, &arc_tb_repr_events, tbl);
sp_repr_synthesize_events(repr, &arc_tb_repr_events, tbl);
@@ -320,6 +429,9 @@ void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObjec
EgeAdjustmentAction* eact = 0;
GtkIconSize secondarySize = ToolboxFactory::prefToSize("/toolbox/secondary", 1);
+ UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR);
+ tracker->setActiveUnit(unit_table.getUnit("px"));
+ g_object_set_data( holder, "tracker", tracker );
{
EgeOutputAction* act = ege_output_action_new( "ArcStateAction", _("<b>New:</b>"), "", 0 );
@@ -328,6 +440,46 @@ void sp_arc_toolbox_prep(SPDesktop *desktop, GtkActionGroup* mainActions, GObjec
g_object_set_data( holder, "mode_action", act );
}
+ /* Radius X */
+ {
+ gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500};
+ eact = create_adjustment_action( "ArcRadiusXAction",
+ _("Horizontal radius"), _("Rx:"), _("Horizontal radius of the circle, ellipse, or arc"),
+ "/tools/shapes/arc/rx", 0,
+ GTK_WIDGET(desktop->canvas), holder, TRUE, "altx-arc",
+ 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
+ labels, values, G_N_ELEMENTS(labels),
+ sp_arctb_rx_value_changed, tracker);
+ tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
+ g_object_set_data( holder, "rx_action", eact );
+ gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+ }
+
+ /* Radius Y */
+ {
+ gchar const* labels[] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
+ gdouble values[] = {1, 2, 3, 5, 10, 20, 50, 100, 200, 500};
+ eact = create_adjustment_action( "ArcRadiusYAction",
+ _("Vertical radius"), _("Ry:"), _("Vertical radius of the circle, ellipse, or arc"),
+ "/tools/shapes/arc/ry", 0,
+ GTK_WIDGET(desktop->canvas), holder, FALSE, NULL,
+ 0, 1e6, SPIN_STEP, SPIN_PAGE_STEP,
+ labels, values, G_N_ELEMENTS(labels),
+ sp_arctb_ry_value_changed, tracker);
+ tracker->addAdjustment( ege_adjustment_action_get_adjustment(eact) );
+ g_object_set_data( holder, "ry_action", eact );
+ gtk_action_set_sensitive( GTK_ACTION(eact), FALSE );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(eact) );
+ }
+
+ // add the units menu
+ {
+ GtkAction* act = tracker->createAction( "ArcUnitsAction", _("Units"), ("") );
+ gtk_action_group_add_action( mainActions, act );
+ }
+
/* Start */
{
eact = create_adjustment_action( "ArcStartAction",
diff --git a/src/widgets/desktop-widget.cpp b/src/widgets/desktop-widget.cpp
index f9c8e4ac6..0f5d8b973 100644
--- a/src/widgets/desktop-widget.cpp
+++ b/src/widgets/desktop-widget.cpp
@@ -388,6 +388,7 @@ void SPDesktopWidget::init( SPDesktopWidget *dtw )
gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), dtw->guides_lock, 0, 0, 1, 1);
gtk_grid_attach(GTK_GRID(dtw->canvas_tbl), eventbox, 1, 0, 1, 1);
+
g_signal_connect (G_OBJECT (dtw->guides_lock), "toggled", G_CALLBACK (sp_update_guides_lock), dtw);
gtk_box_pack_start( GTK_BOX(dtw->hbox), tbl_wrapper, TRUE, TRUE, 1 );
@@ -993,7 +994,7 @@ void sp_update_guides_lock( GtkWidget */*button*/, gpointer data )
if ( down != nv->lockguides ) {
nv->lockguides = down;
- sp_namedview_guides_toggle_lock(doc, repr);
+ sp_namedview_guides_toggle_lock(doc, nv);
if (down) {
dtw->setMessage (Inkscape::NORMAL_MESSAGE, _("Locked all guides"));
} else {
@@ -1658,7 +1659,6 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview)
/* Once desktop is set, we can update rulers */
sp_desktop_widget_update_rulers (dtw);
- sp_button_toggle_set_down( SP_BUTTON(dtw->guides_lock), namedview->lockguides );
sp_view_widget_set_view (SP_VIEW_WIDGET (dtw), dtw->desktop);
@@ -1670,7 +1670,7 @@ SPDesktopWidget* SPDesktopWidget::createInstance(SPNamedView *namedview)
dtw->menubar = sp_ui_main_menubar (dtw->desktop);
gtk_widget_set_name(dtw->menubar, "MenuBar");
gtk_widget_show_all (dtw->menubar);
- SPNamedView *nv = dtw->desktop->namedview;
+
gtk_box_pack_start (GTK_BOX (dtw->vbox), dtw->menubar, FALSE, FALSE, 0);
dtw->layoutWidgets();