summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGeoff Lankow <geoff@darktrojan.net>2017-12-04 23:35:57 +0000
committerGeoff Lankow <geoff@darktrojan.net>2017-12-04 23:35:57 +0000
commitd1395472c4b20d4e4763364b61e3d6caedb29444 (patch)
tree069d23a7ebef5ae1f8bacc935a9fc0c5c72c4bcd /src
parentAdd controls for rx/ry to arc toolbar (diff)
downloadinkscape-d1395472c4b20d4e4763364b61e3d6caedb29444.tar.gz
inkscape-d1395472c4b20d4e4763364b61e3d6caedb29444.zip
Add arc radius to toolbar
Diffstat (limited to 'src')
-rw-r--r--src/sp-ellipse.cpp59
-rw-r--r--src/sp-ellipse.h13
-rw-r--r--src/widgets/arc-toolbar.cpp57
3 files changed, 95 insertions, 34 deletions
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/widgets/arc-toolbar.cpp b/src/widgets/arc-toolbar.cpp
index 3faea1750..907285a60 100644
--- a/src/widgets/arc-toolbar.cpp
+++ b/src/widgets/arc-toolbar.cpp
@@ -122,9 +122,9 @@ static void sp_arctb_value_changed(GtkAdjustment *adj, GObject *tbl, gchar const
SPGenericEllipse *ge = SP_GENERICELLIPSE(item);
if (!strcmp(value_name, "rx")) {
- ge->rx = Quantity::convert(gtk_adjustment_get_value(adj), unit, "px") / scale[Geom::X];
+ ge->setVisibleRx(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px"));
} else {
- ge->ry = Quantity::convert(gtk_adjustment_get_value(adj), unit, "px") / scale[Geom::Y];
+ ge->setVisibleRy(Quantity::convert(gtk_adjustment_get_value(adj), unit, "px"));
}
ge->normalize();
@@ -308,37 +308,25 @@ 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) );
- UnitTracker* tracker = reinterpret_cast<UnitTracker*>( g_object_get_data( tbl, "tracker" ) );
- Unit const *unit = tracker->getActiveUnit();
- g_return_if_fail(unit != NULL);
-
- gdouble radius = 0;
- gdouble rx = 0;
- gdouble ry = 0;
- sp_repr_get_double(repr, "r", &radius);
- if (radius) {
- rx = ry = radius;
- } else {
- sp_repr_get_double(repr, "rx", &rx);
- sp_repr_get_double(repr, "ry", &ry);
- }
- if (!rx) {
- sp_repr_get_double(repr, "sodipodi:rx", &rx);
- sp_repr_get_double(repr, "sodipodi:ry", &ry);
- }
+ gpointer item = g_object_get_data( tbl, "item" );
+ if (item && SP_IS_GENERICELLIPSE(item)) {
+ SPGenericEllipse *ge = SP_GENERICELLIPSE(item);
- SPDesktop *desktop = static_cast<SPDesktop *>(g_object_get_data( tbl, "desktop" ));
- SPDocument* document = desktop->getDocument();
- Geom::Scale scale = document->getDocumentScale();
+ 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") );
- gtk_adjustment_set_value(adj, Quantity::convert(rx, "px", unit) * scale[Geom::X]);
- gtk_adjustment_value_changed(adj);
+ 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") );
- gtk_adjustment_set_value(adj, Quantity::convert(ry, "px", unit) * scale[Geom::Y]);
- 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.;
@@ -387,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();
}
}
@@ -415,6 +407,7 @@ static void sp_arc_toolbox_selection_changed(Inkscape::Selection *selection, GOb
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);