/* <copyright> This file contains proprietary software owned by Motorola Mobility, Inc.<br/> No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.<br/> (c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. </copyright> */ var Montage = require("montage/core/core").Montage, ShapeTool = require("js/tools/ShapeTool").ShapeTool, DrawingToolBase = require("js/tools/drawing-tool-base").DrawingToolBase, NJUtils = require("js/lib/NJUtils").NJUtils, TagTool = require("js/tools/TagTool").TagTool, 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" }, _toolImageClass: { value: "lineToolUp" }, _selectedToolImageClass: { value: "lineToolDown" }, _toolTipText: { value: "Line Tool (L)" }, _tmpDrawIndex : { value : 1, writable:true}, _mode: {value: null, writable:true}, // Need to keep track of current mouse position for KEY modifiers event which do not have mouse coordinates _currentX: {value: 0, writable: true}, _currentY: {value: 0, writable: true}, _lineView: {value: null, writable:true}, _ovalView: {value: null, writable:true}, _strokeSize: { value: 1 }, _strokeColor: { value: null }, HandleLeftButtonDown: { value: function (event) { if(this._canDraw) { this._isDrawing = true; } this._strokeSize = ShapesController.GetValueInPixels(this.options.strokeSize.value, this.options.strokeSize.units, null); if (this.options.stroke.color) this._strokeColor = this.options.stroke.color.css; else this._strokeColor = [0,0,0,1]; this.startDraw(event); } }, HandleLeftButtonUp: { value: function (event) { var slope = this._getSlope(), canvas, xAdj = 0, yAdj = 0, w, h; if(slope) { this.drawData = this.getDrawingData(); if(this.drawData) { w = Math.floor(this.drawData.width); h = Math.floor(this.drawData.height); if(!this._useExistingCanvas()) { // set the dimensions if(slope === "horizontal") { h = Math.max(this._strokeSize, 1); w = Math.max(w, 1); } else if(slope === "vertical") { w = Math.max(this._strokeSize, 1); h = Math.max(h, 1); } else { // else make the line's stroke fit inside the canvas by growing the canvas var theta = Math.atan(slope); xAdj = Math.abs((this._strokeSize/2)*Math.sin(theta)); yAdj = Math.abs((this._strokeSize/2)*Math.cos(theta)); w += ~~(xAdj*2); h += ~~(yAdj*2); } canvas = document.application.njUtils.make("canvas", {"data-RDGE-id": NJUtils.generateRandom()}, this.application.ninja.currentDocument); var styles = document.application.njUtils.stylesFromDraw(canvas, w, h, this.drawData); this.application.ninja.elementMediator.addElements(canvas, styles); } else { canvas = this._targetedElement; canvas.elementModel.controller = ShapesController; if(!canvas.elementModel.shapeModel) { canvas.elementModel.shapeModel = Montage.create(ShapeModel); } } } } this.endDraw(event); this._isDrawing = false; this._hasDraw=false; this.DrawHandles(); } }, onAddElements: { value: function(el) { var xAdj = 0, yAdj = 0, w, h, slope = this._getSlope(); if(this.drawData) { // set the dimensions w = Math.floor(this.drawData.width); h = Math.floor(this.drawData.height); if(slope === "horizontal") { h = Math.max(this._strokeSize, 1); w = Math.max(w, 1); } else if(slope === "vertical") { w = Math.max(this._strokeSize, 1); h = Math.max(h, 1); } else { // else make the line's stroke fit inside the canvas by growing the canvas var theta = Math.atan(slope); xAdj = Math.abs((this._strokeSize/2)*Math.sin(theta)); yAdj = Math.abs((this._strokeSize/2)*Math.cos(theta)); w += ~~(xAdj*2); h += ~~(yAdj*2); } this.RenderShape(w, h, this.drawData.planeMat, this.drawData.midPt, el, slope, xAdj, yAdj); } } }, _getSlope: { value: function() { var hitRec0 = this._mouseDownHitRec, hitRec1 = this._mouseUpHitRec, slope, dx, dy; if (hitRec0 && hitRec1) { var p0 = hitRec0.getLocalPoint(), p1 = hitRec1.getLocalPoint(); dx = Math.floor(p0[0] - p1[0]); dy = Math.floor(p0[1] - p1[1]); if( (dx === 0) && (dy === 0) ) { return null; } // check for divide by 0 for vertical line: if(dx === 0) { // vertical line slope = "vertical"; } else if (dy === 0) { // horizontal line slope = "horizontal"; } else { // if slope is positive, draw a line from top-left to bottom-right slope = dy/dx; } } return slope; } }, _doDraw: { value: function () { if (this.mouseDownHitRec !== null) { DrawingToolBase.stageComponent = this.application.ninja.stage; DrawingToolBase.drawLine(this.mouseDownHitRec, this.mouseUpHitRec, this._strokeSize, this._strokeColor); } } }, HandleShiftKeyDown: { value: function (event) { if (this._isDrawing) { var slope = Math.abs((this.downPoint.y - this.currentY)/(this.downPoint.x - this.currentX)); // If slope is less than 0.5, make it a horizontal line if(slope < 0.5) { this._mouseUpHitRec = DrawingToolBase.getUpdatedSnapPoint(this.currentX, this.downPoint.y, false, this._mouseDownHitRec); } // If slope is greater than 2, make it a vertical line else if(slope > 2) { this._mouseUpHitRec = DrawingToolBase.getUpdatedSnapPoint(this.downPoint.x, this.currentY, false, this._mouseDownHitRec); } // make it a 45 degree line else { var square = this.toSquare(this.downPoint.x, this.currentX, this.downPoint.y, this.currentY); this._mouseUpHitRec = DrawingToolBase.getUpdatedSnapPoint(square[0] + square[2], square[1] + square[3], false, this._mouseDownHitRec); } this._doDraw(); } } }, HandleShiftKeyUp: { value: function () { if (this._isDrawing) { this.mouseUpHitRec = DrawingToolBase.getUpdatedSnapPoint(this.currentX, this.currentY, false, this.mouseDownHitRec); this._doDraw(); } } }, RenderShape: { value: function (w, h, planeMat, midPt, canvas, slope, xAdj, yAdj) { var strokeStyleIndex = this.options.strokeStyleIndex; var strokeStyle = this.options.strokeStyle; var strokeSize = this._strokeSize; var left = Math.round(midPt[0] - 0.5*w); var top = Math.round(midPt[1] - 0.5*h); var strokeColor = this.options.stroke.webGlColor; // for default stroke and fill/no materials var strokeMaterial = null; if(this.options.use3D) { var strokeM = this.options.strokeMaterial; if(strokeM) { strokeMaterial = Object.create(MaterialsModel.getMaterial(strokeM)); } strokeColor = ShapesController.getMaterialColor(strokeM) || strokeColor; } 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 line = Object.create(Line, {}); line.init(world, xOffset, yOffset, w, h, slope, strokeSize, strokeColor, strokeMaterial, strokeStyle, xAdj, yAdj); world.addObject(line); world.render(); canvas.elementModel.shapeModel.shapeCount++; if(canvas.elementModel.shapeModel.shapeCount === 1) { // canvas.elementModel.selection = "Line"; canvas.elementModel.pi = "LinePi"; canvas.elementModel.shapeModel.strokeSize = this.options.strokeSize.value + " " + this.options.strokeSize.units; canvas.elementModel.shapeModel.strokeStyleIndex = strokeStyleIndex; canvas.elementModel.shapeModel.strokeStyle = strokeStyle; canvas.elementModel.shapeModel.GLGeomObj = line; canvas.elementModel.shapeModel.useWebGl = this.options.use3D; canvas.elementModel.shapeModel.slope = slope; } else { // TODO - update the shape's info only. shapeModel will likely need an array of shapes. } // TODO - This needs to be moved into geom obj's init routine instead of here this.setColor(this.options.stroke, null, canvas, "lineTool"); if(canvas.elementModel.isShape) { this.application.ninja.selectionController.selectElement(canvas); } } } });