Merge pull request #1634 from nasa/open1405

[Fixed Position] Add numerical inputs for size and position of elements
This commit is contained in:
Pete Richards 2017-07-05 11:45:36 -07:00 committed by GitHub
commit 318aecb7bc
22 changed files with 525 additions and 53 deletions

View File

@ -142,7 +142,90 @@ define([
"cssClass": "l-input-lg", "cssClass": "l-input-lg",
"required": true "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", "property": "text",
"cssClass": "icon-gear", "cssClass": "icon-gear",

View File

@ -19,12 +19,12 @@
this source code distribution or the Licensing information page available this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information. at runtime from the About dialog for additional information.
--> -->
<svg ng-attr-width="{{parameters.gridSize[0] * ngModel.width()}}" <svg ng-attr-width="{{ngModel.getGridSize()[0] * ngModel.width()}}"
ng-attr-height="{{parameters.gridSize[1] * ngModel.height()}}"> ng-attr-height="{{ngModel.getGridSize()[1] * ngModel.height()}}">
<line ng-attr-x1="{{parameters.gridSize[0] * ngModel.x1() + 1}}" <line ng-attr-x1="{{ngModel.getGridSize()[0] * ngModel.x1() + 1}}"
ng-attr-y1="{{parameters.gridSize[1] * ngModel.y1() + 1}}" ng-attr-y1="{{ngModel.getGridSize()[1] * ngModel.y1() + 1}}"
ng-attr-x2="{{parameters.gridSize[0] * ngModel.x2() + 1}}" ng-attr-x2="{{ngModel.getGridSize()[0] * ngModel.x2() + 1}}"
ng-attr-y2="{{parameters.gridSize[1] * ngModel.y2() + 1}}" ng-attr-y2="{{ngModel.getGridSize()[1] * ngModel.y2() + 1}}"
ng-attr-stroke="{{ngModel.stroke()}}" ng-attr-stroke="{{ngModel.stroke()}}"
stroke-width="2"> stroke-width="2">
</line> </line>

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -75,7 +75,7 @@ define(
// Convert from element x/y/width/height to an // Convert from element x/y/width/height to an
// appropriate ng-style argument, to position elements. // appropriate ng-style argument, to position elements.
function convertPosition(elementProxy) { function convertPosition(elementProxy) {
var gridSize = self.gridSize; var gridSize = elementProxy.getGridSize();
// Multiply position/dimensions by grid size // Multiply position/dimensions by grid size
return { return {
left: (gridSize[0] * elementProxy.x()) + 'px', left: (gridSize[0] * elementProxy.x()) + 'px',
@ -114,6 +114,7 @@ define(
self.gridSize = layoutGrid; self.gridSize = layoutGrid;
self.elementProxies.forEach(function (elementProxy) { self.elementProxies.forEach(function (elementProxy) {
elementProxy.setGridSize(self.gridSize);
elementProxy.style = convertPosition(elementProxy); elementProxy.style = convertPosition(elementProxy);
}); });
} }
@ -121,7 +122,7 @@ define(
// Decorate an element for display // Decorate an element for display
function makeProxyElement(element, index, elements) { function makeProxyElement(element, index, elements) {
var ElementProxy = ElementProxies[element.type], var ElementProxy = ElementProxies[element.type],
e = ElementProxy && new ElementProxy(element, index, elements); e = ElementProxy && new ElementProxy(element, index, elements, self.gridSize);
if (e) { if (e) {
// Provide a displayable position (convert from grid to px) // Provide a displayable position (convert from grid to px)
@ -254,7 +255,8 @@ define(
color: "", color: "",
titled: true, titled: true,
width: DEFAULT_DIMENSIONS[0], width: DEFAULT_DIMENSIONS[0],
height: DEFAULT_DIMENSIONS[1] height: DEFAULT_DIMENSIONS[1],
useGrid: true
}); });
//Re-initialize objects, and subscribe to new object //Re-initialize objects, and subscribe to new object
@ -518,4 +520,3 @@ define(
return FixedController; return FixedController;
} }
); );

View File

@ -47,9 +47,10 @@ define(
* @memberof platform/features/layout.FixedDragHandle# * @memberof platform/features/layout.FixedDragHandle#
*/ */
FixedDragHandle.prototype.style = function () { FixedDragHandle.prototype.style = function () {
var gridSize = this.elementHandle.getGridSize();
// Adjust from grid to pixel coordinates // Adjust from grid to pixel coordinates
var x = this.elementHandle.x() * this.gridSize[0], var x = this.elementHandle.x() * gridSize[0],
y = this.elementHandle.y() * this.gridSize[1]; y = this.elementHandle.y() * gridSize[1];
// Convert to a CSS style centered on that point // Convert to a CSS style centered on that point
return { return {
@ -78,13 +79,14 @@ define(
* started * started
*/ */
FixedDragHandle.prototype.continueDrag = function (delta) { FixedDragHandle.prototype.continueDrag = function (delta) {
var gridSize = this.elementHandle.getGridSize();
if (this.dragging) { if (this.dragging) {
// Update x/y positions (snapping to grid) // Update x/y positions (snapping to grid)
this.elementHandle.x( 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.elementHandle.y(
this.dragging.y + Math.round(delta[1] / this.gridSize[1]) this.dragging.y + Math.round(delta[1] / gridSize[1])
); );
// Invoke update callback // Invoke update callback
if (this.update) { if (this.update) {

View File

@ -61,6 +61,7 @@ define(
element.width = element.width || 1; element.width = element.width || 1;
element.height = element.height || 1; element.height = element.height || 1;
element.type = type; element.type = type;
element.useGrid = true;
// Finally, add it to the view's configuration // Finally, add it to the view's configuration
addElementCallback(element); addElementCallback(element);

View File

@ -37,10 +37,11 @@ define(
* @param element the fixed position element, as stored in its * @param element the fixed position element, as stored in its
* configuration * configuration
* @param index the element's index within its array * @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 * @param {Array} elements the full array of elements
*/ */
function BoxProxy(element, index, elements) { function BoxProxy(element, index, elements, gridSize) {
var proxy = new ElementProxy(element, index, elements); var proxy = new ElementProxy(element, index, elements, gridSize);
/** /**
* Get/set this element's fill color. (Omitting the * Get/set this element's fill color. (Omitting the
@ -52,6 +53,12 @@ define(
*/ */
proxy.fill = new AccessorMutator(element, 'fill'); 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; return proxy;
} }

View File

@ -21,8 +21,8 @@
*****************************************************************************/ *****************************************************************************/
define( define(
['./AccessorMutator', './ResizeHandle'], ['./AccessorMutator', './ResizeHandle', './UnitAccessorMutator'],
function (AccessorMutator, ResizeHandle) { function (AccessorMutator, ResizeHandle, UnitAccessorMutator) {
// Index deltas for changes in order // Index deltas for changes in order
var ORDERS = { var ORDERS = {
@ -32,6 +32,10 @@ define(
bottom: Number.NEGATIVE_INFINITY 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) // Ensure a value is non-negative (for x/y setters)
function clamp(value) { function clamp(value) {
return Math.max(value, 0); return Math.max(value, 0);
@ -51,17 +55,29 @@ define(
* @param element the fixed position element, as stored in its * @param element the fixed position element, as stored in its
* configuration * configuration
* @param index the element's index within its array * @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 * @param {Array} elements the full array of elements
*/ */
function ElementProxy(element, index, elements) { function ElementProxy(element, index, elements, gridSize) {
this.resizeHandles = [new ResizeHandle(element, 1, 1)];
/** /**
* The element as stored in the view configuration. * The element as stored in the view configuration.
* @memberof platform/features/layout.ElementProxy# * @memberof platform/features/layout.ElementProxy#
*/ */
this.element = element; 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. * Get and/or set the x position of this element.
* Units are in fixed position grid space. * Units are in fixed position grid space.
@ -106,6 +122,8 @@ define(
*/ */
this.height = new AccessorMutator(element, 'height'); this.height = new AccessorMutator(element, 'height');
this.useGrid = new UnitAccessorMutator(this);
this.index = index; this.index = index;
this.elements = elements; this.elements = elements;
} }
@ -156,6 +174,51 @@ define(
return this.resizeHandles; 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; return ElementProxy;
} }
); );

View File

@ -36,10 +36,11 @@ define(
* configuration * configuration
* @param index the element's index within its array * @param index the element's index within its array
* @param {Array} elements the full array of elements * @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} * @augments {platform/features/layout.ElementProxy}
*/ */
function ImageProxy(element, index, elements) { function ImageProxy(element, index, elements, gridSize) {
var proxy = new ElementProxy(element, index, elements); var proxy = new ElementProxy(element, index, elements, gridSize);
/** /**
* Get and/or set the displayed text of this element. * Get and/or set the displayed text of this element.
@ -49,6 +50,12 @@ define(
*/ */
proxy.url = new AccessorMutator(element, 'url'); 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; return proxy;
} }

View File

@ -35,14 +35,16 @@ define(
* @param {string} yProperty field which stores x position * @param {string} yProperty field which stores x position
* @param {string} xOther field which stores x of other end * @param {string} xOther field which stores x of other end
* @param {string} yOther field which stores y 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} * @implements {platform/features/layout.ElementHandle}
*/ */
function LineHandle(element, xProperty, yProperty, xOther, yOther) { function LineHandle(element, xProperty, yProperty, xOther, yOther, gridSize) {
this.element = element; this.element = element;
this.xProperty = xProperty; this.xProperty = xProperty;
this.yProperty = yProperty; this.yProperty = yProperty;
this.xOther = xOther; this.xOther = xOther;
this.yOther = yOther; this.yOther = yOther;
this.gridSize = gridSize;
} }
LineHandle.prototype.x = function (value) { LineHandle.prototype.x = function (value) {
@ -83,6 +85,10 @@ define(
return element[yProperty]; return element[yProperty];
}; };
LineHandle.prototype.getGridSize = function () {
return this.gridSize;
};
return LineHandle; return LineHandle;
} }

View File

@ -21,8 +21,8 @@
*****************************************************************************/ *****************************************************************************/
define( define(
['./ElementProxy', './LineHandle'], ['./ElementProxy', './LineHandle', './AccessorMutator'],
function (ElementProxy, LineHandle) { function (ElementProxy, LineHandle, AccessorMutator) {
/** /**
* Selection/diplay proxy for line elements of a fixed position * Selection/diplay proxy for line elements of a fixed position
@ -33,13 +33,14 @@ define(
* configuration * configuration
* @param index the element's index within its array * @param index the element's index within its array
* @param {Array} elements the full array of elements * @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} * @augments {platform/features/layout.ElementProxy}
*/ */
function LineProxy(element, index, elements) { function LineProxy(element, index, elements, gridSize) {
var proxy = new ElementProxy(element, index, elements), var proxy = new ElementProxy(element, index, elements, gridSize),
handles = [ handles = [
new LineHandle(element, 'x', 'y', 'x2', 'y2'), new LineHandle(element, 'x', 'y', 'x2', 'y2', proxy.getGridSize()),
new LineHandle(element, 'x2', 'y2', 'x', 'y') new LineHandle(element, 'x2', 'y2', 'x', 'y', proxy.getGridSize())
]; ];
/** /**
@ -148,6 +149,12 @@ define(
return handles; 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; return proxy;
} }

View File

@ -35,12 +35,14 @@ define(
* @memberof platform/features/layout * @memberof platform/features/layout
* @constructor * @constructor
*/ */
function ResizeHandle(element, minWidth, minHeight) { function ResizeHandle(element, minWidth, minHeight, gridSize) {
this.element = element; this.element = element;
// Ensure reasonable defaults // Ensure reasonable defaults
this.minWidth = minWidth || 0; this.minWidth = minWidth || 0;
this.minHeight = minHeight || 0; this.minHeight = minHeight || 0;
this.gridSize = gridSize;
} }
ResizeHandle.prototype.x = function (value) { ResizeHandle.prototype.x = function (value) {
@ -65,6 +67,10 @@ define(
return element.y + element.height; return element.y + element.height;
}; };
ResizeHandle.prototype.getGridSize = function () {
return this.gridSize;
};
return ResizeHandle; return ResizeHandle;
} }

View File

@ -39,10 +39,11 @@ define(
* configuration * configuration
* @param index the element's index within its array * @param index the element's index within its array
* @param {Array} elements the full array of elements * @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} * @augments {platform/features/layout.ElementProxy}
*/ */
function TelemetryProxy(element, index, elements) { function TelemetryProxy(element, index, elements, gridSize) {
var proxy = new TextProxy(element, index, elements); var proxy = new TextProxy(element, index, elements, gridSize);
// Toggle the visibility of the title // Toggle the visibility of the title
function toggle() { function toggle() {

View File

@ -36,10 +36,11 @@ define(
* configuration * configuration
* @param index the element's index within its array * @param index the element's index within its array
* @param {Array} elements the full array of elements * @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} * @augments {platform/features/layout.ElementProxy}
*/ */
function TextProxy(element, index, elements) { function TextProxy(element, index, elements, gridSize) {
var proxy = new BoxProxy(element, index, elements); var proxy = new BoxProxy(element, index, elements, gridSize);
/** /**
* Get and/or set the text color of this element. * Get and/or set the text color of this element.

View File

@ -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;
}
);

View File

@ -157,9 +157,9 @@ define(
}; };
testValues = { a: 10, b: 42, c: 31.42 }; testValues = { a: 10, b: 42, c: 31.42 };
testConfiguration = { elements: [ testConfiguration = { elements: [
{ type: "fixed.telemetry", id: 'a', x: 1, y: 1 }, { type: "fixed.telemetry", id: 'a', x: 1, y: 1, useGrid: true},
{ type: "fixed.telemetry", id: 'b', x: 1, y: 1 }, { type: "fixed.telemetry", id: 'b', x: 1, y: 1, useGrid: true},
{ type: "fixed.telemetry", id: 'c', x: 1, y: 1 } { type: "fixed.telemetry", id: 'c', x: 1, y: 1, useGrid: true}
]}; ]};
mockChildren = testModel.composition.map(makeMockDomainObject); mockChildren = testModel.composition.map(makeMockDomainObject);

View File

@ -35,13 +35,14 @@ define(
beforeEach(function () { beforeEach(function () {
mockElementHandle = jasmine.createSpyObj( mockElementHandle = jasmine.createSpyObj(
'elementHandle', 'elementHandle',
['x', 'y'] ['x', 'y','getGridSize']
); );
mockUpdate = jasmine.createSpy('update'); mockUpdate = jasmine.createSpy('update');
mockCommit = jasmine.createSpy('commit'); mockCommit = jasmine.createSpy('commit');
mockElementHandle.x.andReturn(6); mockElementHandle.x.andReturn(6);
mockElementHandle.y.andReturn(8); mockElementHandle.y.andReturn(8);
mockElementHandle.getGridSize.andReturn(TEST_GRID_SIZE);
handle = new FixedDragHandle( handle = new FixedDragHandle(
mockElementHandle, mockElementHandle,

View File

@ -61,7 +61,8 @@ define(
x: 0, x: 0,
y: 0, y: 0,
width: 1, width: 1,
height: 1 height: 1,
useGrid: true
}); });
}); });

View File

@ -35,13 +35,15 @@ define(
y: 2, y: 2,
stroke: '#717171', stroke: '#717171',
width: 42, width: 42,
height: 24 height: 24,
useGrid: true
}; };
testElements = [{}, {}, testElement, {}]; testElements = [{}, {}, testElement, {}];
proxy = new ElementProxy( proxy = new ElementProxy(
testElement, testElement,
testElements.indexOf(testElement), testElements.indexOf(testElement),
testElements testElements,
[13,21]
); );
}); });
@ -73,6 +75,29 @@ define(
expect(proxy.x()).toEqual(0); expect(proxy.x()).toEqual(0);
expect(proxy.y()).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);
});
}); });
} }
); );

View File

@ -33,10 +33,11 @@ define(
x: 3, x: 3,
y: 42, y: 42,
x2: 8, 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 () { it("provides x/y grid coordinates for its corner", function () {
@ -67,6 +68,9 @@ define(
expect(testElement.y).not.toEqual(testElement.y2); expect(testElement.y).not.toEqual(testElement.y2);
}); });
it("returns the correct grid size", function () {
expect(handle.getGridSize()).toEqual([45,21]);
});
}); });
} }

View File

@ -28,10 +28,10 @@ define(
var vertical, horizontal, diagonal, reversed; var vertical, horizontal, diagonal, reversed;
beforeEach(function () { beforeEach(function () {
vertical = { x: 1, y: 4, x2: 1, y2: 8 }; vertical = { x: 1, y: 4, x2: 1, y2: 8};
horizontal = { x: 3, y: 3, x2: 12, y2: 3 }; horizontal = { x: 3, y: 3, x2: 12, y2: 3};
diagonal = { x: 3, y: 8, x2: 5, y2: 11 }; diagonal = { x: 3, y: 8, x2: 5, y2: 11};
reversed = { x2: 3, y2: 8, x: 5, y: 11 }; reversed = { x2: 3, y2: 8, x: 5, y: 11};
}); });
it("ensures visible width for vertical lines", function () { it("ensures visible width for vertical lines", function () {
@ -63,13 +63,13 @@ define(
it("adjusts both ends when mutating x", function () { it("adjusts both ends when mutating x", function () {
var proxy = new LineProxy(diagonal); var proxy = new LineProxy(diagonal);
proxy.x(6); 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 () { it("adjusts both ends when mutating y", function () {
var proxy = new LineProxy(diagonal); var proxy = new LineProxy(diagonal);
proxy.y(6); 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 () { it("provides internal positions for SVG lines", function () {

View File

@ -24,7 +24,8 @@ define(
['../../src/elements/ResizeHandle'], ['../../src/elements/ResizeHandle'],
function (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 () { describe("A fixed position drag handle", function () {
var testElement, var testElement,
@ -35,13 +36,15 @@ define(
x: 3, x: 3,
y: 42, y: 42,
width: 30, width: 30,
height: 36 height: 36,
useGrid: true
}; };
handle = new ResizeHandle( handle = new ResizeHandle(
testElement, testElement,
TEST_MIN_WIDTH, TEST_MIN_WIDTH,
TEST_MIN_HEIGHT TEST_MIN_HEIGHT,
[34,81]
); );
}); });
@ -73,6 +76,10 @@ define(
expect(testElement.height).toEqual(TEST_MIN_HEIGHT); expect(testElement.height).toEqual(TEST_MIN_HEIGHT);
}); });
it("returns the correct grid size", function () {
expect(handle.getGridSize()).toEqual([34,81]);
});
}); });
} }
); );

View File

@ -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);
});
});
}
);