summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJabier Arraiza Cenoz <jabier.arraiza@marker.es>2015-10-12 10:37:15 +0000
committerJabiertxof <jtx@jtx.marker.es>2015-10-12 10:37:15 +0000
commit2653fd7c3a138f91181f7bb64e1fd342c943ee7b (patch)
tree208c04e67468b39db595cdb539ed3914a7c9d7af /src
parentupdate to trunk (diff)
downloadinkscape-2653fd7c3a138f91181f7bb64e1fd342c943ee7b.tar.gz
inkscape-2653fd7c3a138f91181f7bb64e1fd342c943ee7b.zip
Convert Measure to Item done
(bzr r14393.1.17)
Diffstat (limited to 'src')
-rw-r--r--src/ui/tools/measure-tool.cpp905
-rw-r--r--src/ui/tools/measure-tool.h21
-rw-r--r--src/widgets/measure-toolbar.cpp17
-rw-r--r--src/widgets/toolbox.cpp1
4 files changed, 638 insertions, 306 deletions
diff --git a/src/ui/tools/measure-tool.cpp b/src/ui/tools/measure-tool.cpp
index 585128135..76b8e931e 100644
--- a/src/ui/tools/measure-tool.cpp
+++ b/src/ui/tools/measure-tool.cpp
@@ -4,6 +4,7 @@
* Authors:
* Felipe Correa da Silva Sanches <juca@members.fsf.org>
* Jon A. Cruz <jon@joncruz.org>
+ * Jabiertxo Arraiza <jabier.arraiza@marker.es>
*
* Copyright (C) 2011 Authors
*
@@ -14,42 +15,44 @@
#include <gdk/gdkkeysyms.h>
#include <boost/none_t.hpp>
#include "util/units.h"
-#include "macros.h"
-#include "rubberband.h"
+#include "display/canvas-text.h"
#include "display/curve.h"
-#include "text-editing.h"
-#include "display/sp-ctrlline.h"
#include "display/sodipodi-ctrl.h"
+#include "display/sp-ctrlline.h"
+#include "display/sp-canvas.h"
#include "display/sp-canvas-item.h"
#include "display/sp-canvas-util.h"
-#include "desktop.h"
#include "svg/svg.h"
-#include "document.h"
-#include "document-undo.h"
-#include <viewbox.h>
-#include "pixmaps/cursor-measure.xpm"
-#include "preferences.h"
-#include "inkscape.h"
-#include "knot.h"
+#include "svg/svg-color.h"
#include "ui/tools/measure-tool.h"
#include "ui/tools/freehand-base.h"
-#include "display/canvas-text.h"
-#include "path-chemistry.h"
-#include "2geom/line.h"
+#include "ui/control-manager.h"
+#include <2geom/line.h>
#include <2geom/path-intersection.h>
#include <2geom/pathvector.h>
#include <2geom/crossing.h>
#include <2geom/angle.h>
#include <2geom/transforms.h>
-#include "snap.h"
#include "sp-namedview.h"
#include "sp-shape.h"
#include "sp-text.h"
#include "sp-flowtext.h"
#include "sp-defs.h"
#include "sp-item.h"
+#include "macros.h"
+#include "rubberband.h"
+#include "path-chemistry.h"
+#include "desktop.h"
+#include "document.h"
+#include "document-undo.h"
+#include "viewbox.h"
+#include "snap.h"
+#include "text-editing.h"
+#include "pixmaps/cursor-measure.xpm"
+#include "preferences.h"
+#include "inkscape.h"
+#include "knot.h"
#include "enums.h"
-#include "ui/control-manager.h"
#include "knot-enums.h"
#include "desktop-style.h"
#include "verbs.h"
@@ -63,20 +66,21 @@ using Inkscape::DocumentUndo;
#define MT_KNOT_COLOR_NORMAL 0xffffff00
#define MT_KNOT_COLOR_MOUSEOVER 0xff000000
+
namespace Inkscape {
namespace UI {
namespace Tools {
std::vector<Inkscape::Display::TemporaryItem*> measure_tmp_items;
-const std::string& MeasureTool::getPrefsPath() {
+const std::string& MeasureTool::getPrefsPath()
+{
return MeasureTool::prefsPath;
}
const std::string MeasureTool::prefsPath = "/tools/measure";
-namespace
-{
+namespace {
gint dimension_offset = 35;
@@ -196,8 +200,9 @@ Geom::Point calcAngleDisplayAnchor(SPDesktop *desktop, double angle, double base
* @param end the point that ends at the edge of the arc segment.
* @param anchor the anchor point for displaying the text label.
* @param angle the angle of the arc segment to draw.
+ * @param measure_rpr the container of the curve if converted to items.
*/
-void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const &center, Geom::Point const &end, Geom::Point const &anchor, double angle)
+void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const &center, Geom::Point const &end, Geom::Point const &anchor, double angle, Inkscape::XML::Node *measure_repr = NULL)
{
// Given that we have a point on the arc's edge and the angle of the arc, we need to get the two endpoints.
@@ -205,7 +210,7 @@ void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const &center, Geom
double sideLen = std::abs((end - center).length());
if (sideLen > 0.0) {
double factor = std::min(1.0, textLen / sideLen);
-
+
// arc start
Geom::Point p1 = end * (Geom::Affine(Geom::Translate(-center))
* Geom::Affine(Geom::Scale(factor))
@@ -235,9 +240,47 @@ void createAngleDisplayCurve(SPDesktop *desktop, Geom::Point const &center, Geom
SPCtrlCurve *curve = ControlManager::getManager().createControlCurve(desktop->getTempGroup(), p1, p2, p3, p4, CTLINE_SECONDARY);
measure_tmp_items.push_back(desktop->add_temporary_canvasitem(SP_CANVAS_ITEM(curve), 0, true));
+ if(measure_repr) {
+ Geom::PathVector c;
+ Geom::Path p;
+ p.start(desktop->doc2dt(p1));
+ p.appendNew<Geom::CubicBezier>(desktop->doc2dt(p2),desktop->doc2dt(p3),desktop->doc2dt(p4));
+ c.push_back(p);
+ c *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
+ SPDocument *doc = desktop->getDocument();
+ Inkscape::XML::Document *xml_doc = doc->getReprDoc();
+ if (c.size() == 1) {
+ Inkscape::XML::Node *repr;
+ repr = xml_doc->createElement("svg:path");
+ gchar const *str = sp_svg_write_path(c);
+ Geom::Point strokewidth = Geom::Point(1,1) * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ std::stringstream stroke_width;
+ stroke_width.imbue(std::locale::classic());
+ stroke_width << strokewidth[Geom::X] / desktop->current_zoom();
+ sp_repr_css_set_property (css, "stroke-width", stroke_width.str().c_str());
+ sp_repr_css_set_property (css, "fill", "none");
+ guint32 line_color_secondary = 0xff00007f;
+ gchar c[64];
+ sp_svg_write_color (c, sizeof(c), line_color_secondary);
+ sp_repr_css_set_property (css, "stroke", c);
+ sp_repr_css_set_property (css, "stroke-linecap", "butt");
+ sp_repr_css_set_property (css, "stroke-linejoin", "miter");
+ sp_repr_css_set_property (css, "stroke-miterlimit", "4");
+ sp_repr_css_set_property (css, "stroke-dasharray", "none");
+ sp_repr_css_set_property (css, "stroke-opacity", "0.5");
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ repr->setAttribute("style", css_str.c_str());
+ sp_repr_css_attr_unref (css);
+ g_assert( str != NULL );
+ repr->setAttribute("d", str);
+ measure_repr->addChild(repr, NULL);
+ Inkscape::GC::release(repr);
+ }
+ }
}
}
-
} // namespace
Geom::Point const MAGIC_POINT = Geom::Point(-0.0003432532004303,-0.006745034004304);
@@ -249,7 +292,7 @@ MeasureTool::MeasureTool()
, grabbed(NULL)
{
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
- // create the knot
+ // create the knots
this->knot_start = new SPKnot(desktop, N_("Measure start"));
this->knot_start->setMode(SP_KNOT_MODE_XOR);
this->knot_start->setFill(MT_KNOT_COLOR_NORMAL, MT_KNOT_COLOR_MOUSEOVER, MT_KNOT_COLOR_MOUSEOVER);
@@ -262,12 +305,13 @@ MeasureTool::MeasureTool()
this->knot_end->setStroke(0x0000007f, 0x0000007f, 0x0000007f);
this->knot_end->setShape(SP_KNOT_SHAPE_CIRCLE);
this->knot_end->updateCtrl();
- if(end_p != MAGIC_POINT){
+ Geom::Rect display_area = desktop->get_display_area () ;
+ if(display_area.interiorContains(start_p) && display_area.interiorContains(end_p) && end_p != MAGIC_POINT) {
this->knot_start->moveto(start_p);
this->knot_start->show();
this->knot_end->moveto(end_p);
this->knot_end->show();
- this->showCanvasItems();
+ showCanvasItems();
}
this->_knot_start_moved_connection = this->knot_start->moved_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotStartMovedHandler));
this->_knot_start_ungrabbed_connection = this->knot_start->ungrabbed_signal.connect(sigc::mem_fun(*this, &MeasureTool::knotUngrabbedHandler));
@@ -276,7 +320,8 @@ MeasureTool::MeasureTool()
}
-MeasureTool::~MeasureTool() {
+MeasureTool::~MeasureTool()
+{
this->_knot_start_moved_connection.disconnect();
this->_knot_start_ungrabbed_connection.disconnect();
this->_knot_end_moved_connection.disconnect();
@@ -291,7 +336,8 @@ MeasureTool::~MeasureTool() {
measure_tmp_items.clear();
}
-void MeasureTool::reverseKnots(){
+void MeasureTool::reverseKnots()
+{
Geom::Point start = start_p;
Geom::Point end = end_p;
this->knot_start->moveto(end);
@@ -301,45 +347,59 @@ void MeasureTool::reverseKnots(){
this->showCanvasItems(end, start);
}
-void MeasureTool::knotStartMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state){
- if (!(state & GDK_SHIFT_MASK)) {
+void MeasureTool::knotStartMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state)
+{
+ Geom::Point point = this->knot_start->position();
+ if (state & GDK_CONTROL_MASK) {
+ spdc_endpoint_snap_rotation(this, point, end_p, state);
+ } else if (!(state & GDK_SHIFT_MASK)) {
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
- Inkscape::SnapCandidatePoint scp(this->knot_start->position(), Inkscape::SNAPSOURCE_OTHER_HANDLE);
+ Inkscape::SnapCandidatePoint scp(point, Inkscape::SNAPSOURCE_OTHER_HANDLE);
scp.addOrigin(this->knot_end->position());
Inkscape::SnappedPoint sp = m.freeSnap(scp);
- if(start_p != sp.getPoint()){
- start_p = sp.getPoint();
- this->knot_start->moveto(start_p);
- }
+ point = sp.getPoint();
m.unSetup();
}
- showCanvasItems(start_p, this->knot_end->position());
+ if(start_p != point) {
+ start_p = point;
+ this->knot_start->moveto(start_p);
+ }
+ showCanvasItems(start_p, end_p);
}
-void MeasureTool::knotEndMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state){
- if (!(state & GDK_SHIFT_MASK)) {
+void MeasureTool::knotEndMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state)
+{
+ Geom::Point point = this->knot_end->position();
+ if (state & GDK_CONTROL_MASK) {
+ spdc_endpoint_snap_rotation(this, point, start_p, state);
+ } else if (!(state & GDK_SHIFT_MASK)) {
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
- Inkscape::SnapCandidatePoint scp(this->knot_end->position(), Inkscape::SNAPSOURCE_OTHER_HANDLE);
+ Inkscape::SnapCandidatePoint scp(point, Inkscape::SNAPSOURCE_OTHER_HANDLE);
scp.addOrigin(this->knot_start->position());
Inkscape::SnappedPoint sp = m.freeSnap(scp);
- if(end_p != sp.getPoint()){
- end_p = sp.getPoint();
- this->knot_end->moveto(end_p);
- }
+ point = sp.getPoint();
m.unSetup();
}
- showCanvasItems(this->knot_start->position(), end_p);
+ if(end_p != point) {
+ end_p = point;
+ this->knot_end->moveto(end_p);
+ }
+ showCanvasItems(start_p, end_p);
}
-void MeasureTool::knotUngrabbedHandler(SPKnot */*knot*/, unsigned int state){
- showCanvasItems(this->knot_start->position(), this->knot_end->position());
+void MeasureTool::knotUngrabbedHandler(SPKnot */*knot*/, unsigned int state)
+{
+ this->knot_start->moveto(start_p);
+ this->knot_end->moveto(end_p);
+ showCanvasItems(start_p, end_p);
}
-void MeasureTool::finish() {
+void MeasureTool::finish()
+{
this->enableGrDrag(false);
if (this->grabbed) {
@@ -386,9 +446,9 @@ static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom:
double eps = 0.0001;
SPDocument* doc = desktop->getDocument();
if (((*m).ta > eps &&
- item == doc->getItemAtPoint(desktop->dkey, lineseg[0].pointAt((*m).ta - eps), false, NULL)) ||
- ((*m).ta + eps < 1 &&
- item == doc->getItemAtPoint(desktop->dkey, lineseg[0].pointAt((*m).ta + eps), false, NULL)) ) {
+ item == doc->getItemAtPoint(desktop->dkey, lineseg[0].pointAt((*m).ta - eps), false, NULL)) ||
+ ((*m).ta + eps < 1 &&
+ item == doc->getItemAtPoint(desktop->dkey, lineseg[0].pointAt((*m).ta + eps), false, NULL)) ) {
intersections.push_back((*m).ta);
}
#else
@@ -398,106 +458,83 @@ static void calculate_intersections(SPDesktop * /*desktop*/, SPItem* item, Geom:
}
}
-bool MeasureTool::root_handler(GdkEvent* event) {
+bool MeasureTool::root_handler(GdkEvent* event)
+{
gint ret = FALSE;
switch (event->type) {
- case GDK_BUTTON_PRESS: {
- this->knot_start->hide();
- this->knot_end->hide();
- Geom::Point const button_w(event->button.x, event->button.y);
- explicitBase = boost::none;
- last_end = boost::none;
- start_point = desktop->w2d(button_w);
-
- if (event->button.button == 1 && !this->space_panning) {
- // save drag origin
- start_point = desktop->w2d(Geom::Point(event->button.x, event->button.y));
- within_tolerance = true;
-
- ret = TRUE;
- }
+ case GDK_BUTTON_PRESS: {
+ this->knot_start->hide();
+ this->knot_end->hide();
+ Geom::Point const button_w(event->button.x, event->button.y);
+ explicitBase = boost::none;
+ last_end = boost::none;
+ start_point = desktop->w2d(button_w);
+
+ if (event->button.button == 1 && !this->space_panning) {
+ // save drag origin
+ start_point = desktop->w2d(Geom::Point(event->button.x, event->button.y));
+ within_tolerance = true;
+
+ ret = TRUE;
+ }
- SnapManager &m = desktop->namedview->snap_manager;
- m.setup(desktop);
- m.freeSnapReturnByRef(start_point, Inkscape::SNAPSOURCE_OTHER_HANDLE);
- m.unSetup();
+ SnapManager &m = desktop->namedview->snap_manager;
+ m.setup(desktop);
+ m.freeSnapReturnByRef(start_point, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+ m.unSetup();
- sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
- GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK,
- NULL, event->button.time);
- this->grabbed = SP_CANVAS_ITEM(desktop->acetate);
- break;
- }
- case GDK_KEY_PRESS: {
- if ((event->key.keyval == GDK_KEY_Shift_L) || (event->key.keyval == GDK_KEY_Shift_R)) {
- if (last_end) {
- explicitBase = last_end;
- }
+ sp_canvas_item_grab(SP_CANVAS_ITEM(desktop->acetate),
+ GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK | GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK,
+ NULL, event->button.time);
+ this->grabbed = SP_CANVAS_ITEM(desktop->acetate);
+ break;
+ }
+ case GDK_KEY_PRESS: {
+ if ((event->key.keyval == GDK_KEY_Shift_L) || (event->key.keyval == GDK_KEY_Shift_R)) {
+ if (last_end) {
+ explicitBase = last_end;
}
- break;
}
- case GDK_MOTION_NOTIFY: {
- if (!(event->motion.state & GDK_BUTTON1_MASK)){
- if(!(event->motion.state & GDK_SHIFT_MASK)) {
- Geom::Point const motion_w(event->motion.x, event->motion.y);
- Geom::Point const motion_dt(desktop->w2d(motion_w));
+ break;
+ }
+ case GDK_MOTION_NOTIFY: {
+ if (!(event->motion.state & GDK_BUTTON1_MASK)) {
+ if(!(event->motion.state & GDK_SHIFT_MASK)) {
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ Geom::Point const motion_dt(desktop->w2d(motion_w));
- SnapManager &m = desktop->namedview->snap_manager;
- m.setup(desktop);
+ SnapManager &m = desktop->namedview->snap_manager;
+ m.setup(desktop);
- Inkscape::SnapCandidatePoint scp(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE);
- scp.addOrigin(start_point);
+ Inkscape::SnapCandidatePoint scp(motion_dt, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+ scp.addOrigin(start_point);
- m.preSnap(scp);
- m.unSetup();
- }
- } else {
- ret = TRUE;
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
- Geom::Point const motion_w(event->motion.x, event->motion.y);
- if ( within_tolerance){
- if ( Geom::LInfty( motion_w - start_point ) < tolerance) {
- return FALSE; // Do not drag if we're within tolerance from origin.
- }
- }
- // 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
- // motion notify coordinates as given (no snapping back to origin)
- within_tolerance = false;
- if(event->motion.time == 0 || !last_end || Geom::LInfty( motion_w - *last_end ) > (tolerance/2)){
- Geom::Point const motion_w(event->motion.x, event->motion.y);
- Geom::Point const motion_dt(desktop->w2d(motion_w));
- Geom::Point end_point = motion_dt;
-
- if (event->motion.state & GDK_CONTROL_MASK) {
- spdc_endpoint_snap_rotation(this, end_point, start_point, event->motion.state);
- } else if (!(event->motion.state & GDK_SHIFT_MASK)) {
- SnapManager &m = desktop->namedview->snap_manager;
- m.setup(desktop);
- Inkscape::SnapCandidatePoint scp(end_point, Inkscape::SNAPSOURCE_OTHER_HANDLE);
- scp.addOrigin(start_point);
- Inkscape::SnappedPoint sp = m.freeSnap(scp);
- end_point = sp.getPoint();
- m.unSetup();
- }
- showCanvasItems(start_point, end_point);
- last_end = motion_w ;
+ m.preSnap(scp);
+ m.unSetup();
+ }
+ } else {
+ ret = TRUE;
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ tolerance = prefs->getIntLimited("/options/dragtolerance/value", 0, 0, 100);
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ if ( within_tolerance) {
+ if ( Geom::LInfty( motion_w - start_point ) < tolerance) {
+ return FALSE; // Do not drag if we're within tolerance from origin.
}
- gobble_motion_events(GDK_BUTTON1_MASK);
}
- break;
- }
- case GDK_BUTTON_RELEASE: {
- this->knot_start->moveto(start_point);
- this->knot_start->show();
- Geom::Point end_point = end_p;
- if(last_end){
- end_point = desktop->w2d(*last_end);
- if (event->button.state & GDK_CONTROL_MASK) {
+ // 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
+ // motion notify coordinates as given (no snapping back to origin)
+ within_tolerance = false;
+ if(event->motion.time == 0 || !last_end || Geom::LInfty( motion_w - *last_end ) > (tolerance/4.0)) {
+ Geom::Point const motion_w(event->motion.x, event->motion.y);
+ Geom::Point const motion_dt(desktop->w2d(motion_w));
+ Geom::Point end_point = motion_dt;
+
+ if (event->motion.state & GDK_CONTROL_MASK) {
spdc_endpoint_snap_rotation(this, end_point, start_point, event->motion.state);
- } else if (!(event->button.state & GDK_SHIFT_MASK)) {
+ } else if (!(event->motion.state & GDK_SHIFT_MASK)) {
SnapManager &m = desktop->namedview->snap_manager;
m.setup(desktop);
Inkscape::SnapCandidatePoint scp(end_point, Inkscape::SNAPSOURCE_OTHER_HANDLE);
@@ -506,153 +543,317 @@ bool MeasureTool::root_handler(GdkEvent* event) {
end_point = sp.getPoint();
m.unSetup();
}
+ showCanvasItems(start_point, end_point);
+ last_end = motion_w ;
}
- this->knot_end->moveto(end_point);
- this->knot_end->show();
- showCanvasItems(start_point, end_point);
- if (this->grabbed) {
- sp_canvas_item_ungrab(this->grabbed, event->button.time);
- this->grabbed = NULL;
+ gobble_motion_events(GDK_BUTTON1_MASK);
+ }
+ break;
+ }
+ case GDK_BUTTON_RELEASE: {
+ this->knot_start->moveto(start_point);
+ this->knot_start->show();
+ Geom::Point end_point = end_p;
+ if(last_end) {
+ end_point = desktop->w2d(*last_end);
+ if (event->button.state & GDK_CONTROL_MASK) {
+ spdc_endpoint_snap_rotation(this, end_point, start_point, event->motion.state);
+ } else if (!(event->button.state & GDK_SHIFT_MASK)) {
+ SnapManager &m = desktop->namedview->snap_manager;
+ m.setup(desktop);
+ Inkscape::SnapCandidatePoint scp(end_point, Inkscape::SNAPSOURCE_OTHER_HANDLE);
+ scp.addOrigin(start_point);
+ Inkscape::SnappedPoint sp = m.freeSnap(scp);
+ end_point = sp.getPoint();
+ m.unSetup();
}
- break;
}
- default:
- break;
+ this->knot_end->moveto(end_point);
+ this->knot_end->show();
+ showCanvasItems(start_point, end_point);
+ if (this->grabbed) {
+ sp_canvas_item_ungrab(this->grabbed, event->button.time);
+ this->grabbed = NULL;
+ }
+ break;
+ }
+ default:
+ break;
}
if (!ret) {
ret = ToolBase::root_handler(event);
}
-
+
return ret;
}
-void MeasureTool::setMarkers(){
- SPDesktop *desktop = this->desktop;
+void MeasureTool::setMarkers()
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
SPDocument *doc = desktop->getDocument();
SPObject *arrowStart = doc->getObjectById("Arrow2Sstart");
SPObject *arrowEnd = doc->getObjectById("Arrow2Send");
if (!arrowStart) {
setMarker(true);
}
- if(!arrowEnd){
+ if(!arrowEnd) {
setMarker(false);
}
}
-void MeasureTool::setMarker(bool isStart){
- SPDesktop *desktop = this->desktop;
+void MeasureTool::setMarker(bool isStart)
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
SPDocument *doc = desktop->getDocument();
SPDefs *defs = doc->getDefs();
- Inkscape::XML::Node *repr;
+ Inkscape::XML::Node *rmarker;
Inkscape::XML::Document *xml_doc = doc->getReprDoc();
- repr = xml_doc->createElement("svg:marker");
- if(isStart){
- repr->setAttribute("id", "Arrow2Sstart");
+ rmarker = xml_doc->createElement("svg:marker");
+ if(isStart) {
+ rmarker->setAttribute("id", "Arrow2Sstart");
} else {
- repr->setAttribute("id", "Arrow2Send");
+ rmarker->setAttribute("id", "Arrow2Send");
}
- repr->setAttribute("inkscape:isstock", "true");
- if(isStart){
- repr->setAttribute("inkscape:stockid", "Arrow2Sstart");
+ rmarker->setAttribute("inkscape:isstock", "true");
+ if(isStart) {
+ rmarker->setAttribute("inkscape:stockid", "Arrow2Sstart");
} else {
- repr->setAttribute("inkscape:stockid", "Arrow2Send");
+ rmarker->setAttribute("inkscape:stockid", "Arrow2Send");
}
- repr->setAttribute("orient", "auto");
- repr->setAttribute("refX", "0.0");
- repr->setAttribute("refY", "0.0");
- repr->setAttribute("style", "overflow:visible;");
- SPItem *item = SP_ITEM(defs->appendChildRepr(repr));
- Inkscape::GC::release(repr);
- item->updateRepr();
- Inkscape::XML::Node *repr2;
- repr2 = xml_doc->createElement("svg:path");
- repr2->setAttribute("d", "M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z");
- if(isStart){
- repr2->setAttribute("id", "Arrow2SstartPath");
+ rmarker->setAttribute("orient", "auto");
+ rmarker->setAttribute("refX", "0.0");
+ rmarker->setAttribute("refY", "0.0");
+ rmarker->setAttribute("style", "overflow:visible;");
+ SPItem *marker = SP_ITEM(defs->appendChildRepr(rmarker));
+ Inkscape::GC::release(rmarker);
+ marker->updateRepr();
+ Inkscape::XML::Node *rpath;
+ rpath = xml_doc->createElement("svg:path");
+ rpath->setAttribute("d", "M 8.72,4.03 L -2.21,0.02 L 8.72,-4.00 C 6.97,-1.63 6.98,1.62 8.72,4.03 z");
+ if(isStart) {
+ rpath->setAttribute("id", "Arrow2SstartPath");
} else {
- repr2->setAttribute("id", "Arrow2SendPath");
+ rpath->setAttribute("id", "Arrow2SendPath");
}
- repr2->setAttribute("style", "stroke:#000000;stroke-opacity:1;fill:#000000;fill-opacity:1");
- if(isStart){
- repr2->setAttribute("transform", "scale(0.3) translate(-2.3,0)");
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ sp_repr_css_set_property (css, "stroke", "none");
+ sp_repr_css_set_property (css, "fill", "#000000");
+ sp_repr_css_set_property (css, "fill-opacity", "1");
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ rpath->setAttribute("style", css_str.c_str());
+ sp_repr_css_attr_unref (css);
+ if(isStart) {
+ rpath->setAttribute("transform", "scale(0.3) translate(-2.3,0)");
} else {
- repr2->setAttribute("transform", "scale(0.3) rotate(180) translate(-2.3,0)");
+ rpath->setAttribute("transform", "scale(0.3) rotate(180) translate(-2.3,0)");
}
- SPItem *item2 = SP_ITEM(item->appendChildRepr(repr2));
- Inkscape::GC::release(repr2);
- item2->updateRepr();
+ SPItem *path = SP_ITEM(marker->appendChildRepr(rpath));
+ Inkscape::GC::release(rpath);
+ path->updateRepr();
+}
+
+void MeasureTool::toItem()
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SPDocument *doc = desktop->getDocument();
+ Geom::Ray ray(start_p,end_p);
+ guint32 line_color_primary = 0x0000ff7f;
+ Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc();
+ Inkscape::XML::Node *rgroup = xml_doc->createElement("svg:g");
+ showCanvasItems(start_p, end_p, true, rgroup);
+ setLine(start_p,end_p, false, &line_color_primary, rgroup);
+ SPItem *measure_item = SP_ITEM(desktop->currentLayer()->appendChildRepr(rgroup));
+ Inkscape::GC::release(rgroup);
+ measure_item->updateRepr();
+ doc->ensureUpToDate();
+ DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Convert measure to items"));
+ reset();
}
-void MeasureTool::toMarkDimension(){
+void MeasureTool::toMarkDimension()
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ SPDocument *doc = desktop->getDocument();
setMarkers();
- Geom::PathVector c;
- Geom::Path p;
Geom::Ray ray(start_p,end_p);
Geom::Point start = start_p + Geom::Point::polar(ray.angle(), 5);
- start = desktop->doc2dt(start + Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), -(dimension_offset / 4.0)));
+ start = start + Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), -(dimension_offset / 4.0));
Geom::Point end = end_p + Geom::Point::polar(ray.angle(), -5);
- end = desktop->doc2dt(end+ Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), -(dimension_offset / 4.0)));
- p.start(start);
- p.appendNew<Geom::LineSegment>(end);
+ end = end+ Geom::Point::polar(ray.angle() + Geom::deg_to_rad(90), -(dimension_offset / 4.0));
+ guint32 color = 0x000000ff;
+ setLine(start, end, true, &color);
+ Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+ Glib::ustring unit_name = prefs->getString("/tools/measure/unit");
+ if (!unit_name.compare("")) {
+ unit_name = "px";
+ }
+ double fontsize = prefs->getInt("/tools/measure/fontsize") * (96/72);
+ Geom::Point middle = Geom::middle_point(start, end);
+ double totallengthval = (end_p - start_p).length();
+ totallengthval = Inkscape::Util::Quantity::convert(totallengthval, "px", unit_name);
+ gchar *totallength_str = g_strdup_printf("%.2f %s", totallengthval, unit_name.c_str());
+ setLabelText(totallength_str, middle, fontsize, Geom::deg_to_rad(180) - ray.angle());
+ doc->ensureUpToDate();
+ DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,_("Add global meassure line"));
+}
+
+void MeasureTool::setLine(Geom::Point start_point,Geom::Point end_point, bool markers, guint32 *color, Inkscape::XML::Node *measure_repr)
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if(!desktop || !start_point.isFinite() || !end_point.isFinite()) {
+ return;
+ }
+ Geom::PathVector c;
+ Geom::Path p;
+ p.start(desktop->doc2dt(start_point));
+ p.appendNew<Geom::LineSegment>(desktop->doc2dt(end_point));
c.push_back(p);
c *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
- SPDesktop *desktop = this->desktop;
SPDocument *doc = desktop->getDocument();
Inkscape::XML::Document *xml_doc = doc->getReprDoc();
if (c.size() == 1) {
Inkscape::XML::Node *repr;
repr = xml_doc->createElement("svg:path");
gchar const *str = sp_svg_write_path(c);
- Geom::Point stroke_width = Geom::Point(1,1) * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
- std::stringstream style_str;
- style_str.imbue(std::locale::classic());
- style_str << "fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:" << stroke_width[Geom::X] << ";stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-start:url(#Arrow2Sstart);marker-end:url(#Arrow2Send)";
+ Geom::Point strokewidth = Geom::Point(1,1) * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ std::stringstream stroke_width;
+ stroke_width.imbue(std::locale::classic());
+ if(measure_repr) {
+ stroke_width << strokewidth[Geom::X] / desktop->current_zoom();
+ } else {
+ stroke_width << strokewidth[Geom::X];
+ }
+ sp_repr_css_set_property (css, "stroke-width", stroke_width.str().c_str());
+ sp_repr_css_set_property (css, "fill", "none");
+ if(color) {
+ gchar c[64];
+ sp_svg_write_color (c, sizeof(c), *color);
+ sp_repr_css_set_property (css, "stroke", c);
+ } else {
+ sp_repr_css_set_property (css, "stroke", "#000000");
+ }
+ sp_repr_css_set_property (css, "stroke-linecap", "butt");
+ sp_repr_css_set_property (css, "stroke-linejoin", "miter");
+ sp_repr_css_set_property (css, "stroke-miterlimit", "4");
+ sp_repr_css_set_property (css, "stroke-dasharray", "none");
+ if(measure_repr) {
+ sp_repr_css_set_property (css, "stroke-opacity", "0.5");
+ } else {
+ sp_repr_css_set_property (css, "stroke-opacity", "1");
+ }
+ if(markers) {
+ sp_repr_css_set_property (css, "marker-start", "url(#Arrow2Sstart)");
+ sp_repr_css_set_property (css, "marker-end", "url(#Arrow2Send)");
+ }
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ repr->setAttribute("style", css_str.c_str());
+ sp_repr_css_attr_unref (css);
g_assert( str != NULL );
repr->setAttribute("d", str);
- repr->setAttribute("style", style_str.str().c_str());
- SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr));
- Inkscape::GC::release(repr);
- item->updateRepr();
+ if(measure_repr) {
+ measure_repr->addChild(repr, NULL);
+ Inkscape::GC::release(repr);
+ } else {
+ SPItem *item = SP_ITEM(desktop->currentLayer()->appendChildRepr(repr));
+ Inkscape::GC::release(repr);
+ item->updateRepr();
+ }
}
+}
- Inkscape::Preferences *prefs = Inkscape::Preferences::get();
- Glib::ustring unit_name = prefs->getString("/tools/measure/unit");
- if (!unit_name.compare("")) {
- unit_name = "px";
+void MeasureTool::setPoint(Geom::Point origin, Inkscape::XML::Node *measure_repr)
+{
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
+ if(!desktop || !origin.isFinite()) {
+ return;
+ }
+ char const * svgd;
+ svgd = "m -3.55,-3.55 7.11,7.11 m 0,-7.11 -7.11,7.11";
+ Geom::PathVector c = sp_svg_read_pathv(svgd);
+ Geom::Scale scale = Geom::Scale(desktop->current_zoom()).inverse();
+ c *= scale;
+ Geom::Point strokewidth = (Geom::Point(1,1) * SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse())/ desktop->current_zoom();
+ c *= Geom::Translate(Geom::Point(strokewidth/2.0) - (scale.vector() * 0.5));
+ c *= Geom::Translate(desktop->doc2dt(origin));
+ c *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
+ SPDocument *doc = desktop->getDocument();
+ Inkscape::XML::Document *xml_doc = doc->getReprDoc();
+ if (c.size() == 2) {
+ Inkscape::XML::Node *repr;
+ repr = xml_doc->createElement("svg:path");
+ gchar const *str = sp_svg_write_path(c);
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ std::stringstream stroke_width;
+ stroke_width.imbue(std::locale::classic());
+ stroke_width << strokewidth[Geom::X];
+ sp_repr_css_set_property (css, "stroke-width", stroke_width.str().c_str());
+ sp_repr_css_set_property (css, "fill", "none");
+ guint32 line_color_secondary = 0xff0000ff;
+ gchar c[64];
+ sp_svg_write_color (c, sizeof(c), line_color_secondary);
+ sp_repr_css_set_property (css, "stroke", c);
+ sp_repr_css_set_property (css, "stroke-linecap", "butt");
+ sp_repr_css_set_property (css, "stroke-linejoin", "miter");
+ sp_repr_css_set_property (css, "stroke-miterlimit", "4");
+ sp_repr_css_set_property (css, "stroke-dasharray", "none");
+ sp_repr_css_set_property (css, "stroke-opacity", "0.5");
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ repr->setAttribute("style", css_str.c_str());
+ sp_repr_css_attr_unref (css);
+ g_assert( str != NULL );
+ repr->setAttribute("d", str);
+ measure_repr->addChild(repr, NULL);
+ Inkscape::GC::release(repr);
}
- double fontsize = prefs->getInt("/tools/measure/fontsize") * (96/72);
- Geom::Point middle = Geom::middle_point(start, end);
- double totallengthval = (end_p - start_p).length();
- totallengthval = Inkscape::Util::Quantity::convert(totallengthval, "px", unit_name);
- gchar *totallength_str = g_strdup_printf("%.2f %s", totallengthval, unit_name.c_str());
- setLabelText(totallength_str, middle, fontsize, Geom::deg_to_rad(180) - ray.angle());
- // Flush pending updates
- doc->ensureUpToDate();
- DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_MEASURE,
- _("Add global meassure line"));
- //reset();
}
-void MeasureTool::setLabelText(const char *value, Geom::Point pos, double fontsize, Geom::Coord angle)
+void MeasureTool::setLabelText(const char *value, Geom::Point pos, double fontsize, Geom::Coord angle, guint32 *background, Inkscape::XML::Node *measure_repr, CanvasTextAnchorPositionEnum text_anchor)
{
- /* Create <text> */
+ SPDesktop *desktop = SP_ACTIVE_DESKTOP;
Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc();
+ /* Create <text> */
+ pos = desktop->doc2dt(pos);
Inkscape::XML::Node *rtext = xml_doc->createElement("svg:text");
rtext->setAttribute("xml:space", "preserve");
/* Set style */
sp_desktop_apply_style_tool(desktop, rtext, "/tools/text", true);
-
- sp_repr_set_svg_double(rtext, "x", 0);
- sp_repr_set_svg_double(rtext, "y", 0);
+ if(measure_repr) {
+ sp_repr_set_svg_double(rtext, "x", 2);
+ sp_repr_set_svg_double(rtext, "y", 2);
+ } else {
+ sp_repr_set_svg_double(rtext, "x", 0);
+ sp_repr_set_svg_double(rtext, "y", 0);
+ }
/* Create <tspan> */
Inkscape::XML::Node *rtspan = xml_doc->createElement("svg:tspan");
rtspan->setAttribute("sodipodi:role", "line"); // otherwise, why bother creating the tspan?
- std::stringstream text_style;
- text_style.imbue(std::locale::classic());
- text_style << "font-style:normal;font-weight:normal;font-size:" << fontsize << "px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1";
- rtspan->setAttribute("style", text_style.str().c_str());
+ SPCSSAttr *css = sp_repr_css_attr_new();
+ std::stringstream font_size;
+ font_size.imbue(std::locale::classic());
+ font_size << fontsize ;
+ sp_repr_css_set_property (css, "font-size", font_size.str().c_str());
+ sp_repr_css_set_property (css, "font-style", "normal");
+ sp_repr_css_set_property (css, "font-weight", "normal");
+ sp_repr_css_set_property (css, "line-height", "125%");
+ sp_repr_css_set_property (css, "letter-spacing", "0px");
+ sp_repr_css_set_property (css, "word-spacing", "0px");
+ if(measure_repr) {
+ sp_repr_css_set_property (css, "fill", "#FFFFFF");
+ } else {
+ sp_repr_css_set_property (css, "fill", "#000000");
+ }
+ sp_repr_css_set_property (css, "fill-opacity", "1");
+ sp_repr_css_set_property (css, "stroke", "none");
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ rtspan->setAttribute("style", css_str.c_str());
+ sp_repr_css_attr_unref (css);
rtext->addChild(rtspan, NULL);
Inkscape::GC::release(rtspan);
/* Create TEXT */
@@ -663,19 +864,63 @@ void MeasureTool::setLabelText(const char *value, Geom::Point pos, double fontsi
Inkscape::GC::release(rtext);
text_item->updateRepr();
Geom::OptRect bbox = text_item->geometricBounds();
- if (bbox) {
- Geom::Coord posX = Geom::middle_point(Geom::Point(bbox->left(), bbox->top()), Geom::Point(bbox->right(), bbox->top()))[Geom::X];
- Geom::Coord posY = Geom::middle_point(Geom::Point(bbox->left(), bbox->top()), Geom::Point(bbox->left(), bbox->bottom()))[Geom::Y];
- text_item->transform *= Geom::Translate(Geom::Point(posX, posY)).inverse();
- pos = pos + Geom::Point::polar(angle + Geom::deg_to_rad(90), -Geom::distance(Geom::Point(bbox->left(), bbox->top()), Geom::Point(bbox->left(), bbox->bottom())));
+ if (!measure_repr && bbox) {
+ Geom::Point center = bbox->midpoint();
+ text_item->transform *= Geom::Translate(center).inverse();
+ pos = pos + Geom::Point::polar(angle+ Geom::deg_to_rad(90), -bbox->height());
+ }
+ if(measure_repr) {
+ /* Create <group> */
+ Inkscape::XML::Node *rgroup = xml_doc->createElement("svg:g");
+ /* Create <rect> */
+ Inkscape::XML::Node *rrect = xml_doc->createElement("svg:rect");
+ SPCSSAttr *css = sp_repr_css_attr_new ();
+ gchar c[64];
+ sp_svg_write_color (c, sizeof(c), *background);
+ sp_repr_css_set_property (css, "fill", c);
+ sp_repr_css_set_property (css, "fill-opacity", "0.5");
+ sp_repr_css_set_property (css, "stroke-width", "0");
+ Glib::ustring css_str;
+ sp_repr_css_write_string(css,css_str);
+ rrect->setAttribute("style", css_str.c_str());
+ sp_repr_css_attr_unref (css);
+ sp_repr_set_svg_double(rgroup, "x", 0);
+ sp_repr_set_svg_double(rgroup, "y", 0);
+ sp_repr_set_svg_double(rrect, "x", 0);
+ sp_repr_set_svg_double(rrect, "y", -bbox->height());
+ sp_repr_set_svg_double(rrect, "width", (bbox->width()) + 6);
+ sp_repr_set_svg_double(rrect, "height", (bbox->height()) + 6);
+ Inkscape::XML::Node *rtextitem = text_item->getRepr();
+ text_item->deleteObject();
+ rgroup->addChild(rtextitem, NULL);
+ Inkscape::GC::release(rtextitem);
+ rgroup->addChild(rrect, NULL);
+ Inkscape::GC::release(rrect);
+ SPItem *text_item_box = SP_ITEM(desktop->currentLayer()->appendChildRepr(rgroup));
+ Geom::Scale scale = Geom::Scale(desktop->current_zoom()).inverse();
+ if(bbox && text_anchor == TEXT_ANCHOR_CENTER) {
+ text_item_box->transform *= Geom::Translate(bbox->midpoint() - Geom::Point(1.0,1.0)).inverse();
+ }
+ text_item_box->transform *= scale;
+ text_item_box->transform *= Geom::Translate(Geom::Point() - (scale.vector() * 0.5));
+ text_item_box->transform *= Geom::Translate(pos);
+ text_item_box->transform *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
+ text_item_box->updateRepr();
+ text_item_box->doWriteTransform(text_item_box->getRepr(), text_item_box->transform, NULL, true);
+ Inkscape::XML::Node *rlabel = text_item_box->getRepr();
+ text_item_box->deleteObject();
+ measure_repr->addChild(rlabel, NULL);
+ Inkscape::GC::release(rlabel);
+ } else {
+ text_item->transform *= Geom::Rotate(angle);
+ text_item->transform *= Geom::Translate(pos);
+ text_item->transform *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
+ text_item->doWriteTransform(text_item->getRepr(), text_item->transform, NULL, true);
}
- text_item->transform *= Geom::Rotate(angle);
- text_item->transform *= Geom::Translate(pos);
- text_item->transform *= SP_ITEM(desktop->currentLayer())->i2doc_affine().inverse();
- text_item->doWriteTransform(text_item->getRepr(), text_item->transform, NULL, true);
}
-void MeasureTool::reset(){
+void MeasureTool::reset()
+{
this->knot_start->hide();
this->knot_end->hide();
for (size_t idx = 0; idx < measure_tmp_items.size(); ++idx) {
@@ -684,15 +929,19 @@ void MeasureTool::reset(){
measure_tmp_items.clear();
}
-void MeasureTool::showCanvasItems(){
+void MeasureTool::showCanvasItems()
+{
showCanvasItems(start_p, end_p);
}
-void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point){
+void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point, bool to_item, Inkscape::XML::Node *measure_repr)
+{
SPDesktop *desktop = SP_ACTIVE_DESKTOP;
- if(!desktop || !start_point.isFinite() || !end_point.isFinite() || end_point == MAGIC_POINT){
+ if(!desktop || !start_point.isFinite() || !end_point.isFinite() || end_point == MAGIC_POINT) {
return;
}
+ guint32 line_color_primary = 0x0000ff7f;
+ guint32 line_color_secondary = 0xff00007f;
start_p = start_point;
end_p = end_point;
//clear previous temporary canvas items, we'll draw new ones
@@ -731,7 +980,7 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point
std::vector<SPItem*> items;
Inkscape::Rubberband *r = Inkscape::Rubberband::get(desktop);
r->setMode(RUBBERBAND_MODE_TOUCHPATH);
- if(!show_in_between){
+ if(!show_in_between) {
r->start(desktop,start_p);
r->move(end_p);
items = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints(), all_layers, 2);
@@ -741,10 +990,10 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point
r->move(start_p);
std::vector<SPItem*> items_reverse = desktop->getDocument()->getItemsAtPoints(desktop->dkey, r->getPoints(), all_layers, 2);
r->stop();
- if(items_reverse.size() == 2 && items_reverse[1] != items[0] && items_reverse[1] != items[1]){
+ if(items_reverse.size() == 2 && items_reverse[1] != items[0] && items_reverse[1] != items[1]) {
items.push_back(items_reverse[1]);
}
- if(items_reverse.size() >= 1 && items_reverse[0] != items[1]){
+ if(items_reverse.size() >= 1 && items_reverse[0] != items[1]) {
items.push_back(items_reverse[0]);
}
} else {
@@ -754,10 +1003,10 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point
r->stop();
}
std::vector<double> intersection_times;
- for (std::vector<SPItem*>::const_iterator i=items.begin();i!=items.end();i++) {
+ for (std::vector<SPItem*>::const_iterator i=items.begin(); i!=items.end(); i++) {
SPItem *item = *i;
if (SP_IS_SHAPE(item)) {
- calculate_intersections(desktop, item, lineseg, SP_SHAPE(item)->getCurve(), intersection_times);
+ calculate_intersections(desktop, item, lineseg, SP_SHAPE(item)->getCurve(), intersection_times);
} else {
if (SP_IS_TEXT(item) || SP_IS_FLOWTEXT(item)) {
Inkscape::Text::Layout::iterator iter = te_get_layout(item)->begin();
@@ -802,11 +1051,11 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point
std::vector<Geom::Point> intersections;
std::sort(intersection_times.begin(), intersection_times.end());
for (std::vector<double>::iterator iter_t = intersection_times.begin(); iter_t != intersection_times.end(); iter_t++) {
- if(show_in_between){
+ if(show_in_between) {
intersections.push_back(lineseg[0].pointAt(*iter_t));
}
}
- if(!show_in_between && intersection_times.size() > 1){
+ if(!show_in_between && intersection_times.size() > 1) {
intersections.push_back(lineseg[0].pointAt(intersection_times[0]));
intersections.push_back(lineseg[0].pointAt(intersection_times[intersection_times.size()-1]));
}
@@ -828,47 +1077,52 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point
// Adjust positions
repositionOverlappingLabels(placements, desktop, windowNormal, fontsize);
- for (std::vector<LabelPlacement>::iterator it = placements.begin(); it != placements.end(); ++it)
- {
+ for (std::vector<LabelPlacement>::iterator it = placements.begin(); it != placements.end(); ++it) {
LabelPlacement &place = *it;
// TODO cleanup memory, Glib::ustring, etc.:
gchar *measure_str = g_strdup_printf("%.2f %s", place.lengthVal, unit_name.c_str());
SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(),
- desktop,
- place.end,
- measure_str);
+ desktop,
+ place.end,
+ measure_str);
sp_canvastext_set_fontsize(canvas_tooltip, fontsize);
canvas_tooltip->rgba = 0xffffffff;
canvas_tooltip->rgba_background = 0x0000007f;
canvas_tooltip->outline = false;
canvas_tooltip->background = true;
canvas_tooltip->anchor_position = TEXT_ANCHOR_CENTER;
-
measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvas_tooltip, 0));
+ if(to_item) {
+ guint32 background = canvas_tooltip->rgba_background;
+ setLabelText(measure_str, place.end, fontsize, 0, &background, measure_repr);
+ }
g_free(measure_str);
}
Geom::Point angleDisplayPt = calcAngleDisplayAnchor(desktop, angle, baseAngle,
- start_point, end_point,
- fontsize);
+ start_point, end_point,
+ fontsize);
{
// TODO cleanup memory, Glib::ustring, etc.:
gchar *angle_str = g_strdup_printf("%.2f °", angle * 180/M_PI);
SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(),
- desktop,
- angleDisplayPt,
- angle_str);
+ desktop,
+ angleDisplayPt,
+ angle_str);
sp_canvastext_set_fontsize(canvas_tooltip, fontsize);
canvas_tooltip->rgba = 0xffffffff;
canvas_tooltip->rgba_background = 0x337f337f;
canvas_tooltip->outline = false;
canvas_tooltip->background = true;
canvas_tooltip->anchor_position = TEXT_ANCHOR_CENTER;
-
measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvas_tooltip, 0));
+ if(to_item) {
+ guint32 background = canvas_tooltip->rgba_background;
+ setLabelText(angle_str, angleDisplayPt, fontsize, 0, &background, measure_repr);
+ }
g_free(angle_str);
}
@@ -879,17 +1133,20 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point
// TODO cleanup memory, Glib::ustring, etc.:
gchar *totallength_str = g_strdup_printf("%.2f %s", totallengthval, unit_name.c_str());
SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(),
- desktop,
- end_point + desktop->w2d(Geom::Point(3*fontsize, -fontsize)),
- totallength_str);
+ desktop,
+ end_point + desktop->w2d(Geom::Point(3*fontsize, -fontsize)),
+ totallength_str);
sp_canvastext_set_fontsize(canvas_tooltip, fontsize);
canvas_tooltip->rgba = 0xffffffff;
canvas_tooltip->rgba_background = 0x3333337f;
canvas_tooltip->outline = false;
canvas_tooltip->background = true;
canvas_tooltip->anchor_position = TEXT_ANCHOR_LEFT;
-
measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvas_tooltip, 0));
+ if(to_item) {
+ guint32 background = canvas_tooltip->rgba_background;
+ setLabelText(totallength_str, end_point + desktop->w2d(Geom::Point(3*fontsize, -fontsize)), fontsize, 0, &background, measure_repr, TEXT_ANCHOR_LEFT);
+ }
g_free(totallength_str);
}
@@ -900,44 +1157,68 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point
// TODO cleanup memory, Glib::ustring, etc.:
gchar *total_str = g_strdup_printf("%.2f %s", totallengthval, unit_name.c_str());
SPCanvasText *canvas_tooltip = sp_canvastext_new(desktop->getTempGroup(),
- desktop,
- desktop->doc2dt((intersections[0] + intersections[intersections.size()-1])/2) + normal * (dimension_offset * 2),
- total_str);
+ desktop,
+ desktop->doc2dt((intersections[0] + intersections[intersections.size()-1])/2) + normal * (dimension_offset * 2),
+ total_str);
sp_canvastext_set_fontsize(canvas_tooltip, fontsize);
canvas_tooltip->rgba = 0xffffffff;
canvas_tooltip->rgba_background = 0x33337f7f;
canvas_tooltip->outline = false;
canvas_tooltip->background = true;
canvas_tooltip->anchor_position = TEXT_ANCHOR_CENTER;
-
measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvas_tooltip, 0));
+ if(to_item) {
+ guint32 background = canvas_tooltip->rgba_background;
+ setLabelText(total_str, desktop->doc2dt((intersections[0] + intersections[intersections.size()-1])/2) + normal * (dimension_offset * 2), fontsize, 0, &background, measure_repr);
+ }
g_free(total_str);
}
+ // Initial point
+ {
+ SPCanvasItem * canvasitem = sp_canvas_item_new(desktop->getTempGroup(),
+ SP_TYPE_CTRL,
+ "anchor", SP_ANCHOR_CENTER,
+ "size", 8.0,
+ "stroked", TRUE,
+ "stroke_color", 0xff0000ff,
+ "mode", SP_KNOT_MODE_XOR,
+ "shape", SP_KNOT_SHAPE_CROSS,
+ NULL );
+
+ SP_CTRL(canvasitem)->moveto(start_point);
+ measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvasitem, 0));
+ if(to_item) {
+ setPoint(start_point, measure_repr);
+ }
+ }
+
// Now that text has been added, we can add lines and controls so that they go underneath
for (size_t idx = 0; idx < intersections.size(); ++idx) {
// Display the intersection indicator (i.e. the cross)
SPCanvasItem * canvasitem = sp_canvas_item_new(desktop->getTempGroup(),
- SP_TYPE_CTRL,
- "anchor", SP_ANCHOR_CENTER,
- "size", 8.0,
- "stroked", TRUE,
- "stroke_color", 0xff0000ff,
- "mode", SP_KNOT_MODE_XOR,
- "shape", SP_KNOT_SHAPE_CROSS,
- NULL );
+ SP_TYPE_CTRL,
+ "anchor", SP_ANCHOR_CENTER,
+ "size", 8.0,
+ "stroked", TRUE,
+ "stroke_color", 0xff0000ff,
+ "mode", SP_KNOT_MODE_XOR,
+ "shape", SP_KNOT_SHAPE_CROSS,
+ NULL );
SP_CTRL(canvasitem)->moveto(desktop->doc2dt(intersections[idx]));
measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvasitem, 0));
+ if(to_item) {
+ setPoint(desktop->doc2dt(intersections[idx]), measure_repr);
+ }
}
-
// Since adding goes to the bottom, do all lines last.
// draw main control line
{
SPCtrlLine *control_line = ControlManager::getManager().createControlLine(desktop->getTempGroup(),
- start_point,
- end_point);
+ start_point,
+ end_point);
measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0));
if ((end_point[Geom::X] != start_point[Geom::X]) && (end_point[Geom::Y] != start_point[Geom::Y])) {
@@ -951,12 +1232,18 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point
}
SPCtrlLine *control_line = ControlManager::getManager().createControlLine(desktop->getTempGroup(),
- start_point,
- anchorEnd,
- CTLINE_SECONDARY);
+ start_point,
+ anchorEnd,
+ CTLINE_SECONDARY);
measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0));
-
- createAngleDisplayCurve(desktop, start_point, end_point, angleDisplayPt, angle);
+ if(to_item) {
+ setLine(start_point,
+ anchorEnd,
+ false,
+ &line_color_secondary,
+ measure_repr);
+ }
+ createAngleDisplayCurve(desktop, start_point, end_point, angleDisplayPt, angle, measure_repr);
}
}
@@ -967,29 +1254,50 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point
desktop->doc2dt(intersections[0]) + normal * (dimension_offset * 2),
desktop->doc2dt(intersections[intersections.size() - 1]) + normal * (dimension_offset * 2));
measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0));
-
+ if(to_item) {
+ setLine(desktop->doc2dt(intersections[0]) + normal * (dimension_offset * 2),
+ desktop->doc2dt(intersections[intersections.size() - 1]) + normal * (dimension_offset * 2),
+ false,
+ &line_color_primary,
+ measure_repr);
+ }
control_line = mgr.createControlLine(desktop->getTempGroup(),
desktop->doc2dt(intersections[0]),
desktop->doc2dt(intersections[0]) + normal * (dimension_offset * 2));
measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0));
-
+ if(to_item) {
+ setLine(desktop->doc2dt(intersections[0]),
+ desktop->doc2dt(intersections[0]) + normal * (dimension_offset * 2),
+ false,
+ &line_color_primary,
+ measure_repr);
+ }
control_line = mgr.createControlLine(desktop->getTempGroup(),
desktop->doc2dt(intersections[intersections.size() - 1]),
desktop->doc2dt(intersections[intersections.size() - 1]) + normal * (dimension_offset * 2));
measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0));
+ if(to_item) {
+ setLine(desktop->doc2dt(intersections[intersections.size() - 1]),
+ desktop->doc2dt(intersections[intersections.size() - 1]) + normal * (dimension_offset * 2),
+ false,
+ &line_color_primary,
+ measure_repr);
+ }
}
// call-out lines
- for (std::vector<LabelPlacement>::iterator it = placements.begin(); it != placements.end(); ++it)
- {
+ for (std::vector<LabelPlacement>::iterator it = placements.begin(); it != placements.end(); ++it) {
LabelPlacement &place = *it;
ControlManager &mgr = ControlManager::getManager();
SPCtrlLine *control_line = mgr.createControlLine(desktop->getTempGroup(),
- place.start,
- place.end,
- CTLINE_SECONDARY);
+ place.start,
+ place.end,
+ CTLINE_SECONDARY);
measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0));
+ if(to_item) {
+ setLine(place.start,place.end, false, &line_color_secondary, measure_repr);
+ }
}
{
@@ -998,28 +1306,19 @@ void MeasureTool::showCanvasItems(Geom::Point start_point, Geom::Point end_point
ControlManager &mgr = ControlManager::getManager();
SPCtrlLine *control_line = mgr.createControlLine(desktop->getTempGroup(),
- desktop->doc2dt(measure_text_pos),
- desktop->doc2dt(measure_text_pos) - (normal * dimension_offset),
- CTLINE_SECONDARY);
+ desktop->doc2dt(measure_text_pos),
+ desktop->doc2dt(measure_text_pos) - (normal * dimension_offset),
+ CTLINE_SECONDARY);
measure_tmp_items.push_back(desktop->add_temporary_canvasitem(control_line, 0));
+ if(to_item) {
+ setLine(desktop->doc2dt(measure_text_pos),
+ desktop->doc2dt(measure_text_pos) - (normal * dimension_offset),
+ false,
+ &line_color_secondary,
+ measure_repr);
+ }
}
}
-
- // Initial point
- {
- SPCanvasItem * canvasitem = sp_canvas_item_new(desktop->getTempGroup(),
- SP_TYPE_CTRL,
- "anchor", SP_ANCHOR_CENTER,
- "size", 8.0,
- "stroked", TRUE,
- "stroke_color", 0xff0000ff,
- "mode", SP_KNOT_MODE_XOR,
- "shape", SP_KNOT_SHAPE_CROSS,
- NULL );
-
- SP_CTRL(canvasitem)->moveto(start_point);
- measure_tmp_items.push_back(desktop->add_temporary_canvasitem(canvasitem, 0));
- }
}
}
}
diff --git a/src/ui/tools/measure-tool.h b/src/ui/tools/measure-tool.h
index 0670fb9f7..ee45c18e5 100644
--- a/src/ui/tools/measure-tool.h
+++ b/src/ui/tools/measure-tool.h
@@ -6,7 +6,7 @@
*
* Authors:
* Felipe Correa da Silva Sanches <juca@members.fsf.org>
- *
+ * Jabiertxo Arraiza <jabier.arraiza@marker.es>
* Copyright (C) 2011 Authors
*
* Released under GNU GPL, read the file 'COPYING' for more information
@@ -15,6 +15,7 @@
#include <sigc++/sigc++.h>
#include "ui/tools/tool-base.h"
#include <2geom/point.h>
+#include "display/canvas-text.h"
#include <boost/optional.hpp>
#define SP_MEASURE_CONTEXT(obj) (dynamic_cast<Inkscape::UI::Tools::MeasureTool*>((Inkscape::UI::Tools::ToolBase*)obj))
@@ -36,14 +37,17 @@ public:
virtual void finish();
virtual bool root_handler(GdkEvent* event);
virtual void showCanvasItems();
- virtual void showCanvasItems(Geom::Point start_point, Geom::Point end_point);
+ virtual void showCanvasItems(Geom::Point start_point, Geom::Point end_point, bool to_item = false, Inkscape::XML::Node *measure_repr = NULL);
virtual void reverseKnots();
virtual void toMarkDimension();
+ virtual void toItem();
virtual void reset();
virtual void setMarkers();
virtual void setMarker(bool isStart);
virtual const std::string& getPrefsPath();
- void setLabelText(const char *value, Geom::Point pos, double fontsize, Geom::Coord angle);
+ void setPoint(Geom::Point origin, Inkscape::XML::Node *measure_repr);
+ void setLine(Geom::Point start_point,Geom::Point end_point, bool markers = false, guint32 *color = NULL, Inkscape::XML::Node *measure_repr = NULL);
+ void setLabelText(const char *value, Geom::Point pos, double fontsize, Geom::Coord angle, guint32 *background = NULL, Inkscape::XML::Node *measure_repr = NULL, CanvasTextAnchorPositionEnum text_anchor = TEXT_ANCHOR_CENTER );
void knotStartMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state);
void knotEndMovedHandler(SPKnot */*knot*/, Geom::Point const &ppointer, guint state);
void knotUngrabbedHandler(SPKnot */*knot*/, unsigned int /*state*/);
@@ -66,3 +70,14 @@ private:
}
#endif // SEEN_SP_MEASURING_CONTEXT_H
+
+/*
+ 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:fileencoding=utf-8:textwidth=99 :
diff --git a/src/widgets/measure-toolbar.cpp b/src/widgets/measure-toolbar.cpp
index 9c782b4b6..48c781fb3 100644
--- a/src/widgets/measure-toolbar.cpp
+++ b/src/widgets/measure-toolbar.cpp
@@ -178,6 +178,13 @@ static void sp_to_mark_dimension(void){
}
}
+static void sp_to_item(void){
+ MeasureTool *mt = get_measure_tool();
+ if (mt) {
+ mt->toItem();
+ }
+}
+
void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, GObject* holder)
{
UnitTracker* tracker = new UnitTracker(Inkscape::Util::UNIT_TYPE_LINEAR);
@@ -283,6 +290,16 @@ void sp_measure_toolbox_prep(SPDesktop * desktop, GtkActionGroup* mainActions, G
g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_mark_dimension), 0 );
gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
}
+ //to item
+ {
+ InkAction* act = ink_action_new( "MeasureToItem",
+ _("Convert to item"),
+ _("Convert to item"),
+ INKSCAPE_ICON("path-reverse"),
+ secondarySize );
+ g_signal_connect_after( G_OBJECT(act), "activate", G_CALLBACK(sp_to_item), 0 );
+ gtk_action_group_add_action( mainActions, GTK_ACTION(act) );
+ }
} // end of sp_measure_toolbox_prep()
diff --git a/src/widgets/toolbox.cpp b/src/widgets/toolbox.cpp
index 3daa3c467..665502745 100644
--- a/src/widgets/toolbox.cpp
+++ b/src/widgets/toolbox.cpp
@@ -348,6 +348,7 @@ static gchar const * ui_descr =
" <toolitem action='MeasureAllLayers' />"
" <toolitem action='MeasureReverse' />"
" <toolitem action='MeasureMarkDimension' />"
+ " <toolitem action='MeasureToItem' />"
" </toolbar>"
" <toolbar name='StarToolbar'>"