From b89a7ee8b956c96a1dcee995ea840feddc5d4b27 Mon Sep 17 00:00:00 2001 From: Pierre Frisch Date: Thu, 22 Dec 2011 07:25:50 -0800 Subject: First commit of Ninja to ninja-internal Signed-off-by: Valerio Virgillito --- js/stage/layout.js | 377 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 377 insertions(+) create mode 100644 js/stage/layout.js (limited to 'js/stage/layout.js') diff --git a/js/stage/layout.js b/js/stage/layout.js new file mode 100644 index 00000000..625c09ad --- /dev/null +++ b/js/stage/layout.js @@ -0,0 +1,377 @@ +/* +This file contains proprietary software owned by Motorola Mobility, Inc.
+No rights, expressed or implied, whatsoever to this software are provided by Motorola Mobility, Inc. hereunder.
+(c) Copyright 2011 Motorola Mobility, Inc. All Rights Reserved. +
*/ + +/** +@module js/document/documentManager +@requires montage/core/core +@requires montage/ui/component +*/ +var Montage = require("montage/core/core").Montage, + Component = require("montage/ui/component").Component, + viewUtils = require("js/helper-classes/3D/view-utils").ViewUtils, + drawUtils = require("js/helper-classes/3D/draw-utils").DrawUtils, + vecUtils = require("js/helper-classes/3D/vec-utils").VecUtils; + +exports.Layout = Montage.create(Component, { + + canvas: { value: null }, + ctx: { value: null }, + + drawFillColor: { value: 'rgba(255,255,255,1)' }, + ctxLineWidth: { value: 0.2 }, + + _layoutView: { + value: "layoutAll" + }, + + layoutView: { + get: function() { + return this._layoutView; + }, + set: function(value) { + if(this._layoutView !== value) { + this._layoutView = value; + this.draw(); + } + } + }, + + domTree: { + value: [] + }, + + elementsToDraw: { + value: [] + }, + + deserializedFromTemplate: { + value: function() { + this.ctx = this.canvas.getContext("2d"); + this.ctx.lineWidth = this.ctxLineWidth; + this.ctx.fillStyle = this.drawFillColor; + + this.eventManager.addEventListener("elementAdded", this, false); + this.eventManager.addEventListener("elementDeleted", this, false); + + this.eventManager.addEventListener("selectionChange", this, false); + + this.eventManager.addEventListener("deleteSelection", this, true); + +// this.addEventListener("change@stage.appModel.layoutView", this.handleLayoutView, false); + + } + }, + + handleLayoutView: { + value: function() { + console.log(this.stage.appModel.layoutView); + } + }, + + handleElementAdded: { + value: function(event) { + this.domTree.push(event.detail); + } + }, + + handleElementDeleted: { + value: function(event) { + this.domTree.splice(this.domTree.indexOf(event.detail), 1); + + this.draw(); + } + }, + + captureDeleteSelection: { + value: function(event) { + //this.redrawDocument(); + + var len = event.detail.length; + for(var i = 0; i < len ; i++) { + this.domTree.splice(this.domTree.indexOf(event.detail[i]),1); + } + + } + }, + + handleSelectionChange: { + value: function(event) { + this.elementsToDraw = []; + + if(!event.detail.isDocument) { + var tmp = event.detail.elements.map(function(element){ return element._element}); + + this.elementsToDraw = this.domTree.filter(function(value) { + return (tmp.indexOf(value) === -1); + }); + } else { + this.elementsToDraw = this.domTree; + } + + this.draw(); // Not a reel yet :) + + + } + }, + + draw: { + value: function() { + this.clearCanvas(); + var els = this.elementsToDraw.length; + for(var i = 0, el; i < els; i++){ + this.drawTagOutline(this.elementsToDraw[i]); + } + } + }, + + draw3DInfo: { + value: function() { + drawUtils.updatePlanes(); + if(this.stage.appModel.show3dGrid) drawUtils.drawWorkingPlane(); + drawUtils.draw3DCompass(); + } + }, + + clearCanvas: { + value: function() { + this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); + } + }, + + drawTagOutline: { + value: function (item) { + + if(!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; + } + */ + + /** + * New Drawing layout code using 3D calculations + */ + viewUtils.setViewportObj( item ); + var bounds3D = viewUtils.getElementViewBounds3D( item ); + var tmpMat = viewUtils.getLocalToGlobalMatrix( item ); + + var zoomFactor = 1; + if (this.stage._viewport.style && this.stage._viewport.style.zoom) + { + zoomFactor = Number(this.stage._viewport.style.zoom); + } + + var sSL = this.stage._scrollLeft; + var sST = this.stage._scrollTop; + + 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] += sSL*(zoomFactor - 1); + tmpPt[1] += sST*(zoomFactor - 1); + } + bounds3D[j] = tmpPt; + } + + // Draw the Item ouline + this._dashedLine(bounds3D[3][0] - 0.5,bounds3D[3][1]- 0.5,bounds3D[0][0] + 2.5, bounds3D[0][1] - 0.5,[5,5]); + this._dashedLine(bounds3D[0][0] - 0.5, bounds3D[0][1] - 0.5, bounds3D[1][0]- 0.5, bounds3D[1][1] + 0.5, [5,5] ); + this._dashedLine(bounds3D[1][0] - 0.5 , bounds3D[1][1] + 0.5, bounds3D[2][0]+ 0.5, bounds3D[2][1] + 0.5, [5,5] ); + this._dashedLine(bounds3D[2][0] + 0.5, bounds3D[2][1] + 0.5, bounds3D[3][0] + 0.5, bounds3D[3][1] - 0.5, [5,5] ); + + // Draw the Label is all mode + if(this.layoutView === "layoutAll") { + this.ctx.strokeStyle = 'rgba(0,0,0,1)'; // Black Stroke + this.ctx.strokeRect(bounds3D[0][0]+5.5, bounds3D[0][1]-15.5, 70, 11); + this.ctx.fillStyle = 'rgba(255,255,255,1)' // White Fill + this.ctx.fillRect(bounds3D[0][0]+6, bounds3D[0][1]-15, 69, 10); + + this.ctx.fillStyle = 'rgba(0,0,0,1)'; + this.ctx.font = "9px Droid Sans"; + + this.ctx.fillText(this._elementName(item), bounds3D[0][0] + 8, bounds3D[0][1] - 7); + } + } + }, + + /** + * redrawDocument: Redraws the outline for the entire document + */ + redrawDocument: { + value: function() { + if(this.application.ninja.currentDocument) { + this.clearCanvas(); + this.WalkDOM(this.application.ninja.currentDocument.documentRoot); + + //drawUtils.updatePlanes(); + //if(this.application.ninja.currentDocument.draw3DGrid) drawUtils.drawWorkingPlane(); + //drawUtils.draw3DCompass(); + } + } + }, + + drawElementsOutline: { + value: function(elements) { + this.clearCanvas(); + this.WalkDOM(this.application.ninja.currentDocument.documentRoot, elements); + + //drawUtils.updatePlanes(); + + if(this.application.ninja.currentDocument.draw3DGrid) { + //drawUtils.drawWorkingPlane(); + } + + //drawUtils.draw3DCompass(); + } + }, + + WalkDOM: { + value: function(element, excludeArray) { + if(!element) + { + return; + } + + try { + if(element.nodeType == 1 && this.application.ninja.currentDocument.inExclusion(element) === -1 ) { + + if(excludeArray) { + var found = false; + for(var j=0, elt; elt = excludeArray[j]; j++) { + + if(elt.uuid === element.uuid) { + found = true; + } + } + + if(!found) { + this.drawTagOutline(element); + } + } else { + this.drawTagOutline(element); + } + + } + + if(element.elementModel && element.elementModel.isComponent) { + this.WalkDOM(element.nextSibling, excludeArray); + } else { + this.WalkDOM(element.firstChild, excludeArray); + this.WalkDOM(element.nextSibling, excludeArray); + } + } catch (err) { + console.log(err); + } + } + }, + + // Alternate dashed line method. + ___dashedLine: { + value: function(x, y, x2, y2, dashArray) { + this.ctx.lineCap = "square"; + this.ctx.beginPath(); + + if(! dashArray) dashArray=[10,5]; + var dashCount = dashArray.length; + var dx = (x2 - x); + var dy = (y2 - y); + var xSlope = (Math.abs(dx) > Math.abs(dy)); + var slope = (xSlope) ? dy / dx : dx / dy; + + this.ctx.moveTo(x, y); + var distRemaining = Math.sqrt(dx * dx + dy * dy); + var dashIndex = 0; + while(distRemaining >= 0.1){ + var dashLength = Math.min(distRemaining, dashArray[dashIndex % dashCount]); + var step = Math.sqrt(dashLength * dashLength / (1 + slope * slope)); + if(xSlope){ + if(dx < 0) step = -step; + x += step + y += slope * step; + }else{ + if(dy < 0) step = -step; + x += slope * step; + y += step; + } + + this.ctx[(dashIndex % 2 == 0) ? 'lineTo' : 'moveTo'](x, y); + distRemaining -= dashLength; + dashIndex++; + } + + this.ctx.closePath(); + this.ctx.stroke(); + } + }, + + _dashedLine: { + value: function (fromX, fromY, toX, toY, pattern){ + this.ctx.beginPath(); + // Our growth rate for our line can be one of the following: + // (+,+), (+,-), (-,+), (-,-) + // Because of this, our algorithm needs to understand if the x-coord and + // y-coord should be getting smaller or larger and properly cap the values + // based on (x,y). + var lt = function (a, b) { return a <= b; }; + var gt = function (a, b) { return a >= b; }; + var capmin = function (a, b) { return Math.min(a, b); }; + var capmax = function (a, b) { return Math.max(a, b); }; + + var checkX = { thereYet: gt, cap: capmin }; + var checkY = { thereYet: gt, cap: capmin }; + + if (fromY - toY > 0) { + checkY.thereYet = lt; + checkY.cap = capmax; + } + if (fromX - toX > 0) { + checkX.thereYet = lt; + checkX.cap = capmax; + } + + this.ctx.moveTo(fromX, fromY); + var offsetX = fromX; + var offsetY = fromY; + var idx = 0, dash = true; + while (!(checkX.thereYet(offsetX, toX) && checkY.thereYet(offsetY, toY))) { + var ang = Math.atan2(toY - fromY, toX - fromX); + var len = pattern[idx]; + + offsetX = checkX.cap(toX, offsetX + (Math.cos(ang) * len)); + offsetY = checkY.cap(toY, offsetY + (Math.sin(ang) * len)); + + if (dash) this.ctx.lineTo(offsetX, offsetY); + else this.ctx.moveTo(offsetX, offsetY); + + idx = (idx + 1) % pattern.length; + dash = !dash; + } + this.ctx.stroke(); + } + }, + + _elementName: { + value: function(item) { + return this.application.ninja.elementMediator.getNJProperty(item, "selection"); + } + } + + +}); \ No newline at end of file -- cgit v1.2.3