Merge lp:~inkscape.dev/inkscape/mesh_improvements into lp:~inkscape.dev/inkscape/trunk
- mesh_improvements
- Merge into trunk
Proposed by
Jabiertxof
Status: | Merged |
---|---|
Merge reported by: | Jabiertxof |
Merged at revision: | not available |
Proposed branch: | lp:~inkscape.dev/inkscape/mesh_improvements |
Merge into: | lp:~inkscape.dev/inkscape/trunk |
Prerequisite: | lp:~inkscape.dev/inkscape/knot_improvements |
Diff against target: |
732 lines (+395/-73) 4 files modified
src/gradient-drag.cpp (+372/-69) src/gradient-drag.h (+20/-2) src/knot.h (+1/-0) src/ui/tools/mesh-tool.cpp (+2/-2) |
To merge this branch: | bzr merge lp:~inkscape.dev/inkscape/mesh_improvements |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jabiertxof | Approve | ||
Tavmjong Bah | Pending | ||
Review via email: mp+312384@code.launchpad.net |
Commit message
Description of the change
This branch improve the mesh gradient code:
Update to angled triangle knots the handles of selected corners.
Highlight current line.
To post a comment you must log in.
- 14415. By Jabiertxof <jtx@jtx>
-
Force knot previously. End of split mesh_and_knot branch. knot branch requred
- 14416. By Jabiertxof <jtx@jtx>
-
Add missing knot code
- 14417. By Jabiertxof <jtx@jtx>
-
Fix indent
- 14418. By Jabiertxof <jtx@jtx>
-
Update to trunk
- 14419. By Jabiertxof <jtx@jtx>
-
Fix blank lines
- 14420. By Jabiertxof <jtx@jtx>
-
Remove knot_improvements data
- 14421. By Jabiertxof <jtx@jtx>
-
Add knot_improvements data
- 14422. By Jabiertxof <jtx@jtx>
-
Update to trunk
- 14423. By Jabiertxof <jtx@jtx>
-
Update to trunk
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/gradient-drag.cpp' |
2 | --- src/gradient-drag.cpp 2016-12-01 13:05:02 +0000 |
3 | +++ src/gradient-drag.cpp 2016-12-03 19:47:59 +0000 |
4 | @@ -62,6 +62,7 @@ |
5 | guint32 const GR_KNOT_COLOR_NORMAL = 0xffffff00; |
6 | guint32 const GR_KNOT_COLOR_MOUSEOVER = 0xff000000; |
7 | guint32 const GR_KNOT_COLOR_SELECTED = 0x0000ff00; |
8 | +guint32 const GR_KNOT_COLOR_HIGHLIGHT = 0xffffff00; |
9 | guint32 const GR_KNOT_COLOR_MESHCORNER = 0xbfbfbf00; |
10 | |
11 | guint32 const GR_LINE_COLOR_FILL = 0x0000ff7f; |
12 | @@ -733,10 +734,12 @@ |
13 | static void gr_knot_moved_handler(SPKnot *knot, Geom::Point const &ppointer, guint state, gpointer data) |
14 | { |
15 | GrDragger *dragger = (GrDragger *) data; |
16 | - GrDrag *drag = dragger->parent; |
17 | - |
18 | + GrDraggable *draggable = (GrDraggable *) dragger->draggables[0]; |
19 | + if (!draggable) return; |
20 | Geom::Point p = ppointer; |
21 | - |
22 | + GrDragger *dragger_corner = dragger->getMgCorner(); |
23 | + GrDrag *drag = dragger_corner->parent; |
24 | + dragger_corner->highlightCorner(true); |
25 | SPDesktop *desktop = dragger->parent->desktop; |
26 | SnapManager &m = desktop->namedview->snap_manager; |
27 | double snap_dist = m.snapprefs.getObjectTolerance() / dragger->parent->desktop->current_zoom(); |
28 | @@ -1058,7 +1061,13 @@ |
29 | static void gr_knot_grabbed_handler(SPKnot */*knot*/, unsigned int /*state*/, gpointer data) |
30 | { |
31 | GrDragger *dragger = (GrDragger *) data; |
32 | - |
33 | + GrDragger *dragger_corner = dragger->getMgCorner(); |
34 | + GrDrag *drag = dragger_corner->parent; |
35 | + for(std::vector<GrDragger *>::const_iterator it = drag->draggers.begin(); it != drag->draggers.end(); ++it) { //for all selected draggers |
36 | + GrDragger *d = *it; |
37 | + d->highlightCorner(false); |
38 | + } |
39 | + dragger_corner->highlightCorner(true); |
40 | dragger->parent->desktop->canvas->forceFullRedrawAfterInterruptions(5); |
41 | } |
42 | |
43 | @@ -1068,7 +1077,6 @@ |
44 | static void gr_knot_ungrabbed_handler(SPKnot *knot, unsigned int state, gpointer data) |
45 | { |
46 | GrDragger *dragger = (GrDragger *) data; |
47 | - |
48 | dragger->parent->desktop->canvas->endForcedFullRedraws(); |
49 | |
50 | dragger->point_original = dragger->point = knot->pos; |
51 | @@ -1107,7 +1115,6 @@ |
52 | GrDragger *dragger = (GrDragger *) data; |
53 | GrDraggable *draggable = dragger->draggables[0]; |
54 | if (!draggable) return; |
55 | - |
56 | if ( (state & GDK_CONTROL_MASK) && (state & GDK_MOD1_MASK ) ) { |
57 | // delete this knot from vector |
58 | SPGradient *gradient = getGradient(draggable->item, draggable->fill_or_stroke); |
59 | @@ -1209,6 +1216,30 @@ |
60 | } |
61 | } |
62 | |
63 | +void GrDragger::updateControlSizesOverload(SPKnot * knot) |
64 | +{ |
65 | + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); |
66 | + int sizes[] = {4, 6, 8, 10, 12, 14, 16}; |
67 | + std::vector<int> sizeTable = std::vector<int>(sizes, sizes + (sizeof(sizes) / sizeof(sizes[0]))); |
68 | + int size = prefs->getIntLimited("/options/grabsize/value", 3, 1, 7); |
69 | + int knot_size = sizeTable[size - 1]; |
70 | + if(knot->shape == SP_KNOT_SHAPE_TRIANGLE){ |
71 | + knot_size *= 2.2; |
72 | + knot_size = floor(knot_size); |
73 | + if ( knot_size % 2 == 0 ){ |
74 | + knot_size += 1; |
75 | + } |
76 | + } |
77 | + knot->setSize(knot_size); |
78 | +} |
79 | + |
80 | +void GrDragger::updateControlSizes() |
81 | +{ |
82 | + updateControlSizesOverload(this->knot); |
83 | + this->knot->updateCtrl(); |
84 | + this->updateKnotShape(); |
85 | +} |
86 | + |
87 | /** |
88 | * Checks if the dragger has a draggable with this point_type. |
89 | */ |
90 | @@ -1385,6 +1416,7 @@ |
91 | for( guint i = 0; i < mg->array.handles.size(); ++i ) { |
92 | GrDragger *handle = drag->getDraggerFor( item, POINT_MG_HANDLE, i, fill_or_stroke ); |
93 | SPKnot *knot = handle->knot; |
94 | + knot->setFill(GR_KNOT_COLOR_NORMAL, GR_KNOT_COLOR_MOUSEOVER, GR_KNOT_COLOR_MOUSEOVER); |
95 | Geom::Point pk = getGradientCoords( item, POINT_MG_HANDLE, i, fill_or_stroke ); |
96 | knot->moveto(pk); |
97 | |
98 | @@ -1462,8 +1494,18 @@ |
99 | { |
100 | if (draggables.empty()) |
101 | return; |
102 | - GrDraggable *last = draggables.back(); |
103 | + GrDraggable *last = draggables.back(); |
104 | + bool highlight = false; |
105 | + if(this->knot->shape == SP_KNOT_SHAPE_TRIANGLE){ |
106 | + highlight = true; |
107 | + } |
108 | g_object_set (G_OBJECT (this->knot->item), "shape", gr_knot_shapes[last->point_type], NULL); |
109 | + if(highlight){ |
110 | + this->knot->setFill(GR_KNOT_COLOR_HIGHLIGHT, GR_KNOT_COLOR_MOUSEOVER, GR_KNOT_COLOR_MOUSEOVER); |
111 | + if(gr_knot_shapes[last->point_type] == SP_KNOT_SHAPE_CIRCLE){ |
112 | + g_object_set (G_OBJECT (this->knot->item), "shape", SP_KNOT_SHAPE_TRIANGLE, NULL); |
113 | + } |
114 | + } |
115 | } |
116 | |
117 | /** |
118 | @@ -1608,6 +1650,7 @@ |
119 | } |
120 | this->knot->setFill(fill_color, GR_KNOT_COLOR_MOUSEOVER, GR_KNOT_COLOR_MOUSEOVER); |
121 | this->knot->setStroke(0x0000007f, 0x0000007f, 0x0000007f); |
122 | + this->updateControlSizesOverload(this->knot); |
123 | this->knot->updateCtrl(); |
124 | |
125 | // move knot to the given point |
126 | @@ -1626,6 +1669,7 @@ |
127 | this->_moved_connection = this->knot->moved_signal.connect(sigc::bind(sigc::ptr_fun(gr_knot_moved_handler), this)); |
128 | } |
129 | |
130 | + this->sizeUpdatedConn = ControlManager::getManager().connectCtrlSizeChanged(sigc::mem_fun(*this, &GrDragger::updateControlSizes)); |
131 | this->_clicked_connection = this->knot->click_signal.connect(sigc::bind(sigc::ptr_fun(gr_knot_clicked_handler), this)); |
132 | this->_doubleclicked_connection = this->knot->doubleclicked_signal.connect(sigc::bind(sigc::ptr_fun(gr_knot_doubleclicked_handler), this)); |
133 | this->_grabbed_connection = this->knot->grabbed_signal.connect(sigc::bind(sigc::ptr_fun(gr_knot_grabbed_handler), this)); |
134 | @@ -1635,7 +1679,7 @@ |
135 | if (draggable) { |
136 | this->addDraggable (draggable); |
137 | } |
138 | - |
139 | + |
140 | updateKnotShape(); |
141 | } |
142 | |
143 | @@ -1648,6 +1692,7 @@ |
144 | //this->parent->setDeselected(this); |
145 | |
146 | // disconnect signals |
147 | + this->sizeUpdatedConn.disconnect(); |
148 | this->_moved_connection.disconnect(); |
149 | this->_clicked_connection.disconnect(); |
150 | this->_doubleclicked_connection.disconnect(); |
151 | @@ -1708,6 +1753,180 @@ |
152 | } |
153 | } |
154 | |
155 | +GrDragger * |
156 | +GrDragger::getMgCorner(){ |
157 | + GrDraggable *draggable = (GrDraggable *) this->draggables[0]; |
158 | + if (draggable){ |
159 | + if(draggable->point_type == POINT_MG_CORNER){ |
160 | + return this; |
161 | + } |
162 | + SPGradient *gradient = getGradient(draggable->item, draggable->fill_or_stroke); |
163 | + if (SP_IS_MESHGRADIENT( gradient ) ){ |
164 | + SPMeshGradient *mg = SP_MESHGRADIENT( gradient ); |
165 | + std::vector< std::vector< SPMeshNode* > > nodes = mg->array.nodes; |
166 | + for( guint i = 0; i < nodes.size(); ++i ) { |
167 | + for( guint j = 0; j < nodes[i].size(); ++j ) { |
168 | + if( nodes[i][j]->set ) { |
169 | + if( nodes[i][j]->node_type == MG_NODE_TYPE_HANDLE){ |
170 | + if(draggable->point_i == (gint)nodes[i][j]->draggable){ |
171 | + if(nodes.size() > i+1 && nodes[i+1].size() > j && nodes[i+1][j]->node_type == MG_NODE_TYPE_CORNER){ |
172 | + return this->parent->getDraggerFor(draggable->item, POINT_MG_CORNER, nodes[i+1][j]->draggable, draggable->fill_or_stroke); |
173 | + } |
174 | + if(j != 0 && nodes.size() > i && nodes[i].size() > j-1 && nodes[i][j-1]->node_type == MG_NODE_TYPE_CORNER){ |
175 | + return this->parent->getDraggerFor(draggable->item, POINT_MG_CORNER, nodes[i][j-1]->draggable, draggable->fill_or_stroke); |
176 | + } |
177 | + if(i != 0 && nodes.size() > i-1 && nodes[i-1].size() > j && nodes[i-1][j]->node_type == MG_NODE_TYPE_CORNER){ |
178 | + return this->parent->getDraggerFor(draggable->item, POINT_MG_CORNER, nodes[i-1][j]->draggable, draggable->fill_or_stroke); |
179 | + } |
180 | + if(nodes.size() > i && nodes[i].size() > j+1 && nodes[i][j+1]->node_type == MG_NODE_TYPE_CORNER){ |
181 | + return this->parent->getDraggerFor(draggable->item, POINT_MG_CORNER, nodes[i][j+1]->draggable, draggable->fill_or_stroke); |
182 | + } |
183 | + } |
184 | + } |
185 | + } |
186 | + } |
187 | + } |
188 | + } |
189 | + } |
190 | + return NULL; |
191 | +} |
192 | + |
193 | +mgDraggerPosition |
194 | +GrDragger::getMgDraggerPosition(){ |
195 | + GrDraggable *draggable = (GrDraggable *) this->draggables[0]; |
196 | + if (draggable && draggable->point_i < G_MAXINT){ |
197 | + NodeType type = MG_NODE_TYPE_TENSOR; |
198 | + if(draggable->point_type == POINT_MG_HANDLE){ |
199 | + type = MG_NODE_TYPE_HANDLE; |
200 | + } else if (draggable->point_type == POINT_MG_CORNER){ |
201 | + type = MG_NODE_TYPE_CORNER; |
202 | + } |
203 | + SPGradient *gradient = getGradient(draggable->item, draggable->fill_or_stroke); |
204 | + if (SP_IS_MESHGRADIENT( gradient ) ){ |
205 | + SPMeshGradient *mg = SP_MESHGRADIENT( gradient ); |
206 | + SPMeshNodeArray mg_arr = mg->array; |
207 | + std::vector< std::vector< SPMeshNode* > > nodes = mg_arr.nodes; |
208 | + for( guint i = 0; i < nodes.size(); ++i ) { |
209 | + for( guint j = 0; j < nodes[i].size(); ++j ) { |
210 | + if( nodes[i][j]->set) { |
211 | + if(draggable->point_i == (gint)nodes[i][j]->draggable && type == nodes[i][j]->node_type){ |
212 | + if( nodes[i][j]->node_type == MG_NODE_TYPE_HANDLE){ |
213 | + if(nodes.size() > i+1 && nodes[i+1].size() > j && nodes[i+1][j]->node_type == MG_NODE_TYPE_CORNER){ |
214 | + return std::make_pair(MG_D_BOTTOM,std::make_pair(i,j)); |
215 | + } |
216 | + if(j != 0 && nodes.size() > i && nodes[i].size() > j-1 && nodes[i][j-1]->node_type == MG_NODE_TYPE_CORNER){ |
217 | + return std::make_pair(MG_D_LEFT,std::make_pair(i,j)); |
218 | + } |
219 | + if(i != 0 && nodes.size() > i-1 && nodes[i-1].size() > j && nodes[i-1][j]->node_type == MG_NODE_TYPE_CORNER){ |
220 | + return std::make_pair(MG_D_TOP,std::make_pair(i,j)); |
221 | + } |
222 | + if(nodes.size() > i && nodes[i].size() > j+1 && nodes[i][j+1]->node_type == MG_NODE_TYPE_CORNER){ |
223 | + return std::make_pair(MG_D_RIGHT,std::make_pair(i,j)); |
224 | + } |
225 | + } |
226 | + if(nodes[i][j]->node_type == MG_NODE_TYPE_CORNER){ |
227 | + return std::make_pair(MG_D_CENTER,std::make_pair(i,j)); |
228 | + } |
229 | + } |
230 | + |
231 | + } |
232 | + } |
233 | + } |
234 | + } |
235 | + } |
236 | + return std::make_pair(MG_D_NONE, std::make_pair(0,0)); |
237 | +} |
238 | + |
239 | +void GrDragger::highlightNode(SPMeshNode* node, bool highlight, Geom::Point corner_pos) |
240 | +{ |
241 | + GrPointType type = POINT_MG_TENSOR; |
242 | + if(node->node_type == MG_NODE_TYPE_HANDLE){ |
243 | + type = POINT_MG_HANDLE; |
244 | + } |
245 | + GrDraggable *draggable = (GrDraggable *) this->draggables[0]; |
246 | + GrDragger *d = this->parent->getDraggerFor(draggable->item, type, node->draggable, draggable->fill_or_stroke); |
247 | + if (d && node->draggable < G_MAXUINT) { |
248 | + Geom::Point end = d->knot->pos; |
249 | + double angl = Geom::Ray(corner_pos, end).angle(); |
250 | + if(highlight && knot->fill[SP_KNOT_VISIBLE] == GR_KNOT_COLOR_HIGHLIGHT && abs(angl - knot->angle) > Geom::rad_from_deg(10.0)){ |
251 | + return; |
252 | + } |
253 | + SPKnot *knot = d->knot; |
254 | + if(highlight){ |
255 | + knot->setFill(GR_KNOT_COLOR_HIGHLIGHT, GR_KNOT_COLOR_MOUSEOVER, GR_KNOT_COLOR_MOUSEOVER); |
256 | + } else { |
257 | + knot->setFill(GR_KNOT_COLOR_NORMAL, GR_KNOT_COLOR_MOUSEOVER, GR_KNOT_COLOR_MOUSEOVER); |
258 | + } |
259 | + if(type == POINT_MG_HANDLE){ |
260 | + if(highlight){ |
261 | + knot->setShape(SP_KNOT_SHAPE_TRIANGLE); |
262 | + } else { |
263 | + knot->setShape(SP_KNOT_SHAPE_CIRCLE); |
264 | + |
265 | + } |
266 | + } else { |
267 | + //Code for tensors |
268 | + return; |
269 | + } |
270 | + this->updateControlSizesOverload(knot); |
271 | + knot->setAngle(angl); |
272 | + knot->updateCtrl(); |
273 | + d->updateKnotShape(); |
274 | + } |
275 | +} |
276 | + |
277 | +void GrDragger::highlightCorner(bool highlight) |
278 | +{ |
279 | + // Must be a mesh gradient |
280 | + GrDraggable *draggable = (GrDraggable *) this->draggables[0]; |
281 | + if (draggable && draggable->point_type == POINT_MG_CORNER){ |
282 | + SPGradient *gradient = getGradient(draggable->item, draggable->fill_or_stroke); |
283 | + if (SP_IS_MESHGRADIENT( gradient ) ){ |
284 | + Geom::Point corner_point = this->point; |
285 | + gint corner = draggable->point_i; |
286 | + SPMeshGradient *mg = SP_MESHGRADIENT( gradient ); |
287 | + SPMeshNodeArray mg_arr = mg->array; |
288 | + std::vector< std::vector< SPMeshNode* > > nodes = mg_arr.nodes; |
289 | + // Find number of patch rows and columns |
290 | + guint mrow = mg_arr.patch_rows(); |
291 | + guint mcol = mg_arr.patch_columns(); |
292 | + // Number of corners in a row of patches. |
293 | + guint ncorners = mcol + 1; |
294 | + // Find corner row/column |
295 | + guint crow = corner / ncorners; |
296 | + guint ccol = corner % ncorners; |
297 | + // Find node row/column |
298 | + guint nrow = crow * 3; |
299 | + guint ncol = ccol * 3; |
300 | + |
301 | + bool patch[4]; |
302 | + patch[0] = patch[1] = patch[2] = patch[3] = false; |
303 | + if( ccol > 0 && crow > 0) patch[0] = true; |
304 | + if( ccol < mcol && crow > 0 ) patch[1] = true; |
305 | + if( ccol < mcol && crow < mrow ) patch[2] = true; |
306 | + if( ccol > 0 && crow < mrow ) patch[3] = true; |
307 | + if( patch[0] || patch[1] ) { |
308 | + highlightNode(nodes[nrow-1][ncol ], highlight, corner_point); |
309 | + } |
310 | + if( patch[1] || patch[2] ) { |
311 | + highlightNode(nodes[nrow ][ncol+1], highlight, corner_point); |
312 | + } |
313 | + if( patch[2] || patch[3] ) { |
314 | + highlightNode(nodes[nrow+1][ncol ], highlight, corner_point); |
315 | + } |
316 | + if( patch[3] || patch[0] ) { |
317 | + highlightNode(nodes[nrow ][ncol-1], highlight, corner_point); |
318 | + } |
319 | + // Highlight tensors |
320 | + /* |
321 | + if( patch[0] ) highlightNode(nodes[nrow-1][ncol-1], highlight, corner_point, point_i); |
322 | + if( patch[1] ) highlightNode(nodes[nrow-1][ncol+1], highlight, corner_point, point_i); |
323 | + if( patch[2] ) highlightNode(nodes[nrow+1][ncol+1], highlight, corner_point, point_i); |
324 | + if( patch[3] ) highlightNode(nodes[nrow+1][ncol-1], highlight, corner_point, point_i); |
325 | + */ |
326 | + } |
327 | + } |
328 | +} |
329 | |
330 | /** |
331 | * Draw this dragger as selected. |
332 | @@ -1716,6 +1935,7 @@ |
333 | { |
334 | this->knot->fill [SP_KNOT_STATE_NORMAL] = GR_KNOT_COLOR_SELECTED; |
335 | g_object_set (G_OBJECT (this->knot->item), "fill_color", GR_KNOT_COLOR_SELECTED, NULL); |
336 | + highlightCorner(true); |
337 | //if( isA(POINT_MG_CORNER) ) { |
338 | // for (GSList * drgble = this->draggables; drgble != NULL; drgble = drgble->next) { |
339 | // GrDraggable *draggable = (GrDraggable*) drgble->data; |
340 | @@ -1733,6 +1953,7 @@ |
341 | guint32 fill_color = isA(POINT_MG_CORNER) ? GR_KNOT_COLOR_MESHCORNER : GR_KNOT_COLOR_NORMAL; |
342 | this->knot->fill [SP_KNOT_STATE_NORMAL] = fill_color; |
343 | g_object_set (G_OBJECT (this->knot->item), "fill_color", fill_color, NULL); |
344 | + highlightCorner(false); |
345 | // MESH FIXME: TURN OFF CORRESPONDING SIDE/TENSOR NODE VISIBILITY |
346 | } |
347 | |
348 | @@ -1903,10 +2124,14 @@ |
349 | * Create a curve from p0 to p3 and add it to the lines list. Used for mesh sides. |
350 | */ |
351 | void GrDrag::addCurve(SPItem *item, Geom::Point p0, Geom::Point p1, Geom::Point p2, Geom::Point p3, |
352 | - int corner0, int corner1, Inkscape::PaintTarget fill_or_stroke) |
353 | + int corner0, int corner1, Inkscape::PaintTarget fill_or_stroke, bool highlight) |
354 | + |
355 | { |
356 | // CtrlLineType only sets color |
357 | CtrlLineType type = (fill_or_stroke == Inkscape::FOR_FILL) ? CTLINE_PRIMARY : CTLINE_SECONDARY; |
358 | + if(highlight){ |
359 | + type = (fill_or_stroke == Inkscape::FOR_FILL) ? CTLINE_SECONDARY : CTLINE_PRIMARY; |
360 | + } |
361 | SPCtrlCurve *line = ControlManager::getManager().createControlCurve(this->desktop->getControls(), p0, p1, p2, p3, type); |
362 | line->corner0 = corner0; |
363 | line->corner1 = corner1; |
364 | @@ -2265,12 +2490,20 @@ |
365 | */ |
366 | bool GrDrag::mouseOver() |
367 | { |
368 | + static bool mouse_out = false; |
369 | + // added knot mouse out for future use |
370 | for (std::vector<GrDragger *>::const_iterator l = this->draggers.begin(); l != this->draggers.end(); ++l) { |
371 | GrDragger *d = *l; |
372 | if (d->knot && (d->knot->flags & SP_KNOT_MOUSEOVER)) { |
373 | + mouse_out = true; |
374 | + updateLines(); |
375 | return true; |
376 | } |
377 | } |
378 | + if(mouse_out == true){ |
379 | + updateLines(); |
380 | + mouse_out = false; |
381 | + } |
382 | return false; |
383 | } |
384 | |
385 | @@ -2284,16 +2517,22 @@ |
386 | for (std::vector<SPCtrlLine *>::const_iterator i = this->lines.begin(); i != this->lines.end(); ++i) { |
387 | sp_canvas_item_destroy(SP_CANVAS_ITEM(*i)); |
388 | } |
389 | + bool highlight = false; |
390 | this->lines.clear(); |
391 | - |
392 | g_return_if_fail(this->selection != NULL); |
393 | |
394 | + mgDraggerPosition mg_dragger_position = std::make_pair(MG_D_NONE, std::make_pair(0,0)); |
395 | + for (std::vector<GrDragger *>::const_iterator it = this->draggers.begin(); it != this->draggers.end() ; ++it ) { |
396 | + GrDragger *d = *it; |
397 | + if (d->knot && (d->knot->flags & SP_KNOT_MOUSEOVER)) { |
398 | + mg_dragger_position = d->getMgDraggerPosition(); |
399 | + break; |
400 | + } |
401 | + } |
402 | auto list = this->selection->items(); |
403 | for (auto i = list.begin(); i != list.end(); ++i) { |
404 | SPItem *item = *i; |
405 | - |
406 | SPStyle *style = item->style; |
407 | - |
408 | if (style && (style->fill.isPaintserver())) { |
409 | SPPaintServer *server = item->style->getFillPaintServer(); |
410 | if ( server && SP_IS_GRADIENT( server ) ) { |
411 | @@ -2307,62 +2546,90 @@ |
412 | addLine(item, center, getGradientCoords(item, POINT_RG_R1, 0, Inkscape::FOR_FILL), Inkscape::FOR_FILL); |
413 | addLine(item, center, getGradientCoords(item, POINT_RG_R2, 0, Inkscape::FOR_FILL), Inkscape::FOR_FILL); |
414 | } else if ( SP_IS_MESHGRADIENT(server) ) { |
415 | - |
416 | Inkscape::Preferences *prefs = Inkscape::Preferences::get(); |
417 | bool edit_fill = abs(prefs->getBool("/tools/mesh/edit_fill", true)); |
418 | - |
419 | SPMeshGradient *mg = SP_MESHGRADIENT(server); |
420 | - |
421 | if (edit_fill) { |
422 | - guint rows = mg->array.patch_rows(); |
423 | - guint columns = mg->array.patch_columns(); |
424 | - for ( guint i = 0; i < rows; ++i ) { |
425 | - for ( guint j = 0; j < columns; ++j ) { |
426 | - |
427 | - std::vector<Geom::Point> h; |
428 | - |
429 | - SPMeshPatchI patch( &(mg->array.nodes), i, j ); |
430 | - |
431 | - // clockwise around patch, used to find corner dragger |
432 | - int corner0 = i * (columns + 1) + j; |
433 | - int corner1 = corner0 + 1; |
434 | - int corner2 = corner1 + columns + 1; |
435 | - int corner3 = corner2 - 1; |
436 | - |
437 | - // Top line |
438 | - h = patch.getPointsForSide( 0 ); |
439 | - for( guint p = 0; p < 4; ++p ) { |
440 | - h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); |
441 | - } |
442 | - addCurve (item, h[0], h[1], h[2], h[3], corner0, corner1, Inkscape::FOR_FILL ); |
443 | - |
444 | - // Right line |
445 | - if( j == columns - 1 ) { |
446 | - h = patch.getPointsForSide( 1 ); |
447 | - for( guint p = 0; p < 4; ++p ) { |
448 | - h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); |
449 | - } |
450 | - addCurve (item, h[0], h[1], h[2], h[3], corner1, corner2, Inkscape::FOR_FILL ); |
451 | - } |
452 | - |
453 | - // Bottom line |
454 | - if( i == rows - 1 ) { |
455 | - h = patch.getPointsForSide( 2 ); |
456 | - for( guint p = 0; p < 4; ++p ) { |
457 | - h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); |
458 | - } |
459 | - addCurve (item, h[0], h[1], h[2], h[3], corner2, corner3, Inkscape::FOR_FILL ); |
460 | - } |
461 | - |
462 | - // Left line |
463 | - h = patch.getPointsForSide( 3 ); |
464 | - for( guint p = 0; p < 4; ++p ) { |
465 | - h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); |
466 | - } |
467 | - addCurve (item, h[0], h[1], h[2], h[3], corner3, corner0, Inkscape::FOR_FILL ); |
468 | + guint rows = mg->array.patch_rows(); |
469 | + guint columns = mg->array.patch_columns(); |
470 | + for ( guint i = 0; i < rows; ++i ) { |
471 | + for ( guint j = 0; j < columns; ++j ) { |
472 | + std::vector<Geom::Point> h; |
473 | + SPMeshPatchI patch( &(mg->array.nodes), i, j ); |
474 | + // clockwise around patch, used to find corner dragger |
475 | + int corner0 = i * (columns + 1) + j; |
476 | + int corner1 = corner0 + 1; |
477 | + int corner2 = corner1 + columns + 1; |
478 | + int corner3 = corner2 - 1; |
479 | + // Top line |
480 | + h = patch.getPointsForSide( 0 ); |
481 | + for( guint p = 0; p < 4; ++p ) { |
482 | + h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); |
483 | + } |
484 | + highlight = false; |
485 | + if(mg_dragger_position.first != MG_D_NONE && |
486 | + ((mg_dragger_position.first == MG_D_CENTER && mg_dragger_position.second.first/3 == i && mg_dragger_position.second.second/3 == j) || |
487 | + (mg_dragger_position.first == MG_D_CENTER && mg_dragger_position.second.first/3 == i && (mg_dragger_position.second.second/3)-1 == j) || |
488 | + (mg_dragger_position.first == MG_D_RIGHT && mg_dragger_position.second.first/3 == i && mg_dragger_position.second.second/3 == j) || |
489 | + (mg_dragger_position.first == MG_D_LEFT && mg_dragger_position.second.first/3 == i && mg_dragger_position.second.second/3 == j))) |
490 | + { |
491 | + highlight = true; |
492 | + } |
493 | + addCurve (item, h[0], h[1], h[2], h[3], corner0, corner1, Inkscape::FOR_FILL, highlight); |
494 | + // Right line |
495 | + if( j == columns - 1 ) { |
496 | + h = patch.getPointsForSide( 1 ); |
497 | + for( guint p = 0; p < 4; ++p ) { |
498 | + h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); |
499 | + } |
500 | + highlight = false; |
501 | + if(mg_dragger_position.first != MG_D_NONE && |
502 | + ((mg_dragger_position.first == MG_D_CENTER && mg_dragger_position.second.first/3 == i && (mg_dragger_position.second.second/3) >j) || |
503 | + (mg_dragger_position.first == MG_D_CENTER && (mg_dragger_position.second.first/3)-1 == i && (mg_dragger_position.second.second/3) > j) || |
504 | + (mg_dragger_position.first == MG_D_TOP && mg_dragger_position.second.first/3 == i && (mg_dragger_position.second.second/3) > j) || |
505 | + (mg_dragger_position.first == MG_D_BOTTOM && mg_dragger_position.second.first/3 == i && (mg_dragger_position.second.second/3) > j))) |
506 | + { |
507 | + highlight = true; |
508 | + } |
509 | + addCurve (item, h[0], h[1], h[2], h[3], corner1, corner2, Inkscape::FOR_FILL, highlight); |
510 | + } |
511 | + |
512 | + // Bottom line |
513 | + if( i == rows - 1 ) { |
514 | + h = patch.getPointsForSide( 2 ); |
515 | + for( guint p = 0; p < 4; ++p ) { |
516 | + h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); |
517 | + } |
518 | + highlight = false; |
519 | + if(mg_dragger_position.first != MG_D_NONE && |
520 | + ((mg_dragger_position.first == MG_D_CENTER && (mg_dragger_position.second.first/3) > i && mg_dragger_position.second.second/3 == j) || |
521 | + (mg_dragger_position.first == MG_D_CENTER && (mg_dragger_position.second.first/3) > i && (mg_dragger_position.second.second/3)-1 == j) || |
522 | + (mg_dragger_position.first == MG_D_RIGHT && (mg_dragger_position.second.first/3) > i && mg_dragger_position.second.second/3 == j) || |
523 | + (mg_dragger_position.first == MG_D_LEFT && (mg_dragger_position.second.first/3) > i && mg_dragger_position.second.second/3 == j))) |
524 | + { |
525 | + highlight = true; |
526 | + } |
527 | + addCurve (item, h[0], h[1], h[2], h[3], corner2, corner3, Inkscape::FOR_FILL, highlight ); |
528 | + } |
529 | + |
530 | + // Left line |
531 | + h = patch.getPointsForSide( 3 ); |
532 | + for( guint p = 0; p < 4; ++p ) { |
533 | + h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); |
534 | + } |
535 | + highlight = false; |
536 | + if(mg_dragger_position.first != MG_D_NONE && |
537 | + ((mg_dragger_position.first == MG_D_CENTER && mg_dragger_position.second.first/3 == i && mg_dragger_position.second.second/3 == j) || |
538 | + (mg_dragger_position.first == MG_D_CENTER && (mg_dragger_position.second.first/3)-1 == i && mg_dragger_position.second.second/3 == j) || |
539 | + (mg_dragger_position.first == MG_D_TOP && mg_dragger_position.second.first/3 == i && mg_dragger_position.second.second/3 == j) || |
540 | + (mg_dragger_position.first == MG_D_BOTTOM && mg_dragger_position.second.first/3 == i && mg_dragger_position.second.second/3 == j))) |
541 | + { |
542 | + highlight = true; |
543 | + } |
544 | + addCurve (item, h[0], h[1], h[2], h[3], corner3, corner0, Inkscape::FOR_FILL, highlight ); |
545 | + } |
546 | } |
547 | } |
548 | - } |
549 | } |
550 | } |
551 | } |
552 | @@ -2388,14 +2655,12 @@ |
553 | |
554 | // MESH FIXME: TURN ROUTINE INTO FUNCTION AND CALL FOR BOTH FILL AND STROKE. |
555 | SPMeshGradient *mg = SP_MESHGRADIENT(server); |
556 | - |
557 | guint rows = mg->array.patch_rows(); |
558 | guint columns = mg->array.patch_columns(); |
559 | for ( guint i = 0; i < rows; ++i ) { |
560 | for ( guint j = 0; j < columns; ++j ) { |
561 | - |
562 | + |
563 | std::vector<Geom::Point> h; |
564 | - |
565 | SPMeshPatchI patch( &(mg->array.nodes), i, j ); |
566 | |
567 | // clockwise around patch, used to find corner dragger |
568 | @@ -2409,7 +2674,17 @@ |
569 | for( guint p = 0; p < 4; ++p ) { |
570 | h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); |
571 | } |
572 | - addCurve (item, h[0], h[1], h[2], h[3], corner0, corner1, Inkscape::FOR_STROKE ); |
573 | + |
574 | + highlight = false; |
575 | + if(mg_dragger_position.first != MG_D_NONE && |
576 | + ((mg_dragger_position.first == MG_D_CENTER && mg_dragger_position.second.first/3 == i && mg_dragger_position.second.second/3 == j) || |
577 | + (mg_dragger_position.first == MG_D_CENTER && mg_dragger_position.second.first/3 == i && (mg_dragger_position.second.second/3)-1 == j) || |
578 | + (mg_dragger_position.first == MG_D_RIGHT && mg_dragger_position.second.first/3 == i && mg_dragger_position.second.second/3 == j) || |
579 | + (mg_dragger_position.first == MG_D_LEFT && mg_dragger_position.second.first/3 == i && mg_dragger_position.second.second/3 == j))) |
580 | + { |
581 | + highlight = true; |
582 | + } |
583 | + addCurve (item, h[0], h[1], h[2], h[3], corner0, corner1, Inkscape::FOR_STROKE, highlight); |
584 | |
585 | // Right line |
586 | if( j == columns - 1 ) { |
587 | @@ -2417,7 +2692,16 @@ |
588 | for( guint p = 0; p < 4; ++p ) { |
589 | h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); |
590 | } |
591 | - addCurve (item, h[0], h[1], h[2], h[3], corner1, corner2, Inkscape::FOR_STROKE ); |
592 | + highlight = false; |
593 | + if(mg_dragger_position.first != MG_D_NONE && |
594 | + ((mg_dragger_position.first == MG_D_CENTER && mg_dragger_position.second.first/3 == i && (mg_dragger_position.second.second/3) >j) || |
595 | + (mg_dragger_position.first == MG_D_CENTER && (mg_dragger_position.second.first/3)-1 == i && (mg_dragger_position.second.second/3) > j) || |
596 | + (mg_dragger_position.first == MG_D_TOP && mg_dragger_position.second.first/3 == i && (mg_dragger_position.second.second/3) > j) || |
597 | + (mg_dragger_position.first == MG_D_BOTTOM && mg_dragger_position.second.first/3 == i && (mg_dragger_position.second.second/3) > j))) |
598 | + { |
599 | + highlight = true; |
600 | + } |
601 | + addCurve (item, h[0], h[1], h[2], h[3], corner1, corner2, Inkscape::FOR_STROKE, highlight ); |
602 | } |
603 | |
604 | // Bottom line |
605 | @@ -2426,7 +2710,16 @@ |
606 | for( guint p = 0; p < 4; ++p ) { |
607 | h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); |
608 | } |
609 | - addCurve (item, h[0], h[1], h[2], h[3], corner2, corner3, Inkscape::FOR_STROKE ); |
610 | + highlight = false; |
611 | + if(mg_dragger_position.first != MG_D_NONE && |
612 | + ((mg_dragger_position.first == MG_D_CENTER && (mg_dragger_position.second.first/3) > i && mg_dragger_position.second.second/3 == j) || |
613 | + (mg_dragger_position.first == MG_D_CENTER && (mg_dragger_position.second.first/3) > i && (mg_dragger_position.second.second/3)-1 == j) || |
614 | + (mg_dragger_position.first == MG_D_RIGHT && (mg_dragger_position.second.first/3) > i && mg_dragger_position.second.second/3 == j) || |
615 | + (mg_dragger_position.first == MG_D_LEFT && (mg_dragger_position.second.first/3) > i && mg_dragger_position.second.second/3 == j))) |
616 | + { |
617 | + highlight = true; |
618 | + } |
619 | + addCurve (item, h[0], h[1], h[2], h[3], corner2, corner3, Inkscape::FOR_STROKE, highlight ); |
620 | } |
621 | |
622 | // Left line |
623 | @@ -2434,7 +2727,17 @@ |
624 | for( guint p = 0; p < 4; ++p ) { |
625 | h[p] *= Geom::Affine(mg->gradientTransform) * (Geom::Affine)item->i2dt_affine(); |
626 | } |
627 | - addCurve (item, h[0], h[1], h[2], h[3], corner3, corner0, Inkscape::FOR_STROKE ); |
628 | + highlight = false; |
629 | + if(mg_dragger_position.first != MG_D_NONE && |
630 | + ((mg_dragger_position.first == MG_D_CENTER && mg_dragger_position.second.first/3 == i && mg_dragger_position.second.second/3 == j) || |
631 | + (mg_dragger_position.first == MG_D_CENTER && (mg_dragger_position.second.first/3)-1 == i && mg_dragger_position.second.second/3 == j) || |
632 | + (mg_dragger_position.first == MG_D_TOP && mg_dragger_position.second.first/3 == i && mg_dragger_position.second.second/3 == j) || |
633 | + (mg_dragger_position.first == MG_D_BOTTOM && mg_dragger_position.second.first/3 == i && mg_dragger_position.second.second/3 == j))) |
634 | + { |
635 | + highlight = true; |
636 | + } |
637 | + addCurve (item, h[0], h[1], h[2], h[3], corner3, corner0, Inkscape::FOR_STROKE, highlight ); |
638 | + |
639 | } |
640 | } |
641 | } |
642 | |
643 | === modified file 'src/gradient-drag.h' |
644 | --- src/gradient-drag.h 2016-11-23 09:23:22 +0000 |
645 | +++ src/gradient-drag.h 2016-12-03 19:47:59 +0000 |
646 | @@ -25,7 +25,6 @@ |
647 | #include <glibmm/ustring.h> |
648 | |
649 | #include <2geom/point.h> |
650 | - |
651 | #include "sp-gradient.h" // TODO refactor enums to external .h file |
652 | #include "sp-mesh-array.h" |
653 | |
654 | @@ -44,6 +43,16 @@ |
655 | class Selection; |
656 | } // namespace Inkscape |
657 | |
658 | +enum GrDraggerPositions { |
659 | + MG_D_CENTER = 0, //Corner |
660 | + MG_D_TOP, //Top dragger |
661 | + MG_D_RIGHT, //Right dragger |
662 | + MG_D_BOTTOM, //Bottom dragger |
663 | + MG_D_LEFT, // Left dragger |
664 | + MG_D_NONE // Invalid dragger |
665 | +}; |
666 | +typedef std::pair<GrDraggerPositions,std::pair<guint,guint> > mgDraggerPosition; |
667 | + |
668 | /** |
669 | This class represents a single draggable point of a gradient. It remembers the item |
670 | which has the gradient, whether it's fill or stroke, the point type (from the |
671 | @@ -94,6 +103,10 @@ |
672 | void updateKnotShape(); |
673 | void updateTip(); |
674 | |
675 | + mgDraggerPosition getMgDraggerPosition(); |
676 | + GrDragger *getMgCorner(); |
677 | + void highlightNode(SPMeshNode* node, bool highlight, Geom::Point corner_pos); |
678 | + void highlightCorner(bool highlight); |
679 | void select(); |
680 | void deselect(); |
681 | bool isSelected(); |
682 | @@ -116,6 +129,11 @@ |
683 | |
684 | void fireDraggables(bool write_repr, bool scale_radial = false, bool merging_focus = false); |
685 | |
686 | +protected: |
687 | + void updateControlSizesOverload(SPKnot * knot); |
688 | + void updateControlSizes(); |
689 | + sigc::connection sizeUpdatedConn; |
690 | + |
691 | private: |
692 | sigc::connection _moved_connection; |
693 | sigc::connection _clicked_connection; |
694 | @@ -205,7 +223,7 @@ |
695 | void deselect_all(); |
696 | |
697 | void addLine( SPItem *item, Geom::Point p1, Geom::Point p2, Inkscape::PaintTarget fill_or_stroke); |
698 | - 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); |
699 | + 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, bool highlight = false); |
700 | |
701 | GrDragger *addDragger(GrDraggable *draggable); |
702 | |
703 | |
704 | === modified file 'src/knot.h' |
705 | --- src/knot.h 2016-12-03 16:11:45 +0000 |
706 | +++ src/knot.h 2016-12-03 19:47:59 +0000 |
707 | @@ -59,6 +59,7 @@ |
708 | |
709 | SPKnotShapeType shape; /**< Shape type. */ |
710 | SPKnotModeType mode; |
711 | + double angle; |
712 | |
713 | guint32 fill[SP_KNOT_VISIBLE_STATES]; |
714 | guint32 stroke[SP_KNOT_VISIBLE_STATES]; |
715 | |
716 | === modified file 'src/ui/tools/mesh-tool.cpp' |
717 | --- src/ui/tools/mesh-tool.cpp 2016-12-02 09:15:24 +0000 |
718 | +++ src/ui/tools/mesh-tool.cpp 2016-12-03 19:47:59 +0000 |
719 | @@ -754,11 +754,11 @@ |
720 | } |
721 | |
722 | // Highlight corner node corresponding to side or tensor node |
723 | - if( drag->mouseOver() ) { |
724 | + //if( drag->mouseOver() ) { |
725 | // MESH FIXME: Light up corresponding corner node corresponding to node we are over. |
726 | // See "pathflash" in ui/tools/node-tool.cpp for ideas. |
727 | // Use desktop->add_temporary_canvasitem( SPCanvasItem, milliseconds ); |
728 | - } |
729 | + //} |
730 | |
731 | // Change cursor shape if over line |
732 | std::vector<SPCtrlCurve *> over_line = |
merged