From 2be58579dc6eb1d81c79536a9bd25c970cfb8b06 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Feb 2015 11:30:04 -0800 Subject: [PATCH 01/15] [Fixed Position] Add 'Add' menu button Add UI for the Add button in fixed position view, WTD-880. --- platform/features/layout/bundle.json | 26 ++++++++++++++++-- platform/forms/bundle.json | 4 +++ .../res/templates/controls/menu-button.html | 27 +++++++++++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) create mode 100644 platform/forms/res/templates/controls/menu-button.html diff --git a/platform/features/layout/bundle.json b/platform/features/layout/bundle.json index 8ded0c2f6f..bdb780513e 100644 --- a/platform/features/layout/bundle.json +++ b/platform/features/layout/bundle.json @@ -26,9 +26,31 @@ "items": [ { "method": "add", - "control": "button", + "control": "menu-button", "text": "Add", - "inclusive": true + "inclusive": true, + "options": [ + { + "name": "Box", + "glyph": "\u2610", + "key": "fixed.box" + }, + { + "name": "Line", + "glyph": "-", + "key": "fixed.line" + }, + { + "name": "Text", + "glyph": "\u1D1B", + "key": "fixed.text" + }, + { + "name": "Image", + "glyph": "\u2353", + "key": "fixed.image" + } + ] } ] }, diff --git a/platform/forms/bundle.json b/platform/forms/bundle.json index d8e3730eca..eb63e22432 100644 --- a/platform/forms/bundle.json +++ b/platform/forms/bundle.json @@ -45,6 +45,10 @@ { "key": "composite", "templateUrl": "templates/controls/composite.html" + }, + { + "key": "menu-button", + "templateUrl": "templates/controls/menu-button.html" } ], "controllers": [ diff --git a/platform/forms/res/templates/controls/menu-button.html b/platform/forms/res/templates/controls/menu-button.html new file mode 100644 index 0000000000..cb6b7e565b --- /dev/null +++ b/platform/forms/res/templates/controls/menu-button.html @@ -0,0 +1,27 @@ + \ No newline at end of file From 6fca03521b11e33f29aa0bc93b7b9816addb6626 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Feb 2015 11:39:29 -0800 Subject: [PATCH 02/15] [Fixed Position] Add initial element templates Add element templates for fixed position elements introduced via the Add button, WTD-880. --- platform/features/layout/bundle.json | 16 ++++++++++++++++ .../layout/res/templates/elements/box.html | 2 ++ .../layout/res/templates/elements/image.html | 1 + .../layout/res/templates/elements/line.html | 3 +++ .../layout/res/templates/elements/text.html | 3 +++ 5 files changed, 25 insertions(+) create mode 100644 platform/features/layout/res/templates/elements/box.html create mode 100644 platform/features/layout/res/templates/elements/image.html create mode 100644 platform/features/layout/res/templates/elements/line.html create mode 100644 platform/features/layout/res/templates/elements/text.html diff --git a/platform/features/layout/bundle.json b/platform/features/layout/bundle.json index bdb780513e..0e709237f5 100644 --- a/platform/features/layout/bundle.json +++ b/platform/features/layout/bundle.json @@ -90,6 +90,22 @@ { "key": "fixed.telemetry", "templateUrl": "templates/elements/telemetry.html" + }, + { + "key": "fixed.box", + "templateUrl": "templates/elements/box.html" + }, + { + "key": "fixed.line", + "templateUrl": "templates/elements/line.html" + }, + { + "key": "fixed.text", + "templateUrl": "templates/elements/text.html" + }, + { + "key": "fixed.image", + "templateUrl": "templates/elements/image.html" } ], "types": [ diff --git a/platform/features/layout/res/templates/elements/box.html b/platform/features/layout/res/templates/elements/box.html new file mode 100644 index 0000000000..88a6987b29 --- /dev/null +++ b/platform/features/layout/res/templates/elements/box.html @@ -0,0 +1,2 @@ +
+
\ No newline at end of file diff --git a/platform/features/layout/res/templates/elements/image.html b/platform/features/layout/res/templates/elements/image.html new file mode 100644 index 0000000000..f4c1b3ac2d --- /dev/null +++ b/platform/features/layout/res/templates/elements/image.html @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/platform/features/layout/res/templates/elements/line.html b/platform/features/layout/res/templates/elements/line.html new file mode 100644 index 0000000000..27eb74fc3d --- /dev/null +++ b/platform/features/layout/res/templates/elements/line.html @@ -0,0 +1,3 @@ +
+ ...line... +
\ No newline at end of file diff --git a/platform/features/layout/res/templates/elements/text.html b/platform/features/layout/res/templates/elements/text.html new file mode 100644 index 0000000000..4cdc956360 --- /dev/null +++ b/platform/features/layout/res/templates/elements/text.html @@ -0,0 +1,3 @@ +
+ {{ngModel.text}} +
\ No newline at end of file From f1a8e84a93fb0275d9e71b22855bd43c77b8b2a3 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Feb 2015 11:53:50 -0800 Subject: [PATCH 03/15] [Fixed Position] Allow adding elements Allow adding of elements (without any element-specific properties beyond type.) WTD-880. --- .../features/layout/res/templates/elements/box.html | 4 +++- .../features/layout/res/templates/elements/line.html | 3 ++- .../features/layout/res/templates/elements/text.html | 3 ++- platform/features/layout/src/FixedProxy.js | 9 ++++++++- .../features/layout/src/elements/ElementProxies.js | 10 +++++++--- 5 files changed, 22 insertions(+), 7 deletions(-) diff --git a/platform/features/layout/res/templates/elements/box.html b/platform/features/layout/res/templates/elements/box.html index 88a6987b29..eab7cf0af5 100644 --- a/platform/features/layout/res/templates/elements/box.html +++ b/platform/features/layout/res/templates/elements/box.html @@ -1,2 +1,4 @@ -
+
+ ???
\ No newline at end of file diff --git a/platform/features/layout/res/templates/elements/line.html b/platform/features/layout/res/templates/elements/line.html index 27eb74fc3d..2556056434 100644 --- a/platform/features/layout/res/templates/elements/line.html +++ b/platform/features/layout/res/templates/elements/line.html @@ -1,3 +1,4 @@ -
+
...line...
\ No newline at end of file diff --git a/platform/features/layout/res/templates/elements/text.html b/platform/features/layout/res/templates/elements/text.html index 4cdc956360..e41d20b639 100644 --- a/platform/features/layout/res/templates/elements/text.html +++ b/platform/features/layout/res/templates/elements/text.html @@ -1,3 +1,4 @@ -
+
{{ngModel.text}}
\ No newline at end of file diff --git a/platform/features/layout/src/FixedProxy.js b/platform/features/layout/src/FixedProxy.js index c99a0e3f92..eb23079d35 100644 --- a/platform/features/layout/src/FixedProxy.js +++ b/platform/features/layout/src/FixedProxy.js @@ -16,7 +16,14 @@ define( * Add a new visual element to this view. */ add: function (type) { - window.alert("Placeholder. Should add a " + type + "."); + configuration.elements = configuration.elements || []; + configuration.elements.push({ + x: configuration.elements.length, + y: configuration.elements.length, + width: 2, + height: 1, + type: type + }); } }; } diff --git a/platform/features/layout/src/elements/ElementProxies.js b/platform/features/layout/src/elements/ElementProxies.js index e8d6b032e5..297c62fb82 100644 --- a/platform/features/layout/src/elements/ElementProxies.js +++ b/platform/features/layout/src/elements/ElementProxies.js @@ -1,12 +1,16 @@ /*global define*/ define( - ['./TelemetryProxy'], - function (TelemetryProxy) { + ['./TelemetryProxy', './ElementProxy'], + function (TelemetryProxy, ElementProxy) { "use strict"; return { - "fixed.telemetry": TelemetryProxy + "fixed.telemetry": TelemetryProxy, + "fixed.line": ElementProxy, + "fixed.box": ElementProxy, + "fixed.image": ElementProxy, + "fixed.text": ElementProxy }; } ); \ No newline at end of file From a947ff1274bb22a279830ccfcd71c32ce5a0080f Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Feb 2015 12:21:28 -0800 Subject: [PATCH 04/15] [Fixed Position] Add element factory Add element factory, which will take on responsibility for populating initial states of elements and (if necessary) prompting for user input. WTD-880. --- platform/features/layout/bundle.json | 8 +++- .../layout/res/templates/elements/image.html | 2 +- .../features/layout/src/FixedController.js | 9 +++- platform/features/layout/src/FixedProxy.js | 39 ++++++++++----- .../layout/src/elements/ElementFactory.js | 48 +++++++++++++++++++ 5 files changed, 90 insertions(+), 16 deletions(-) create mode 100644 platform/features/layout/src/elements/ElementFactory.js diff --git a/platform/features/layout/bundle.json b/platform/features/layout/bundle.json index 0e709237f5..7a99fcbb0b 100644 --- a/platform/features/layout/bundle.json +++ b/platform/features/layout/bundle.json @@ -83,7 +83,13 @@ { "key": "FixedController", "implementation": "FixedController.js", - "depends": [ "$scope", "telemetrySubscriber", "telemetryFormatter" ] + "depends": [ + "$scope", + "$q", + "dialogService", + "telemetrySubscriber", + "telemetryFormatter" + ] } ], "templates": [ diff --git a/platform/features/layout/res/templates/elements/image.html b/platform/features/layout/res/templates/elements/image.html index f4c1b3ac2d..a00e18faaa 100644 --- a/platform/features/layout/res/templates/elements/image.html +++ b/platform/features/layout/res/templates/elements/image.html @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/platform/features/layout/src/FixedController.js b/platform/features/layout/src/FixedController.js index d18d286840..89581093b4 100644 --- a/platform/features/layout/src/FixedController.js +++ b/platform/features/layout/src/FixedController.js @@ -17,7 +17,7 @@ define( * @constructor * @param {Scope} $scope the controller's Angular scope */ - function FixedController($scope, telemetrySubscriber, telemetryFormatter) { + function FixedController($scope, $q, dialogService, telemetrySubscriber, telemetryFormatter) { var gridSize = DEFAULT_GRID_SIZE, gridExtent = DEFAULT_GRID_EXTENT, dragging, @@ -190,7 +190,12 @@ define( if (Array.isArray($scope.selection)) { selection = new LayoutSelection( $scope.selection, - new FixedProxy($scope.configuration) + new FixedProxy( + $scope.configuration, + $q, + dialogService, + refreshElements + ) ); } diff --git a/platform/features/layout/src/FixedProxy.js b/platform/features/layout/src/FixedProxy.js index eb23079d35..3dceeff4de 100644 --- a/platform/features/layout/src/FixedProxy.js +++ b/platform/features/layout/src/FixedProxy.js @@ -1,29 +1,44 @@ /*global define,window*/ define( - [], - function () { + ['./elements/ElementFactory'], + function (ElementFactory) { "use strict"; /** * Proxy for configuring a fixed position view via the toolbar. * @constructor - * @param configuration the view configuration object + * @param configuration the view configuration object to manage */ - function FixedProxy(configuration) { + function FixedProxy(configuration, $q, dialogService, callback) { + var factory = new ElementFactory(dialogService); + return { /** * Add a new visual element to this view. */ add: function (type) { - configuration.elements = configuration.elements || []; - configuration.elements.push({ - x: configuration.elements.length, - y: configuration.elements.length, - width: 2, - height: 1, - type: type - }); + // Place a configured element into the view configuration + function addElement(element) { + // Ensure that there is an Elements array + configuration.elements = configuration.elements || []; + + // Configure common properties of the element + element.x = element.x || 0; + element.y = element.y || 0; + element.width = element.width || 1; + element.height = element.height || 1; + element.type = type; + + // Finally, add it to the view's configuration + configuration.elements.push(element); + + // Let the view know it needs to refresh + callback(); + } + + // Defer creation to the factory + $q.when(factory.createElement(type)).then(addElement); } }; } diff --git a/platform/features/layout/src/elements/ElementFactory.js b/platform/features/layout/src/elements/ElementFactory.js new file mode 100644 index 0000000000..c1824a7f1f --- /dev/null +++ b/platform/features/layout/src/elements/ElementFactory.js @@ -0,0 +1,48 @@ +/*global define*/ + +define( + [], + function () { + "use strict"; + + var INITIAL_STATES = { + "fixed.image": { + url: "http://www.nasa.gov/sites/default/themes/NASAPortal/images/nasa-logo.gif" + } + }, + DIALOGS = { + + }; + + /** + * The ElementFactory creates new instances of elements for the + * fixed position view, prompting for user input where necessary. + * @param {DialogService} dialogService service to request user input + * @constructor + */ + function ElementFactory(dialogService) { + return { + /** + * Create a new element for the fixed position view. + * @param {string} type the type of element to create + * @returns {Promise|object} the created element, or a promise + * for that element + */ + createElement: function (type) { + var initialState = INITIAL_STATES[type] || {}; + + // Clone that state + initialState = JSON.parse(JSON.stringify(initialState)); + + // Show a dialog to configure initial state, if appropriate + return DIALOGS[type] ? dialogService.getUserInput( + DIALOGS[type], + initialState + ) : initialState; + } + }; + } + + return ElementFactory; + } +); \ No newline at end of file From f5b6be9b5d4eede0a6bbe132b7c3e7ac0ee2baa6 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Feb 2015 12:28:52 -0800 Subject: [PATCH 05/15] [Fixed Position] Add Image Properties dialog Add Image Properties dialog, for when a new image element is created. WTD-880. --- .../layout/src/elements/ElementFactory.js | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/platform/features/layout/src/elements/ElementFactory.js b/platform/features/layout/src/elements/ElementFactory.js index c1824a7f1f..9e1ee6e2b9 100644 --- a/platform/features/layout/src/elements/ElementFactory.js +++ b/platform/features/layout/src/elements/ElementFactory.js @@ -11,7 +11,21 @@ define( } }, DIALOGS = { - + "fixed.image": { + name: "Image Properties", + sections: [ + { + rows: [ + { + key: "url", + control: "textfield", + name: "Image URL", + required: true + } + ] + } + ] + } }; /** From 638a7c86099bdd70196d13f3aa1fe284e1d2c131 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Feb 2015 12:57:15 -0800 Subject: [PATCH 06/15] [Fixed Position] Add dialog for text Add dialog for text elements in fixed position view; tweak styling on some other element types. WTD-880. --- .../layout/res/templates/elements/box.html | 1 - .../layout/res/templates/elements/image.html | 4 ++- .../layout/res/templates/elements/text.html | 6 ++--- .../layout/src/elements/ElementFactory.js | 26 +++++++++++++++++-- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/platform/features/layout/res/templates/elements/box.html b/platform/features/layout/res/templates/elements/box.html index eab7cf0af5..5938549bad 100644 --- a/platform/features/layout/res/templates/elements/box.html +++ b/platform/features/layout/res/templates/elements/box.html @@ -1,4 +1,3 @@
- ???
\ No newline at end of file diff --git a/platform/features/layout/res/templates/elements/image.html b/platform/features/layout/res/templates/elements/image.html index a00e18faaa..041147df27 100644 --- a/platform/features/layout/res/templates/elements/image.html +++ b/platform/features/layout/res/templates/elements/image.html @@ -1 +1,3 @@ - \ No newline at end of file +
+
\ No newline at end of file diff --git a/platform/features/layout/res/templates/elements/text.html b/platform/features/layout/res/templates/elements/text.html index e41d20b639..2b52f04598 100644 --- a/platform/features/layout/res/templates/elements/text.html +++ b/platform/features/layout/res/templates/elements/text.html @@ -1,4 +1,4 @@ -
- {{ngModel.text}} +
+ {{ngModel.element.text}}
\ No newline at end of file diff --git a/platform/features/layout/src/elements/ElementFactory.js b/platform/features/layout/src/elements/ElementFactory.js index 9e1ee6e2b9..dc1eb27e82 100644 --- a/platform/features/layout/src/elements/ElementFactory.js +++ b/platform/features/layout/src/elements/ElementFactory.js @@ -6,8 +6,15 @@ define( "use strict"; var INITIAL_STATES = { - "fixed.image": { - url: "http://www.nasa.gov/sites/default/themes/NASAPortal/images/nasa-logo.gif" + "fixed.image": {}, + "fixed.box": { + fill: "#888", + border: "transparent" + }, + "fixed.line": {}, + "fixed.text": { + fill: "transparent", + border: "transparent" } }, DIALOGS = { @@ -25,6 +32,21 @@ define( ] } ] + }, + "fixed.text": { + name: "Text Element Properties", + sections: [ + { + rows: [ + { + key: "text", + control: "textfield", + name: "Text", + required: true + } + ] + } + ] } }; From 2c0180ebda6546acc5e682d930de83b722e910a6 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Feb 2015 15:02:16 -0800 Subject: [PATCH 07/15] [Fixed Position] Draw line as SVG Draw line elements as SVG, WTD-880. --- .../layout/res/templates/elements/line.html | 14 +++-- .../features/layout/res/templates/fixed.html | 1 + .../features/layout/src/FixedController.js | 24 ++++--- .../layout/src/elements/ElementFactory.js | 7 ++- .../layout/src/elements/ElementProxies.js | 6 +- .../features/layout/src/elements/LineProxy.js | 63 +++++++++++++++++++ 6 files changed, 100 insertions(+), 15 deletions(-) create mode 100644 platform/features/layout/src/elements/LineProxy.js diff --git a/platform/features/layout/res/templates/elements/line.html b/platform/features/layout/res/templates/elements/line.html index 2556056434..690fd1a9db 100644 --- a/platform/features/layout/res/templates/elements/line.html +++ b/platform/features/layout/res/templates/elements/line.html @@ -1,4 +1,10 @@ -
- ...line... -
\ No newline at end of file + + + + \ No newline at end of file diff --git a/platform/features/layout/res/templates/fixed.html b/platform/features/layout/res/templates/fixed.html index 0b7e1ef056..9d6d741a62 100644 --- a/platform/features/layout/res/templates/fixed.html +++ b/platform/features/layout/res/templates/fixed.html @@ -14,6 +14,7 @@ 0 && delta) { + element.x += delta; + element.x2 += delta; + } + return x; + }; + + proxy.y = function (v) { + var y = Math.min(element.y, element.y2), + delta = v - y; + if (arguments.length > 0 && delta) { + element.y += delta; + element.y2 += delta; + } + return y; + }; + + proxy.width = function () { + return Math.max(element.x, element.x2) - proxy.x(); + }; + + proxy.height = function () { + return Math.max(element.y, element.y2) - proxy.y(); + }; + + proxy.x1 = function () { + return element.x - proxy.x(); + }; + + proxy.y1 = function () { + return element.y - proxy.y(); + }; + + proxy.x2 = function () { + return element.x2 - proxy.x(); + }; + + proxy.y2 = function () { + return element.y2 - proxy.y(); + }; + + return proxy; + } + + return LineProxy; + } +); \ No newline at end of file From f9043fdb7db117f25739822594ae40045c196c26 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Feb 2015 15:25:27 -0800 Subject: [PATCH 08/15] [Fixed Position] Allow straight lines Pad width/height to give enough space to draw straight lines; fix usage of background for boxes. WTD-880. --- platform/features/layout/res/templates/elements/box.html | 2 +- platform/features/layout/res/templates/elements/line.html | 8 ++++---- platform/features/layout/src/elements/ElementFactory.js | 8 ++++---- platform/features/layout/src/elements/LineProxy.js | 4 ++-- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/platform/features/layout/res/templates/elements/box.html b/platform/features/layout/res/templates/elements/box.html index 5938549bad..58ecf860d7 100644 --- a/platform/features/layout/res/templates/elements/box.html +++ b/platform/features/layout/res/templates/elements/box.html @@ -1,3 +1,3 @@ -
\ No newline at end of file diff --git a/platform/features/layout/res/templates/elements/line.html b/platform/features/layout/res/templates/elements/line.html index 690fd1a9db..524cd451ca 100644 --- a/platform/features/layout/res/templates/elements/line.html +++ b/platform/features/layout/res/templates/elements/line.html @@ -1,9 +1,9 @@ - diff --git a/platform/features/layout/src/elements/ElementFactory.js b/platform/features/layout/src/elements/ElementFactory.js index bb85efdec3..4ad229e30a 100644 --- a/platform/features/layout/src/elements/ElementFactory.js +++ b/platform/features/layout/src/elements/ElementFactory.js @@ -12,10 +12,10 @@ define( border: "transparent" }, "fixed.line": { - x: 0, - y: 0, - x2: 5, - y2: 3 + x: 5, + y: 9, + x2: 6, + y2: 6 }, "fixed.text": { fill: "transparent", diff --git a/platform/features/layout/src/elements/LineProxy.js b/platform/features/layout/src/elements/LineProxy.js index f5c3d6bc65..fbba73abdb 100644 --- a/platform/features/layout/src/elements/LineProxy.js +++ b/platform/features/layout/src/elements/LineProxy.js @@ -32,11 +32,11 @@ define( }; proxy.width = function () { - return Math.max(element.x, element.x2) - proxy.x(); + return Math.max(Math.abs(element.x - element.x2), 1); }; proxy.height = function () { - return Math.max(element.y, element.y2) - proxy.y(); + return Math.max(Math.abs(element.y - element.y2), 1); }; proxy.x1 = function () { From 668a1e4534fe7de32be082488fa8e883240b7c58 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Feb 2015 15:29:37 -0800 Subject: [PATCH 09/15] [Fixed Position] Add empty specs Add empty specs for classes introduced in support of Add menu options for fixed position view, WTD-880. --- .../layout/test/elements/ElementFactorySpec.js | 11 +++++++++++ .../features/layout/test/elements/LineProxySpec.js | 11 +++++++++++ platform/features/layout/test/suite.json | 2 ++ 3 files changed, 24 insertions(+) create mode 100644 platform/features/layout/test/elements/ElementFactorySpec.js create mode 100644 platform/features/layout/test/elements/LineProxySpec.js diff --git a/platform/features/layout/test/elements/ElementFactorySpec.js b/platform/features/layout/test/elements/ElementFactorySpec.js new file mode 100644 index 0000000000..795a06f314 --- /dev/null +++ b/platform/features/layout/test/elements/ElementFactorySpec.js @@ -0,0 +1,11 @@ +/*global define,describe,it,expect,beforeEach,jasmine*/ + +define( + ['../../src/elements/ElementFactory'], + function (ElementFactory) { + "use strict"; + + describe("The fixed position element factory", function () { + }); + } +); \ No newline at end of file diff --git a/platform/features/layout/test/elements/LineProxySpec.js b/platform/features/layout/test/elements/LineProxySpec.js new file mode 100644 index 0000000000..08cba55b6e --- /dev/null +++ b/platform/features/layout/test/elements/LineProxySpec.js @@ -0,0 +1,11 @@ +/*global define,describe,it,expect,beforeEach,jasmine*/ + +define( + ['../../src/elements/LineProxy'], + function (LineProxy) { + "use strict"; + + describe("A fixed position line proxy", function () { + }); + } +); \ No newline at end of file diff --git a/platform/features/layout/test/suite.json b/platform/features/layout/test/suite.json index af82513e01..c895900595 100644 --- a/platform/features/layout/test/suite.json +++ b/platform/features/layout/test/suite.json @@ -5,7 +5,9 @@ "LayoutDrag", "LayoutSelection", "elements/AccessorMutator", + "elements/ElementFactory", "elements/ElementProxies", "elements/ElementProxy", + "elements/LineProxy", "elements/TelemetryProxy" ] \ No newline at end of file From 84e90f6ad1f10ecb3c38d4ffde60700e0fc09b45 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Feb 2015 15:47:07 -0800 Subject: [PATCH 10/15] [Fixed Position] Select newly-created elements When elements are added to a fixed position view, select them immediately. WTD-880. --- .../features/layout/src/FixedController.js | 34 ++++++++++++------- platform/features/layout/src/FixedProxy.js | 16 ++++----- 2 files changed, 28 insertions(+), 22 deletions(-) diff --git a/platform/features/layout/src/FixedController.js b/platform/features/layout/src/FixedController.js index c9da43711e..442f966033 100644 --- a/platform/features/layout/src/FixedController.js +++ b/platform/features/layout/src/FixedController.js @@ -163,8 +163,8 @@ define( subscribe($scope.domainObject); } - // Position a panel after a drop event - function handleDrop(e, id, position) { + // Add an element to this view + function addElement(element) { // Ensure that configuration field is populated $scope.configuration = $scope.configuration || {}; // Make sure there is a "elements" field in the @@ -172,7 +172,23 @@ define( $scope.configuration.elements = $scope.configuration.elements || []; // Store the position of this element. - $scope.configuration.elements.push({ + $scope.configuration.elements.push(element); + // Refresh displayed elements + refreshElements(); + // Select the newly-added element + if (selection) { + selection.select(elementProxies[elementProxies.length - 1]); + } + // Mark change as persistable + if ($scope.commit) { + $scope.commit("Dropped an element."); + } + } + + // Position a panel after a drop event + function handleDrop(e, id, position) { + // Store the position of this element. + addElement({ type: "fixed.telemetry", x: Math.floor(position.x / gridSize[0]), y: Math.floor(position.y / gridSize[1]), @@ -180,22 +196,14 @@ define( width: DEFAULT_DIMENSIONS[0], height: DEFAULT_DIMENSIONS[1] }); - // Mark change as persistable - if ($scope.commit) { - $scope.commit("Dropped an element."); - } } + // Track current selection state if (Array.isArray($scope.selection)) { selection = new LayoutSelection( $scope.selection, - new FixedProxy( - $scope.configuration, - $q, - dialogService, - refreshElements - ) + new FixedProxy(addElement, $q, dialogService) ); } diff --git a/platform/features/layout/src/FixedProxy.js b/platform/features/layout/src/FixedProxy.js index 3dceeff4de..4b5b4312e0 100644 --- a/platform/features/layout/src/FixedProxy.js +++ b/platform/features/layout/src/FixedProxy.js @@ -8,9 +8,13 @@ define( /** * Proxy for configuring a fixed position view via the toolbar. * @constructor - * @param configuration the view configuration object to manage + * @param {Function} addElementCallback callback to invoke when + * elements are created + * @param $q Angular's $q, for promise-handling + * @param {DialogService} dialogService dialog service to use + * when adding a new element will require user input */ - function FixedProxy(configuration, $q, dialogService, callback) { + function FixedProxy(addElementCallback, $q, dialogService) { var factory = new ElementFactory(dialogService); return { @@ -20,9 +24,6 @@ define( add: function (type) { // Place a configured element into the view configuration function addElement(element) { - // Ensure that there is an Elements array - configuration.elements = configuration.elements || []; - // Configure common properties of the element element.x = element.x || 0; element.y = element.y || 0; @@ -31,10 +32,7 @@ define( element.type = type; // Finally, add it to the view's configuration - configuration.elements.push(element); - - // Let the view know it needs to refresh - callback(); + addElementCallback(element); } // Defer creation to the factory From 68145671162c2c0ccb6047836e6d9b1a367558a7 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Feb 2015 15:53:41 -0800 Subject: [PATCH 11/15] [Fixed Position] Update failing specs Update existing tests to account for changes from WTD-880. --- .../layout/test/FixedControllerSpec.js | 9 ++++++ .../features/layout/test/FixedProxySpec.js | 28 +++++++++++++++---- .../test/elements/ElementProxiesSpec.js | 7 ++++- 3 files changed, 37 insertions(+), 7 deletions(-) diff --git a/platform/features/layout/test/FixedControllerSpec.js b/platform/features/layout/test/FixedControllerSpec.js index 460228e362..e9b131e8fd 100644 --- a/platform/features/layout/test/FixedControllerSpec.js +++ b/platform/features/layout/test/FixedControllerSpec.js @@ -7,6 +7,8 @@ define( describe("The Fixed Position controller", function () { var mockScope, + mockQ, + mockDialogService, mockSubscriber, mockFormatter, mockDomainObject, @@ -58,6 +60,11 @@ define( 'telemetrySubscriber', [ 'subscribe' ] ); + mockQ = jasmine.createSpyObj('$q', ['when']); + mockDialogService = jasmine.createSpyObj( + 'dialogService', + ['getUserInput'] + ); mockFormatter = jasmine.createSpyObj( 'telemetryFormatter', [ 'formatDomainValue', 'formatRangeValue' ] @@ -99,6 +106,8 @@ define( controller = new FixedController( mockScope, + mockQ, + mockDialogService, mockSubscriber, mockFormatter ); diff --git a/platform/features/layout/test/FixedProxySpec.js b/platform/features/layout/test/FixedProxySpec.js index 224b19f022..f5fd464a7b 100644 --- a/platform/features/layout/test/FixedProxySpec.js +++ b/platform/features/layout/test/FixedProxySpec.js @@ -6,12 +6,28 @@ define( "use strict"; describe("Fixed Position view's selection proxy", function () { - it("has a placeholder message when clicked", function () { - var oldAlert = window.alert; - window.alert = jasmine.createSpy('alert'); - new FixedProxy({}).add(''); - expect(window.alert).toHaveBeenCalledWith(jasmine.any(String)); - window.alert = oldAlert; + var mockCallback, + mockQ, + mockDialogService, + mockPromise, + proxy; + + beforeEach(function () { + mockCallback = jasmine.createSpy('callback'); + mockQ = jasmine.createSpyObj('$q', ['when']); + mockDialogService = jasmine.createSpyObj('dialogService', ['getUserInput']); + mockPromise = jasmine.createSpyObj('promise', ['then']); + + mockQ.when.andReturn(mockPromise); + + proxy = new FixedProxy(mockCallback, mockQ, mockDialogService); + }); + + it("handles promised element creation", function () { + // The element factory may return promises (e.g. if + // user input is required) so make sure proxy is wrapping these + proxy.add("fixed.box"); + expect(mockQ.when).toHaveBeenCalled(); }); }); } diff --git a/platform/features/layout/test/elements/ElementProxiesSpec.js b/platform/features/layout/test/elements/ElementProxiesSpec.js index cf771a043a..1e58fb8826 100644 --- a/platform/features/layout/test/elements/ElementProxiesSpec.js +++ b/platform/features/layout/test/elements/ElementProxiesSpec.js @@ -5,8 +5,13 @@ define( function (ElementProxies) { "use strict"; + // Expect these element types to have proxies var ELEMENT_TYPES = [ - "fixed.telemetry" + "fixed.telemetry", + "fixed.line", + "fixed.box", + "fixed.text", + "fixed.image" ]; // Verify that the set of proxies exposed matches the specific From e50e57b0be24bbd960df8cd9aaa39e8a24094bb4 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Feb 2015 15:59:22 -0800 Subject: [PATCH 12/15] [Fixed Position] Add tests for FixedController Add tests for FixedController and FixedProxy which reflect added/changed behavior for Add button, WTD-880. --- .../features/layout/test/FixedControllerSpec.js | 8 ++++++-- platform/features/layout/test/FixedProxySpec.js | 17 +++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/platform/features/layout/test/FixedControllerSpec.js b/platform/features/layout/test/FixedControllerSpec.js index e9b131e8fd..c8b943cc62 100644 --- a/platform/features/layout/test/FixedControllerSpec.js +++ b/platform/features/layout/test/FixedControllerSpec.js @@ -272,8 +272,6 @@ define( .toHaveBeenCalledWith(jasmine.any(String)); }); - - it("unsubscribes when destroyed", function () { // Make an object available findWatch('domainObject')(mockDomainObject); @@ -284,6 +282,12 @@ define( // Should have unsubscribed expect(mockSubscription.unsubscribe).toHaveBeenCalled(); }); + + it("exposes its grid size", function () { + // Template needs to be able to pass this into line + // elements to size SVGs appropriately + expect(controller.getGridSize()).toEqual(testGrid); + }); }); } ); \ No newline at end of file diff --git a/platform/features/layout/test/FixedProxySpec.js b/platform/features/layout/test/FixedProxySpec.js index f5fd464a7b..dde97fa142 100644 --- a/platform/features/layout/test/FixedProxySpec.js +++ b/platform/features/layout/test/FixedProxySpec.js @@ -29,6 +29,23 @@ define( proxy.add("fixed.box"); expect(mockQ.when).toHaveBeenCalled(); }); + + it("notifies its callback when an element is created", function () { + proxy.add("fixed.box"); + // Callback should not have been invoked yet + expect(mockCallback).not.toHaveBeenCalled(); + // Resolve the promise + mockPromise.then.mostRecentCall.args[0]({}); + // Should have fired the callback + expect(mockCallback).toHaveBeenCalledWith({ + type: "fixed.box", + x: 0, + y: 0, + width: 1, + height: 1 + }); + }); + }); } ); From d75f9e51ac23ed49baee7b46096e6bc6cac40181 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Feb 2015 16:18:19 -0800 Subject: [PATCH 13/15] [Fixed Position] Add tests for new classes Add test cases for new classes introduced to support Add options in the Fixed Position toolbar, WTD-880. --- .../test/elements/ElementFactorySpec.js | 39 ++++++++++++ .../layout/test/elements/LineProxySpec.js | 61 +++++++++++++++++++ 2 files changed, 100 insertions(+) diff --git a/platform/features/layout/test/elements/ElementFactorySpec.js b/platform/features/layout/test/elements/ElementFactorySpec.js index 795a06f314..4dec7a4357 100644 --- a/platform/features/layout/test/elements/ElementFactorySpec.js +++ b/platform/features/layout/test/elements/ElementFactorySpec.js @@ -5,7 +5,46 @@ define( function (ElementFactory) { "use strict"; + var DIALOG_ELEMENTS = [ 'image', 'text' ], + NON_DIALOG_ELEMENTS = [ 'box', 'line' ]; + describe("The fixed position element factory", function () { + var mockDialogService, + mockPromise, + factory; + + beforeEach(function () { + mockDialogService = jasmine.createSpyObj( + 'dialogService', + [ 'getUserInput' ] + ); + mockPromise = jasmine.createSpyObj( + 'promise', + [ 'then' ] + ); + + mockDialogService.getUserInput.andReturn(mockPromise); + mockPromise.then.andReturn(mockPromise); + + factory = new ElementFactory(mockDialogService); + }); + + DIALOG_ELEMENTS.forEach(function (type) { + it("shows a dialog for " + type + " elements", function () { + expect(factory.createElement('fixed.' + type)) + .toEqual(mockPromise); + expect(mockDialogService.getUserInput).toHaveBeenCalled(); + }); + }); + + NON_DIALOG_ELEMENTS.forEach(function (type) { + it("immediately provides " + type + " elements", function () { + var result = factory.createElement('fixed.' + type); + expect(result).toBeDefined(); + expect(result).not.toEqual(mockPromise); + expect(mockDialogService.getUserInput).not.toHaveBeenCalled(); + }); + }); }); } ); \ No newline at end of file diff --git a/platform/features/layout/test/elements/LineProxySpec.js b/platform/features/layout/test/elements/LineProxySpec.js index 08cba55b6e..fe38c7c3c9 100644 --- a/platform/features/layout/test/elements/LineProxySpec.js +++ b/platform/features/layout/test/elements/LineProxySpec.js @@ -6,6 +6,67 @@ define( "use strict"; describe("A fixed position line proxy", function () { + 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 }; + }); + + it("ensures visible width for vertical lines", function () { + expect(new LineProxy(vertical).width()).toEqual(1); + }); + + it("ensures visible height for horizontal lines", function () { + expect(new LineProxy(horizontal).height()).toEqual(1); + }); + + it("provides a bounding box for lines", function () { + var proxy = new LineProxy(diagonal); + expect(proxy.x()).toEqual(3); + expect(proxy.y()).toEqual(8); + expect(proxy.width()).toEqual(2); + expect(proxy.height()).toEqual(3); + }); + + it("bounds lines identically regardless of point order", function () { + // That is, x(), width(), y(), and height() should always give + // the same results for the same line segments, regardless of + // which point is x,y and which is x2,y2 + ['x', 'y', 'width', 'height'].forEach(function (method) { + expect(new LineProxy(diagonal)[method]()) + .toEqual(new LineProxy(reversed)[method]()); + }); + }); + + 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 }); + }); + + 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 }); + }); + + it("provides internal positions for SVG lines", function () { + var proxy; + proxy = new LineProxy(diagonal); + expect(proxy.x1()).toEqual(0); + expect(proxy.y1()).toEqual(0); + expect(proxy.x2()).toEqual(2); + expect(proxy.y2()).toEqual(3); + proxy = new LineProxy(reversed); + expect(proxy.x1()).toEqual(2); + expect(proxy.y1()).toEqual(3); + expect(proxy.x2()).toEqual(0); + expect(proxy.y2()).toEqual(0); + }); + }); } ); \ No newline at end of file From a2295e841640553a783d2bcd9c89871d5ad3bb33 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Feb 2015 16:26:10 -0800 Subject: [PATCH 14/15] [Fixed Position] Add JSDoc Add clarifying comments to different elements proxies, WTD-880. --- .../layout/src/elements/ElementProxy.js | 38 +++++++++++++- .../features/layout/src/elements/LineProxy.js | 52 ++++++++++++++++++- 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/platform/features/layout/src/elements/ElementProxy.js b/platform/features/layout/src/elements/ElementProxy.js index f580b509cd..277353e315 100644 --- a/platform/features/layout/src/elements/ElementProxy.js +++ b/platform/features/layout/src/elements/ElementProxy.js @@ -11,18 +11,54 @@ define( * This handles the generic operations (e.g. remove) so that * subclasses only need to implement element-specific behaviors. * @constructor - * @param element the telemetry element + * @param element the fixed position element, as stored in its + * configuration * @param index the element's index within its array * @param {Array} elements the full array of elements */ function ElementProxy(element, index, elements) { return { + /** + * The element as stored in the view configuration. + */ element: element, + /** + * Get and/or set the x position of this element. + * Units are in fixed position grid space. + * @param {number} [x] the new x position (if setting) + * @returns {number} the x position + */ x: new AccessorMutator(element, 'x'), + /** + * Get and/or set the y position of this element. + * Units are in fixed position grid space. + * @param {number} [y] the new y position (if setting) + * @returns {number} the y position + */ y: new AccessorMutator(element, 'y'), + /** + * Get and/or set the z index of this element. + * @param {number} [z] the new z index (if setting) + * @returns {number} the z index + */ z: new AccessorMutator(element, 'z'), + /** + * Get and/or set the width of this element. + * Units are in fixed position grid space. + * @param {number} [w] the new width (if setting) + * @returns {number} the width + */ width: new AccessorMutator(element, 'width'), + /** + * Get and/or set the height of this element. + * Units are in fixed position grid space. + * @param {number} [h] the new height (if setting) + * @returns {number} the height + */ height: new AccessorMutator(element, 'height'), + /** + * Remove this element from the fixed position view. + */ remove: function () { if (elements[index] === element) { elements.splice(index, 1); diff --git a/platform/features/layout/src/elements/LineProxy.js b/platform/features/layout/src/elements/LineProxy.js index fbba73abdb..14671689dd 100644 --- a/platform/features/layout/src/elements/LineProxy.js +++ b/platform/features/layout/src/elements/LineProxy.js @@ -6,11 +6,22 @@ define( 'use strict'; /** - * + * Selection/diplay proxy for line elements of a fixed position + * view. + * @constructor + * @param element the fixed position element, as stored in its + * configuration + * @param index the element's index within its array + * @param {Array} elements the full array of elements */ function LineProxy(element, index, elements) { var proxy = new ElementProxy(element, index, elements); + /** + * Get the top-left x coordinate, in grid space, of + * this line's bounding box. + * @returns {number} the x coordinate + */ proxy.x = function (v) { var x = Math.min(element.x, element.x2), delta = v - x; @@ -21,6 +32,11 @@ define( return x; }; + /** + * Get the top-left y coordinate, in grid space, of + * this line's bounding box. + * @returns {number} the y coordinate + */ proxy.y = function (v) { var y = Math.min(element.y, element.y2), delta = v - y; @@ -31,26 +47,60 @@ define( return y; }; + /** + * Get the width, in grid space, of + * this line's bounding box. + * @returns {number} the width + */ proxy.width = function () { return Math.max(Math.abs(element.x - element.x2), 1); }; + /** + * Get the height, in grid space, of + * this line's bounding box. + * @returns {number} the height + */ proxy.height = function () { return Math.max(Math.abs(element.y - element.y2), 1); }; + /** + * Get the x position, in grid units relative to + * the top-left corner, of the first point in this line + * segment. + * @returns {number} the x position of the first point + */ proxy.x1 = function () { return element.x - proxy.x(); }; + /** + * Get the y position, in grid units relative to + * the top-left corner, of the first point in this line + * segment. + * @returns {number} the y position of the first point + */ proxy.y1 = function () { return element.y - proxy.y(); }; + /** + * Get the x position, in grid units relative to + * the top-left corner, of the second point in this line + * segment. + * @returns {number} the x position of the second point + */ proxy.x2 = function () { return element.x2 - proxy.x(); }; + /** + * Get the y position, in grid units relative to + * the top-left corner, of the second point in this line + * segment. + * @returns {number} the y position of the second point + */ proxy.y2 = function () { return element.y2 - proxy.y(); }; From 0de06b0594e2254d5764830281bb03934c5fdb49 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 20 Feb 2015 16:30:00 -0800 Subject: [PATCH 15/15] [Fixed Position] Specify glyph for Add Specify glyph for the Add button in the Fixed Position view's toolbar, WTD-880. --- platform/features/layout/bundle.json | 1 + 1 file changed, 1 insertion(+) diff --git a/platform/features/layout/bundle.json b/platform/features/layout/bundle.json index 7a99fcbb0b..d7fb512219 100644 --- a/platform/features/layout/bundle.json +++ b/platform/features/layout/bundle.json @@ -26,6 +26,7 @@ "items": [ { "method": "add", + "glyph": "+", "control": "menu-button", "text": "Add", "inclusive": true,