From 40a4d9dbc12e802e2d0a7c3acd69bc7e394d4529 Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Fri, 27 Apr 2012 10:03:58 -0700 Subject: Fix for 1525 Pen: "Uncaught RangeError: Maximum call stack size exceeded". (check if the second mouse click actually selects the existing first anchor point) --- js/helper-classes/3D/math-utils.js | 11 ++++++----- js/tools/PenTool.js | 38 ++++++++++++++++++++++++++++++-------- 2 files changed, 36 insertions(+), 13 deletions(-) diff --git a/js/helper-classes/3D/math-utils.js b/js/helper-classes/3D/math-utils.js index 2f0283a9..35ee8112 100755 --- a/js/helper-classes/3D/math-utils.js +++ b/js/helper-classes/3D/math-utils.js @@ -928,17 +928,18 @@ var MathUtilsClass = exports.MathUtilsClass = Object.create(Object.prototype, { return 0; } //TODO testing...remove this block - console.log("getAxisAngleBetween3DVectors Angle: "+angle); if (isNaN(angle)){ - console.log("getAxisAngleBetween3DVectors Angle is NaN"); + console.log("Warning! getAxisAngleBetween3DVectors Angle is NaN"); } //TODO end testing block //optionally, if axis is provided, create the axis of rotation as well var rotAxis = VecUtils.vecCross(3, v1n, v2n); rotAxis = VecUtils.vecNormalize(3, rotAxis, 1); - axis[0] = rotAxis[0]; - axis[1] = rotAxis[1]; - axis[2] = rotAxis[2]; + if (axis){ + axis[0] = rotAxis[0]; + axis[1] = rotAxis[1]; + axis[2] = rotAxis[2]; + } return angle; } }, diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js index 8ecc9f79..8cc32536 100755 --- a/js/tools/PenTool.js +++ b/js/tools/PenTool.js @@ -273,14 +273,36 @@ exports.PenTool = Montage.create(ShapeTool, { var swMousePos = hitRec.calculateStageWorldPoint(); swMousePos[0]+= snapManager.getStageWidth()*0.5; swMousePos[1]+= snapManager.getStageHeight()*0.5; - this._selectedSubpath.addAnchor(new AnchorPoint()); - var newAnchor = this._selectedSubpath.getAnchor(this._selectedSubpath.getSelectedAnchorIndex()); - newAnchor.setPos(swMousePos[0], swMousePos[1], swMousePos[2]); - newAnchor.setPrevPos(swMousePos[0], swMousePos[1], swMousePos[2]); - newAnchor.setNextPos(swMousePos[0], swMousePos[1], swMousePos[2]); - //set the mode so that dragging will update the next and previous locations - this._editMode = this.EDIT_PREV_NEXT; - } + //check if the mouse click location is close to the existing anchor + var indexAndCode = this._selectedSubpath.pickAnchor(swMousePos[0], swMousePos[1], swMousePos[2], this._PICK_POINT_RADIUS); + if (indexAndCode[0]>=0){ + //the anchor point was hit, so we do not add another anchor + switch(indexAndCode[1]){ + case this._selectedSubpath.SEL_ANCHOR: + this._editMode = this.EDIT_ANCHOR; + break; + case this._selectedSubpath.SEL_PREV: + this._editMode = this.EDIT_PREV; + break; + case this._selectedSubpath.SEL_NEXT: + this._editMode = this.EDIT_NEXT; + break; + default: + this._editMode = this.EDIT_ANCHOR; + console.log("WARNING picked anchor point with incorrect mode"); + break; + } + + } else { + this._selectedSubpath.addAnchor(new AnchorPoint()); + var newAnchor = this._selectedSubpath.getAnchor(this._selectedSubpath.getSelectedAnchorIndex()); + newAnchor.setPos(swMousePos[0], swMousePos[1], swMousePos[2]); + newAnchor.setPrevPos(swMousePos[0], swMousePos[1], swMousePos[2]); + newAnchor.setNextPos(swMousePos[0], swMousePos[1], swMousePos[2]); + //set the mode so that dragging will update the next and previous locations + this._editMode = this.EDIT_PREV_NEXT; + } + } //if we have not yet created a canvas for this path //the selected subpath has a canvas, so test within that canvas' space else -- cgit v1.2.3 From ed7d22edf3cbca82ae43a4e3373a93a8666ba4a1 Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Fri, 27 Apr 2012 10:47:42 -0700 Subject: add event handlers for open, close, and switch document to pen tool, fixes: 1532 Pen: Anchor points get carried over to the new document --- js/tools/PenTool.js | 47 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 43 insertions(+), 4 deletions(-) diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js index 8cc32536..016d6ded 100755 --- a/js/tools/PenTool.js +++ b/js/tools/PenTool.js @@ -1278,10 +1278,45 @@ exports.PenTool = Montage.create(ShapeTool, { } //value: function() { }, //DrawSubpathAnchors { + deselectPenTool:{ + value: function() { + this._selectedSubpath = null; + this._selectedSubpathCanvas = null; + this._selectedSubpathPlaneMat = null; + this._snapTargetIndex = -1; + } + }, + //if the document is opened with the pen tool being active, we do the same thing as when configure(false) is called + handleOpenDocument: { + value: function() { + this.deselectPenTool(); + //clear the canvas + this.application.ninja.stage.clearDrawingCanvas(); + } + }, + //if the document is switched with the pen tool being active, we do the same thing as when configure(false) is called + handleSwitchDocument: { + value: function() { + this.deselectPenTool(); + //clear the canvas + this.application.ninja.stage.clearDrawingCanvas(); + } + }, + //if the document is closed with the pen tool being active, we do the same thing as when configure(false) is called + handleCloseDocument: { + value: function() { + this.deselectPenTool(); + //clear the canvas + this.application.ninja.stage.clearDrawingCanvas(); + } + }, Configure: { value: function (wasSelected) { if (wasSelected) { + //first nullify any set values + this.deselectPenTool(); + defaultEventManager.addEventListener("resetPenTool", this, false); this.application.ninja.elementMediator.deleteDelegate = this; this.application.ninja.stage.drawingCanvas.style.cursor = //"auto"; @@ -1335,17 +1370,21 @@ exports.PenTool = Montage.create(ShapeTool, { if (this._trackMouseMoveWhenUp){ NJevent("enableStageMove"); } + this.eventManager.addEventListener("openDocument", this, false); + this.eventManager.addEventListener("switchDocument", this, false); + this.eventManager.addEventListener("closeDocument", this, false); } //if the pen tool was selected else { if (this._trackMouseMoveWhenUp){ NJevent("disableStageMove"); } - this._selectedSubpath = null; - this._selectedSubpathCanvas = null; - this._selectedSubpathPlaneMat = null; - this._snapTargetIndex = -1; + this.deselectPenTool(); defaultEventManager.removeEventListener("resetPenTool", this, false); this.application.ninja.elementMediator.deleteDelegate = null; + + this.eventManager.removeEventListener("openDocument", this, false); + this.eventManager.removeEventListener("switchDocument", this, false); + this.eventManager.removeEventListener("closeDocument", this, false); } //if the pen tool was de-selected } }, -- cgit v1.2.3 From 28d1594b868e3c08e5603adbd5b29df1e24d57e9 Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Fri, 27 Apr 2012 12:40:18 -0700 Subject: Fix for 1524 Pen: Unable to add anchor to a closed path ---behavior is unchanged, but the realtime feedback for the tool (i.e. mouse cursor) will correctly reflect that a click after closing a path will start a new path, not add to that path --- js/tools/PenTool.js | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js index 016d6ded..d18f371a 100755 --- a/js/tools/PenTool.js +++ b/js/tools/PenTool.js @@ -737,14 +737,24 @@ exports.PenTool = Montage.create(ShapeTool, { this._isDrawing = false; this._editMode = this.EDIT_NONE; + //if we're not in edit_path mode and we closed the selected subpath, then we are going to start a new subpath, so we nullify the selected subpath + if (this._selectedSubpath.getIsClosed() && this._entryEditMode !== this.ENTRY_SELECT_PATH){ + this._selectedSubpath = null; + } + if (this._selectedSubpath){ this.DrawSubpathAnchors(this._selectedSubpath);//render the subpath anchors on canvas + }else{ + //clear the canvas + this.application.ninja.stage.clearDrawingCanvas(); } if (!this._trackMouseMoveWhenUp){ NJevent("disableStageMove"); } this._hoveredAnchorIndex = -1; + + } }, -- cgit v1.2.3 From 57c373259fb22a6c20248ef338dc2766a364ac59 Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Fri, 27 Apr 2012 15:38:17 -0700 Subject: scale the brush stroke according to the input width and height Fixes: 1444 Brush: Unable to scale brushstroke using the Transform handles --- js/lib/geom/brush-stroke.js | 62 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 58 insertions(+), 4 deletions(-) diff --git a/js/lib/geom/brush-stroke.js b/js/lib/geom/brush-stroke.js index 1fae0c1d..d5d9a893 100755 --- a/js/lib/geom/brush-stroke.js +++ b/js/lib/geom/brush-stroke.js @@ -264,13 +264,67 @@ var BrushStroke = function GLBrushStroke() { this._strokeStyle = s; }; - this.setWidth = function () { + this.setWidth = function (newW) { + if (newW<1) { + newW=1; //clamp minimum width to 1 + } + + //scale the contents of this subpath to lie within this width + //determine the scale factor by comparing with the old width + var oldWidth = this._BBoxMax[0]-this._BBoxMin[0]; + if (oldWidth<1) { + oldWidth=1; + } + + var scaleX = newW/oldWidth; + if (scaleX===1) { + return; //no need to do anything + } + + //scale the local point positions such that the width of the bbox is the newW + var origX = this._BBoxMin[0]; + var numPoints = this._LocalPoints.length; + for (var i=0;i0) { - alphaVal = 1.0 - distFromOpaqueRegion/maxTransparentRegionHalfWidth; - alphaVal *= 1.0/ctx.lineWidth; //factor that accounts for lineWidth !== 1 + var transparencyFactor = distFromOpaqueRegion/maxTransparentRegionHalfWidth; + alphaVal = 1.0 - transparencyFactor;//(transparencyFactor*transparencyFactor);//the square term produces nonlinearly varying alpha values } ctx.save(); - if (t === (numTraces-1)){ + if (t === (numTraces-1) || t === 0){ ctx.lineWidth = 1; } else { //todo figure out the correct formula for the line width ctx.lineWidth=2; + alphaVal *= 0.5; //factor that accounts for lineWidth == 2 } ctx.strokeStyle="rgba("+parseInt(255*this._strokeColor[0])+","+parseInt(255*this._strokeColor[1])+","+parseInt(255*this._strokeColor[2])+","+alphaVal+")"; //linearly interpolate between the two stroke colors -- cgit v1.2.3 From b9262c831952e77135b79c2de7c455d5e7ff0589 Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Tue, 1 May 2012 17:00:40 -0700 Subject: undo some previous change that was halving the alpha value of the stroke --- js/lib/geom/brush-stroke.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/lib/geom/brush-stroke.js b/js/lib/geom/brush-stroke.js index a1746d95..519e0433 100755 --- a/js/lib/geom/brush-stroke.js +++ b/js/lib/geom/brush-stroke.js @@ -665,6 +665,7 @@ var BrushStroke = function GLBrushStroke() { if (distFromOpaqueRegion>0) { var transparencyFactor = distFromOpaqueRegion/maxTransparentRegionHalfWidth; alphaVal = 1.0 - transparencyFactor;//(transparencyFactor*transparencyFactor);//the square term produces nonlinearly varying alpha values + alphaVal *= 0.5; //factor that accounts for lineWidth == 2 } ctx.save(); if (t === (numTraces-1) || t === 0){ @@ -672,7 +673,6 @@ var BrushStroke = function GLBrushStroke() { } else { //todo figure out the correct formula for the line width ctx.lineWidth=2; - alphaVal *= 0.5; //factor that accounts for lineWidth == 2 } ctx.strokeStyle="rgba("+parseInt(255*this._strokeColor[0])+","+parseInt(255*this._strokeColor[1])+","+parseInt(255*this._strokeColor[2])+","+alphaVal+")"; //linearly interpolate between the two stroke colors -- cgit v1.2.3 From cd5d64aae3d0b0395e3163fab17e09e9eda01a85 Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Wed, 2 May 2012 14:29:02 -0700 Subject: flip the action of the alt key when modifying anchor handles (this essentially forces the need for a keyboard...must be addressed by a fix later on) --- js/tools/PenTool.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js index d18f371a..2e2570e3 100755 --- a/js/tools/PenTool.js +++ b/js/tools/PenTool.js @@ -476,19 +476,18 @@ exports.PenTool = Montage.create(ShapeTool, { else if (this._editMode & this.EDIT_PREV) { localTranslation = VecUtils.vecSubtract(3, localMousePos, selAnchorPos[0]); selAnchor.translatePrev(localTranslation[0], localTranslation[1], localTranslation[2]); - - //move the next point if Alt key is down to ensure relative angle between prev and next - if (this._isAltDown) { - selAnchor.translateNextFromPrev(localTranslation[0], localTranslation[1], localTranslation[2]); + if (!this._isAltDown){ + //selAnchor.translateNextFromPrev(localTranslation[0], localTranslation[1], localTranslation[2]); + selAnchor.setNextFromPrev(); } } else if (this._editMode & this.EDIT_NEXT) { localTranslation = VecUtils.vecSubtract(3, localMousePos, selAnchorPos[2]); - selAnchor.translateNext(localTranslation[0], localTranslation[1], localTranslation[2]); - //move the prev point if Alt key is down to ensure relative angle between prev and next - if (this._isAltDown) { - selAnchor.translatePrevFromNext(localTranslation[0], localTranslation[1], localTranslation[2]); + selAnchor.translateNext(localTranslation[0], localTranslation[1], localTranslation[2]); + if (!this._isAltDown){ + //selAnchor.translatePrevFromNext(localTranslation[0], localTranslation[1], localTranslation[2]); + selAnchor.setPrevFromNext(); } } else if (this._editMode & this.EDIT_PREV_NEXT) { -- cgit v1.2.3 From ba890518b5a35d5e6893f9fc72d2eee30ae07e17 Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Fri, 4 May 2012 16:04:04 -0700 Subject: handle delete more correctly than before (selected subpaths are deleted)....this is buggy when the second anchor of a two-anchor subpath is deleted (since the first anchor needs to be converted back into stage world coords) --- js/tools/PenTool.js | 55 ++++++++++++++++++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 17 deletions(-) diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js index 2e2570e3..fb7f6d6d 100755 --- a/js/tools/PenTool.js +++ b/js/tools/PenTool.js @@ -1402,38 +1402,57 @@ exports.PenTool = Montage.create(ShapeTool, { value: function(event){ //clear the selected subpath...the only new additions to this function w.r.t. ToolBase if (this._selectedSubpath){ + var removeSelectedSubpathCanvas = false; + var removeSelectedSubpath = true; //this is applicable only if the subpath canvas is to be removed if (this._selectedSubpath.getSelectedAnchorIndex()>=0){ this._hoveredAnchorIndex=-1; this._selectedSubpath.removeAnchor(this._selectedSubpath.getSelectedAnchorIndex()); this._selectedSubpath.createSamples(false); //clear the canvas this.application.ninja.stage.clearDrawingCanvas();//stageManagerModule.stageManager.clearDrawingCanvas(); + this.PrepareSelectedSubpathForRendering(); this.DrawSubpathAnchors(this._selectedSubpath); - this.ShowSelectedSubpath(); + var newNumAnchors = this._selectedSubpath.getNumAnchors(); + if (newNumAnchors>1) { + this.ShowSelectedSubpath(); + } else { + if (newNumAnchors===0){ + removeSelectedSubpath = true; + } else{ + removeSelectedSubpath = false; //don't remove the selected subpath if there is still one anchor + } + removeSelectedSubpathCanvas = true; + } + } else { + //if no anchor was selected but the subpath was selected, we will remove the subpath + removeSelectedSubpathCanvas = true; + } + if (removeSelectedSubpathCanvas) { + if (removeSelectedSubpath){ + this._selectedSubpath.clearAllAnchors(); //perhaps unnecessary + this._selectedSubpath = null; + if (this._entryEditMode === this.ENTRY_SELECT_PATH){ + this._entryEditMode = this.ENTRY_SELECT_NONE; + } + } + //clear the canvas + this.application.ninja.stage.clearDrawingCanvas();//stageManagerModule.stageManager.clearDrawingCanvas(); + + //undo/redo...go through ElementController and NJEvent + var els = []; + ElementController.removeElement(this._selectedSubpathCanvas); + els.push(this._selectedSubpathCanvas); + NJevent( "elementsRemoved", els ); + this._selectedSubpathCanvas = null; } - else { - this._selectedSubpath.clearAllAnchors(); //perhaps unnecessary - this._selectedSubpath = null; - if (this._entryEditMode === this.ENTRY_SELECT_PATH){ - this._entryEditMode = this.ENTRY_SELECT_NONE; - } - //clear the canvas - this.application.ninja.stage.clearDrawingCanvas();//stageManagerModule.stageManager.clearDrawingCanvas(); - - //undo/redo...go through ElementController and NJEvent - var els = []; - ElementController.removeElement(this._selectedSubpathCanvas); - els.push(this._selectedSubpathCanvas); - NJevent( "elementsRemoved", els ); - this._selectedSubpathCanvas = null; - } } else { //undo/redo...go through ElementMediator (see ElementMediator.handleDeleting() from where the much of this function is copied) //clear the canvas this.application.ninja.stage.clearDrawingCanvas();//stageManagerModule.stageManager.clearDrawingCanvas(); var els = []; + var len = this.application.ninja.selectedElements.length; for(var i = 0; i1) { + this.ShowSelectedSubpath(); + } + else { + if (newNumAnchors===0){ + removeSelectedSubpath = true; + } else{ + removeSelectedSubpath = false; //don't remove the selected subpath if there is still one anchor + } + removeSelectedSubpathCanvas = true; + } + this._removeSelectedSubpathAndCanvas(removeSelectedSubpath, removeSelectedSubpathCanvas); + } + }, + // ********************************************************************************************************** // Mouse down handler // IF the selected subpath is null, it means we're going to start a new subpath @@ -220,6 +277,11 @@ exports.PenTool = Montage.create(ShapeTool, { if (this._entryEditMode !== this.ENTRY_SELECT_PATH && this._selectedSubpath && this._selectedSubpath.getIsClosed() && this._makeMultipleSubpaths) { this._selectedSubpath = null; } + + if (this._subtool !== this.SUBTOOL_NONE && this._selectedSubpath===null) { + //do nothing because the pen plus and pen minus subtools need a selected subpath + return; + } if (this._selectedSubpath === null) { this._selectedSubpath = new SubPath(); this._selectedSubpathCanvas = null; @@ -255,7 +317,7 @@ exports.PenTool = Montage.create(ShapeTool, { colorArray = [1,1,1,0]; } this._selectedSubpath.setFillColor(colorArray); - } + } //if the selectedSubpath was null and needed to be constructed //build the hit record for the current mouse position (on the stage or the plane of the path canvas) var hitRec = this.getHitRecord(event.pageX, event.pageY, false); @@ -333,6 +395,11 @@ exports.PenTool = Montage.create(ShapeTool, { if (whichPoint !== this._selectedSubpath.SEL_NONE){ //if we hit the anchor point itself if (whichPoint & this._selectedSubpath.SEL_ANCHOR) { + if (this._subtool===this.SUBTOOL_PENMINUS){ + //remove the selected anchor, similar to HandleDelete + this._removeSelectedAnchorPoint(); + return; + } //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 if (this._entryEditMode === this.ENTRY_SELECT_PATH && this._isPickedEndPointInSelectPathMode === false){ var selAnchorIndex = this._selectedSubpath.getSelectedAnchorIndex(); @@ -438,6 +505,7 @@ exports.PenTool = Montage.create(ShapeTool, { "url('images/cursors/penCursors/Pen_newPath.png') 5 1, default"; } + if (!this._selectedSubpath ){ return; //nothing to do in case no subpath is selected } @@ -528,21 +596,28 @@ exports.PenTool = Montage.create(ShapeTool, { { //the anchor was hit this._hoveredAnchorIndex = selAnchorAndParamAndCode[0]; var lastAnchorIndex = this._selectedSubpath.getNumAnchors()-1; - var cursor = "url('images/cursors/penCursors/Pen_anchorSelect.png') 5 1, default"; - if (this._selectedSubpath.getIsClosed()===false){ - if (this._entryEditMode === this.ENTRY_SELECT_PATH && !this._isPickedEndPointInSelectPathMode && (this._hoveredAnchorIndex===0 || this._hoveredAnchorIndex===lastAnchorIndex)){ - //if we're in SELECT_PATH mode, have not yet clicked on the end anchors, AND we hovered over one of the end anchors - cursor = "url('images/cursors/penCursors/Pen_append.png') 5 1, default"; - } else if ( this._selectedSubpath.getSelectedAnchorIndex()===lastAnchorIndex && this._hoveredAnchorIndex===0) { - //if we've selected the last anchor and hover over the first anchor - cursor = "url('images/cursors/penCursors/Pen_closePath.png') 5 1, default"; - } - } //if path is not closed + var cursor; + if (this._subtool===this.SUBTOOL_NONE){ + cursor = "url('images/cursors/penCursors/Pen_anchorSelect.png') 5 1, default"; + if (this._selectedSubpath.getIsClosed()===false){ + if (this._entryEditMode === this.ENTRY_SELECT_PATH && !this._isPickedEndPointInSelectPathMode && (this._hoveredAnchorIndex===0 || this._hoveredAnchorIndex===lastAnchorIndex)){ + //if we're in SELECT_PATH mode, have not yet clicked on the end anchors, AND we hovered over one of the end anchors + cursor = "url('images/cursors/penCursors/Pen_append.png') 5 1, default"; + } else if ( this._selectedSubpath.getSelectedAnchorIndex()===lastAnchorIndex && this._hoveredAnchorIndex===0) { + //if we've selected the last anchor and hover over the first anchor + cursor = "url('images/cursors/penCursors/Pen_closePath.png') 5 1, default"; + } + } //if path is not closed + } else if (this._subtool === this.SUBTOOL_PENMINUS){ + cursor = "url('images/cursors/penCursors/Pen_minus.png') 5 1, default"; + } this.application.ninja.stage.drawingCanvas.style.cursor = cursor; } else if (selAnchorAndParamAndCode[2] & this._selectedSubpath.SEL_PATH) { - //change the cursor - var cursor = "url('images/cursors/penCursors/Pen_plus.png') 5 1, default"; - this.application.ninja.stage.drawingCanvas.style.cursor = cursor; + //change the cursor only if we're not in pen-minus subtool + if (this._subtool!==this.SUBTOOL_PENMINUS){ + var cursor = "url('images/cursors/penCursors/Pen_plus.png') 5 1, default"; + this.application.ninja.stage.drawingCanvas.style.cursor = cursor; + } } } //something on the path was hit } //mouse is not down @@ -688,6 +763,11 @@ exports.PenTool = Montage.create(ShapeTool, { // ********************************************************************************************************** HandleLeftButtonUp: { value: function (event) { + //do nothing in case of pen minus tool + if (this._subtool===this.SUBTOOL_PENMINUS){ + return; + } + // ******************** snapping *********************** // if there was a snapTarget and a selected anchor, move the anchor to the snap target if (this._snapTargetIndex !== -1 && this._selectedSubpath && this._selectedSubpath.getSelectedAnchorIndex() !== -1) { @@ -724,7 +804,7 @@ exports.PenTool = Montage.create(ShapeTool, { this._snapTargetIndex = -1; //if we have some samples to render... - if (this._selectedSubpath.getNumAnchors() > 1) { + if (this._selectedSubpath && this._selectedSubpath.getNumAnchors() > 1) { //prepare the selected subpath for rendering this.PrepareSelectedSubpathForRendering(); this.ShowSelectedSubpath(); @@ -736,7 +816,7 @@ exports.PenTool = Montage.create(ShapeTool, { this._editMode = this.EDIT_NONE; //if we're not in edit_path mode and we closed the selected subpath, then we are going to start a new subpath, so we nullify the selected subpath - if (this._selectedSubpath.getIsClosed() && this._entryEditMode !== this.ENTRY_SELECT_PATH){ + if (this._selectedSubpath && this._selectedSubpath.getIsClosed() && this._entryEditMode !== this.ENTRY_SELECT_PATH){ this._selectedSubpath = null; } @@ -1375,6 +1455,9 @@ exports.PenTool = Montage.create(ShapeTool, { } this._isPickedEndPointInSelectPathMode = false; //only applies to the ENTRY_SELECT_PATH mode + this._subtool = this.SUBTOOL_NONE; + //this.SUBTOOL_PENMINUS; + if (this._trackMouseMoveWhenUp){ NJevent("enableStageMove"); } @@ -1401,49 +1484,10 @@ exports.PenTool = Montage.create(ShapeTool, { value: function(event){ //clear the selected subpath...the only new additions to this function w.r.t. ToolBase if (this._selectedSubpath){ - var removeSelectedSubpathCanvas = false; - var removeSelectedSubpath = true; //this is applicable only if the subpath canvas is to be removed if (this._selectedSubpath.getSelectedAnchorIndex()>=0){ - this._hoveredAnchorIndex=-1; - this._selectedSubpath.removeAnchor(this._selectedSubpath.getSelectedAnchorIndex()); - this._selectedSubpath.createSamples(false); - //clear the canvas - this.application.ninja.stage.clearDrawingCanvas();//stageManagerModule.stageManager.clearDrawingCanvas(); - - this.PrepareSelectedSubpathForRendering(); - this.DrawSubpathAnchors(this._selectedSubpath); - var newNumAnchors = this._selectedSubpath.getNumAnchors(); - if (newNumAnchors>1) { - this.ShowSelectedSubpath(); - } else { - if (newNumAnchors===0){ - removeSelectedSubpath = true; - } else{ - removeSelectedSubpath = false; //don't remove the selected subpath if there is still one anchor - } - removeSelectedSubpathCanvas = true; - } + this._removeSelectedAnchorPoint(); } else { - //if no anchor was selected but the subpath was selected, we will remove the subpath - removeSelectedSubpathCanvas = true; - } - if (removeSelectedSubpathCanvas) { - if (removeSelectedSubpath){ - this._selectedSubpath.clearAllAnchors(); //perhaps unnecessary - this._selectedSubpath = null; - if (this._entryEditMode === this.ENTRY_SELECT_PATH){ - this._entryEditMode = this.ENTRY_SELECT_NONE; - } - } - //clear the canvas - this.application.ninja.stage.clearDrawingCanvas();//stageManagerModule.stageManager.clearDrawingCanvas(); - - //undo/redo...go through ElementController and NJEvent - var els = []; - ElementController.removeElement(this._selectedSubpathCanvas); - els.push(this._selectedSubpathCanvas); - NJevent( "elementsRemoved", els ); - this._selectedSubpathCanvas = null; + this._removeSelectedSubpathAndCanvas(true, true); } } else { -- cgit v1.2.3 From 4cb3612c9a67f4020d2949b5e5e5d84a90017974 Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Fri, 11 May 2012 10:40:12 -0700 Subject: handle anchor point deletion correctly (does not yet fully work for PEN-MINUS subtool) --- js/tools/PenTool.js | 64 ++++++++++++++++++++++++++++++++--------------------- 1 file changed, 39 insertions(+), 25 deletions(-) diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js index d5cf6439..0cfc9331 100755 --- a/js/tools/PenTool.js +++ b/js/tools/PenTool.js @@ -186,26 +186,26 @@ exports.PenTool = Montage.create(ShapeTool, { }, _removeSelectedSubpathAndCanvas:{ - value: function(removeSelectedSubpath, removeSelectedSubpathCanvas){ - if (removeSelectedSubpathCanvas) { - if (removeSelectedSubpath){ - this._selectedSubpath.clearAllAnchors(); //perhaps unnecessary - this._selectedSubpath = null; - if (this._entryEditMode === this.ENTRY_SELECT_PATH){ - this._entryEditMode = this.ENTRY_SELECT_NONE; - } - this._subtool = this.SUBTOOL_NONE; + value: function(removeSelectedSubpath){ + if (removeSelectedSubpath){ + this._selectedSubpath.clearAllAnchors(); //perhaps unnecessary + this._selectedSubpath = null; + if (this._entryEditMode === this.ENTRY_SELECT_PATH){ + this._entryEditMode = this.ENTRY_SELECT_NONE; } - //clear the canvas - this.application.ninja.stage.clearDrawingCanvas();//stageManagerModule.stageManager.clearDrawingCanvas(); - - //undo/redo...go through ElementController and NJEvent - var els = []; - ElementController.removeElement(this._selectedSubpathCanvas); - els.push(this._selectedSubpathCanvas); - NJevent( "elementsRemoved", els ); - this._selectedSubpathCanvas = null; + this._subtool = this.SUBTOOL_NONE; + } else { + this._selectedSubpath.setCanvas(null); } + //clear the canvas + this.application.ninja.stage.clearDrawingCanvas();//stageManagerModule.stageManager.clearDrawingCanvas(); + + //undo/redo...go through ElementController and NJEvent + var els = []; + ElementController.removeElement(this._selectedSubpathCanvas); + els.push(this._selectedSubpathCanvas); + NJevent( "elementsRemoved", els ); + this._selectedSubpathCanvas = null; } }, @@ -213,26 +213,39 @@ exports.PenTool = Montage.create(ShapeTool, { value: function(){ this._hoveredAnchorIndex=-1; this._selectedSubpath.removeAnchor(this._selectedSubpath.getSelectedAnchorIndex()); - this._selectedSubpath.createSamples(false); + if (this._selectedSubpath.getNumAnchors()===1){ + //convert the remaining anchor point to stage world coords + var xDelta = snapManager.getStageWidth()*0.5; + var yDelta = snapManager.getStageHeight()*0.5; + var anchor = this._selectedSubpath.getAnchor(0); + var swPos = ViewUtils.localToStageWorld([anchor.getPosX(),anchor.getPosY(),anchor.getPosZ()], this._selectedSubpathCanvas); + anchor.setPos(swPos[0]+xDelta, swPos[1]+yDelta, swPos[2]); + swPos = ViewUtils.localToStageWorld([anchor.getPrevX(),anchor.getPrevY(),anchor.getPrevZ()], this._selectedSubpathCanvas); + anchor.setPrevPos(swPos[0]+xDelta, swPos[1]+yDelta, swPos[2]); + swPos = ViewUtils.localToStageWorld([anchor.getNextX(),anchor.getNextY(),anchor.getNextZ()], this._selectedSubpathCanvas); + anchor.setNextPos(swPos[0]+xDelta, swPos[1]+yDelta, swPos[2]); + } //clear the canvas this.application.ninja.stage.clearDrawingCanvas();//stageManagerModule.stageManager.clearDrawingCanvas(); - this.PrepareSelectedSubpathForRendering(); - this.DrawSubpathAnchors(this._selectedSubpath); var removeSelectedSubpath=true; - var removeSelectedSubpathCanvas=false; var newNumAnchors = this._selectedSubpath.getNumAnchors(); if (newNumAnchors>1) { + this._selectedSubpath.createSamples(false); + this.PrepareSelectedSubpathForRendering(); this.ShowSelectedSubpath(); } else { + //since we have 0 or 1 anchors, we will remove the selected canvas (as the path does not exist) if (newNumAnchors===0){ removeSelectedSubpath = true; } else{ removeSelectedSubpath = false; //don't remove the selected subpath if there is still one anchor } - removeSelectedSubpathCanvas = true; + this._removeSelectedSubpathAndCanvas(removeSelectedSubpath); + } + if (!removeSelectedSubpath){ + this.DrawSubpathAnchors(this._selectedSubpath); } - this._removeSelectedSubpathAndCanvas(removeSelectedSubpath, removeSelectedSubpathCanvas); } }, @@ -1487,7 +1500,8 @@ exports.PenTool = Montage.create(ShapeTool, { if (this._selectedSubpath.getSelectedAnchorIndex()>=0){ this._removeSelectedAnchorPoint(); } else { - this._removeSelectedSubpathAndCanvas(true, true); + //remove the entire subpath and its canvas if no anchor was selected + this._removeSelectedSubpathAndCanvas(true); } } else { -- cgit v1.2.3 From f4df8204a57e1bc6021b651ebb2259f9931cf26f Mon Sep 17 00:00:00 2001 From: Pushkar Joshi Date: Tue, 22 May 2012 13:21:32 -0700 Subject: allow changes in the pen subtool in options to be seen by the pen tool code (can now select the pen plus, pen minus subtools) AND add keyboard shortcut for brush tool --- .../pen-properties.reel/pen-properties.js | 28 +++++++++++++++++++ js/data/tools-data.js | 4 +-- js/mediators/keyboard-mediator.js | 7 +++++ js/tools/PenTool.js | 31 ++++++++++++++++++++-- 4 files changed, 66 insertions(+), 4 deletions(-) diff --git a/js/components/tools-properties/pen-properties.reel/pen-properties.js b/js/components/tools-properties/pen-properties.reel/pen-properties.js index cd205e07..aba6cb61 100755 --- a/js/components/tools-properties/pen-properties.reel/pen-properties.js +++ b/js/components/tools-properties/pen-properties.reel/pen-properties.js @@ -9,6 +9,17 @@ var ToolProperties = require("js/components/tools-properties/tool-properties").T var PenProperties = exports.PenProperties = Montage.create(ToolProperties, { addedColorChips: { value: false }, + _penToolRadio: { value: null, enumerable: false }, + _penPlusRadio: { value: null, enumerable: false }, + _penMinusRadio: { value: null, enumerable: false }, + + _subPrepare: { + value: function() { + this._penToolRadio.addEventListener("click", this, false); + this._penPlusRadio.addEventListener("click", this, false); + this._penMinusRadio.addEventListener("click", this, false); + } + }, _fill: { enumerable: false, @@ -50,6 +61,23 @@ var PenProperties = exports.PenProperties = Montage.create(ToolProperties, { } }, + _selectedSubtool: { + value: "pen", enumerable: false + }, + + selectedSubtool: { + get: function() { return this._selectedSubtool;}, + set: function(value) { this._selectedSubtool = value; } + }, + + handleClick: { + value: function(event) { + this._selectedSubtool = event._event.target.value; + console.log("handleClick changing pen tool subtool to "+this.selectedSubtool); + NJevent("penSubToolChange"); + } + }, + draw: { enumerable: false, value: function () { diff --git a/js/data/tools-data.js b/js/data/tools-data.js index 32eaf24d..179e8e81 100755 --- a/js/data/tools-data.js +++ b/js/data/tools-data.js @@ -100,7 +100,7 @@ exports.ToolsData = Montage.create(Montage, { "properties": "penProperties", "spriteSheet": true, "action": "PenTool", - "toolTip": "Pen Tool", + "toolTip": "Pen Tool (P)", "cursor": "auto", "lastInGroup": false, "container": false, @@ -159,7 +159,7 @@ exports.ToolsData = Montage.create(Montage, { "properties": "brushProperties", "spriteSheet": true, "action": "BrushTool", - "toolTip": "Brush Tool", + "toolTip": "Brush Tool (B)", "cursor": "url('images/tools/brush_down.png') 9 17, default", "lastInGroup": false, "container": false, diff --git a/js/mediators/keyboard-mediator.js b/js/mediators/keyboard-mediator.js index 029c0916..5d5537d5 100755 --- a/js/mediators/keyboard-mediator.js +++ b/js/mediators/keyboard-mediator.js @@ -142,6 +142,13 @@ exports.KeyboardMediator = Montage.create(Component, { return; } + // shortcut for Brush tool is B + if (evt.keyCode === Keyboard.B){ + evt.preventDefault(); + this.application.ninja.handleSelectTool({ "detail": this.application.ninja.toolsData.defaultToolsData[this.application.ninja.toolsData.brushToolIndex] }); + return; + } + // Shortcut for Rectangle Tool is R // unless the user is pressing the command key. // If the user is pressing the command key, they want to refresh the browser. diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js index cc8ec394..bbde7374 100755 --- a/js/tools/PenTool.js +++ b/js/tools/PenTool.js @@ -1468,8 +1468,8 @@ exports.PenTool = Montage.create(ShapeTool, { } this._isPickedEndPointInSelectPathMode = false; //only applies to the ENTRY_SELECT_PATH mode - this._subtool = this.SUBTOOL_NONE; - //this.SUBTOOL_PENMINUS; + this.handlePenSubToolChange(); + //this._subtool = this.SUBTOOL_NONE; //this.SUBTOOL_PENMINUS; if (this._trackMouseMoveWhenUp){ NJevent("enableStageMove"); @@ -1477,6 +1477,7 @@ exports.PenTool = Montage.create(ShapeTool, { this.eventManager.addEventListener("openDocument", this, false); this.eventManager.addEventListener("switchDocument", this, false); this.eventManager.addEventListener("closeDocument", this, false); + this.eventManager.addEventListener("penSubToolChange", this, false); } //if the pen tool was selected else { if (this._trackMouseMoveWhenUp){ @@ -1489,10 +1490,36 @@ exports.PenTool = Montage.create(ShapeTool, { this.eventManager.removeEventListener("openDocument", this, false); this.eventManager.removeEventListener("switchDocument", this, false); this.eventManager.removeEventListener("closeDocument", this, false); + this.eventManager.removeEventListener("penSubToolChange", this, false); } //if the pen tool was de-selected } }, + handlePenSubToolChange: { + value: function() { + switch (this.options.selectedSubtool){ + case "pen": + this._subtool = this.SUBTOOL_NONE; + console.log("Setting pen tool subtool to NONE"); + break; + + case "penPlus": + console.log("Setting pen tool subtool to PLUS"); + this._subtool = this.SUBTOOL_PENPLUS; + break; + + case "penMinus": + console.log("Setting pen tool subtool to MINUS"); + this._subtool = this.SUBTOOL_PENMINUS; + break; + + default: + console.log("Setting pen tool subtool to NONE"); + this._subtool = this.SUBTOOL_NONE; + break; + } + } + }, handleDelete:{ value: function(event){ //clear the selected subpath...the only new additions to this function w.r.t. ToolBase -- cgit v1.2.3 From 2154ace6bdc2abe55fae353849d3beb64b8ada25 Mon Sep 17 00:00:00 2001 From: Nivesh Rajbhandari Date: Thu, 24 May 2012 16:14:40 -0700 Subject: Don't loop through layout drawing code if layout view is off. Signed-off-by: Nivesh Rajbhandari --- js/stage/layout.js | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/js/stage/layout.js b/js/stage/layout.js index 460c8b4a..7b4ccc17 100755 --- a/js/stage/layout.js +++ b/js/stage/layout.js @@ -121,6 +121,10 @@ exports.Layout = Montage.create(Component, { value: function() { this.clearCanvas(); + // TODO Bind the layoutview mode to the current document + // var mode = this.application.ninja.currentDocument.layoutMode; + if(this.layoutView === "layoutOff") return; + var els = this.elementsToDraw.length; for(var i = 0, el; i < els; i++){ this.drawTagOutline(this.elementsToDraw[i]); @@ -154,11 +158,6 @@ exports.Layout = Montage.create(Component, { if(!item || !this.application.ninja.selectionController.isNodeTraversable(item)) return; - // TODO Bind the layoutview mode to the current document - // var mode = this.application.ninja.currentDocument.layoutMode; - - if(this.layoutView === "layoutOff") return; - // Don't draw outlines for shapes. // TODO Use the element mediator/controller/model to see if its a shape // if (utilsModule.utils.isElementAShape(item)) return; -- cgit v1.2.3 From fa50874d9ca03540dc5741fb51261ef2b56f89ea Mon Sep 17 00:00:00 2001 From: Nivesh Rajbhandari Date: Fri, 25 May 2012 15:34:44 -0700 Subject: IKNinja-1491 - Adding slice value to border gradients. Note that using "circle cover" comes close to matching our canvas 2d/WebGL shape's stroke gradients, but still a little off. Signed-off-by: Nivesh Rajbhandari --- js/controllers/elements/element-controller.js | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/js/controllers/elements/element-controller.js b/js/controllers/elements/element-controller.js index 20225c61..7bb07976 100755 --- a/js/controllers/elements/element-controller.js +++ b/js/controllers/elements/element-controller.js @@ -159,8 +159,6 @@ exports.ElementController = Montage.create(Component, { el.elementModel.stroke = null; return; case 'gradient': - this.setProperty(el, "border-image", color.color.css); - this.setProperty(el, "border-color", "none"); if(color.borderInfo) { if(color.borderInfo.borderWidth) { this.setProperty(el, "border-width", color.borderInfo.borderWidth + color.borderInfo.borderUnits); @@ -169,9 +167,11 @@ exports.ElementController = Montage.create(Component, { this.setProperty(el, "border-style", color.borderInfo.borderStyle); } } + this.setGradientBorder(el, color.color.gradientMode, color.color.css); break; default: this.setProperty(el, "border-image", "none"); + this.setProperty(el, "border-image-slice", ""); this.setProperty(el, "border-color", color.color.css); if(color.borderInfo) { if(color.borderInfo.borderWidth) { @@ -188,6 +188,25 @@ exports.ElementController = Montage.create(Component, { } }, + setGradientBorder: { + value: function(el, gradientMode, css) { + if(gradientMode === "radial") { + this.setProperty(el, "border-image", css.replace("ellipse", "circle")); + } else { + this.setProperty(el, "border-image", css); + } + this.setProperty(el, "border-color", "none"); + // gradient slice = borderWidth/totalWidth + var b = parseInt(this.getProperty(el, "b