summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2016-11-23 09:23:22 +0000
committertavmjong-free <tavmjong@free.fr>2016-11-23 09:23:22 +0000
commitc4922f5c1b54802623bc43f04191495e2338fc24 (patch)
tree3aa8ec0dfee887305fdcf7d02430ff8484dc11cf /src
parentFix a typo in inkscape-preferences.cpp. (diff)
downloadinkscape-c4922f5c1b54802623bc43f04191495e2338fc24.tar.gz
inkscape-c4922f5c1b54802623bc43f04191495e2338fc24.zip
Select mesh nodes by clicking on control lines.
(bzr r15267)
Diffstat (limited to 'src')
-rw-r--r--src/display/sp-ctrlcurve.cpp2
-rw-r--r--src/display/sp-ctrlcurve.h3
-rw-r--r--src/display/sp-ctrlline.cpp1
-rw-r--r--src/display/sp-ctrlline.h2
-rw-r--r--src/gradient-drag.cpp36
-rw-r--r--src/gradient-drag.h2
-rw-r--r--src/ui/tools/mesh-tool.cpp52
7 files changed, 77 insertions, 21 deletions
diff --git a/src/display/sp-ctrlcurve.cpp b/src/display/sp-ctrlcurve.cpp
index 2e0e8105b..79ef20d6c 100644
--- a/src/display/sp-ctrlcurve.cpp
+++ b/src/display/sp-ctrlcurve.cpp
@@ -47,6 +47,8 @@ sp_ctrlcurve_init(SPCtrlCurve *ctrlcurve)
// Points are initialized to 0,0
ctrlcurve->rgba = 0x0000ff7f;
ctrlcurve->item=NULL;
+ ctrlcurve->corner0 = -1;
+ ctrlcurve->corner1 = -1;
}
namespace {
diff --git a/src/display/sp-ctrlcurve.h b/src/display/sp-ctrlcurve.h
index 847944f38..56b3089d9 100644
--- a/src/display/sp-ctrlcurve.h
+++ b/src/display/sp-ctrlcurve.h
@@ -31,6 +31,9 @@ struct SPCtrlCurve : public SPCtrlLine {
Geom::Point const &q2, Geom::Point const &q3);
Geom::Point p0, p1, p2, p3;
+
+ int corner0; // Used to store index of corner for finding dragger.
+ int corner1;
};
GType sp_ctrlcurve_get_type();
diff --git a/src/display/sp-ctrlline.cpp b/src/display/sp-ctrlline.cpp
index 6c5674935..c4ced2a33 100644
--- a/src/display/sp-ctrlline.cpp
+++ b/src/display/sp-ctrlline.cpp
@@ -52,6 +52,7 @@ static void sp_ctrlline_init(SPCtrlLine *ctrlline)
ctrlline->rgba = 0x0000ff7f;
ctrlline->s[Geom::X] = ctrlline->s[Geom::Y] = ctrlline->e[Geom::X] = ctrlline->e[Geom::Y] = 0.0;
ctrlline->item=NULL;
+ ctrlline->is_fill = true;
}
namespace {
diff --git a/src/display/sp-ctrlline.h b/src/display/sp-ctrlline.h
index b2e222437..bac0cfa54 100644
--- a/src/display/sp-ctrlline.h
+++ b/src/display/sp-ctrlline.h
@@ -33,6 +33,8 @@ struct SPCtrlLine : public SPCanvasItem {
SPItem *item; // the item to which this line belongs in some sense; may be NULL for some users
+ bool is_fill; // fill or stroke... used with meshes.
+
guint32 rgba;
Geom::Point s;
Geom::Point e;
diff --git a/src/gradient-drag.cpp b/src/gradient-drag.cpp
index 370f4fcba..81ae7869b 100644
--- a/src/gradient-drag.cpp
+++ b/src/gradient-drag.cpp
@@ -1885,6 +1885,7 @@ void GrDrag::addLine(SPItem *item, Geom::Point p1, Geom::Point p2, Inkscape::Pai
sp_canvas_item_move_to_z(line, 0);
line->item = item;
+ line->is_fill = (fill_or_stroke == Inkscape::FOR_FILL);
sp_canvas_item_show(line);
this->lines.push_back(line);
}
@@ -1894,13 +1895,18 @@ void GrDrag::addLine(SPItem *item, Geom::Point p1, Geom::Point p2, Inkscape::Pai
/**
* Create a curve from p0 to p3 and add it to the lines list. Used for mesh sides.
*/
-void GrDrag::addCurve(SPItem *item, Geom::Point p0, Geom::Point p1, Geom::Point p2, Geom::Point p3, Inkscape::PaintTarget fill_or_stroke)
+void GrDrag::addCurve(SPItem *item, Geom::Point p0, Geom::Point p1, Geom::Point p2, Geom::Point p3,
+ int corner0, int corner1, Inkscape::PaintTarget fill_or_stroke)
{
+ // CtrlLineType only sets color
CtrlLineType type = (fill_or_stroke == Inkscape::FOR_FILL) ? CTLINE_PRIMARY : CTLINE_SECONDARY;
SPCtrlCurve *line = ControlManager::getManager().createControlCurve(this->desktop->getControls(), p0, p1, p2, p3, type);
+ line->corner0 = corner0;
+ line->corner1 = corner1;
sp_canvas_item_move_to_z(line, 0);
line->item = item;
+ line->is_fill = (fill_or_stroke == Inkscape::FOR_FILL);
sp_canvas_item_show (line);
this->lines.push_back(line);
}
@@ -2304,12 +2310,18 @@ void GrDrag::updateLines()
SPMeshPatchI patch( &(mg->array.nodes), i, j );
+ // clockwise around patch, used to find corner dragger
+ int corner0 = i * (columns + 1) + j;
+ int corner1 = corner0 + 1;
+ int corner2 = corner1 + columns + 1;
+ int corner3 = corner2 - 1;
+
// Top line
h = patch.getPointsForSide( 0 );
for( guint p = 0; p < 4; ++p ) {
h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine();
}
- addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_FILL );
+ addCurve (item, h[0], h[1], h[2], h[3], corner0, corner1, Inkscape::FOR_FILL );
// Right line
if( j == columns - 1 ) {
@@ -2317,7 +2329,7 @@ void GrDrag::updateLines()
for( guint p = 0; p < 4; ++p ) {
h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine();
}
- addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_FILL );
+ addCurve (item, h[0], h[1], h[2], h[3], corner1, corner2, Inkscape::FOR_FILL );
}
// Bottom line
@@ -2326,7 +2338,7 @@ void GrDrag::updateLines()
for( guint p = 0; p < 4; ++p ) {
h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine();
}
- addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_FILL );
+ addCurve (item, h[0], h[1], h[2], h[3], corner2, corner3, Inkscape::FOR_FILL );
}
// Left line
@@ -2334,7 +2346,7 @@ void GrDrag::updateLines()
for( guint p = 0; p < 4; ++p ) {
h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine();
}
- addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_FILL );
+ addCurve (item, h[0], h[1], h[2], h[3], corner3, corner0, Inkscape::FOR_FILL );
}
}
}
@@ -2367,12 +2379,18 @@ void GrDrag::updateLines()
SPMeshPatchI patch( &(mg->array.nodes), i, j );
+ // clockwise around patch, used to find corner dragger
+ int corner0 = i * (columns + 1) + j;
+ int corner1 = corner0 + 1;
+ int corner2 = corner1 + columns + 1;
+ int corner3 = corner2 - 1;
+
// Top line
h = patch.getPointsForSide( 0 );
for( guint p = 0; p < 4; ++p ) {
h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine();
}
- addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_STROKE );
+ addCurve (item, h[0], h[1], h[2], h[3], corner0, corner1, Inkscape::FOR_STROKE );
// Right line
if( j == columns - 1 ) {
@@ -2380,7 +2398,7 @@ void GrDrag::updateLines()
for( guint p = 0; p < 4; ++p ) {
h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine();
}
- addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_STROKE );
+ addCurve (item, h[0], h[1], h[2], h[3], corner1, corner2, Inkscape::FOR_STROKE );
}
// Bottom line
@@ -2389,7 +2407,7 @@ void GrDrag::updateLines()
for( guint p = 0; p < 4; ++p ) {
h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine();
}
- addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_STROKE );
+ addCurve (item, h[0], h[1], h[2], h[3], corner2, corner3, Inkscape::FOR_STROKE );
}
// Left line
@@ -2397,7 +2415,7 @@ void GrDrag::updateLines()
for( guint p = 0; p < 4; ++p ) {
h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine();
}
- addCurve (item, h[0], h[1], h[2], h[3], Inkscape::FOR_STROKE );
+ addCurve (item, h[0], h[1], h[2], h[3], corner3, corner0, Inkscape::FOR_STROKE );
}
}
}
diff --git a/src/gradient-drag.h b/src/gradient-drag.h
index a50bb24ed..a18511e69 100644
--- a/src/gradient-drag.h
+++ b/src/gradient-drag.h
@@ -205,7 +205,7 @@ private:
void deselect_all();
void addLine( SPItem *item, Geom::Point p1, Geom::Point p2, Inkscape::PaintTarget fill_or_stroke);
- void addCurve(SPItem *item, Geom::Point p0, Geom::Point p1, Geom::Point p2, Geom::Point p3, Inkscape::PaintTarget fill_or_stroke);
+ void addCurve(SPItem *item, Geom::Point p0, Geom::Point p1, Geom::Point p2, Geom::Point p3, int corner0, int corner1, Inkscape::PaintTarget fill_or_stroke);
GrDragger *addDragger(GrDraggable *draggable);
diff --git a/src/ui/tools/mesh-tool.cpp b/src/ui/tools/mesh-tool.cpp
index 7f05906f4..61232fb2c 100644
--- a/src/ui/tools/mesh-tool.cpp
+++ b/src/ui/tools/mesh-tool.cpp
@@ -41,6 +41,7 @@
#include "sp-text.h"
#include "sp-defs.h"
#include "style.h"
+#include "ui/control-manager.h"
// Gradient specific
#include "gradient-drag.h"
@@ -280,7 +281,7 @@ sp_mesh_context_select_prev (ToolBase *event_context)
/**
Returns vector of control lines mouse is over. Returns only first if 'first' is true.
*/
-static std::vector<SPCtrlLine *>
+static std::vector<SPCtrlCurve *>
sp_mesh_context_over_line (MeshTool *rc, Geom::Point event_p, bool first = true)
{
SPDesktop *desktop = SP_EVENT_CONTEXT (rc)->desktop;
@@ -292,7 +293,7 @@ sp_mesh_context_over_line (MeshTool *rc, Geom::Point event_p, bool first = true)
GrDrag *drag = rc->_grdrag;
- std::vector<SPCtrlLine *> selected;
+ std::vector<SPCtrlCurve *> selected;
for (std::vector<SPCtrlLine *>::const_iterator l = drag->lines.begin(); l != drag->lines.end(); ++l) {
if (!SP_IS_CTRLCURVE(*l)) continue;
@@ -304,7 +305,7 @@ sp_mesh_context_over_line (MeshTool *rc, Geom::Point event_p, bool first = true)
double dist_screen = Geom::L2 (rc->mousepoint_doc - nearest) * desktop->current_zoom();
if (dist_screen < tolerance) {
- selected.push_back(*l);
+ selected.push_back(curve);
if (first) {
break;
}
@@ -560,7 +561,7 @@ bool MeshTool::root_handler(GdkEvent* event) {
if ( event->button.button == 1 ) {
// Are we over a mesh line?
- std::vector<SPCtrlLine *> over_line =
+ std::vector<SPCtrlCurve *> over_line =
sp_mesh_context_over_line(this, Geom::Point(event->motion.x, event->motion.y));
if (!over_line.empty()) {
@@ -607,6 +608,31 @@ bool MeshTool::root_handler(GdkEvent* event) {
// If mesh already exists, do rubber band selection.
// Else set origin for drag which will create a new gradient.
if ( event->button.button == 1 && !this->space_panning ) {
+
+ // Are we over a mesh line?
+ std::vector<SPCtrlCurve *> over_line =
+ sp_mesh_context_over_line(this, Geom::Point(event->motion.x, event->motion.y), false);
+
+ if (!over_line.empty()) {
+ for (std::vector<SPCtrlCurve *>::const_iterator it = over_line.begin();
+ it != over_line.end(); ++it ) {
+ SPItem *item = (*it)->item;
+ Inkscape::PaintTarget fill_or_stroke =
+ (*it)->is_fill ? Inkscape::FOR_FILL : Inkscape::FOR_STROKE;
+ GrDragger* dragger0 = drag->getDraggerFor(item, POINT_MG_CORNER, (*it)->corner0, fill_or_stroke);
+ GrDragger* dragger1 = drag->getDraggerFor(item, POINT_MG_CORNER, (*it)->corner1, fill_or_stroke);
+ bool add = (event->button.state & GDK_SHIFT_MASK);
+ bool toggle = (event->button.state & GDK_CONTROL_MASK);
+ if ( !add && !toggle ) {
+ drag->deselectAll();
+ }
+ drag->setSelected( dragger0, true, !toggle );
+ drag->setSelected( dragger1, true, !toggle );
+ }
+ ret = true;
+ break; // To avoid putting the following code in an else block.
+ }
+
Geom::Point button_w(event->button.x, event->button.y);
// save drag origin
@@ -714,7 +740,7 @@ bool MeshTool::root_handler(GdkEvent* event) {
}
// Change cursor shape if over line
- std::vector<SPCtrlLine *> over_line =
+ std::vector<SPCtrlCurve *> over_line =
sp_mesh_context_over_line(this, Geom::Point(event->motion.x, event->motion.y));
if (this->cursor_addnode && over_line.empty()) {
@@ -740,7 +766,7 @@ bool MeshTool::root_handler(GdkEvent* event) {
if ( event->button.button == 1 && !this->space_panning ) {
// Check if over line
- std::vector<SPCtrlLine *> over_line =
+ std::vector<SPCtrlCurve *> over_line =
sp_mesh_context_over_line(this, Geom::Point(event->motion.x, event->motion.y));
if ( (event->button.state & GDK_CONTROL_MASK) && (event->button.state & GDK_MOD1_MASK ) ) {
@@ -812,11 +838,16 @@ bool MeshTool::root_handler(GdkEvent* event) {
}
}
} else {
- // click in an empty space; do the same as Esc
- if (!drag->selected.empty()) {
- drag->deselectAll();
+ if (!over_line.empty()) {
+ // Clicked on an existing mesh line, don't change selection. This stops
+ // possible change in selection during a double click with overlapping objects
} else {
- selection->clear();
+ // click in an empty space; do the same as Esc
+ if (!drag->selected.empty()) {
+ drag->deselectAll();
+ } else {
+ selection->clear();
+ }
}
}
@@ -989,7 +1020,6 @@ bool MeshTool::root_handler(GdkEvent* event) {
case GDK_KEY_KP_Delete:
case GDK_KEY_BackSpace:
if ( !drag->selected.empty() ) {
- std::cout << "Deleting mesh stops not implemented yet" << std::endl;
ret = TRUE;
}
break;