From 342fb451bd251358068a0dcb10e9dc218b79a176 Mon Sep 17 00:00:00 2001 From: Jonathan Duran Date: Tue, 6 Mar 2012 11:38:39 -0800 Subject: Squashed commit of the following: commit 1cd89d4d06e3a8f2c221628b19cf26a2c69f5d3f Author: Jose Antonio Marquez Date: Tue Mar 6 11:24:25 2012 -0800 Fixing WebGL not available bug commit 84332ab81c1b445195f1d9be8bbeae0725c8e758 Author: Valerio Virgillito Date: Tue Mar 6 10:58:25 2012 -0800 Squashed commit of preload-fix into Master - Requiring all the previously pre-loaded files - RDGE, Codemirror and gl-matrix are not included via a script tag. Signed-off-by: Valerio Virgillito commit 13f52cf0c74f53a919fa864f86669e8155f82961 Merge: dced508 abc04f3 Author: Valerio Virgillito Date: Fri Mar 2 15:46:11 2012 -0800 Merge pull request #93 from imix23ways/Timeline Timeline: Critical bug fixes commit dced508bb19a7bcd467ff1b86b5df5bbec4be794 Merge: 0aeb400 cc772ef Author: Valerio Virgillito Date: Fri Mar 2 15:45:35 2012 -0800 Merge pull request #92 from mqg734/WebGLFixes Selection Tool Fixes for elements flying off into space when they overlap commit 0aeb400070762cf01d83cf9f9ee25a5595098b7f Merge: ff0a956 aabb48a Author: Valerio Virgillito Date: Fri Mar 2 14:05:21 2012 -0800 Merge pull request #94 from ericguzman/PresetsPanel Presets Panel - Fix single-click activation, and transition cut-off bug. commit cc772ef3333ed419d269a2bda7aea5b0150a7bd9 Author: Nivesh Rajbhandari Date: Fri Mar 2 11:34:58 2012 -0800 Fixing flying off into space bug for translate tool too. Signed-off-by: Nivesh Rajbhandari commit abc04f3d50311ed1c21067344bc7e448686f8c5c Author: Jonathan Duran Date: Fri Mar 2 11:26:25 2012 -0800 Timeline Fix timing function Signed-off-by: Jonathan Duran commit aabb48a1c8d34bc968f4c6b0ffee4e31c1d5d286 Author: Eric Guzman Date: Fri Mar 2 11:22:44 2012 -0800 Presets Panel - Fix single-click activation, and transition cut-off bug. Use double-click as the activation event for transition presets. Also fixed the bug when applying a style preset before the transition preset, which disabled transitions after the first one. commit f3207f39ea9d8c1c34246217a23d3a689671903d Author: Nivesh Rajbhandari Date: Fri Mar 2 11:21:29 2012 -0800 Don't draw transform handles if the stage is the target element. Signed-off-by: Nivesh Rajbhandari commit 5425be91e7125c22955b4459a62412ff574e49a8 Author: Jonathan Duran Date: Fri Mar 2 11:11:48 2012 -0800 Timeline: Fix for animation iteration count Add default webkit css properties to allow animations with integer iteration counts. Signed-off-by: Jonathan Duran commit 1760bac1da9218315ad1bacdcf3a157495a049e8 Author: Nivesh Rajbhandari Date: Fri Mar 2 10:48:41 2012 -0800 Fix for jumping issue when moving items that have any 3d on them. We can't translate 3d moves into 2d space due to perspective, so we must update the matrix3d values instead of the top-left values if items have 3d. Signed-off-by: Nivesh Rajbhandari commit 2c04935f0ccb1cb7c98371fc10b43155f2d956c4 Author: Nivesh Rajbhandari Date: Thu Mar 1 22:20:06 2012 -0800 Fix for elements flying off into space when moving elements that overlap. This was happening because our hit record's element and the browser's element from point did not match. Signed-off-by: Nivesh Rajbhandari commit 50058746779f714ed9b0287f49e56c9f0d35593e Merge: 500426d ff0a956 Author: Nivesh Rajbhandari Date: Thu Mar 1 21:49:44 2012 -0800 Merge branch 'refs/heads/ninja-internal' into WebGLFixes commit 500426dea0ca95a6b45be8ea8d132cfdb4d2c940 Author: Nivesh Rajbhandari Date: Thu Mar 1 10:11:39 2012 -0800 Fixed logic error when resizing with the top-left transform handles. Signed-off-by: Nivesh Rajbhandari commit 7980d9bde2b43aa5a494ddf6f1db5c4959a57b91 Author: Nivesh Rajbhandari Date: Thu Mar 1 10:04:15 2012 -0800 Re-fixing IKNinja-940 - Can't select objects when in side/top view. Signed-off-by: Nivesh Rajbhandari commit f04cc0146d8f7573628678613a99c270116768e4 Author: Nivesh Rajbhandari Date: Wed Feb 29 16:45:40 2012 -0800 Last-used material (instead of FlatMaterial) is applied to shape when turning on use WebGL checkbox in the PI. Signed-off-by: Nivesh Rajbhandari Signed-off-by: Jonathan Duran --- js/tools/BrushTool.js | 6 +- js/tools/LineTool.js | 14 +- js/tools/OvalTool.js | 25 ++-- js/tools/PenTool.js | 25 ++-- js/tools/RectTool.js | 24 ++-- js/tools/SelectionTool.js | 282 +++++++++++++++++++++++++++++--------- js/tools/ShapeTool.js | 4 +- js/tools/TranslateObject3DTool.js | 7 + js/tools/drawing-tool-base.js | 18 +-- js/tools/modifier-tool-base.js | 7 + 10 files changed, 304 insertions(+), 108 deletions(-) (limited to 'js/tools') diff --git a/js/tools/BrushTool.js b/js/tools/BrushTool.js index fec89eb2..752aa2a3 100644 --- a/js/tools/BrushTool.js +++ b/js/tools/BrushTool.js @@ -13,6 +13,8 @@ var ElementMediator = require("js/mediators/element-mediator").ElementMediator; var TagTool = require("js/tools/TagTool").TagTool; var snapManager = require("js/helper-classes/3D/snap-manager").SnapManager; +var BrushStroke = require("js/lib/geom/brush-stroke").BrushStroke; + exports.BrushTool = Montage.create(ShapeTool, { hasReel: { value: false }, _toolID: { value: "brushTool" }, @@ -63,7 +65,7 @@ exports.BrushTool = Montage.create(ShapeTool, { } //start a new brush stroke if (this._selectedBrushStroke === null){ - this._selectedBrushStroke = new GLBrushStroke(); + this._selectedBrushStroke = new BrushStroke(); if (this.application.ninja.colorController.colorToolbar.stroke.webGlColor){ this._selectedBrushStroke.setStrokeColor(this.application.ninja.colorController.colorToolbar.stroke.webGlColor); } @@ -192,7 +194,7 @@ exports.BrushTool = Montage.create(ShapeTool, { var bboxMax = this._selectedBrushStroke.getBBoxMax(); var bboxWidth = bboxMax[0] - bboxMin[0]; var bboxHeight = bboxMax[1] - bboxMin[1]; - var bboxMid = Vector.create([0.5 * (bboxMax[0] + bboxMin[0]), 0.5 * (bboxMax[1] + bboxMin[1]), 0.5 * (bboxMax[2] + bboxMin[2])]); + var bboxMid = [0.5 * (bboxMax[0] + bboxMin[0]), 0.5 * (bboxMax[1] + bboxMin[1]), 0.5 * (bboxMax[2] + bboxMin[2])]; this._selectedBrushStroke.setCanvasX(bboxMid[0]); this._selectedBrushStroke.setCanvasY(bboxMid[1]); diff --git a/js/tools/LineTool.js b/js/tools/LineTool.js index 0a7c0534..a61f8f79 100755 --- a/js/tools/LineTool.js +++ b/js/tools/LineTool.js @@ -13,6 +13,9 @@ var Montage = require("montage/core/core").Montage, ShapesController = require("js/controllers/elements/shapes-controller").ShapesController, ShapeModel = require("js/models/shape-model").ShapeModel; +var Line = require("js/lib/geom/line").Line; +var MaterialsModel = require("js/models/materials-model").MaterialsModel; + exports.LineTool = Montage.create(ShapeTool, { _toolID: { value: "lineTool" }, _imageID: { value: "lineToolImg" }, @@ -206,10 +209,13 @@ exports.LineTool = Montage.create(ShapeTool, { // for default stroke and fill/no materials var strokeMaterial = null; - var strokeM = this.options.strokeMaterial; - if(strokeM) + if(this.options.use3D) { - strokeMaterial = Object.create(MaterialsLibrary.getMaterial(strokeM)); + var strokeM = this.options.strokeMaterial; + if(strokeM) + { + strokeMaterial = Object.create(MaterialsModel.getMaterial(strokeM)); + } } var world = this.getGLWorld(canvas, this.options.use3D); @@ -217,7 +223,7 @@ exports.LineTool = Montage.create(ShapeTool, { var xOffset = ((left - canvas.offsetLeft + w/2) - canvas.width/2); var yOffset = (canvas.height/2 - (top - canvas.offsetTop + h/2)); - var line = new GLLine(world, xOffset, yOffset, w, h, slope, strokeSize, strokeColor, strokeMaterial, strokeStyle, xAdj, yAdj); + var line = new Line(world, xOffset, yOffset, w, h, slope, strokeSize, strokeColor, strokeMaterial, strokeStyle, xAdj, yAdj); world.addObject(line); world.render(); diff --git a/js/tools/OvalTool.js b/js/tools/OvalTool.js index 14655312..a10e0bb5 100755 --- a/js/tools/OvalTool.js +++ b/js/tools/OvalTool.js @@ -8,6 +8,9 @@ var Montage = require("montage/core/core").Montage, ShapeTool = require("js/tools/ShapeTool").ShapeTool, ShapesController = require("js/controllers/elements/shapes-controller").ShapesController; +var Circle = require("js/lib/geom/circle").Circle; +var MaterialsModel = require("js/models/materials-model").MaterialsModel; + exports.OvalTool = Montage.create(ShapeTool, { _toolID: { value: "ovalTool" }, @@ -43,25 +46,27 @@ exports.OvalTool = Montage.create(ShapeTool, { var strokeMaterial = null; var fillMaterial = null; - var strokeM = this.options.strokeMaterial; - if(strokeM) + if(this.options.use3D) { - strokeMaterial = Object.create(MaterialsLibrary.getMaterial(strokeM)); - } + var strokeM = this.options.strokeMaterial; + if(strokeM) + { + strokeMaterial = Object.create(MaterialsModel.getMaterial(strokeM)); + } - var fillM = this.options.fillMaterial; - if(fillM) - { - fillMaterial = Object.create(MaterialsLibrary.getMaterial(fillM)); + var fillM = this.options.fillMaterial; + if(fillM) + { + fillMaterial = Object.create(MaterialsModel.getMaterial(fillM)); + } } - var world = this.getGLWorld(canvas, this.options.use3D); var xOffset = ((left - canvas.offsetLeft + w/2) - canvas.width/2); var yOffset = (canvas.height/2 - (top - canvas.offsetTop + h/2)); - var oval = new GLCircle(); + var oval = new Circle(); //GLCircle(); oval.init(world, xOffset, yOffset, w, h, strokeSize, strokeColor, fillColor, innerRadius, strokeMaterial, fillMaterial, strokeStyle); world.addObject(oval); diff --git a/js/tools/PenTool.js b/js/tools/PenTool.js index ddc8bc04..71a91870 100755 --- a/js/tools/PenTool.js +++ b/js/tools/PenTool.js @@ -15,6 +15,9 @@ var TagTool = require("js/tools/TagTool").TagTool; var ElementController = require("js/controllers/elements/element-controller").ElementController; var snapManager = require("js/helper-classes/3D/snap-manager").SnapManager; +var AnchorPoint = require("js/lib/geom/anchor-point").AnchorPoint; +var SubPath = require("js/lib/geom/sub-path").SubPath; + //todo remove this global var var g_DoPenToolMouseMove = true; @@ -146,7 +149,7 @@ exports.PenTool = Montage.create(ShapeTool, { if (mouseDownPos) { //if we had closed the selected subpath previously, or if we have not yet started anything, create a subpath if (this._selectedSubpath === null) { - this._selectedSubpath = new GLSubpath(); + this._selectedSubpath = new SubPath(); this._isNewPath = true; if (this._entryEditMode === this.ENTRY_SELECT_PATH){ //this should not happen, as ENTRY_SELECT_PATH implies there was a selected subpath @@ -212,13 +215,13 @@ exports.PenTool = Montage.create(ShapeTool, { this._penCanvas = null; this._penPlaneMat = null; this._snapTarget = null; - this._selectedSubpath = new GLSubpath(); + this._selectedSubpath = new SubPath(); this._isNewPath = true; } //add an anchor point to end of the subpath, and make it the selected anchor point if (!this._selectedSubpath.getIsClosed() || this._makeMultipleSubpaths) { - this._selectedSubpath.addAnchor(new GLAnchorPoint()); + this._selectedSubpath.addAnchor(new AnchorPoint()); var newAnchor = this._selectedSubpath.getAnchor(this._selectedSubpath.getSelectedAnchorIndex()); newAnchor.setPos(mouseDownPos[0], mouseDownPos[1], mouseDownPos[2]); newAnchor.setPrevPos(mouseDownPos[0], mouseDownPos[1], mouseDownPos[2]); @@ -231,7 +234,7 @@ exports.PenTool = Montage.create(ShapeTool, { if (this._isPickedEndPointInSelectPathMode){ //TODO clean up this code...very similar to the code block above if (!this._selectedSubpath.getIsClosed()) { - this._selectedSubpath.addAnchor(new GLAnchorPoint()); + this._selectedSubpath.addAnchor(new AnchorPoint()); var newAnchor = this._selectedSubpath.getAnchor(this._selectedSubpath.getSelectedAnchorIndex()); newAnchor.setPos(mouseDownPos[0], mouseDownPos[1], mouseDownPos[2]); newAnchor.setPrevPos(mouseDownPos[0], mouseDownPos[1], mouseDownPos[2]); @@ -389,7 +392,7 @@ exports.PenTool = Montage.create(ShapeTool, { var bboxMax = this._selectedSubpath.getBBoxMax(); var bboxWidth = bboxMax[0] - bboxMin[0]; var bboxHeight = bboxMax[1] - bboxMin[1]; - var bboxMid = Vector.create([0.5 * (bboxMax[0] + bboxMin[0]), 0.5 * (bboxMax[1] + bboxMin[1]), 0.5 * (bboxMax[2] + bboxMin[2])]); + var bboxMid = [0.5 * (bboxMax[0] + bboxMin[0]), 0.5 * (bboxMax[1] + bboxMin[1]), 0.5 * (bboxMax[2] + bboxMin[2])]; this._selectedSubpath.setCanvasX(bboxMid[0]); this._selectedSubpath.setCanvasY(bboxMid[1]); @@ -638,7 +641,7 @@ exports.PenTool = Montage.create(ShapeTool, { var baseline = VecUtils.vecNormalize(3, baselineOrig); var delta = VecUtils.vecSubtract(3, p2, p3); //component of the delta along baseline - var deltaB = Vector.create(baseline); + var deltaB = baseline; VecUtils.vecScale(3, deltaB, VecUtils.vecDot(3, baseline, delta)); //component of the delta orthogonal to baseline var deltaO = VecUtils.vecSubtract(3, delta, deltaB); @@ -655,7 +658,7 @@ exports.PenTool = Montage.create(ShapeTool, { //if there is a selected anchor point if (this._selectedSubpath && this._selectedSubpath.getSelectedAnchorIndex() !== -1) { var selAnchor = this._selectedSubpath.getAnchor(this._selectedSubpath.getSelectedAnchorIndex()); - var pos = Vector.create([selAnchor.getPosX(), selAnchor.getPosY(), selAnchor.getPosZ()]); + var pos = [selAnchor.getPosX(), selAnchor.getPosY(), selAnchor.getPosZ()]; var distToPrev = selAnchor.getPrevDistanceSq(pos[0], pos[1], pos[2]); var distToNext = selAnchor.getNextDistanceSq(pos[0], pos[1], pos[2]); var threshSq = 0; // 4 * this._PICK_POINT_RADIUS * this._PICK_POINT_RADIUS; @@ -671,8 +674,8 @@ exports.PenTool = Montage.create(ShapeTool, { nextAnchor = this._selectedSubpath.getAnchor(this._selectedSubpath.getSelectedAnchorIndex()+1); else nextAnchor = this._selectedSubpath.getAnchor(0); - var nextAnchorPrev = Vector.create([nextAnchor.getPrevX(), nextAnchor.getPrevY(), nextAnchor.getPrevZ()]); - var nextAnchorPos = Vector.create([nextAnchor.getPosX(), nextAnchor.getPosY(), nextAnchor.getPosZ()]) + var nextAnchorPrev = [nextAnchor.getPrevX(), nextAnchor.getPrevY(), nextAnchor.getPrevZ()]; + var nextAnchorPos = [nextAnchor.getPosX(), nextAnchor.getPosY(), nextAnchor.getPosZ()]; var newNext = this.BuildSecondCtrlPoint(pos, nextAnchorPrev, nextAnchorPos); selAnchor.setNextPos(newNext[0], newNext[1], newNext[2]); //check if the next is still not over the threshSq..if so, add a constant horizontal amount @@ -688,8 +691,8 @@ exports.PenTool = Montage.create(ShapeTool, { prevAnchor = this._selectedSubpath.getAnchor(this._selectedSubpath.getSelectedAnchorIndex()-1); else prevAnchor = this._selectedSubpath.getAnchor(numAnchors-1); - var prevAnchorNext = Vector.create([prevAnchor.getNextX(), prevAnchor.getNextY(), prevAnchor.getNextZ()]); - var prevAnchorPos = Vector.create([prevAnchor.getPosX(), prevAnchor.getPosY(), prevAnchor.getPosZ()]) + var prevAnchorNext = [prevAnchor.getNextX(), prevAnchor.getNextY(), prevAnchor.getNextZ()]; + var prevAnchorPos = [prevAnchor.getPosX(), prevAnchor.getPosY(), prevAnchor.getPosZ()]; var newPrev = this.BuildSecondCtrlPoint(pos, prevAnchorNext, prevAnchorPos); selAnchor.setPrevPos(newPrev[0], newPrev[1], newPrev[2]); //check if the prev is still not over the threshSq..if so, add a constant horizontal amount diff --git a/js/tools/RectTool.js b/js/tools/RectTool.js index 31ac7faa..957afea9 100755 --- a/js/tools/RectTool.js +++ b/js/tools/RectTool.js @@ -8,6 +8,9 @@ var Montage = require("montage/core/core").Montage, ShapeTool = require("js/tools/ShapeTool").ShapeTool, ShapesController = require("js/controllers/elements/shapes-controller").ShapesController; +var Rectangle = require("js/lib/geom/rectangle").Rectangle; +var MaterialsModel = require("js/models/materials-model").MaterialsModel; + exports.RectTool = Montage.create(ShapeTool, { _toolID: { value: "rectTool" }, @@ -62,16 +65,19 @@ exports.RectTool = Montage.create(ShapeTool, { var strokeMaterial = null; var fillMaterial = null; - var strokeM = this.options.strokeMaterial; - if(strokeM) + if(this.options.use3D) { - strokeMaterial = Object.create(MaterialsLibrary.getMaterial(strokeM)); - } + var strokeM = this.options.strokeMaterial; + if(strokeM) + { + strokeMaterial = Object.create(MaterialsModel.getMaterial(strokeM)); + } - var fillM = this.options.fillMaterial; - if(fillM) - { - fillMaterial = Object.create(MaterialsLibrary.getMaterial(fillM)); + var fillM = this.options.fillMaterial; + if(fillM) + { + fillMaterial = Object.create(MaterialsModel.getMaterial(fillM)); + } } var world = this.getGLWorld(canvas, this.options.use3D); @@ -79,7 +85,7 @@ exports.RectTool = Montage.create(ShapeTool, { var xOffset = ((left - canvas.offsetLeft + w/2) - canvas.width/2); var yOffset = (canvas.height/2 - (top - canvas.offsetTop + h/2)); - var rect = new GLRectangle(); + var rect = new Rectangle(); rect.init(world, xOffset, yOffset, w, h, strokeSize, strokeColor, fillColor, tlRadius, trRadius, blRadius, brRadius, strokeMaterial, fillMaterial, strokeStyle); diff --git a/js/tools/SelectionTool.js b/js/tools/SelectionTool.js index caa9e8d6..6d8ff175 100755 --- a/js/tools/SelectionTool.js +++ b/js/tools/SelectionTool.js @@ -19,6 +19,7 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { _canOperateOnStage: { value: true}, _isSelecting: {value: false, writable:true}, _shiftMove: { value: 10}, + _use3DMode: { value: false }, _showTransformHandles: { value: false, enumerable: true }, @@ -29,6 +30,27 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { } }, + _areElementsOnSamePlane : { + value: function () { + if(this._targets && this._targets.length) + { + // TODO - drawUtils's elementPlanes check in drawSelectionBounds doesn't seem to work, + // so temporary workaround to simply check if all elements have identity matrix + // TODO - Eventually, this should instead check if all the selected items are on the view plane + var len = this._targets.length; + for(var i = 0; i < len; i++) + { + var mat = this._targets[i].mat; + if(!MathUtils.isIdentityMatrix(mat)) + { + return false; + } + } + } + return true; + } + }, + startDraw: { value: function(event) { if(!this.application.ninja.selectedElements.length) @@ -44,9 +66,13 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { this.isDrawing = true; this.application.ninja.stage.showSelectionBounds = false; + this._use3DMode = false; + if(this._canSnap) { this.initializeSnapping(event); + this._use3DMode = !this._areElementsOnSamePlane(); +// console.log("use3DMode = " + this._use3DMode); } else { @@ -122,6 +148,8 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { if(this._escape) { this._escape = false; this._isSelecting = false; + this._canSnap = true; + this._use3DMode = false; return; } @@ -153,6 +181,8 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { } this.endDraw(event); + this._canSnap = true; + this._use3DMode = false; return; } @@ -180,6 +210,8 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { } this.endDraw(event); + this._canSnap = true; + this._use3DMode = false; } }, @@ -211,7 +243,7 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { case Keyboard.LEFT: var newLeft = []; var leftArr = this.application.ninja.selectedElements.map(function(item) { - newLeft.push( (parseFloat(ElementsMediator.getProperty(item._element, "left")) - inc) + "px" ); + newLeft.push( (parseInt(ElementsMediator.getProperty(item._element, "left")) - inc) + "px" ); return ElementsMediator.getProperty(item._element, "left"); }); @@ -220,7 +252,7 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { case Keyboard.UP: var newTop = []; var topArr = this.application.ninja.selectedElements.map(function(item) { - newTop.push( (parseFloat(ElementsMediator.getProperty(item._element, "top")) - inc) + "px" ); + newTop.push( (parseInt(ElementsMediator.getProperty(item._element, "top")) - inc) + "px" ); return ElementsMediator.getProperty(item._element, "top"); }); @@ -229,7 +261,7 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { case Keyboard.RIGHT: var newLeft = []; var leftArr = this.application.ninja.selectedElements.map(function(item) { - newLeft.push( (parseFloat(ElementsMediator.getProperty(item._element, "left")) + inc) + "px" ); + newLeft.push( (parseInt(ElementsMediator.getProperty(item._element, "left")) + inc) + "px" ); return ElementsMediator.getProperty(item._element, "left"); }); @@ -238,7 +270,7 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { case Keyboard.DOWN: var newTop = []; var topArr = this.application.ninja.selectedElements.map(function(item) { - newTop.push( (parseFloat(ElementsMediator.getProperty(item._element, "top")) + inc) + "px" ); + newTop.push( (parseInt(ElementsMediator.getProperty(item._element, "top")) + inc) + "px" ); return ElementsMediator.getProperty(item._element, "top"); }); @@ -269,10 +301,12 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { newTop = [], newWidth = [], newHeight = [], + newStyles = [], previousLeft = [], previousTop = [], previousWidth = [], - previousHeight = []; + previousHeight = [], + previousStyles = []; var len = this.application.ninja.selectedElements.length; this._targets = []; for(var i = 0; i < len; i++) @@ -285,52 +319,97 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { this._targets.push({elt:elt, mat:curMat, matInv:curMatInv}); if(addToUndoStack) { - var previousMat = this._undoArray[i].mat.slice(0); - var prevX = this._undoArray[i]._x; - var prevY = this._undoArray[i]._y; - var prevW = this._undoArray[i]._w; - var prevH = this._undoArray[i]._h; - var _x = parseFloat(ElementsMediator.getProperty(elt, "left")) + curMat[12] - previousMat[12]; - var _y = parseFloat(ElementsMediator.getProperty(elt, "top")) + curMat[13] - previousMat[13]; - var _w = parseFloat(ElementsMediator.getProperty(elt, "width")); - var _h = parseFloat(ElementsMediator.getProperty(elt, "height")); - - previousLeft.push(prevX + "px"); - previousTop.push(prevY + "px"); - previousWidth.push(prevW + "px"); - previousHeight.push(prevH + "px"); - newLeft.push(_x + "px"); - newTop.push(_y + "px"); - newWidth.push(_w + "px"); - newHeight.push(_h + "px"); - - viewUtils.setMatrixForElement(elt, previousMat); - this._targets[i].mat = previousMat; - this._targets[i].matInv = glmat4.inverse(previousMat, []); + if(!this._use3DMode) + { + var previousMat = this._undoArray[i].mat.slice(0); + var prevX = this._undoArray[i]._x; + var prevY = this._undoArray[i]._y; + var prevW = this._undoArray[i]._w; + var prevH = this._undoArray[i]._h; + var _x = parseInt(ElementsMediator.getProperty(elt, "left")) + curMat[12] - previousMat[12]; + var _y = parseInt(ElementsMediator.getProperty(elt, "top")) + curMat[13] - previousMat[13]; + var _w = parseInt(ElementsMediator.getProperty(elt, "width")); + var _h = parseInt(ElementsMediator.getProperty(elt, "height")); + + previousLeft.push(prevX + "px"); + previousTop.push(prevY + "px"); + previousWidth.push(prevW + "px"); + previousHeight.push(prevH + "px"); + newLeft.push(_x + "px"); + newTop.push(_y + "px"); + newWidth.push(_w + "px"); + newHeight.push(_h + "px"); + + viewUtils.setMatrixForElement(elt, previousMat); + + this._targets[i].mat = previousMat; + this._targets[i].matInv = glmat4.inverse(previousMat, []); + } + else + { + var previousMat = this._undoArray[i].mat.slice(0); + var prevW = this._undoArray[i]._w; + var prevH = this._undoArray[i]._h; + var _w = parseInt(ElementsMediator.getProperty(elt, "width")); + var _h = parseInt(ElementsMediator.getProperty(elt, "height")); + previousWidth.push(prevW + "px"); + previousHeight.push(prevH + "px"); + newWidth.push(_w + "px"); + newHeight.push(_h + "px"); + + var previousStyleStr = {dist:this._undoArray[i].dist, + mat:MathUtils.scientificToDecimal(previousMat, 5)}; + var newStyleStr = {dist:viewUtils.getPerspectiveDistFromElement(elt), + mat:MathUtils.scientificToDecimal(curMat, 5)}; + previousStyles.push(previousStyleStr); + newStyles.push(newStyleStr); + + this._targets[i].mat = curMat; + this._targets[i].matInv = curMatInv; + } } } if(addToUndoStack) { - // if we have a delta, that means the transform handles were used and - // we should update the width and height too. Otherwise, just update left and top. - if(this._delta) + if(!this._use3DMode) { - ElementsMediator.setProperties(this.application.ninja.selectedElements, - { "left": newLeft, "top": newTop, "width": newWidth, "height": newHeight }, - "Change", - "selectionTool", - { "left" : previousLeft, "top" : previousTop, "width": previousWidth, "height": previousHeight} - ); + // if we have a delta, that means the transform handles were used and + // we should update the width and height too. Otherwise, just update left and top. + if(this._delta) + { + ElementsMediator.setProperties(this.application.ninja.selectedElements, + { "left": newLeft, "top": newTop, "width": newWidth, "height": newHeight }, + "Change", + "selectionTool", + { "left" : previousLeft, "top" : previousTop, "width": previousWidth, "height": previousHeight} + ); + } + else + { + ElementsMediator.setProperties(this.application.ninja.selectedElements, + { "left": newLeft, "top": newTop }, + "Change", + "selectionTool", + { "left" : previousLeft, "top" : previousTop } + ); + } } else { + // TODO - We don't support transform handles in 3d space for now ElementsMediator.setProperties(this.application.ninja.selectedElements, - { "left": newLeft, "top": newTop }, + { "width": newWidth, "height": newHeight }, "Change", "selectionTool", - { "left" : previousLeft, "top" : previousTop } + { "width": previousWidth, "height": previousHeight} ); + ElementsMediator.set3DProperties(this.application.ninja.selectedElements, + newStyles, + "Change", + "translateTool", + previousStyles + ); } } // Save previous value for undo/redo @@ -338,12 +417,13 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { for(i = 0, len = this._targets.length; i < len; i++) { var item = this._targets[i]; - var _x = parseFloat(ElementsMediator.getProperty(item.elt, "left")); - var _y = parseFloat(ElementsMediator.getProperty(item.elt, "top")); - var _w = parseFloat(ElementsMediator.getProperty(item.elt, "width")); - var _h = parseFloat(ElementsMediator.getProperty(item.elt, "height")); + _x = parseInt(ElementsMediator.getProperty(item.elt, "left")); + _y = parseInt(ElementsMediator.getProperty(item.elt, "top")); + _w = parseInt(ElementsMediator.getProperty(item.elt, "width")); + _h = parseInt(ElementsMediator.getProperty(item.elt, "height")); var _mat = viewUtils.getMatrixFromElement(item.elt); - this._undoArray.push({_x:_x, _y:_y, _w:_w, _h:_h, mat:_mat}); + var _dist = viewUtils.getPerspectiveDistFromElement(item.elt); + this._undoArray.push({_x:_x, _y:_y, _w:_w, _h:_h, mat:_mat, dist:_dist}); } } @@ -355,7 +435,9 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { i, item, elt, - curMat; + curMat, + newLeft = [], + newTop = []; var matInv = glmat4.inverse(this._startMat, []); var nMat = glmat4.multiply(transMat, this._startMat, [] ); @@ -367,16 +449,35 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { { item = this._targets[i]; elt = item.elt; - curMat = item.mat; - -// curMat = curMat.multiply(qMat); - glmat4.multiply(curMat, qMat, curMat); - - viewUtils.setMatrixForElement( elt, curMat, true); + if(this._use3DMode) + { + curMat = item.mat; + glmat4.multiply(curMat, qMat, curMat); + viewUtils.setMatrixForElement( elt, curMat, true); + this._targets[i].mat = curMat; + } + else + { + curMat = item.mat.slice(0); + glmat4.multiply(curMat, qMat, curMat); + var previousMat = this._undoArray[i].mat.slice(0); + var _x = parseInt(ElementsMediator.getProperty(elt, "left")) + curMat[12] - previousMat[12]; + var _y = parseInt(ElementsMediator.getProperty(elt, "top")) + curMat[13] - previousMat[13]; - this._targets[i].mat = curMat; + newLeft.push(_x + "px"); + newTop.push(_y + "px"); + } } - NJevent("elementChanging", {type : "Changing", redraw: false}); + + if(newLeft.length) + { + ElementsMediator.setProperties(this.application.ninja.selectedElements, + { "left": newLeft, "top": newTop }, "Changing", "SelectionTool" ); + } + else + { + NJevent("elementChanging", {type : "Changing", redraw: false}); + } } }, @@ -400,7 +501,7 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { case 0: // Resize North-West delta = ~~(data.pt1[0] - data.pt0[0]); - deltaW = this._undoArray.map(function(item) { return item._w + delta + "px"}); + deltaW = this._undoArray.map(function(item) { return item._w - delta + "px"}); deltaL = this._undoArray.map(function(item) { return item._x + delta + "px"}); delta = ~~(data.pt1[1] - data.pt0[1]); deltaH = this._undoArray.map(function(item) { return item._h - delta + "px"}); @@ -654,8 +755,13 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { this.application.ninja.stage.clearDrawingCanvas(); var item = this._target; - if(!item || !this._showTransformHandles) + if(!item || (item === this.application.ninja.currentDocument.documentRoot)) + { + return; + } + if(!this._showTransformHandles) { + this._drawTopLeft(item); return; } @@ -744,13 +850,14 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { var left = x; var top = y; - if(delta) +// if(delta) + if(!this._use3DMode && this.isDrawing) { context.font = "10px sans-serif"; context.textAlign = "right"; - context.fillText("( " + (left - this.application.ninja.stage.userContentLeft) + " , " + - (top - this.application.ninja.stage.userContentTop) + " )", x-10, y-4); + context.fillText("( " + ~~(left - this.application.ninja.stage.userContentLeft) + " , " + + ~~(top - this.application.ninja.stage.userContentTop) + " )", x-10, y-4); } // W @@ -779,10 +886,11 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { context.moveTo( x, y ); this._handles[4].draw(x, y); - if(delta) +// if(delta) + if(!this._use3DMode && this.isDrawing) { - context.fillText("H: " + (y - top), x+38, y - 4); - context.fillText("W: " + (x - left), x-5, y + 12); + context.fillText("H: " + ~~(y - top), x+38, y - 4); + context.fillText("W: " + ~~(x - left), x-5, y + 12); } // E @@ -809,9 +917,59 @@ var SelectionTool = exports.SelectionTool = Montage.create(ModifierToolBase, { } }, + _drawTopLeft: { + value: function(item) + { + if(!this.isDrawing || this._use3DMode) + { + return; + } + viewUtils.setViewportObj( item ); + var bounds3D = viewUtils.getElementViewBounds3D( item ); + + var zoomFactor = 1; + var viewPort = this.application.ninja.stage._viewport; + if (viewPort.style && viewPort.style.zoom) + { + zoomFactor = Number(viewPort.style.zoom); + } + var tmpMat = viewUtils.getLocalToGlobalMatrix( item ); + for (var j=0; j<4; j++) + { + var localPt = bounds3D[j]; + var tmpPt = viewUtils.localToGlobal2(localPt, tmpMat); + + if(zoomFactor !== 1) + { + tmpPt = vecUtils.vecScale(3, tmpPt, zoomFactor); + + tmpPt[0] += this.application.ninja.stage._scrollLeft*(zoomFactor - 1); + tmpPt[1] += this.application.ninja.stage._scrollTop*(zoomFactor - 1); + } + bounds3D[j] = tmpPt; + } + + // Draw tool handles + var context = this.application.ninja.stage.drawingContext; + context.beginPath(); + + // NW + var x = bounds3D[0][0]; + var y = bounds3D[0][1]; + context.moveTo(x, y); + + context.font = "10px sans-serif"; + context.textAlign = "right"; + + context.fillText("( " + ~~(x - this.application.ninja.stage.userContentLeft) + " , " + + ~~(y - this.application.ninja.stage.userContentTop) + " )", x-10, y-4); + + context.closePath(); + } + }, + // TODO : Use the new element mediator to get element offsets - _complicatedCollisionDetection: - { + _complicatedCollisionDetection: { value: function(elt, box) { var left, top, width, height; diff --git a/js/tools/ShapeTool.js b/js/tools/ShapeTool.js index 29e9b99f..d3a36163 100755 --- a/js/tools/ShapeTool.js +++ b/js/tools/ShapeTool.js @@ -14,6 +14,8 @@ var Montage = require("montage/core/core").Montage, ShapeModel = require("js/models/shape-model").ShapeModel, TagTool = require("js/tools/TagTool").TagTool; +var World = require("js/lib/drawing/world").World; + exports.ShapeTool = Montage.create(DrawingTool, { drawingFeedback: { value: { mode: "Draw3D", type: "rectangle" } }, @@ -176,7 +178,7 @@ exports.ShapeTool = Montage.create(DrawingTool, { if(!world) { // create all the GL stuff - var world = new GLWorld(canvas, use3D); + var world = new World(canvas, use3D); ElementMediator.setShapeProperty(canvas, "GLWorld", world); } diff --git a/js/tools/TranslateObject3DTool.js b/js/tools/TranslateObject3DTool.js index bbbbc871..5157e39c 100755 --- a/js/tools/TranslateObject3DTool.js +++ b/js/tools/TranslateObject3DTool.js @@ -65,6 +65,13 @@ exports.TranslateObject3DTool = Object.create(Translate3DToolBase, { // a snap on the mouse down var hitRec = snapManager.snap(point.x, point.y, do3DSnap); + // TODO - Check that hitRec's element matches element that browser says we clicked on + var elt = this.application.ninja.stage.GetElement(event); + if(elt !== hitRec.getElement()) + { + hitRec = snapManager.findHitRecordForElement(elt); + } + // we don't want to snap to selected objects during the drag var len = this._targets.length; for(var i=0; i