diff options
| author | Tavmjong Bah <tavmjong@free.fr> | 2016-11-23 09:23:22 +0000 |
|---|---|---|
| committer | tavmjong-free <tavmjong@free.fr> | 2016-11-23 09:23:22 +0000 |
| commit | c4922f5c1b54802623bc43f04191495e2338fc24 (patch) | |
| tree | 3aa8ec0dfee887305fdcf7d02430ff8484dc11cf /src | |
| parent | Fix a typo in inkscape-preferences.cpp. (diff) | |
| download | inkscape-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.cpp | 2 | ||||
| -rw-r--r-- | src/display/sp-ctrlcurve.h | 3 | ||||
| -rw-r--r-- | src/display/sp-ctrlline.cpp | 1 | ||||
| -rw-r--r-- | src/display/sp-ctrlline.h | 2 | ||||
| -rw-r--r-- | src/gradient-drag.cpp | 36 | ||||
| -rw-r--r-- | src/gradient-drag.h | 2 | ||||
| -rw-r--r-- | src/ui/tools/mesh-tool.cpp | 52 |
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; |
