~mjmendoza/kagestudio/KageStudio-trunk

« back to all changes in this revision

Viewing changes to studio/kage/stage_node.cpp

  • Committer: creek23
  • Date: 2020-04-24 16:31:12 UTC
  • Revision ID: svn-v4:b8ed6fa5-ed16-4a64-bb8f-f59368054108::754
Fixes, Stage-revamp!
 * Fixed Issue #51 - https://sourceforge.net/p/kage/tickets/51/
 * spliced stage.cpp as code keeps getting bigger

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
//part of stage.cpp
 
2
 
 
3
void KageStage::initNodeTool() {
 
4
        selectedNode = -1;
 
5
        selectedShape = -1;
 
6
        selectedNodes.clear();
 
7
        selectedShapes.clear();
 
8
        _mouseLocationShapeIndex = _NO_SELECTION;
 
9
        
 
10
        _rotateMode = false;
 
11
}
 
12
 
 
13
bool KageStage::isSelectedNode(unsigned int p_index) {
 
14
        bool l_gotit = false;
 
15
        unsigned int nsize = selectedNodes.size();
 
16
        if (nsize == 0) {
 
17
                return false;
 
18
        }
 
19
        
 
20
        for (unsigned int i = 0; i < nsize; ++i) {
 
21
                if (selectedNodes[i] == p_index) {
 
22
                        l_gotit = true;
 
23
                        break;
 
24
                }
 
25
        }
 
26
        return l_gotit;
 
27
}
 
28
void KageStage::addSelectedNode(unsigned int p_index) {
 
29
        if (p_index == _NO_SELECTION) return;
 
30
        if (isSelectedNode(p_index) == false) {
 
31
                selectedNodes.push_back(p_index);
 
32
                updateNodeXY();
 
33
        }
 
34
}
 
35
 
 
36
void KageStage::updateNodeX(double p_value, bool p_stackDo) {
 
37
        Kage::timestamp();
 
38
        std::cout << " KageStage::updateNodeX " << selectedNodes.size() << " " << p_value << std::endl;
 
39
        
 
40
        if (selectedNodes.size() == 0) {
 
41
                return;
 
42
        }
 
43
        
 
44
        double l_propXdiff = 0;
 
45
        vector<VectorData> v = win->getFrameData().getVectorData();
 
46
        cout << " nodeIndexX " << nodeIndexX << " " << isSelectedNode(nodeIndexX) << endl;
 
47
        //calculate xDIFF from selected base Node
 
48
        for (unsigned int l_selectedNode = 0; l_selectedNode < selectedNodes.size(); ++l_selectedNode) {
 
49
                if (selectedNodes[l_selectedNode] == nodeIndexX) {
 
50
                        l_propXdiff = p_value - v[selectedNodes[l_selectedNode]].points[2].x;
 
51
                        break;
 
52
                }
 
53
        }
 
54
        cout << " l_propXdiff " << l_propXdiff << endl;
 
55
        for (unsigned int l_selectedNode = 0; l_selectedNode < selectedNodes.size(); ++l_selectedNode) {
 
56
//              l_propXdiff = p_value - v[selectedNodes[l_selectedNode]].points[2].x;
 
57
                if (v[selectedNodes[l_selectedNode]].vectorType == VectorData::TYPE_CURVE_CUBIC) {
 
58
                        v[selectedNodes[l_selectedNode]].points[1].x += l_propXdiff;
 
59
                        v[selectedNodes[l_selectedNode]].points[2].x += l_propXdiff;
 
60
                        
 
61
                        if (v[selectedNodes[l_selectedNode]+1].getPoints().size() != 0) {
 
62
                                v[selectedNodes[l_selectedNode]+1].points[0].x += l_propXdiff;
 
63
                        } else {
 
64
                        //this part of code is trying to resolve this problematic code
 
65
                        // above code is problematic if for last Node; this will use shape's first Node's point 0 instead
 
66
                                std::cout << " KageStage::updateNodeX points.size is zero" << std::endl;
 
67
                                for (unsigned int i = selectedNodes[l_selectedNode]-1; i >= 0; --i) {
 
68
                                        if (v[i].vectorType == VectorData::TYPE_MOVE) {
 
69
                                                std::cout << " KageStage::updateNodeX got MOVE" << std::endl;
 
70
                                                if (i+1 != selectedNodes[l_selectedNode]) {
 
71
                                                        std::cout << " KageStage::updateNodeX moving control point :) " << std::endl;
 
72
                                                        v[i  ].points[0].x += l_propXdiff; // for Node MOVE
 
73
                                                        v[i+1].points[0].x += l_propXdiff; // for Node Curve's control point being used by Node MOVE
 
74
                                                }
 
75
                                                break;
 
76
                                        }
 
77
                                }
 
78
                        }
 
79
                } else if (v[selectedNodes[l_selectedNode]].vectorType == VectorData::TYPE_IMAGE) {
 
80
                        //TODO:handle X for images
 
81
                }
 
82
        }
 
83
        
 
84
        win->setFrameData(v);
 
85
        
 
86
        if (p_stackDo) {
 
87
                win->stackDo();
 
88
        }
 
89
        
 
90
        render();
 
91
}
 
92
void KageStage::updateNodeY(double p_value) {
 
93
        Kage::timestamp();
 
94
        std::cout << " KageStage::updateNodeY " << selectedNodes.size() << " " << p_value << std::endl;
 
95
        
 
96
        if (selectedNodes.size() == 0) {
 
97
                return;
 
98
        }
 
99
        
 
100
        double l_propYdiff = 0;
 
101
        vector<VectorData> v = win->getFrameData().getVectorData();
 
102
        
 
103
        //calculate yDIFF from selected base Node
 
104
        for (unsigned int l_selectedNode = 0; l_selectedNode < selectedNodes.size(); ++l_selectedNode) {
 
105
                if (selectedNodes[l_selectedNode] == nodeIndexY) {
 
106
                        l_propYdiff = p_value - v[selectedNodes[l_selectedNode]].points[2].y;
 
107
                        break;
 
108
                }
 
109
        }
 
110
        for (unsigned int l_selectedNode = 0; l_selectedNode < selectedNodes.size(); ++l_selectedNode) {
 
111
//              l_propYdiff = p_value - v[selectedNodes[l_selectedNode]].points[2].y;
 
112
                if (v[selectedNodes[l_selectedNode]].vectorType == VectorData::TYPE_CURVE_CUBIC) {
 
113
                        v[selectedNodes[l_selectedNode]].points[1].y += l_propYdiff;
 
114
                        v[selectedNodes[l_selectedNode]].points[2].y += l_propYdiff;
 
115
                        
 
116
                        if (v[selectedNodes[l_selectedNode]+1].getPoints().size() != 0) {
 
117
                                v[selectedNodes[l_selectedNode]+1].points[0].y += l_propYdiff;
 
118
                        } else {
 
119
                                for (unsigned int i = selectedNodes[l_selectedNode]-1; i >= 0; --i) {
 
120
                                        if (v[i].vectorType == VectorData::TYPE_MOVE) {
 
121
                                                if (i+1 != selectedNodes[l_selectedNode]) {
 
122
                                                        v[i  ].points[0].y += l_propYdiff;
 
123
                                                        v[i+1].points[0].y += l_propYdiff;
 
124
                                                }
 
125
                                                break;
 
126
                                        }
 
127
                                }
 
128
                        }
 
129
                } else if (v[selectedNodes[l_selectedNode]].vectorType == VectorData::TYPE_IMAGE) {
 
130
                        //TODO:handle Y for images
 
131
                }
 
132
        }
 
133
        
 
134
        win->setFrameData(v);
 
135
        
 
136
        win->stackDo();
 
137
        
 
138
        render();
 
139
}
 
140
 
 
141
 
 
142
 
 
143
 
 
144
void KageStage::handleNodes() {
 
145
        handleNodes_selection();
 
146
        handleNodes_relocation();
 
147
        handleNodes_rendering();
 
148
}
 
149
void KageStage::handleNodes_selection() {
 
150
        if (mouseDown == true && _isModifyingShape == false) {
 
151
                drawSelectionArea();
 
152
        }
 
153
        
 
154
        vector<VectorData> v = win->getFrameData().getVectorData();
 
155
        unsigned int vsize = v.size();
 
156
        mouseOnNodeHover = UINT_MAX;
 
157
        unsigned int typeMovesIndex = _NO_SELECTION;
 
158
        bool l_shapeGotClose = false;
 
159
        for (unsigned int l_selectedShape = 0; l_selectedShape < selectedShapes.size(); ++l_selectedShape) {
 
160
                for (unsigned int i = selectedShapes[l_selectedShape]; i < vsize; ++i) {
 
161
                        switch (v[i].vectorType) {
 
162
                                case VectorData::TYPE_CLOSE_PATH:
 
163
                                        l_shapeGotClose = true;
 
164
                                        break;
 
165
                                case VectorData::TYPE_FILL:
 
166
                                        l_shapeGotClose = false;
 
167
                                        break;
 
168
                                case VectorData::TYPE_ENDFILL:
 
169
                                        if (l_shapeGotClose == false && typeMovesIndex != _NO_SELECTION) {
 
170
                                                //check if mouse is on Move' location
 
171
                                                if (isMouseOnNode(
 
172
                                                                v[typeMovesIndex].points[0].x + origin.x,
 
173
                                                                v[typeMovesIndex].points[0].y + origin.y) == true) {
 
174
                                                        mouseOnNodeHover = typeMovesIndex;
 
175
                                                        if (mouseDown == true) {
 
176
                                                                if (mouseOnNode == _NO_SELECTION) {
 
177
                                                                        mouseOnNode = typeMovesIndex;
 
178
                                                                }
 
179
                                                                if (isSelectedNode(typeMovesIndex) == false && keyShiftDown == false) {
 
180
                                                                        selectedNodes.clear();
 
181
                                                                }
 
182
                                                                        addSelectedNode(typeMovesIndex);
 
183
                                                                if (mouseOnNodeIndex == _NO_SELECTION) {
 
184
                                                                        mouseOnNodeIndex = 3;
 
185
                                                                }
 
186
                                                                mouseOnNodeOffset.x = _mouseLocation.x - v[typeMovesIndex].points[0].x - origin.x;
 
187
                                                                mouseOnNodeOffset.y = _mouseLocation.y - v[typeMovesIndex].points[0].y - origin.y;
 
188
                                                        }
 
189
                                                }
 
190
                                        }
 
191
                                        i = vsize;
 
192
                                        break;
 
193
                                case VectorData::TYPE_STROKE:
 
194
                                        break;
 
195
                                case VectorData::TYPE_MOVE:
 
196
                                        typeMovesIndex = i;
 
197
                                case VectorData::TYPE_LINE:
 
198
                                        break;
 
199
                                case VectorData::TYPE_CURVE_QUADRATIC:
 
200
                                case VectorData::TYPE_CURVE_CUBIC:
 
201
                                        //check anchor
 
202
                                        if (isMouseOnNode(
 
203
                                                        v[i].points[2].x + origin.x,
 
204
                                                        v[i].points[2].y + origin.y) == true) {
 
205
                                                mouseOnNodeHover = i;
 
206
                                                if (mouseDown == true) {
 
207
                                                        if (mouseOnNode == _NO_SELECTION) {
 
208
                                                                mouseOnNode = i;
 
209
                                                        }
 
210
                                                        if (isSelectedNode(i) == false && keyShiftDown == false) {
 
211
                                                                selectedNodes.clear();
 
212
                                                        }
 
213
                                                                addSelectedNode(i);
 
214
                                                        if (mouseOnNodeIndex == _NO_SELECTION) {
 
215
                                                                mouseOnNodeIndex = 3;
 
216
                                                        }
 
217
                                                        mouseOnNodeOffset.x = _mouseLocation.x - v[i].points[2].x - origin.x;
 
218
                                                        mouseOnNodeOffset.y = _mouseLocation.y - v[i].points[2].y - origin.y;
 
219
                                                }
 
220
                                        }
 
221
                                        
 
222
                                        //check control points
 
223
                                        if (isMouseOnNode(
 
224
                                                        v[i].points[0].x + origin.x,
 
225
                                                        v[i].points[0].y + origin.y) == true) {
 
226
                                                if (mouseDown == true) {
 
227
                                                        if (mouseOnNode == _NO_SELECTION) {
 
228
                                                                mouseOnNode = i;
 
229
                                                        }
 
230
                                                        if (keyShiftDown == false) { selectedNodes.clear(); }
 
231
                                                        if (i > 0 && (
 
232
                                                                        v[i-1].vectorType == VectorData::TYPE_LINE
 
233
                                                                        || v[i-1].vectorType == VectorData::TYPE_CURVE_QUADRATIC
 
234
                                                                        || v[i-1].vectorType == VectorData::TYPE_CURVE_CUBIC)) {
 
235
                                                                addSelectedNode(i-1);
 
236
                                                        }
 
237
                                                        if (mouseOnNodeIndex == _NO_SELECTION) {
 
238
                                                                mouseOnNodeIndex = 1;
 
239
                                                        }
 
240
                                                }
 
241
                                        }
 
242
                                        
 
243
                                        if (isMouseOnNode(
 
244
                                                        v[i].points[1].x + origin.x,
 
245
                                                        v[i].points[1].y + origin.y) == true) {
 
246
                                                if (mouseDown == true) {
 
247
                                                        if (mouseOnNode == _NO_SELECTION) {
 
248
                                                                mouseOnNode = i;
 
249
                                                        }
 
250
                                                        if (keyShiftDown == false) { selectedNodes.clear(); }
 
251
                                                        addSelectedNode(i);
 
252
                                                        if (mouseOnNodeIndex == _NO_SELECTION) {
 
253
                                                                mouseOnNodeIndex = 2;
 
254
                                                        }
 
255
                                                }
 
256
                                        }
 
257
                                        break;
 
258
                                case VectorData::TYPE_TEXT:
 
259
                                case VectorData::TYPE_IMAGE:
 
260
                                case VectorData::TYPE_INIT:
 
261
                                        typeMovesIndex = _NO_SELECTION;
 
262
                                default:
 
263
                                        break;
 
264
                        }
 
265
                }
 
266
        }
 
267
}
 
268
void KageStage::handleNodes_relocation() {
 
269
        if (selectedShapes.size() == 0) {
 
270
                return;
 
271
        }
 
272
        
 
273
        vector<VectorData> v = win->getFrameData().getVectorData();
 
274
        bool l_editingNode = false;
 
275
        double l_x;
 
276
        double l_y;
 
277
        unsigned int typeMovesIndex = _NO_SELECTION;
 
278
        unsigned int typeEndsPointSize;
 
279
        unsigned int typeCubicCurvesIndex = _NO_SELECTION;
 
280
        bool l_useEndPoint = false;
 
281
        unsigned int vsize = v.size();
 
282
        bool l_shapeGotClose = false;
 
283
        PointData g_typeMovesXY;
 
284
        for (unsigned int l_selectedShape = 0; l_selectedShape < selectedShapes.size(); ++l_selectedShape) {
 
285
                for (unsigned int i = selectedShapes[l_selectedShape]; i < vsize; ++i) {
 
286
                        switch (v[i].vectorType) {
 
287
                                case VectorData::TYPE_CLOSE_PATH:
 
288
                                        l_shapeGotClose = true;
 
289
                                        if (typeMovesIndex != UINT_MAX) {
 
290
                                                typeEndsPointSize = v[i-1].points.size()-1;
 
291
                                                if (v[typeMovesIndex].points[0].x != v[typeMovesIndex].points[typeEndsPointSize].x
 
292
                                                                || v[typeMovesIndex].points[0].y != v[typeMovesIndex].points[typeEndsPointSize].y) {
 
293
                                                        v[typeMovesIndex].points[0].x = v[i-1].points[typeEndsPointSize].x;
 
294
                                                        v[typeMovesIndex].points[0].y = v[i-1].points[typeEndsPointSize].y;
 
295
                                                }
 
296
                                                typeMovesIndex = UINT_MAX;
 
297
                                        }
 
298
                                        l_useEndPoint = true;
 
299
                                        break;
 
300
                                case VectorData::TYPE_FILL:
 
301
                                        l_shapeGotClose = false;
 
302
                                        break;
 
303
                                case VectorData::TYPE_ENDFILL:
 
304
                                        ///make sure last point before end fill is in-sync with MOVE(shape's start point)
 
305
                                        if (typeMovesIndex != UINT_MAX && mouseDown == true && mouseOnNode == i-1) {
 
306
                                                if (l_useEndPoint == true) {
 
307
                                                        typeEndsPointSize = v[i-1].points.size()-1;
 
308
                                                        if (v[typeMovesIndex].points[0].x != v[typeMovesIndex].points[typeEndsPointSize].x
 
309
                                                                        || v[typeMovesIndex].points[0].y != v[typeMovesIndex].points[typeEndsPointSize].y) {
 
310
                                                                v[typeMovesIndex].points[0].x = v[i-1].points[typeEndsPointSize].x;
 
311
                                                                v[typeMovesIndex].points[0].y = v[i-1].points[typeEndsPointSize].y;
 
312
                                                        }
 
313
                                                }
 
314
                                        }
 
315
                                        if (l_shapeGotClose == false && mouseDown == true && mouseOnNode == typeMovesIndex && mouseOnNodeIndex == 3) {
 
316
                                                l_editingNode = true;
 
317
                                                        l_x = ((draw1.x - origin.x - mouseOnNodeOffset.x) - v[typeMovesIndex].points[0].x);
 
318
                                                        l_y = ((draw1.y - origin.y - mouseOnNodeOffset.y) - v[typeMovesIndex].points[0].y);
 
319
                                                        if (keyControlDown == true) {
 
320
                                                                if (keyShiftDown == true) {
 
321
                                                                        l_x = 0; //restraint on X axis
 
322
                                                                } else {
 
323
                                                                        l_y = 0; //restraint on Y axis
 
324
                                                                }
 
325
                                                        }
 
326
                                                        for (unsigned int j = 0; j < selectedNodes.size(); ++j) {
 
327
                                                                unsigned int k = selectedNodes[j];
 
328
                                                                //move control A of selected node's next curve
 
329
                                                                if (k+1 < v.size()-1 && v[k+1].vectorType == VectorData::TYPE_CURVE_CUBIC) {
 
330
                                                                        v[k+1].points[0].x += l_x;
 
331
                                                                        v[k+1].points[0].y += l_y;
 
332
                                                                } else if (k+2 < vsize && v[k+2].vectorType == VectorData::TYPE_ENDFILL) {
 
333
                                                                        v[typeMovesIndex+1].points[0].x += l_x;
 
334
                                                                        v[typeMovesIndex+1].points[0].y += l_y;
 
335
                                                                }
 
336
                                                                //move anchor of selected node
 
337
                                                                if (k != typeMovesIndex) {
 
338
                                                                        v[k].points[2].x += l_x;
 
339
                                                                        v[k].points[2].y += l_y;
 
340
                                                                }
 
341
                                                        }
 
342
                                                        v[typeMovesIndex].points[0].x += l_x;
 
343
                                                        v[typeMovesIndex].points[0].y += l_y;
 
344
                                        }
 
345
                                        i = vsize;
 
346
                                        break;
 
347
                                case VectorData::TYPE_STROKE:
 
348
                                        break;
 
349
                                case VectorData::TYPE_MOVE:
 
350
                                        ///register i for later use in ENDFILL
 
351
                                        typeMovesIndex = i;
 
352
                                        break;
 
353
                                case VectorData::TYPE_LINE:
 
354
                                        if (mouseDown == true && mouseOnNode == i) {
 
355
                                                v[i].points[0].x = draw1.x - origin.x;
 
356
                                                v[i].points[0].y = draw1.y - origin.y;
 
357
                                        }
 
358
                                        l_x = v[i].points[0].x + origin.x;
 
359
                                        l_y = v[i].points[0].y + origin.y;
 
360
                                        
 
361
                                        if (isMouseOnNode(l_x, l_y) == true) {
 
362
                                                if (mouseDown == true) {
 
363
                                                        v[i].points[0].x = draw1.x - origin.x;
 
364
                                                        v[i].points[0].y = draw1.y - origin.y;
 
365
                                                        
 
366
                                                        l_x = v[i].points[0].x + origin.x;
 
367
                                                        l_y = v[i].points[0].y + origin.y;
 
368
                                                }
 
369
                                        }
 
370
                                        break;
 
371
                                case VectorData::TYPE_CURVE_QUADRATIC:
 
372
                                case VectorData::TYPE_CURVE_CUBIC:
 
373
                                        ///register i for later use in ENDFILL <-- note from newer handling of Poly
 
374
                                        if (typeCubicCurvesIndex == _NO_SELECTION) {
 
375
                                                typeCubicCurvesIndex = i;
 
376
                                        }
 
377
                                        
 
378
                                        //relocate anchors
 
379
                                        if (mouseDown == true && mouseOnNode == i && mouseOnNodeIndex == 3) {
 
380
                                                l_editingNode = true;
 
381
                                                        l_x = ((draw1.x - origin.x - mouseOnNodeOffset.x) - v[i].points[2].x);
 
382
                                                        l_y = ((draw1.y - origin.y - mouseOnNodeOffset.y) - v[i].points[2].y);
 
383
                                                        if (keyControlDown == true) {
 
384
                                                                if (keyShiftDown == true) {
 
385
                                                                        l_x = 0; //restraint on X axis
 
386
                                                                } else {
 
387
                                                                        l_y = 0; //restraint on Y axis
 
388
                                                                }
 
389
                                                        }
 
390
                                                        for (unsigned int j = 0; j < selectedNodes.size(); ++j) {
 
391
                                                                unsigned int k = selectedNodes[j];
 
392
                                                                //move control B of selected node's current curve
 
393
                                                                v[k].points[1].x += l_x;
 
394
                                                                v[k].points[1].y += l_y;
 
395
                                                                //move control A of selected node's next curve
 
396
                                                                if (k+1 < v.size()-1 && v[k+1].vectorType == VectorData::TYPE_CURVE_CUBIC) {
 
397
                                                                        v[k+1].points[0].x += l_x;
 
398
                                                                        v[k+1].points[0].y += l_y;
 
399
                                                                } else if (k+2 < vsize && v[k+2].vectorType == VectorData::TYPE_ENDFILL) {
 
400
                                                                        v[typeMovesIndex+1].points[0].x += l_x;
 
401
                                                                        v[typeMovesIndex+1].points[0].y += l_y;
 
402
                                                                }
 
403
                                                                //move anchor of selected node
 
404
                                                                if (k != i) {
 
405
                                                                        v[k].points[2].x += l_x;
 
406
                                                                        v[k].points[2].y += l_y;
 
407
                                                                }
 
408
                                                        }
 
409
                                                        
 
410
                                                        v[i].points[2].x += l_x;
 
411
                                                        v[i].points[2].y += l_y;
 
412
                                        }
 
413
                                        
 
414
                                        //relocate control points
 
415
                                        if (mouseDown == true && mouseOnNode == i && mouseOnNodeIndex == 1) {
 
416
                                                l_editingNode = true;
 
417
                                                v[i].points[0].x = draw1.x - origin.x;
 
418
                                                v[i].points[0].y = draw1.y - origin.y;
 
419
                                        }
 
420
                                        
 
421
                                        if (mouseDown == true && mouseOnNode == i && mouseOnNodeIndex == 2) {
 
422
                                                l_editingNode = true;
 
423
                                                v[i].points[1].x = draw1.x - origin.x;
 
424
                                                v[i].points[1].y = draw1.y - origin.y;
 
425
                                        }
 
426
                                        break;
 
427
                                case VectorData::TYPE_TEXT:
 
428
                                case VectorData::TYPE_IMAGE:
 
429
                                case VectorData::TYPE_INIT:
 
430
                                default:
 
431
                                        break;
 
432
                        }
 
433
                }
 
434
        }
 
435
        
 
436
        if (l_editingNode == true) {
 
437
                win->setFrameData(v);
 
438
        }
 
439
//      cout << " \t l_editingNode " << l_editingNode << endl;
 
440
        _isModifyingShape = l_editingNode;
 
441
}
 
442
void KageStage::handleNodes_rendering() {
 
443
        if (selectedShapes.size() == 0) {
 
444
                return;
 
445
        }
 
446
        
 
447
        vector<VectorData> v = win->getFrameData().getVectorData();
 
448
        double l_x;
 
449
        double l_y;
 
450
        bool l_shapeGotClose = false;
 
451
        unsigned int vsize = v.size();
 
452
        unsigned int typeMovesIndex = _NO_SELECTION;
 
453
        for (unsigned int l_selectedShape = 0; l_selectedShape < selectedShapes.size(); ++l_selectedShape) {
 
454
                for (unsigned int i = selectedShapes[l_selectedShape]; i < vsize; ++i) {
 
455
                        switch (v[i].vectorType) {
 
456
                                case VectorData::TYPE_CLOSE_PATH:
 
457
                                        l_shapeGotClose = true;
 
458
                                        break;
 
459
                                case VectorData::TYPE_FILL:
 
460
                                        l_shapeGotClose = false;
 
461
                                        break;
 
462
                                case VectorData::TYPE_ENDFILL:
 
463
//                                      i = vsize;
 
464
                                        if (l_shapeGotClose == false && typeMovesIndex != UINT_MAX) {
 
465
                                                //draw anchors
 
466
                                                cr->move_to(
 
467
                                                        v[typeMovesIndex].points[0].x + origin.x,
 
468
                                                        v[typeMovesIndex].points[0].y + origin.y
 
469
                                                );
 
470
                                                
 
471
                                                l_x = v[typeMovesIndex].points[0].x + origin.x;
 
472
                                                l_y = v[typeMovesIndex].points[0].y + origin.y;
 
473
                                                if (mouseOnNodeHover == typeMovesIndex) {
 
474
                                                        renderNode(l_x, l_y, 1);
 
475
                                                } else {
 
476
                                                        if (selectedNodes.size() == 0) {
 
477
                                                                renderNode(l_x, l_y, 0);
 
478
                                                        } else {
 
479
                                                                bool l_selectedNode = false;
 
480
                                                                for (unsigned int j = 0; j < selectedNodes.size(); ++j) {
 
481
                                                                        if (selectedNodes[j] == i) {
 
482
                                                                                l_selectedNode = true;
 
483
                                                                                break;
 
484
                                                                        }
 
485
                                                                }
 
486
                                                                if (l_selectedNode == true) {
 
487
                                                                        renderNode(l_x, l_y, 2);
 
488
                                                                } else {
 
489
                                                                        renderNode(l_x, l_y, 0);
 
490
                                                                }
 
491
                                                        }
 
492
                                                }
 
493
                                        }
 
494
                                        break;
 
495
                                case VectorData::TYPE_STROKE:
 
496
                                        break;
 
497
                                case VectorData::TYPE_MOVE:
 
498
                                        typeMovesIndex = i;
 
499
                                        break;
 
500
                                case VectorData::TYPE_LINE:
 
501
                                        if (isMouseOnNode(l_x, l_y) == true) {
 
502
                                                renderNode(l_x, l_y, 1);
 
503
                                        } else {
 
504
                                                renderNode(l_x, l_y, 0);
 
505
                                        }
 
506
                                        break;
 
507
                                case VectorData::TYPE_CURVE_QUADRATIC:
 
508
                                case VectorData::TYPE_CURVE_CUBIC:
 
509
                                        //draw lines to anchor
 
510
                                        cr->move_to(
 
511
                                                v[i-1].points[v[i-1].points.size()-1].x + origin.x,
 
512
                                                v[i-1].points[v[i-1].points.size()-1].y + origin.y
 
513
                                        );
 
514
                                                cr->line_to(
 
515
                                                        v[i].points[0].x + origin.x,
 
516
                                                        v[i].points[0].y + origin.y
 
517
                                                );
 
518
                                                cr->set_source_rgba(0.0,0.7,0.7,1.0);
 
519
                                                cr->set_line_width(1.0);
 
520
                                                        cr->set_line_cap(Cairo::LINE_CAP_ROUND);
 
521
                                                                cr->stroke();
 
522
                                        
 
523
                                        cr->move_to(
 
524
                                                v[i].points[1].x + origin.x,
 
525
                                                v[i].points[1].y + origin.y
 
526
                                        );
 
527
                                                cr->line_to(
 
528
                                                        v[i].points[2].x + origin.x,
 
529
                                                        v[i].points[2].y + origin.y
 
530
                                                );
 
531
                                                cr->set_source_rgba(0.0,0.7,0.7,1.0);
 
532
                                                cr->set_line_width(1.0);
 
533
                                                        cr->set_line_cap(Cairo::LINE_CAP_ROUND);
 
534
                                                                cr->stroke();
 
535
                                        
 
536
                                        //draw anchors
 
537
                                        cr->move_to(
 
538
                                                v[i].points[2].x + origin.x,
 
539
                                                v[i].points[2].y + origin.y
 
540
                                        );
 
541
                                        
 
542
                                        l_x = v[i].points[2].x + origin.x;
 
543
                                        l_y = v[i].points[2].y + origin.y;
 
544
                                        if (mouseOnNodeHover == i) {
 
545
                                                renderNode(l_x, l_y, 1);
 
546
                                        } else {
 
547
                                                if (selectedNodes.size() == 0) {
 
548
                                                        renderNode(l_x, l_y, 0);
 
549
                                                } else {
 
550
                                                        bool l_selectedNode = false;
 
551
                                                        for (unsigned int j = 0; j < selectedNodes.size(); ++j) {
 
552
                                                                if (selectedNodes[j] == i) {
 
553
                                                                        l_selectedNode = true;
 
554
                                                                        break;
 
555
                                                                }
 
556
                                                        }
 
557
                                                        if (l_selectedNode == true) {
 
558
                                                                renderNode(l_x, l_y, 2);
 
559
                                                        } else {
 
560
                                                                renderNode(l_x, l_y, 0);
 
561
                                                        }
 
562
                                                }
 
563
                                        }
 
564
                                        
 
565
                                        //draw control points
 
566
                                        if (mouseDown == true && mouseOnNode == i && mouseOnNodeIndex == 1) {
 
567
                                                renderNodeControl(v[i].points[0].x + origin.x, v[i].points[0].y + origin.y, true);
 
568
                                        } else {
 
569
                                                renderNodeControl(v[i].points[0].x + origin.x, v[i].points[0].y + origin.y, false);
 
570
                                        }
 
571
                                        
 
572
                                        if (mouseDown == true && mouseOnNode == i && mouseOnNodeIndex == 2) {
 
573
                                                renderNodeControl(v[i].points[1].x + origin.x, v[i].points[1].y + origin.y, true);
 
574
                                        } else {
 
575
                                                renderNodeControl(v[i].points[1].x + origin.x, v[i].points[1].y + origin.y, false);
 
576
                                        }
 
577
                                        break;
 
578
                                case VectorData::TYPE_TEXT:
 
579
                                case VectorData::TYPE_IMAGE:
 
580
                                case VectorData::TYPE_INIT:
 
581
                                        if (i != selectedShapes[l_selectedShape]) {
 
582
                                                i = vsize;
 
583
                                        }
 
584
                                default:
 
585
                                        break;
 
586
                        }
 
587
                }
 
588
        }
 
589
}
 
590
void KageStage::handleNodesMouseDown() {
 
591
//      handleNodesMouseUp();
 
592
}
 
593
void KageStage::handleNodesMouseUp() {
 
594
        _nodeToMouseDistance = 1080;
 
595
        vector<VectorData> v = win->getFrameData().getVectorData();
 
596
        if (v.size() == 0) {
 
597
                return;
 
598
        }
 
599
        selectedNode = -1;
 
600
        mouseOnNode = _NO_SELECTION;
 
601
        if (keyShiftDown == false) {
 
602
                selectedShapes.clear();
 
603
        }
 
604
        selectedNodes.clear();
 
605
        unsigned int vsize = v.size();
 
606
        unsigned int l_vStartIndex = 0;
 
607
        if (_mouseLocationShapeIndex != _NO_SELECTION) {
 
608
                l_vStartIndex = _mouseLocationShapeIndex;
 
609
        }
 
610
        for (unsigned int i = l_vStartIndex; i < vsize; ++i) {
 
611
                if (v[i].vectorType == VectorData::TYPE_CURVE_CUBIC) {
 
612
                        if (handleNodes_getNearestShape(v[i].points[0].x + origin.x, v[i].points[0].y + origin.y, i, v)) {
 
613
                                selectedNodes.push_back(i-1); //visualization-wise, the control-point is for the previous Node -- it is its right control-point
 
614
                        }
 
615
                        if (handleNodes_getNearestShape(v[i].points[1].x + origin.x, v[i].points[1].y + origin.y, i, v)) {
 
616
                                selectedNodes.push_back(i);
 
617
                        }
 
618
                        if (handleNodes_getNearestShape(v[i].points[2].x + origin.x, v[i].points[2].y + origin.y, i, v)) {
 
619
                                selectedNodes.push_back(i);
 
620
                        }
 
621
                }
 
622
        }
 
623
        if (selectedShape != UINT_MAX) {
 
624
                addSelectedShape(selectedShape);
 
625
                if (KageStage::toolMode == MODE_SELECT) {
 
626
                        win->propStageSetVisible(false);
 
627
                        win->propFillStrokeSetVisible(true);
 
628
                        win->propShapePropertiesSetVisible(true);
 
629
                }
 
630
        }
 
631
        if (selectedNodes.size() > 0) {
 
632
                if (KageStage::toolMode == MODE_NODE) {
 
633
                        double l_nodeX = DBL_MAX;
 
634
                        double l_nodeY = DBL_MAX;
 
635
                                for (unsigned int i = 0; i < selectedNodes.size(); ++i) {
 
636
                                        if (v[selectedNodes[i]].getPoints().size() == 3) {
 
637
                                                if (v[selectedNodes[i]].points[2].x < l_nodeX) {
 
638
                                                        l_nodeX = v[selectedNodes[i]].points[2].x;
 
639
                                                }
 
640
                                                if (v[selectedNodes[i]].points[2].y < l_nodeY) {
 
641
                                                        l_nodeY = v[selectedNodes[i]].points[2].y;
 
642
                                                }
 
643
                                        }
 
644
                                }
 
645
                        if (l_nodeX == DBL_MAX) { l_nodeX = 0; }
 
646
                        nodeX = l_nodeX;
 
647
                        if (l_nodeY == DBL_MAX) { l_nodeY = 0; }
 
648
                        nodeY = l_nodeY;
 
649
                        win->updateNodeXY();
 
650
                        win->propStageSetVisible(false);
 
651
                        win->propNodeXYSetVisible(true);
 
652
                }
 
653
        }
 
654
        
 
655
        render();
 
656
}
 
657
bool KageStage::handleNodes_getNearestShape(double p_x, double p_y, unsigned int p_index, vector<VectorData> p_v) {
 
658
        double l_vXdiff, l_vYdiff;
 
659
        double l_distance;
 
660
        
 
661
        if (p_x >= draw1.x) {
 
662
                l_vXdiff = p_x - draw1.x;
 
663
        } else {
 
664
                l_vXdiff = draw1.x - p_x;
 
665
        }
 
666
        if (p_y >= draw1.y) {
 
667
                l_vYdiff = p_y - draw1.y;
 
668
        } else {
 
669
                l_vYdiff = draw1.y - p_y;
 
670
        }
 
671
        
 
672
        l_distance = sqrt((l_vXdiff * l_vXdiff) + (l_vYdiff * l_vYdiff));
 
673
        if (l_distance <= _nodeToMouseDistance
 
674
                        && isMouseOnNode(p_x, p_y, 100) == true) {
 
675
                _nodeToMouseDistance = l_distance;
 
676
                selectedShape = getSelectedShapeViaNode(p_index, p_v);
 
677
//              addSelectedShape(selectedShape);
 
678
                return true;
 
679
        }
 
680
        
 
681
        return false;
 
682
}
 
683
 
 
684
unsigned int KageStage::getSelectedShapeViaNode(unsigned int p_index, vector<VectorData> p_v) {
 
685
        if (p_index >= p_v.size()) {
 
686
                return UINT_MAX;
 
687
        }
 
688
        
 
689
        unsigned int l_tmp = selectedShape;
 
690
        
 
691
        propX = DBL_MAX;
 
692
        propXindex1 = -1;
 
693
        propXindex2 = -1;
 
694
        propY = DBL_MAX;
 
695
        propYindex1 = -1;
 
696
        propYindex2 = -1;
 
697
        propWidth = 0.0;
 
698
        propHeight = 0.0;
 
699
        for (unsigned int i = p_index; i >= 0; --i) {
 
700
                switch (p_v[i].vectorType) {
 
701
                        case VectorData::TYPE_FILL:
 
702
                                fillColor = p_v[i].fillColor.clone();
 
703
                                break;
 
704
                        case VectorData::TYPE_ENDFILL:
 
705
                                break;
 
706
                        case VectorData::TYPE_STROKE:
 
707
                                stroke = p_v[i].stroke.clone();
 
708
                                
 
709
                                break;
 
710
                        case VectorData::TYPE_MOVE: {
 
711
                                if (propX > p_v[i].points[0].x) {
 
712
                                        propX = p_v[i].points[0].x;
 
713
                                        propXindex1 = i;
 
714
                                        propXindex2 = 0;
 
715
                                }
 
716
                                if (propY > p_v[i].points[0].y) {
 
717
                                        propY = p_v[i].points[0].y;
 
718
                                        propYindex1 = i;
 
719
                                        propYindex2 = 0;
 
720
                                }
 
721
                                break;
 
722
                        }
 
723
                        case VectorData::TYPE_LINE:
 
724
                        case VectorData::TYPE_CURVE_QUADRATIC:
 
725
                                break;
 
726
                        case VectorData::TYPE_CURVE_CUBIC: {
 
727
                                if (propX > p_v[i].points[0].x) {
 
728
                                        propX = p_v[i].points[0].x;
 
729
                                        propXindex1 = i;
 
730
                                        propXindex2 = 0;
 
731
                                }
 
732
                                if (propX > p_v[i].points[1].x) {
 
733
                                        propX = p_v[i].points[1].x;
 
734
                                        propXindex1 = i;
 
735
                                        propXindex2 = 1;
 
736
                                }
 
737
                                if (propX > p_v[i].points[2].x) {
 
738
                                        propX = p_v[i].points[2].x;
 
739
                                        propXindex1 = i;
 
740
                                        propXindex2 = 2;
 
741
                                }
 
742
                                if (propY > p_v[i].points[0].y) {
 
743
                                        propY = p_v[i].points[0].y;
 
744
                                        propYindex1 = i;
 
745
                                        propYindex2 = 0;
 
746
                                }
 
747
                                if (propY > p_v[i].points[1].y) {
 
748
                                        propY = p_v[i].points[1].y;
 
749
                                        propYindex1 = i;
 
750
                                        propYindex2 = 1;
 
751
                                }
 
752
                                if (propY > p_v[i].points[2].y) {
 
753
                                        propY = p_v[i].points[2].y;
 
754
                                        propYindex1 = i;
 
755
                                        propYindex2 = 2;
 
756
                                }
 
757
                                break;
 
758
                        }
 
759
                        case VectorData::TYPE_TEXT:
 
760
                        case VectorData::TYPE_IMAGE:
 
761
                                break;
 
762
                        case VectorData::TYPE_INIT: {
 
763
                                unsigned int vsize = p_v.size();
 
764
                                for (unsigned int j = i; j < vsize; ++j) {
 
765
                                        if (p_v[j].vectorType == VectorData::TYPE_ENDFILL) {
 
766
                                                break;
 
767
                                        } else if (p_v[j].vectorType == VectorData::TYPE_MOVE) {
 
768
                                                if (propX < p_v[j].points[0].x
 
769
                                                                && propWidth < (p_v[j].points[0].x - propX)) {
 
770
                                                        propWidth = p_v[j].points[0].x - propX;
 
771
                                                        cout << "\npropWidth " << propWidth << " _zoomValueShapeProperty " << _zoomValueShapeProperty << endl;
 
772
                                                        propWidth = propWidth * _zoomValueShapeProperty;
 
773
                                                }
 
774
                                                if (propY < p_v[j].points[0].y
 
775
                                                                && propHeight < (p_v[j].points[0].y - propY)) {
 
776
                                                        propHeight = p_v[j].points[0].y - propY;
 
777
                                                        propHeight = propHeight * _zoomValueShapeProperty;
 
778
                                                }
 
779
                                        } else if (p_v[j].vectorType == VectorData::TYPE_CURVE_CUBIC) {
 
780
                                                for (int k = 0; k < 3; ++k) {
 
781
                                                        if (propX < p_v[j].points[k].x
 
782
                                                                        && propWidth < (p_v[j].points[k].x - propX)) {
 
783
                                                                propWidth = p_v[j].points[k].x - propX;
 
784
                                                                cout << "\npropWidth " << propWidth << " _zoomValueShapeProperty " << _zoomValueShapeProperty << endl;
 
785
                                                                propWidth = propWidth * _zoomValueShapeProperty;
 
786
                                                        }
 
787
                                                        if (propY < p_v[j].points[k].y
 
788
                                                                        && propHeight < (p_v[j].points[k].y - propY)) {
 
789
                                                                propHeight = p_v[j].points[k].y - propY;
 
790
                                                                propHeight = propHeight * _zoomValueShapeProperty;
 
791
                                                        }
 
792
                                                }
 
793
                                        }
 
794
                                }
 
795
                                //got it!
 
796
                                return i;
 
797
                        }
 
798
                        default:
 
799
                                break;
 
800
                }
 
801
        }
 
802
        return l_tmp;
 
803
}
 
804
 
 
805
void KageStage::renderNode(double p_x, double p_y, unsigned int p_state) {
 
806
        cr->move_to(p_x-5, p_y);
 
807
                cr->line_to(p_x  , p_y-5);
 
808
                cr->line_to(p_x+5, p_y  );
 
809
                cr->line_to(p_x  , p_y+5);
 
810
        cr->close_path();
 
811
        if (p_state == 1) {
 
812
                cr->set_source_rgba(1.00, 0.00, 0.00, 1.00);
 
813
        } else if (p_state == 0) {
 
814
                cr->set_source_rgba(0.75, 0.75, 0.75, 1.00);
 
815
        } else if (p_state == 2) {
 
816
                cr->set_source_rgba(0.00, 0.00, 1.00, 1.00);
 
817
        }
 
818
                cr->fill_preserve();
 
819
        
 
820
        cr->set_source_rgba(0.0, 0.0, 0.0, 1.0);
 
821
                cr->set_line_width(0.5);
 
822
                        cr->set_line_cap(Cairo::LINE_CAP_ROUND);
 
823
                                cr->stroke();
 
824
}
 
825
 
 
826
void KageStage::renderNodeControl(double p_x, double p_y, bool p_selected) {
 
827
        cr->set_line_width(1.0);
 
828
        cr->arc(p_x, p_y, 3, 0, 2 * M_PI);
 
829
        
 
830
        if (p_selected == true) {
 
831
                cr->set_source_rgba(1.0,0.0,0.0,1.0);
 
832
                cr->fill_preserve();
 
833
        } else {
 
834
                cr->set_source_rgba(1.0,1.0,1.0,1.0);
 
835
                cr->fill_preserve();
 
836
        }
 
837
        
 
838
        cr->set_source_rgba(0.0, 0.0, 0.0, 1.0);
 
839
                cr->stroke();
 
840
}
 
841
 
 
842
bool KageStage::isSelectionBoxNormalized() {
 
843
        if (selectionBox1.x <= selectionBox2.x && selectionBox1.y <= selectionBox2.y) {
 
844
                return true;
 
845
        }
 
846
        return false;
 
847
}
 
848
void KageStage::normalizeSelectionBox() {
 
849
        if (isSelectionBoxNormalized() == true) {
 
850
                return;
 
851
        }
 
852
        double l_x1 = 0.0f;
 
853
        double l_y1 = 0.0f;
 
854
        double l_x2 = 0.0f;
 
855
        double l_y2 = 0.0f;
 
856
        if (selectionBox1.x < selectionBox2.x) {
 
857
                l_x1 = selectionBox1.x;
 
858
                l_x2 = selectionBox2.x;
 
859
        } else {
 
860
                l_x1 = selectionBox2.x;
 
861
                l_x2 = selectionBox1.x;
 
862
        }
 
863
        if (selectionBox1.y < selectionBox2.y) {
 
864
                l_y1 = selectionBox1.y;
 
865
                l_y2 = selectionBox2.y;
 
866
        } else {
 
867
                l_y1 = selectionBox2.y;
 
868
                l_y2 = selectionBox1.y;
 
869
        }
 
870
        
 
871
        selectionBox1.x = l_x1;
 
872
        selectionBox1.y = l_y1;
 
873
        selectionBox2.x = l_x2;
 
874
        selectionBox2.y = l_y2;
 
875
}
 
876
bool KageStage::isNodeOnSelectionBox(double p_nodeX, double p_nodeY) {
 
877
        normalizeSelectionBox();
 
878
        
 
879
        if (selectionBox1.x <= p_nodeX && selectionBox2.x >= p_nodeX
 
880
                        && selectionBox1.y <= p_nodeY && selectionBox2.y >= p_nodeY) {
 
881
                return true;
 
882
        }
 
883
        return false;
 
884
}
 
885
bool KageStage::isMouseOnNode(double p_x, double p_y, unsigned int p_buffer) {
 
886
        if (p_x-p_buffer <= draw1.x && p_x+p_buffer >= draw1.x
 
887
                        && p_y-p_buffer <= draw1.y && p_y+p_buffer >= draw1.y) {
 
888
                return true;
 
889
        }
 
890
        return false;
 
891
}
 
892
 
 
893
bool KageStage::deselectSelectedNodes() {
 
894
        Kage::timestamp();
 
895
        std::cout << " KageStage::deselectSelectedNodes " << selectedNodes.size() << std::endl;
 
896
        
 
897
        if (selectedNodes.size() == 0) {
 
898
                return false;
 
899
        }
 
900
        
 
901
        initNodeTool();
 
902
        win->propStageSetVisible(true);
 
903
        win->propNodeXYSetVisible(false);
 
904
        
 
905
        return true;
 
906
}
 
907
 
 
908
bool KageStage::deleteSelectedNodes() {
 
909
        if (win->isLayerLocked() == true) {
 
910
                return false;
 
911
        }
 
912
        bool l_return = false;
 
913
        
 
914
        if (selectedNodes.size() == 0) {
 
915
                return false;
 
916
        }
 
917
        
 
918
        Kage::timestamp();
 
919
        std::cout << " KageStage::deleteSelectedNodes " << selectedNodes.size() << endl;
 
920
        
 
921
        sort(selectedNodes.begin(), selectedNodes.end(), greater <unsigned int>());
 
922
        
 
923
        for (unsigned int l_selectedNode = 0; l_selectedNode < selectedNodes.size(); ++l_selectedNode) {
 
924
        Kage::timestamp();
 
925
        std::cout << " KageStage::deleteSelectedNodes " << l_selectedNode << " " << selectedNodes.size() << endl;
 
926
                l_return = deleteSelectedNode(selectedNodes[l_selectedNode]);
 
927
        }
 
928
        
 
929
        selectedNodes.clear();
 
930
        
 
931
        if (l_return == true) {
 
932
                win->stackDo();
 
933
        }
 
934
        
 
935
        return l_return;
 
936
}
 
937
bool KageStage::deleteSelectedNode(unsigned int p_index) {
 
938
        if (win->isLayerLocked() == true) {
 
939
                return false;
 
940
        }
 
941
        vector<VectorData> v = win->getFrameData().getVectorData();
 
942
        
 
943
        selectedShape = getSelectedShapeViaNode(p_index, v);
 
944
        
 
945
        //avoid deletion of selectedNode as non-Curve/Line; ex: selectedNode is Move
 
946
        if (selectedShape == _NO_SELECTION
 
947
                        || (v[p_index].vectorType != VectorData::TYPE_CURVE_CUBIC
 
948
                        && v[p_index].vectorType != VectorData::TYPE_CURVE_QUADRATIC
 
949
                        && v[p_index].vectorType != VectorData::TYPE_LINE)) {
 
950
                return false;
 
951
        }
 
952
        
 
953
        unsigned int l_sequence = 0;
 
954
        bool l_closepath = false;
 
955
        if (v.size() >= 5) {
 
956
                if (v[selectedShape + 0].vectorType == VectorData::TYPE_INIT       ) ++l_sequence;
 
957
                if (v[selectedShape + 1].vectorType == VectorData::TYPE_FILL       ) ++l_sequence;
 
958
                if (v[selectedShape + 2].vectorType == VectorData::TYPE_STROKE     ) ++l_sequence;
 
959
                if (v[selectedShape + 3].vectorType == VectorData::TYPE_MOVE       ) ++l_sequence;
 
960
                if (v[selectedShape + 4].vectorType == VectorData::TYPE_CURVE_CUBIC
 
961
                        || v[selectedShape + 4].vectorType == VectorData::TYPE_CURVE_QUADRATIC
 
962
                        || v[selectedShape + 4].vectorType == VectorData::TYPE_LINE) {
 
963
                        ++l_sequence;
 
964
                }
 
965
                if (v[selectedShape + 5].vectorType == VectorData::TYPE_CLOSE_PATH ) {
 
966
                        ++l_sequence;
 
967
                        l_closepath = true;
 
968
                        if (v[selectedShape + 6].vectorType == VectorData::TYPE_ENDFILL) {
 
969
                                ++l_sequence;
 
970
                        }
 
971
                } else if (v[selectedShape + 5].vectorType == VectorData::TYPE_ENDFILL) {
 
972
                        ++l_sequence;
 
973
                }
 
974
        }
 
975
        
 
976
        if (l_sequence == 6 && l_closepath == false) {
 
977
                v.erase (v.begin() + selectedShape,
 
978
                                 v.begin() + selectedShape + l_sequence);
 
979
                
 
980
                cout << " DELETE A " << endl;
 
981
//                      selectedShapes.erase(selectedShapes.begin() + l_selectedShape);
 
982
        } else if (l_sequence == 7 && l_closepath == true) {
 
983
                v.erase (v.begin() + selectedShape,
 
984
                                 v.begin() + selectedShape + l_sequence);
 
985
                
 
986
                cout << " DELETE B " << endl;
 
987
//                      selectedShapes.erase(selectedShapes.begin() + l_selectedShape);
 
988
        } else {
 
989
                if (v[p_index-1].vectorType != VectorData::TYPE_MOVE &&
 
990
                                (v[p_index+1].vectorType == VectorData::TYPE_ENDFILL ||
 
991
                                 v[p_index+1].vectorType == VectorData::TYPE_CLOSE_PATH)) {
 
992
                        for (unsigned int i = p_index; i > 0; --i) {
 
993
                                if (v[i].vectorType == VectorData::TYPE_MOVE) {
 
994
                                        v[i+1].points[0].x = v[p_index].points[0].x;
 
995
                                        v[i+1].points[0].y = v[p_index].points[0].y;
 
996
                                        v[i].points[0].x = v[p_index-1].points[2].x;
 
997
                                        v[i].points[0].y = v[p_index-1].points[2].y;
 
998
                                        break;
 
999
                                }
 
1000
                        }
 
1001
                } else {
 
1002
                        v[p_index+1].points[0].x = v[p_index].points[0].x;
 
1003
                        v[p_index+1].points[0].y = v[p_index].points[0].y;
 
1004
                }
 
1005
                cout << " DELETE C " << endl;
 
1006
                
 
1007
                v.erase (v.begin() + p_index);
 
1008
        }
 
1009
        
 
1010
        win->setFrameData(v);
 
1011
        
 
1012
        return true;
 
1013
}
 
1014
 
 
1015
bool KageStage::toggleLineSelectedNodes() {
 
1016
        vector<VectorData> v = win->getFrameData().getVectorData();
 
1017
        
 
1018
        unsigned int nsize = selectedNodes.size();
 
1019
        
 
1020
        bool l_gotit = false;
 
1021
        unsigned int l_currentNode;
 
1022
        unsigned int l_nextNode;
 
1023
        for (unsigned int i = 0; i < nsize; ++i) {
 
1024
                l_currentNode = selectedNodes[i];
 
1025
                l_nextNode = l_currentNode+1;
 
1026
                if (l_currentNode < v.size()
 
1027
                                && isSelectedNode(l_nextNode) == true) {
 
1028
                        if (       (v[l_nextNode   ].vectorType == VectorData::TYPE_CURVE_CUBIC || v[l_nextNode   ].vectorType == VectorData::TYPE_CURVE_QUADRATIC)
 
1029
                                        && (v[l_currentNode].vectorType == VectorData::TYPE_CURVE_CUBIC || v[l_currentNode].vectorType == VectorData::TYPE_CURVE_QUADRATIC)) {
 
1030
                                v[l_nextNode].points[0].x = (v[l_currentNode].points[2].x + v[l_nextNode].points[2].x) / 2;
 
1031
                                v[l_nextNode].points[0].y = (v[l_currentNode].points[2].y + v[l_nextNode].points[2].y) / 2;
 
1032
                                
 
1033
                                v[l_nextNode].points[1].x = v[l_nextNode].points[0].x;
 
1034
                                v[l_nextNode].points[1].y = v[l_nextNode].points[0].y;
 
1035
                                l_gotit = true;
 
1036
                        }
 
1037
                } else if (v[l_nextNode].vectorType == VectorData::TYPE_CLOSE_PATH) {
 
1038
                        //The user just selected the very end of an enclosed shape and the very first node
 
1039
                        //so, search for very first curve/line if also currently selected
 
1040
                        for (unsigned int l_firstNode = l_currentNode-1; l_firstNode > 0; --l_firstNode) {
 
1041
                                if (v[l_firstNode].vectorType == VectorData::TYPE_MOVE) {
 
1042
                                        ++l_firstNode;
 
1043
                                        if (isSelectedNode(l_firstNode) == true) {
 
1044
                                                if (       (v[l_firstNode  ].vectorType == VectorData::TYPE_CURVE_CUBIC || v[l_firstNode  ].vectorType == VectorData::TYPE_CURVE_QUADRATIC)
 
1045
                                                                && (v[l_currentNode].vectorType == VectorData::TYPE_CURVE_CUBIC || v[l_currentNode].vectorType == VectorData::TYPE_CURVE_QUADRATIC)) {
 
1046
                                                        v[l_firstNode].points[0].x = (v[l_currentNode].points[2].x + v[l_firstNode].points[2].x) / 2;
 
1047
                                                        v[l_firstNode].points[0].y = (v[l_currentNode].points[2].y + v[l_firstNode].points[2].y) / 2;
 
1048
                                                        
 
1049
                                                        v[l_firstNode].points[1].x = v[l_firstNode].points[0].x;
 
1050
                                                        v[l_firstNode].points[1].y = v[l_firstNode].points[0].y;
 
1051
                                                        l_gotit = true;
 
1052
                                                }
 
1053
                                        }
 
1054
                                        break;
 
1055
                                }
 
1056
                        }
 
1057
                }
 
1058
        }
 
1059
        
 
1060
        if (l_gotit == true) {
 
1061
                win->setFrameData(v);
 
1062
                
 
1063
                win->stackDo();
 
1064
        }
 
1065
        
 
1066
        return l_gotit;
 
1067
}
 
1068
 
 
1069
void KageStage::updateNodeXY() {
 
1070
        unsigned int nsize = selectedNodes.size();
 
1071
        if (nsize == 0) {
 
1072
                nodeX = 0;
 
1073
                nodeY = 0;
 
1074
                nodeIndexX = UINT_MAX;
 
1075
                nodeIndexY = UINT_MAX;
 
1076
        } else {
 
1077
                nodeX = DBL_MAX;
 
1078
                nodeY = DBL_MAX;
 
1079
                vector<VectorData> v = win->getFrameData().getVectorData();
 
1080
                unsigned int vsize = v.size();
 
1081
                for (unsigned int i = 0; i < nsize; ++i) {
 
1082
                        for (unsigned int j = i; j < vsize; ++j) {
 
1083
                                if (isSelectedNode(j) == true) {
 
1084
                                        if (       v[j].vectorType == VectorData::TYPE_CURVE_QUADRATIC
 
1085
                                                        || v[j].vectorType == VectorData::TYPE_CURVE_CUBIC) {
 
1086
                                                if (v[j].points[2].x < nodeX) {
 
1087
                                                        nodeX = v[j].points[2].x;
 
1088
                                                        nodeIndexX = j;
 
1089
                                                }
 
1090
                                                if (v[j].points[2].y < nodeY) {
 
1091
                                                        nodeY = v[j].points[2].y;
 
1092
                                                        nodeIndexY = j;
 
1093
                                                }
 
1094
                                        } else if (v[j].vectorType == VectorData::TYPE_INIT
 
1095
                                                        && j != selectedShapes[i]) {
 
1096
                                                break;
 
1097
                                        }
 
1098
                                }
 
1099
                        }
 
1100
                }
 
1101
                if (nodeX == DBL_MAX) {
 
1102
                        nodeX = 0;
 
1103
                        nodeIndexX = UINT_MAX;
 
1104
                }
 
1105
                if (nodeY == DBL_MAX) {
 
1106
                        nodeY = 0;
 
1107
                        nodeIndexY = UINT_MAX;
 
1108
                }
 
1109
        }
 
1110
        win->propNodeXYSetVisible(true);
 
1111
}
 
1112