aboutsummaryrefslogtreecommitdiff
path: root/js/tools
diff options
context:
space:
mode:
Diffstat (limited to 'js/tools')
-rwxr-xr-xjs/tools/PenTool.js205
1 files changed, 155 insertions, 50 deletions
diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js
index 4d439dd3..bbde7374 100755
--- a/js/tools/PenTool.js
+++ b/js/tools/PenTool.js
@@ -33,10 +33,10 @@ exports.PenTool = Montage.create(ShapeTool, {
33 _parentNode: { enumerable: false, value: null, writable: true }, 33 _parentNode: { enumerable: false, value: null, writable: true },
34 _toolsPropertiesContainer: { enumerable: false, value: null, writable: true }, 34 _toolsPropertiesContainer: { enumerable: false, value: null, writable: true },
35 35
36 //set this to true if you want to keep making subpaths after closing current subpath (debugging only) 36 //set this to true if you want to keep making subpaths after closing current subpath (debugging only...should always be true)
37 _makeMultipleSubpaths: { value: true, writable: true }, 37 _makeMultipleSubpaths: { value: true, writable: true },
38 38
39 //set this to false if you don't want the mouse move handler being called when the mouse is not down (debugging only) 39 //set this to false if you don't want the mouse move handler being called when the mouse is not down (debugging only...should always be true)
40 _trackMouseMoveWhenUp: {value: true, writable: false}, 40 _trackMouseMoveWhenUp: {value: true, writable: false},
41 41
42 //whether the user has held down the Alt key 42 //whether the user has held down the Alt key
@@ -95,6 +95,12 @@ exports.PenTool = Montage.create(ShapeTool, {
95 ENTRY_SELECT_PATH: { value: 2, writable: false}, 95 ENTRY_SELECT_PATH: { value: 2, writable: false},
96 _entryEditMode: {value: this.ENTRY_SELECT_NONE, writable: true}, 96 _entryEditMode: {value: this.ENTRY_SELECT_NONE, writable: true},
97 97
98 //constants used for determining whether a subtool has been selected (mutually exclusive i.e. cannot be OR-ed)
99 SUBTOOL_NONE: {value: 0, writable: false},
100 SUBTOOL_PENPLUS: {value: 1, writable: false},
101 SUBTOOL_PENMINUS: {value: 2, writable: false},
102 _subtool: {value: this.SUBTOOL_NONE, writable: true},
103
98 //constants used for limiting size of the subpath canvas 104 //constants used for limiting size of the subpath canvas
99 _MAX_CANVAS_DIMENSION: {value: 3000, writable: false}, 105 _MAX_CANVAS_DIMENSION: {value: 3000, writable: false},
100 106
@@ -179,6 +185,70 @@ exports.PenTool = Montage.create(ShapeTool, {
179 } 185 }
180 }, 186 },
181 187
188 _removeSelectedSubpathAndCanvas:{
189 value: function(removeSelectedSubpath){
190 if (removeSelectedSubpath){
191 this._selectedSubpath.clearAllAnchors(); //perhaps unnecessary
192 this._selectedSubpath = null;
193 if (this._entryEditMode === this.ENTRY_SELECT_PATH){
194 this._entryEditMode = this.ENTRY_SELECT_NONE;
195 }
196 this._subtool = this.SUBTOOL_NONE;
197 } else {
198 this._selectedSubpath.setCanvas(null);
199 }
200 //clear the canvas
201 this.application.ninja.stage.clearDrawingCanvas();//stageManagerModule.stageManager.clearDrawingCanvas();
202
203 //undo/redo...go through ElementController and NJEvent
204 var els = [];
205 ElementController.removeElement(this._selectedSubpathCanvas);
206 els.push(this._selectedSubpathCanvas);
207 NJevent( "elementsRemoved", els );
208 this._selectedSubpathCanvas = null;
209 }
210 },
211
212 _removeSelectedAnchorPoint:{
213 value: function(){
214 this._hoveredAnchorIndex=-1;
215 this._selectedSubpath.removeAnchor(this._selectedSubpath.getSelectedAnchorIndex());
216 if (this._selectedSubpath.getNumAnchors()===1){
217 //convert the remaining anchor point to stage world coords
218 var xDelta = snapManager.getStageWidth()*0.5;
219 var yDelta = snapManager.getStageHeight()*0.5;
220 var anchor = this._selectedSubpath.getAnchor(0);
221 var swPos = ViewUtils.localToStageWorld([anchor.getPosX(),anchor.getPosY(),anchor.getPosZ()], this._selectedSubpathCanvas);
222 anchor.setPos(swPos[0]+xDelta, swPos[1]+yDelta, swPos[2]);
223 swPos = ViewUtils.localToStageWorld([anchor.getPrevX(),anchor.getPrevY(),anchor.getPrevZ()], this._selectedSubpathCanvas);
224 anchor.setPrevPos(swPos[0]+xDelta, swPos[1]+yDelta, swPos[2]);
225 swPos = ViewUtils.localToStageWorld([anchor.getNextX(),anchor.getNextY(),anchor.getNextZ()], this._selectedSubpathCanvas);
226 anchor.setNextPos(swPos[0]+xDelta, swPos[1]+yDelta, swPos[2]);
227 }
228 //clear the canvas
229 this.application.ninja.stage.clearDrawingCanvas();//stageManagerModule.stageManager.clearDrawingCanvas();
230 var removeSelectedSubpath=true;
231 var newNumAnchors = this._selectedSubpath.getNumAnchors();
232 if (newNumAnchors>1) {
233 this._selectedSubpath.createSamples(false);
234 this.PrepareSelectedSubpathForRendering();
235 this.ShowSelectedSubpath();
236 }
237 else {
238 //since we have 0 or 1 anchors, we will remove the selected canvas (as the path does not exist)
239 if (newNumAnchors===0){
240 removeSelectedSubpath = true;
241 } else{
242 removeSelectedSubpath = false; //don't remove the selected subpath if there is still one anchor
243 }
244 this._removeSelectedSubpathAndCanvas(removeSelectedSubpath);
245 }
246 if (!removeSelectedSubpath){
247 this.DrawSubpathAnchors(this._selectedSubpath);
248 }
249 }
250 },
251
182 // ********************************************************************************************************** 252 // **********************************************************************************************************
183 // Mouse down handler 253 // Mouse down handler
184 // IF the selected subpath is null, it means we're going to start a new subpath 254 // IF the selected subpath is null, it means we're going to start a new subpath
@@ -220,6 +290,11 @@ exports.PenTool = Montage.create(ShapeTool, {
220 if (this._entryEditMode !== this.ENTRY_SELECT_PATH && this._selectedSubpath && this._selectedSubpath.getIsClosed() && this._makeMultipleSubpaths) { 290 if (this._entryEditMode !== this.ENTRY_SELECT_PATH && this._selectedSubpath && this._selectedSubpath.getIsClosed() && this._makeMultipleSubpaths) {
221 this._selectedSubpath = null; 291 this._selectedSubpath = null;
222 } 292 }
293
294 if (this._subtool !== this.SUBTOOL_NONE && this._selectedSubpath===null) {
295 //do nothing because the pen plus and pen minus subtools need a selected subpath
296 return;
297 }
223 if (this._selectedSubpath === null) { 298 if (this._selectedSubpath === null) {
224 this._selectedSubpath = new SubPath(); 299 this._selectedSubpath = new SubPath();
225 this._selectedSubpathCanvas = null; 300 this._selectedSubpathCanvas = null;
@@ -255,7 +330,7 @@ exports.PenTool = Montage.create(ShapeTool, {
255 colorArray = [1,1,1,0]; 330 colorArray = [1,1,1,0];
256 } 331 }
257 this._selectedSubpath.setFillColor(colorArray); 332 this._selectedSubpath.setFillColor(colorArray);
258 } 333 } //if the selectedSubpath was null and needed to be constructed
259 334
260 //build the hit record for the current mouse position (on the stage or the plane of the path canvas) 335 //build the hit record for the current mouse position (on the stage or the plane of the path canvas)
261 var hitRec = this.getHitRecord(event.pageX, event.pageY, false); 336 var hitRec = this.getHitRecord(event.pageX, event.pageY, false);
@@ -333,6 +408,11 @@ exports.PenTool = Montage.create(ShapeTool, {
333 if (whichPoint !== this._selectedSubpath.SEL_NONE){ 408 if (whichPoint !== this._selectedSubpath.SEL_NONE){
334 //if we hit the anchor point itself 409 //if we hit the anchor point itself
335 if (whichPoint & this._selectedSubpath.SEL_ANCHOR) { 410 if (whichPoint & this._selectedSubpath.SEL_ANCHOR) {
411 if (this._subtool===this.SUBTOOL_PENMINUS){
412 //remove the selected anchor, similar to HandleDelete
413 this._removeSelectedAnchorPoint();
414 return;
415 }
336 //if we're in ENTRY_SELECT_PATH mode AND we have not yet clicked on the endpoint AND if we have now clicked on the endpoint 416 //if we're in ENTRY_SELECT_PATH mode AND we have not yet clicked on the endpoint AND if we have now clicked on the endpoint
337 if (this._entryEditMode === this.ENTRY_SELECT_PATH && this._isPickedEndPointInSelectPathMode === false){ 417 if (this._entryEditMode === this.ENTRY_SELECT_PATH && this._isPickedEndPointInSelectPathMode === false){
338 var selAnchorIndex = this._selectedSubpath.getSelectedAnchorIndex(); 418 var selAnchorIndex = this._selectedSubpath.getSelectedAnchorIndex();
@@ -438,6 +518,7 @@ exports.PenTool = Montage.create(ShapeTool, {
438 "url('images/cursors/penCursors/Pen_newPath.png') 5 1, default"; 518 "url('images/cursors/penCursors/Pen_newPath.png') 5 1, default";
439 } 519 }
440 520
521
441 if (!this._selectedSubpath ){ 522 if (!this._selectedSubpath ){
442 return; //nothing to do in case no subpath is selected 523 return; //nothing to do in case no subpath is selected
443 } 524 }
@@ -476,19 +557,18 @@ exports.PenTool = Montage.create(ShapeTool, {
476 else if (this._editMode & this.EDIT_PREV) { 557 else if (this._editMode & this.EDIT_PREV) {
477 localTranslation = VecUtils.vecSubtract(3, localMousePos, selAnchorPos[0]); 558 localTranslation = VecUtils.vecSubtract(3, localMousePos, selAnchorPos[0]);
478 selAnchor.translatePrev(localTranslation[0], localTranslation[1], localTranslation[2]); 559 selAnchor.translatePrev(localTranslation[0], localTranslation[1], localTranslation[2]);
479 560 if (!this._isAltDown){
480 //move the next point if Alt key is down to ensure relative angle between prev and next 561 //selAnchor.translateNextFromPrev(localTranslation[0], localTranslation[1], localTranslation[2]);
481 if (this._isAltDown) { 562 selAnchor.setNextFromPrev();
482 selAnchor.translateNextFromPrev(localTranslation[0], localTranslation[1], localTranslation[2]);
483 } 563 }
484 } 564 }
485 else if (this._editMode & this.EDIT_NEXT) { 565 else if (this._editMode & this.EDIT_NEXT) {
486 localTranslation = VecUtils.vecSubtract(3, localMousePos, selAnchorPos[2]); 566 localTranslation = VecUtils.vecSubtract(3, localMousePos, selAnchorPos[2]);
487 selAnchor.translateNext(localTranslation[0], localTranslation[1], localTranslation[2]);
488
489 //move the prev point if Alt key is down to ensure relative angle between prev and next 567 //move the prev point if Alt key is down to ensure relative angle between prev and next
490 if (this._isAltDown) { 568 selAnchor.translateNext(localTranslation[0], localTranslation[1], localTranslation[2]);
491 selAnchor.translatePrevFromNext(localTranslation[0], localTranslation[1], localTranslation[2]); 569 if (!this._isAltDown){
570 //selAnchor.translatePrevFromNext(localTranslation[0], localTranslation[1], localTranslation[2]);
571 selAnchor.setPrevFromNext();
492 } 572 }
493 } 573 }
494 else if (this._editMode & this.EDIT_PREV_NEXT) { 574 else if (this._editMode & this.EDIT_PREV_NEXT) {
@@ -529,21 +609,28 @@ exports.PenTool = Montage.create(ShapeTool, {
529 { //the anchor was hit 609 { //the anchor was hit
530 this._hoveredAnchorIndex = selAnchorAndParamAndCode[0]; 610 this._hoveredAnchorIndex = selAnchorAndParamAndCode[0];
531 var lastAnchorIndex = this._selectedSubpath.getNumAnchors()-1; 611 var lastAnchorIndex = this._selectedSubpath.getNumAnchors()-1;
532 var cursor = "url('images/cursors/penCursors/Pen_anchorSelect.png') 5 1, default"; 612 var cursor;
533 if (this._selectedSubpath.getIsClosed()===false){ 613 if (this._subtool===this.SUBTOOL_NONE){
534 if (this._entryEditMode === this.ENTRY_SELECT_PATH && !this._isPickedEndPointInSelectPathMode && (this._hoveredAnchorIndex===0 || this._hoveredAnchorIndex===lastAnchorIndex)){ 614 cursor = "url('images/cursors/penCursors/Pen_anchorSelect.png') 5 1, default";
535 //if we're in SELECT_PATH mode, have not yet clicked on the end anchors, AND we hovered over one of the end anchors 615 if (this._selectedSubpath.getIsClosed()===false){
536 cursor = "url('images/cursors/penCursors/Pen_append.png') 5 1, default"; 616 if (this._entryEditMode === this.ENTRY_SELECT_PATH && !this._isPickedEndPointInSelectPathMode && (this._hoveredAnchorIndex===0 || this._hoveredAnchorIndex===lastAnchorIndex)){
537 } else if ( this._selectedSubpath.getSelectedAnchorIndex()===lastAnchorIndex && this._hoveredAnchorIndex===0) { 617 //if we're in SELECT_PATH mode, have not yet clicked on the end anchors, AND we hovered over one of the end anchors
538 //if we've selected the last anchor and hover over the first anchor 618 cursor = "url('images/cursors/penCursors/Pen_append.png') 5 1, default";
539 cursor = "url('images/cursors/penCursors/Pen_closePath.png') 5 1, default"; 619 } else if ( this._selectedSubpath.getSelectedAnchorIndex()===lastAnchorIndex && this._hoveredAnchorIndex===0) {
540 } 620 //if we've selected the last anchor and hover over the first anchor
541 } //if path is not closed 621 cursor = "url('images/cursors/penCursors/Pen_closePath.png') 5 1, default";
622 }
623 } //if path is not closed
624 } else if (this._subtool === this.SUBTOOL_PENMINUS){
625 cursor = "url('images/cursors/penCursors/Pen_minus.png') 5 1, default";
626 }
542 this.application.ninja.stage.drawingCanvas.style.cursor = cursor; 627 this.application.ninja.stage.drawingCanvas.style.cursor = cursor;
543 } else if (selAnchorAndParamAndCode[2] & this._selectedSubpath.SEL_PATH) { 628 } else if (selAnchorAndParamAndCode[2] & this._selectedSubpath.SEL_PATH) {
544 //change the cursor 629 //change the cursor only if we're not in pen-minus subtool
545 var cursor = "url('images/cursors/penCursors/Pen_plus.png') 5 1, default"; 630 if (this._subtool!==this.SUBTOOL_PENMINUS){
546 this.application.ninja.stage.drawingCanvas.style.cursor = cursor; 631 var cursor = "url('images/cursors/penCursors/Pen_plus.png') 5 1, default";
632