diff --git a/platform/features/fixed/bundle.js b/platform/features/fixed/bundle.js index edc52d48f6..4dc01d682e 100644 --- a/platform/features/fixed/bundle.js +++ b/platform/features/fixed/bundle.js @@ -142,7 +142,90 @@ define([ "cssClass": "l-input-lg", "required": true } + } + ] + }, + { + "items": [ + { + "property": "editX", + "text": "X", + "name": "X", + "cssClass": "l-input-sm", + "control": "numberfield", + "min": "0" }, + { + "property": "editY", + "text": "Y", + "name": "Y", + "cssClass": "l-input-sm", + "control": "numberfield", + "min": "0" + }, + { + "property": "editX1", + "text": "X1", + "name": "X1", + "cssClass": "l-input-sm", + "control" : "numberfield", + "min": "0" + }, + { + "property": "editY1", + "text": "Y1", + "name": "Y1", + "cssClass": "l-input-sm", + "control" : "numberfield", + "min": "0" + }, + { + "property": "editX2", + "text": "X2", + "name": "X2", + "cssClass": "l-input-sm", + "control" : "numberfield", + "min": "0" + }, + { + "property": "editY2", + "text": "Y2", + "name": "Y2", + "cssClass": "l-input-sm", + "control" : "numberfield", + "min": "0" + }, + { + "property": "editHeight", + "text": "H", + "name": "H", + "cssClass": "l-input-sm", + "control": "numberfield", + "description": "Resize object height", + "min": "1" + }, + { + "property": "editWidth", + "text": "W", + "name": "W", + "cssClass": "l-input-sm", + "control": "numberfield", + "description": "Resize object width", + "min": "1" + } + ] + }, + { + "items": [ + { + "property": "useGrid", + "name": "Snap to Grid", + "control": "checkbox" + } + ] + }, + { + "items": [ { "property": "text", "cssClass": "icon-gear", diff --git a/platform/features/layout/res/templates/elements/line.html b/platform/features/layout/res/templates/elements/line.html index f040a8abc6..402a70bd41 100644 --- a/platform/features/layout/res/templates/elements/line.html +++ b/platform/features/layout/res/templates/elements/line.html @@ -19,12 +19,12 @@ this source code distribution or the Licensing information page available at runtime from the About dialog for additional information. --> - - + diff --git a/platform/features/layout/src/FixedController.js b/platform/features/layout/src/FixedController.js index 613a146974..de3c5a32f6 100644 --- a/platform/features/layout/src/FixedController.js +++ b/platform/features/layout/src/FixedController.js @@ -75,7 +75,7 @@ define( // Convert from element x/y/width/height to an // appropriate ng-style argument, to position elements. function convertPosition(elementProxy) { - var gridSize = self.gridSize; + var gridSize = elementProxy.getGridSize(); // Multiply position/dimensions by grid size return { left: (gridSize[0] * elementProxy.x()) + 'px', @@ -114,6 +114,7 @@ define( self.gridSize = layoutGrid; self.elementProxies.forEach(function (elementProxy) { + elementProxy.setGridSize(self.gridSize); elementProxy.style = convertPosition(elementProxy); }); } @@ -121,7 +122,7 @@ define( // Decorate an element for display function makeProxyElement(element, index, elements) { var ElementProxy = ElementProxies[element.type], - e = ElementProxy && new ElementProxy(element, index, elements); + e = ElementProxy && new ElementProxy(element, index, elements, self.gridSize); if (e) { // Provide a displayable position (convert from grid to px) @@ -254,7 +255,8 @@ define( color: "", titled: true, width: DEFAULT_DIMENSIONS[0], - height: DEFAULT_DIMENSIONS[1] + height: DEFAULT_DIMENSIONS[1], + useGrid: true }); //Re-initialize objects, and subscribe to new object @@ -518,4 +520,3 @@ define( return FixedController; } ); - diff --git a/platform/features/layout/src/FixedDragHandle.js b/platform/features/layout/src/FixedDragHandle.js index ca3f8f78fd..7ff5fb0576 100644 --- a/platform/features/layout/src/FixedDragHandle.js +++ b/platform/features/layout/src/FixedDragHandle.js @@ -47,9 +47,10 @@ define( * @memberof platform/features/layout.FixedDragHandle# */ FixedDragHandle.prototype.style = function () { + var gridSize = this.elementHandle.getGridSize(); // Adjust from grid to pixel coordinates - var x = this.elementHandle.x() * this.gridSize[0], - y = this.elementHandle.y() * this.gridSize[1]; + var x = this.elementHandle.x() * gridSize[0], + y = this.elementHandle.y() * gridSize[1]; // Convert to a CSS style centered on that point return { @@ -78,13 +79,14 @@ define( * started */ FixedDragHandle.prototype.continueDrag = function (delta) { + var gridSize = this.elementHandle.getGridSize(); if (this.dragging) { // Update x/y positions (snapping to grid) this.elementHandle.x( - this.dragging.x + Math.round(delta[0] / this.gridSize[0]) + this.dragging.x + Math.round(delta[0] / gridSize[0]) ); this.elementHandle.y( - this.dragging.y + Math.round(delta[1] / this.gridSize[1]) + this.dragging.y + Math.round(delta[1] / gridSize[1]) ); // Invoke update callback if (this.update) { diff --git a/platform/features/layout/src/FixedProxy.js b/platform/features/layout/src/FixedProxy.js index 8d2c03f7f2..6e62b26249 100644 --- a/platform/features/layout/src/FixedProxy.js +++ b/platform/features/layout/src/FixedProxy.js @@ -61,6 +61,7 @@ define( element.width = element.width || 1; element.height = element.height || 1; element.type = type; + element.useGrid = true; // Finally, add it to the view's configuration addElementCallback(element); diff --git a/platform/features/layout/src/elements/BoxProxy.js b/platform/features/layout/src/elements/BoxProxy.js index c1d61fcc41..a18d8f3fba 100644 --- a/platform/features/layout/src/elements/BoxProxy.js +++ b/platform/features/layout/src/elements/BoxProxy.js @@ -37,10 +37,11 @@ define( * @param element the fixed position element, as stored in its * configuration * @param index the element's index within its array + * @param {number[]} gridSize the current layout grid size in [x,y] from * @param {Array} elements the full array of elements */ - function BoxProxy(element, index, elements) { - var proxy = new ElementProxy(element, index, elements); + function BoxProxy(element, index, elements, gridSize) { + var proxy = new ElementProxy(element, index, elements, gridSize); /** * Get/set this element's fill color. (Omitting the @@ -52,6 +53,12 @@ define( */ proxy.fill = new AccessorMutator(element, 'fill'); + //Expose x,y, width and height for editing + proxy.editWidth = new AccessorMutator(element, 'width'); + proxy.editHeight = new AccessorMutator(element, 'height'); + proxy.editX = new AccessorMutator(element, 'x'); + proxy.editY = new AccessorMutator(element, 'y'); + return proxy; } diff --git a/platform/features/layout/src/elements/ElementProxy.js b/platform/features/layout/src/elements/ElementProxy.js index 7d75219adb..cab7970a41 100644 --- a/platform/features/layout/src/elements/ElementProxy.js +++ b/platform/features/layout/src/elements/ElementProxy.js @@ -21,8 +21,8 @@ *****************************************************************************/ define( - ['./AccessorMutator', './ResizeHandle'], - function (AccessorMutator, ResizeHandle) { + ['./AccessorMutator', './ResizeHandle', './UnitAccessorMutator'], + function (AccessorMutator, ResizeHandle, UnitAccessorMutator) { // Index deltas for changes in order var ORDERS = { @@ -32,6 +32,10 @@ define( bottom: Number.NEGATIVE_INFINITY }; + // Mininmum pixel height and width for objects + var MIN_WIDTH = 10; + var MIN_HEIGHT = 10; + // Ensure a value is non-negative (for x/y setters) function clamp(value) { return Math.max(value, 0); @@ -51,17 +55,29 @@ define( * @param element the fixed position element, as stored in its * configuration * @param index the element's index within its array + * @param {number[]} gridSize the current layout grid size in [x,y] from * @param {Array} elements the full array of elements */ - function ElementProxy(element, index, elements) { - this.resizeHandles = [new ResizeHandle(element, 1, 1)]; - + function ElementProxy(element, index, elements, gridSize) { /** * The element as stored in the view configuration. * @memberof platform/features/layout.ElementProxy# */ this.element = element; + /** + * The current grid size of the layout. + * @memberof platform/features/layout.ElementProxy# + */ + this.gridSize = gridSize || [1,1]; //Ensure a reasonable default + + this.resizeHandles = [new ResizeHandle( + this.element, + this.getMinWidth(), + this.getMinHeight(), + this.getGridSize() + )]; + /** * Get and/or set the x position of this element. * Units are in fixed position grid space. @@ -106,6 +122,8 @@ define( */ this.height = new AccessorMutator(element, 'height'); + this.useGrid = new UnitAccessorMutator(this); + this.index = index; this.elements = elements; } @@ -156,6 +174,51 @@ define( return this.resizeHandles; }; + /** + * Returns which grid size the element is currently using. + * @return {number[]} The current grid size in [x,y] form if the element + * is currently using the grid, [1,1] if it is using + * pixels. + */ + ElementProxy.prototype.getGridSize = function () { + var gridSize; + // Default to using the grid if useGrid was not defined + if (typeof this.element.useGrid === 'undefined') { + this.element.useGrid = true; + } + if (this.element.useGrid) { + gridSize = this.gridSize; + } else { + gridSize = [1,1]; + } + return gridSize; + }; + + /** + * Set the current grid size stored by this element proxy + * @param {number[]} gridSize The current layout grid size in [x,y] form + */ + ElementProxy.prototype.setGridSize = function (gridSize) { + this.gridSize = gridSize; + }; + + /** + * Get the current minimum element width in grid units + * @return {number} The current minimum element width + */ + ElementProxy.prototype.getMinWidth = function () { + return Math.ceil(MIN_WIDTH / this.getGridSize()[0]); + + }; + + /** + * Get the current minimum element height in grid units + * @return {number} The current minimum element height + */ + ElementProxy.prototype.getMinHeight = function () { + return Math.ceil(MIN_HEIGHT / this.getGridSize()[1]); + }; + return ElementProxy; } ); diff --git a/platform/features/layout/src/elements/ImageProxy.js b/platform/features/layout/src/elements/ImageProxy.js index e2a27e64ff..0477d7b444 100644 --- a/platform/features/layout/src/elements/ImageProxy.js +++ b/platform/features/layout/src/elements/ImageProxy.js @@ -36,10 +36,11 @@ define( * configuration * @param index the element's index within its array * @param {Array} elements the full array of elements + * @param {number[]} gridSize the current layout grid size in [x,y] from * @augments {platform/features/layout.ElementProxy} */ - function ImageProxy(element, index, elements) { - var proxy = new ElementProxy(element, index, elements); + function ImageProxy(element, index, elements, gridSize) { + var proxy = new ElementProxy(element, index, elements, gridSize); /** * Get and/or set the displayed text of this element. @@ -49,6 +50,12 @@ define( */ proxy.url = new AccessorMutator(element, 'url'); + //Expose x,y, width and height properties for editing + proxy.editWidth = new AccessorMutator(element, 'width'); + proxy.editHeight = new AccessorMutator(element, 'height'); + proxy.editX = new AccessorMutator(element, 'x'); + proxy.editY = new AccessorMutator(element, 'y'); + return proxy; } diff --git a/platform/features/layout/src/elements/LineHandle.js b/platform/features/layout/src/elements/LineHandle.js index d51d5b4631..d9c30238e2 100644 --- a/platform/features/layout/src/elements/LineHandle.js +++ b/platform/features/layout/src/elements/LineHandle.js @@ -35,14 +35,16 @@ define( * @param {string} yProperty field which stores x position * @param {string} xOther field which stores x of other end * @param {string} yOther field which stores y of other end + * @param {number[]} gridSize the current layout grid size in [x,y] from * @implements {platform/features/layout.ElementHandle} */ - function LineHandle(element, xProperty, yProperty, xOther, yOther) { + function LineHandle(element, xProperty, yProperty, xOther, yOther, gridSize) { this.element = element; this.xProperty = xProperty; this.yProperty = yProperty; this.xOther = xOther; this.yOther = yOther; + this.gridSize = gridSize; } LineHandle.prototype.x = function (value) { @@ -83,6 +85,10 @@ define( return element[yProperty]; }; + LineHandle.prototype.getGridSize = function () { + return this.gridSize; + }; + return LineHandle; } diff --git a/platform/features/layout/src/elements/LineProxy.js b/platform/features/layout/src/elements/LineProxy.js index 92d19c0db3..f1cebfa78b 100644 --- a/platform/features/layout/src/elements/LineProxy.js +++ b/platform/features/layout/src/elements/LineProxy.js @@ -21,8 +21,8 @@ *****************************************************************************/ define( - ['./ElementProxy', './LineHandle'], - function (ElementProxy, LineHandle) { + ['./ElementProxy', './LineHandle', './AccessorMutator'], + function (ElementProxy, LineHandle, AccessorMutator) { /** * Selection/diplay proxy for line elements of a fixed position @@ -33,13 +33,14 @@ define( * configuration * @param index the element's index within its array * @param {Array} elements the full array of elements + * @param {number[]} gridSize the current layout grid size in [x,y] from * @augments {platform/features/layout.ElementProxy} */ - function LineProxy(element, index, elements) { - var proxy = new ElementProxy(element, index, elements), + function LineProxy(element, index, elements, gridSize) { + var proxy = new ElementProxy(element, index, elements, gridSize), handles = [ - new LineHandle(element, 'x', 'y', 'x2', 'y2'), - new LineHandle(element, 'x2', 'y2', 'x', 'y') + new LineHandle(element, 'x', 'y', 'x2', 'y2', proxy.getGridSize()), + new LineHandle(element, 'x2', 'y2', 'x', 'y', proxy.getGridSize()) ]; /** @@ -148,6 +149,12 @@ define( return handles; }; + // Expose endpoint coordinates for editing + proxy.editX1 = new AccessorMutator(element, 'x'); + proxy.editY1 = new AccessorMutator(element, 'y'); + proxy.editX2 = new AccessorMutator(element, 'x2'); + proxy.editY2 = new AccessorMutator(element, 'y2'); + return proxy; } diff --git a/platform/features/layout/src/elements/ResizeHandle.js b/platform/features/layout/src/elements/ResizeHandle.js index 7c5d7384db..f2c3526bf1 100644 --- a/platform/features/layout/src/elements/ResizeHandle.js +++ b/platform/features/layout/src/elements/ResizeHandle.js @@ -35,12 +35,14 @@ define( * @memberof platform/features/layout * @constructor */ - function ResizeHandle(element, minWidth, minHeight) { + function ResizeHandle(element, minWidth, minHeight, gridSize) { this.element = element; // Ensure reasonable defaults this.minWidth = minWidth || 0; this.minHeight = minHeight || 0; + + this.gridSize = gridSize; } ResizeHandle.prototype.x = function (value) { @@ -65,6 +67,10 @@ define( return element.y + element.height; }; + ResizeHandle.prototype.getGridSize = function () { + return this.gridSize; + }; + return ResizeHandle; } diff --git a/platform/features/layout/src/elements/TelemetryProxy.js b/platform/features/layout/src/elements/TelemetryProxy.js index 2841e59f51..bff852af9e 100644 --- a/platform/features/layout/src/elements/TelemetryProxy.js +++ b/platform/features/layout/src/elements/TelemetryProxy.js @@ -39,10 +39,11 @@ define( * configuration * @param index the element's index within its array * @param {Array} elements the full array of elements + * @param {number[]} gridSize the current layout grid size in [x,y] form * @augments {platform/features/layout.ElementProxy} */ - function TelemetryProxy(element, index, elements) { - var proxy = new TextProxy(element, index, elements); + function TelemetryProxy(element, index, elements, gridSize) { + var proxy = new TextProxy(element, index, elements, gridSize); // Toggle the visibility of the title function toggle() { diff --git a/platform/features/layout/src/elements/TextProxy.js b/platform/features/layout/src/elements/TextProxy.js index 4d76d9d896..939c88c5ef 100644 --- a/platform/features/layout/src/elements/TextProxy.js +++ b/platform/features/layout/src/elements/TextProxy.js @@ -36,10 +36,11 @@ define( * configuration * @param index the element's index within its array * @param {Array} elements the full array of elements + * @param {number[]} gridSize the current layout grid size in [x,y] from * @augments {platform/features/layout.ElementProxy} */ - function TextProxy(element, index, elements) { - var proxy = new BoxProxy(element, index, elements); + function TextProxy(element, index, elements, gridSize) { + var proxy = new BoxProxy(element, index, elements, gridSize); /** * Get and/or set the text color of this element. diff --git a/platform/features/layout/src/elements/UnitAccessorMutator.js b/platform/features/layout/src/elements/UnitAccessorMutator.js new file mode 100644 index 0000000000..c0b6d5c58f --- /dev/null +++ b/platform/features/layout/src/elements/UnitAccessorMutator.js @@ -0,0 +1,92 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2017, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ + +define( + [], + function () { + + /** + * Variant of AccessorMutator to handle the specific case of updating + * useGrid, in order update the positions appropriately from within + * the scope of UnitAccessorMutator + * + * @memberof platform/features/layout + * @constructor + * @param {ElementProxy} proxy ElementProxy object to perform the update + * upon + */ + function UnitAccessorMutator(elementProxy) { + var self = this; + + this.elementProxy = elementProxy; + return function (useGrid) { + var current = elementProxy.element.useGrid; + if (arguments.length > 0) { + elementProxy.element.useGrid = useGrid; + if (useGrid && !current) { + self.convertCoordsTo('grid'); + } else if (!useGrid && current) { + self.convertCoordsTo('px'); + } + } + + return elementProxy.element.useGrid; + }; + } + + /** + * For the elementProxy object called upon, convert its element's + * coordinates and size from pixels to grid units, or vice-versa. + * @param {string} unit When called with 'px', converts grid units to + * pixels; when called with 'grid', snaps element + * to grid units + */ + UnitAccessorMutator.prototype.convertCoordsTo = function (unit) { + var proxy = this.elementProxy, + gridSize = proxy.gridSize, + element = proxy.element, + minWidth = proxy.getMinWidth(), + minHeight = proxy.getMinHeight(); + if (unit === 'px') { + element.x = element.x * gridSize[0]; + element.y = element.y * gridSize[1]; + element.width = element.width * gridSize[0]; + element.height = element.height * gridSize[1]; + if (element.x2 && element.y2) { + element.x2 = element.x2 * gridSize[0]; + element.y2 = element.y2 * gridSize[1]; + } + } else if (unit === 'grid') { + element.x = Math.round(element.x / gridSize[0]); + element.y = Math.round(element.y / gridSize[1]); + element.width = Math.max(Math.round(element.width / gridSize[0]), minWidth); + element.height = Math.max(Math.round(element.height / gridSize[1]), minHeight); + if (element.x2 && element.y2) { + element.x2 = Math.round(element.x2 / gridSize[0]); + element.y2 = Math.round(element.y2 / gridSize[1]); + } + } + }; + + return UnitAccessorMutator; + } +); diff --git a/platform/features/layout/test/FixedControllerSpec.js b/platform/features/layout/test/FixedControllerSpec.js index f2c4ed9494..8849fb00e6 100644 --- a/platform/features/layout/test/FixedControllerSpec.js +++ b/platform/features/layout/test/FixedControllerSpec.js @@ -157,9 +157,9 @@ define( }; testValues = { a: 10, b: 42, c: 31.42 }; testConfiguration = { elements: [ - { type: "fixed.telemetry", id: 'a', x: 1, y: 1 }, - { type: "fixed.telemetry", id: 'b', x: 1, y: 1 }, - { type: "fixed.telemetry", id: 'c', x: 1, y: 1 } + { type: "fixed.telemetry", id: 'a', x: 1, y: 1, useGrid: true}, + { type: "fixed.telemetry", id: 'b', x: 1, y: 1, useGrid: true}, + { type: "fixed.telemetry", id: 'c', x: 1, y: 1, useGrid: true} ]}; mockChildren = testModel.composition.map(makeMockDomainObject); diff --git a/platform/features/layout/test/FixedDragHandleSpec.js b/platform/features/layout/test/FixedDragHandleSpec.js index 930df524cc..fde2dda2e8 100644 --- a/platform/features/layout/test/FixedDragHandleSpec.js +++ b/platform/features/layout/test/FixedDragHandleSpec.js @@ -35,13 +35,14 @@ define( beforeEach(function () { mockElementHandle = jasmine.createSpyObj( 'elementHandle', - ['x', 'y'] + ['x', 'y','getGridSize'] ); mockUpdate = jasmine.createSpy('update'); mockCommit = jasmine.createSpy('commit'); mockElementHandle.x.andReturn(6); mockElementHandle.y.andReturn(8); + mockElementHandle.getGridSize.andReturn(TEST_GRID_SIZE); handle = new FixedDragHandle( mockElementHandle, diff --git a/platform/features/layout/test/FixedProxySpec.js b/platform/features/layout/test/FixedProxySpec.js index 9d70191b50..a91607208f 100644 --- a/platform/features/layout/test/FixedProxySpec.js +++ b/platform/features/layout/test/FixedProxySpec.js @@ -61,7 +61,8 @@ define( x: 0, y: 0, width: 1, - height: 1 + height: 1, + useGrid: true }); }); diff --git a/platform/features/layout/test/elements/ElementProxySpec.js b/platform/features/layout/test/elements/ElementProxySpec.js index 74eeef249c..6248af2328 100644 --- a/platform/features/layout/test/elements/ElementProxySpec.js +++ b/platform/features/layout/test/elements/ElementProxySpec.js @@ -35,13 +35,15 @@ define( y: 2, stroke: '#717171', width: 42, - height: 24 + height: 24, + useGrid: true }; testElements = [{}, {}, testElement, {}]; proxy = new ElementProxy( testElement, testElements.indexOf(testElement), - testElements + testElements, + [13,21] ); }); @@ -73,6 +75,29 @@ define( expect(proxy.x()).toEqual(0); expect(proxy.y()).toEqual(0); }); + + it("allows modifying the current grid size", function () { + proxy.setGridSize([112,420]); + expect(proxy.gridSize).toEqual([112,420]); + }); + + it("returns the current grid size only if the element snaps to grid", function () { + expect(proxy.getGridSize()).toEqual([13,21]); + proxy.useGrid(false); + expect(proxy.getGridSize()).toEqual([1,1]); + }); + + it("returns the mininum height and width of an element currently used units", function () { + // Assumes mininum height and width are 10, in pixels + expect(proxy.getMinWidth()).toEqual(1); + expect(proxy.getMinHeight()).toEqual(1); + proxy.setGridSize([7,4]); + expect(proxy.getMinWidth()).toEqual(2); + expect(proxy.getMinHeight()).toEqual(3); + proxy.useGrid(false); + expect(proxy.getMinWidth()).toEqual(10); + expect(proxy.getMinHeight()).toEqual(10); + }); }); } ); diff --git a/platform/features/layout/test/elements/LineHandleSpec.js b/platform/features/layout/test/elements/LineHandleSpec.js index 36fb582e8a..69dfff61ca 100644 --- a/platform/features/layout/test/elements/LineHandleSpec.js +++ b/platform/features/layout/test/elements/LineHandleSpec.js @@ -33,10 +33,11 @@ define( x: 3, y: 42, x2: 8, - y2: 11 + y2: 11, + useGrid: true }; - handle = new LineHandle(testElement, 'x', 'y', 'x2', 'y2'); + handle = new LineHandle(testElement, 'x', 'y', 'x2', 'y2', [45,21]); }); it("provides x/y grid coordinates for its corner", function () { @@ -67,6 +68,9 @@ define( expect(testElement.y).not.toEqual(testElement.y2); }); + it("returns the correct grid size", function () { + expect(handle.getGridSize()).toEqual([45,21]); + }); }); } diff --git a/platform/features/layout/test/elements/LineProxySpec.js b/platform/features/layout/test/elements/LineProxySpec.js index 088592b9f8..95ce1b35b0 100644 --- a/platform/features/layout/test/elements/LineProxySpec.js +++ b/platform/features/layout/test/elements/LineProxySpec.js @@ -28,10 +28,10 @@ define( var vertical, horizontal, diagonal, reversed; beforeEach(function () { - vertical = { x: 1, y: 4, x2: 1, y2: 8 }; - horizontal = { x: 3, y: 3, x2: 12, y2: 3 }; - diagonal = { x: 3, y: 8, x2: 5, y2: 11 }; - reversed = { x2: 3, y2: 8, x: 5, y: 11 }; + vertical = { x: 1, y: 4, x2: 1, y2: 8}; + horizontal = { x: 3, y: 3, x2: 12, y2: 3}; + diagonal = { x: 3, y: 8, x2: 5, y2: 11}; + reversed = { x2: 3, y2: 8, x: 5, y: 11}; }); it("ensures visible width for vertical lines", function () { @@ -63,13 +63,13 @@ define( it("adjusts both ends when mutating x", function () { var proxy = new LineProxy(diagonal); proxy.x(6); - expect(diagonal).toEqual({ x: 6, y: 8, x2: 8, y2: 11 }); + expect(diagonal).toEqual({ x: 6, y: 8, x2: 8, y2: 11, useGrid: true }); }); it("adjusts both ends when mutating y", function () { var proxy = new LineProxy(diagonal); proxy.y(6); - expect(diagonal).toEqual({ x: 3, y: 6, x2: 5, y2: 9 }); + expect(diagonal).toEqual({ x: 3, y: 6, x2: 5, y2: 9, useGrid: true }); }); it("provides internal positions for SVG lines", function () { diff --git a/platform/features/layout/test/elements/ResizeHandleSpec.js b/platform/features/layout/test/elements/ResizeHandleSpec.js index def167e98e..2af54caa89 100644 --- a/platform/features/layout/test/elements/ResizeHandleSpec.js +++ b/platform/features/layout/test/elements/ResizeHandleSpec.js @@ -24,7 +24,8 @@ define( ['../../src/elements/ResizeHandle'], function (ResizeHandle) { - var TEST_MIN_WIDTH = 4, TEST_MIN_HEIGHT = 2; + var TEST_MIN_WIDTH = 4, + TEST_MIN_HEIGHT = 2; describe("A fixed position drag handle", function () { var testElement, @@ -35,13 +36,15 @@ define( x: 3, y: 42, width: 30, - height: 36 + height: 36, + useGrid: true }; handle = new ResizeHandle( testElement, TEST_MIN_WIDTH, - TEST_MIN_HEIGHT + TEST_MIN_HEIGHT, + [34,81] ); }); @@ -73,6 +76,10 @@ define( expect(testElement.height).toEqual(TEST_MIN_HEIGHT); }); + it("returns the correct grid size", function () { + expect(handle.getGridSize()).toEqual([34,81]); + }); + }); } ); diff --git a/platform/features/layout/test/elements/UnitAccessorMutatorSpec.js b/platform/features/layout/test/elements/UnitAccessorMutatorSpec.js new file mode 100644 index 0000000000..68b24b8eb1 --- /dev/null +++ b/platform/features/layout/test/elements/UnitAccessorMutatorSpec.js @@ -0,0 +1,157 @@ +/***************************************************************************** + * Open MCT, Copyright (c) 2014-2017, United States Government + * as represented by the Administrator of the National Aeronautics and Space + * Administration. All rights reserved. + * + * Open MCT is licensed under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + * Open MCT includes source code licensed under additional open source + * licenses. See the Open Source Licenses file (LICENSES.md) included with + * this source code distribution or the Licensing information page available + * at runtime from the About dialog for additional information. + *****************************************************************************/ + +define( + ['../../src/elements/UnitAccessorMutator'], + function (UnitAccessorMutator) { + + var GRID_SIZE = [13,17]; + + describe("An elementProxy.gridSize accessor-mutator", function () { + var mockElementProxy, + testElement, + mockLineProxy, + testLine, + uAM, + uAMLine; + + beforeEach(function () { + testElement = { + x: 2, + y: 3, + width: 4, + height: 5, + useGrid: true + }; + + mockElementProxy = { + element: testElement, + gridSize: GRID_SIZE, + getMinHeight: jasmine.createSpy('minHeight'), + getMinWidth: jasmine.createSpy('minWidth') + }; + + testLine = { + x: 7, + y: 8, + x2: 9, + y2: 10, + width: 11, + height: 12, + useGrid: true + }; + + mockLineProxy = { + element: testLine, + gridSize: GRID_SIZE, + getMinHeight: jasmine.createSpy('minHeight'), + getMinWidth: jasmine.createSpy('minWidth') + }; + + + + uAM = new UnitAccessorMutator(mockElementProxy); + uAMLine = new UnitAccessorMutator(mockLineProxy); + + mockElementProxy.getMinWidth.andReturn(1); + mockElementProxy.getMinHeight.andReturn(1); + + mockLineProxy.getMinWidth.andReturn(1); + mockLineProxy.getMinHeight.andReturn(1); + }); + + it("allows access to useGrid", function () { + expect(uAM()).toEqual(mockElementProxy.element.useGrid); + }); + + it("allows mutation of useGrid", function () { + uAM(false); + expect(mockElementProxy.element.useGrid).toEqual(false); + }); + + it("converts coordinates appropriately for a box", function () { + uAM(false); + expect(mockElementProxy.element.x).toEqual(26); + expect(mockElementProxy.element.y).toEqual(51); + expect(mockElementProxy.element.width).toEqual(52); + expect(mockElementProxy.element.height).toEqual(85); + uAM(true); + expect(mockElementProxy.element.x).toEqual(2); + expect(mockElementProxy.element.y).toEqual(3); + expect(mockElementProxy.element.width).toEqual(4); + expect(mockElementProxy.element.height).toEqual(5); + }); + + it("converts coordinates appropriately for a line", function () { + uAMLine(false); + expect(mockLineProxy.element.x).toEqual(91); + expect(mockLineProxy.element.y).toEqual(136); + expect(mockLineProxy.element.x2).toEqual(117); + expect(mockLineProxy.element.y2).toEqual(170); + expect(mockLineProxy.element.width).toEqual(143); + expect(mockLineProxy.element.height).toEqual(204); + uAMLine(true); + expect(mockLineProxy.element.x).toEqual(7); + expect(mockLineProxy.element.y).toEqual(8); + expect(mockLineProxy.element.x2).toEqual(9); + expect(mockLineProxy.element.y2).toEqual(10); + expect(mockLineProxy.element.width).toEqual(11); + expect(mockLineProxy.element.height).toEqual(12); + }); + + it("doesn't covert coordinates unecessarily", function () { + uAM(false); + expect(mockElementProxy.element.x).toEqual(26); + expect(mockElementProxy.element.y).toEqual(51); + expect(mockElementProxy.element.width).toEqual(52); + expect(mockElementProxy.element.height).toEqual(85); + uAM(false); + expect(mockElementProxy.element.x).toEqual(26); + expect(mockElementProxy.element.y).toEqual(51); + expect(mockElementProxy.element.width).toEqual(52); + expect(mockElementProxy.element.height).toEqual(85); + }); + + it("snaps coordinates onto the grid", function () { + uAM(false); + mockElementProxy.element.x += 11; + mockElementProxy.element.y -= 27; + mockElementProxy.element.width -= 14; + mockElementProxy.element.height += 4; + uAM(true); + expect(mockElementProxy.element.x).toEqual(3); + expect(mockElementProxy.element.y).toEqual(1); + expect(mockElementProxy.element.width).toEqual(3); + expect(mockElementProxy.element.height).toEqual(5); + }); + + it("enforces a minimum height and width", function () { + uAM(false); + mockElementProxy.element.width = 4; + mockElementProxy.element.height = 4; + uAM(true); + expect(mockElementProxy.element.width).toEqual(1); + expect(mockElementProxy.element.height).toEqual(1); + }); + }); + } +);