mirror of
https://github.com/nasa/openmct.git
synced 2025-06-16 06:08:11 +00:00
[Fixed Position] Initially implement handles
Initially implement handles for resizing elements in a fixed position view, WTD-882.
This commit is contained in:
@ -24,13 +24,15 @@
|
|||||||
<!-- Selection highlight, handles -->
|
<!-- Selection highlight, handles -->
|
||||||
<span ng-if="controller.selected()">
|
<span ng-if="controller.selected()">
|
||||||
<div class="test"
|
<div class="test"
|
||||||
|
style="position: absolute;"
|
||||||
mct-drag-down="controller.startDrag(controller.selected())"
|
mct-drag-down="controller.startDrag(controller.selected())"
|
||||||
mct-drag="controller.continueDrag(delta)"
|
mct-drag="controller.continueDrag(delta)"
|
||||||
mct-drag-up="controller.endDrag()"
|
mct-drag-up="controller.endDrag()"
|
||||||
ng-style="controller.selected().style">
|
ng-style="controller.selected().style">
|
||||||
</div>
|
</div>
|
||||||
<div ng-repeat="handle in controller.handles()"
|
<div ng-repeat="handle in controller.handles()"
|
||||||
ng-style="handle.style"
|
style="position: absolute;"
|
||||||
|
ng-style="handle.style()"
|
||||||
mct-drag-down="handle.startDrag()"
|
mct-drag-down="handle.startDrag()"
|
||||||
mct-drag="handle.continueDrag(delta)"
|
mct-drag="handle.continueDrag(delta)"
|
||||||
mct-drag-up="handle.endDrag()">
|
mct-drag-up="handle.endDrag()">
|
||||||
|
@ -15,8 +15,10 @@ define(
|
|||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
function FixedDragHandle(elementHandle, gridSize, commit) {
|
function FixedDragHandle(elementHandle, gridSize, commit) {
|
||||||
var self = {};
|
var self = {},
|
||||||
|
dragging;
|
||||||
|
|
||||||
|
// Generate ng-style-appropriate style for positioning
|
||||||
function getStyle() {
|
function getStyle() {
|
||||||
// Adjust from grid to pixel coordinates
|
// Adjust from grid to pixel coordinates
|
||||||
var x = elementHandle.x() * gridSize[0],
|
var x = elementHandle.x() * gridSize[0],
|
||||||
@ -25,14 +27,39 @@ define(
|
|||||||
// Convert to a CSS style centered on that point
|
// Convert to a CSS style centered on that point
|
||||||
return {
|
return {
|
||||||
left: (x - DRAG_HANDLE_SIZE[0] / 2) + 'px',
|
left: (x - DRAG_HANDLE_SIZE[0] / 2) + 'px',
|
||||||
right: (x - DRAG_HANDLE_SIZE[1] / 2) + 'px',
|
top: (y - DRAG_HANDLE_SIZE[1] / 2) + 'px',
|
||||||
width: DRAG_HANDLE_SIZE[0] + 'px',
|
width: DRAG_HANDLE_SIZE[0] + 'px',
|
||||||
height: DRAG_HANDLE_SIZE[1] + 'px'
|
height: DRAG_HANDLE_SIZE[1] + 'px'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function noop() {
|
// Begin a drag gesture
|
||||||
|
function startDrag() {
|
||||||
|
// Cache initial x/y positions
|
||||||
|
dragging = { x: elementHandle.x(), y: elementHandle.y() };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reposition during drag
|
||||||
|
function continueDrag(delta) {
|
||||||
|
if (dragging) {
|
||||||
|
// Update x/y positions (snapping to grid)
|
||||||
|
elementHandle.x(
|
||||||
|
dragging.x + Math.round(delta[0] / gridSize[0])
|
||||||
|
);
|
||||||
|
elementHandle.y(
|
||||||
|
dragging.y + Math.round(delta[1] / gridSize[1])
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Conclude a drag gesture
|
||||||
|
function endDrag() {
|
||||||
|
// Clear cached state
|
||||||
|
dragging = undefined;
|
||||||
|
// Mark change as complete
|
||||||
|
if (commit) {
|
||||||
|
commit("Dragged handle.");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@ -41,9 +68,22 @@ define(
|
|||||||
* @returns CSS style object (for `ng-style`)
|
* @returns CSS style object (for `ng-style`)
|
||||||
*/
|
*/
|
||||||
style: getStyle,
|
style: getStyle,
|
||||||
startDrag: noop,
|
/**
|
||||||
continueDrag: noop,
|
* Start a drag gesture. This should be called when a drag
|
||||||
endDrag: noop
|
* begins to track initial state.
|
||||||
|
*/
|
||||||
|
startDrag: startDrag,
|
||||||
|
/**
|
||||||
|
* Continue a drag gesture; update x/y positions.
|
||||||
|
* @param {number[]} delta x/y pixel difference since drag
|
||||||
|
* started
|
||||||
|
*/
|
||||||
|
continueDrag: continueDrag,
|
||||||
|
/**
|
||||||
|
* End a drag gesture. This should be callled when a drag
|
||||||
|
* concludes to trigger commit of changes.
|
||||||
|
*/
|
||||||
|
endDrag: endDrag
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
62
platform/features/layout/test/FixedDragHandleSpec.js
Normal file
62
platform/features/layout/test/FixedDragHandleSpec.js
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
/*global define,describe,it,expect,beforeEach,jasmine,xit*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
['../src/FixedDragHandle'],
|
||||||
|
function (FixedDragHandle) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var TEST_GRID_SIZE = [ 13, 33 ];
|
||||||
|
|
||||||
|
describe("A fixed position drag handle", function () {
|
||||||
|
var mockElementHandle,
|
||||||
|
mockCommit,
|
||||||
|
handle;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
mockElementHandle = jasmine.createSpyObj(
|
||||||
|
'elementHandle',
|
||||||
|
[ 'x', 'y' ]
|
||||||
|
);
|
||||||
|
mockCommit = jasmine.createSpy('commit');
|
||||||
|
|
||||||
|
mockElementHandle.x.andReturn(6);
|
||||||
|
mockElementHandle.y.andReturn(8);
|
||||||
|
|
||||||
|
handle = new FixedDragHandle(
|
||||||
|
mockElementHandle,
|
||||||
|
TEST_GRID_SIZE,
|
||||||
|
mockCommit
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("provides a style for positioning", function () {
|
||||||
|
var style = handle.style();
|
||||||
|
// 6 grid coords * 13 pixels - 4 pixels for centering
|
||||||
|
expect(style.left).toEqual('74px');
|
||||||
|
// 8 grid coords * 33 pixels - 4 pixels for centering
|
||||||
|
expect(style.top).toEqual('260px');
|
||||||
|
});
|
||||||
|
|
||||||
|
it("allows handles to be dragged", function () {
|
||||||
|
handle.startDrag();
|
||||||
|
handle.continueDrag([ 16, 8 ]);
|
||||||
|
|
||||||
|
// Should update x/y, snapped to grid
|
||||||
|
expect(mockElementHandle.x).toHaveBeenCalledWith(7);
|
||||||
|
expect(mockElementHandle.y).toHaveBeenCalledWith(8);
|
||||||
|
|
||||||
|
handle.continueDrag([ -16, -35 ]);
|
||||||
|
|
||||||
|
// Should have interpreted relative to initial state
|
||||||
|
expect(mockElementHandle.x).toHaveBeenCalledWith(5);
|
||||||
|
expect(mockElementHandle.y).toHaveBeenCalledWith(7);
|
||||||
|
|
||||||
|
// Finally, ending drag should commit
|
||||||
|
expect(mockCommit).not.toHaveBeenCalled();
|
||||||
|
handle.endDrag();
|
||||||
|
expect(mockCommit).toHaveBeenCalled();
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
59
platform/features/layout/test/elements/ResizeHandleSpec.js
Normal file
59
platform/features/layout/test/elements/ResizeHandleSpec.js
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/*global define,describe,it,expect,beforeEach,jasmine,xit*/
|
||||||
|
|
||||||
|
define(
|
||||||
|
['../../src/elements/ResizeHandle'],
|
||||||
|
function (ResizeHandle) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var TEST_MIN_WIDTH = 4, TEST_MIN_HEIGHT = 2;
|
||||||
|
|
||||||
|
describe("A fixed position drag handle", function () {
|
||||||
|
var testElement,
|
||||||
|
handle;
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
testElement = {
|
||||||
|
x: 3,
|
||||||
|
y: 42,
|
||||||
|
width: 30,
|
||||||
|
height: 36
|
||||||
|
};
|
||||||
|
|
||||||
|
handle = new ResizeHandle(
|
||||||
|
testElement,
|
||||||
|
TEST_MIN_WIDTH,
|
||||||
|
TEST_MIN_HEIGHT
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("provides x/y grid coordinates for lower-right corner", function () {
|
||||||
|
expect(handle.x()).toEqual(33);
|
||||||
|
expect(handle.y()).toEqual(78);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("changes width of an element", function () {
|
||||||
|
handle.x(30);
|
||||||
|
// Should change width, not x
|
||||||
|
expect(testElement.x).toEqual(3);
|
||||||
|
expect(testElement.width).toEqual(27);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("changes height of an element", function () {
|
||||||
|
handle.y(60);
|
||||||
|
// Should change height, not y
|
||||||
|
expect(testElement.y).toEqual(42);
|
||||||
|
expect(testElement.height).toEqual(18);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("enforces minimum width/height", function () {
|
||||||
|
handle.x(testElement.x);
|
||||||
|
handle.y(testElement.y);
|
||||||
|
expect(testElement.x).toEqual(3);
|
||||||
|
expect(testElement.y).toEqual(42);
|
||||||
|
expect(testElement.width).toEqual(TEST_MIN_WIDTH);
|
||||||
|
expect(testElement.height).toEqual(TEST_MIN_HEIGHT);
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
@ -1,5 +1,6 @@
|
|||||||
[
|
[
|
||||||
"FixedController",
|
"FixedController",
|
||||||
|
"FixedDragHandle",
|
||||||
"FixedProxy",
|
"FixedProxy",
|
||||||
"LayoutController",
|
"LayoutController",
|
||||||
"LayoutDrag",
|
"LayoutDrag",
|
||||||
@ -10,6 +11,7 @@
|
|||||||
"elements/ElementProxies",
|
"elements/ElementProxies",
|
||||||
"elements/ElementProxy",
|
"elements/ElementProxy",
|
||||||
"elements/LineProxy",
|
"elements/LineProxy",
|
||||||
|
"elements/ResizeHandle",
|
||||||
"elements/TelemetryProxy",
|
"elements/TelemetryProxy",
|
||||||
"elements/TextProxy"
|
"elements/TextProxy"
|
||||||
]
|
]
|
Reference in New Issue
Block a user