From 7f21cc044db578504aa17145b1d3c713f52aca34 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Wed, 14 Jan 2015 17:48:57 -0800 Subject: [PATCH 01/10] [Fixed Position] Initial template Add initial template, declaration for fixed position view, WTD-615. --- platform/features/layout/bundle.json | 8 ++++++ .../features/layout/res/templates/fixed.html | 26 +++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 platform/features/layout/res/templates/fixed.html diff --git a/platform/features/layout/bundle.json b/platform/features/layout/bundle.json index 67d91281fe..80de35aacd 100644 --- a/platform/features/layout/bundle.json +++ b/platform/features/layout/bundle.json @@ -10,6 +10,14 @@ "type": "layout", "templateUrl": "templates/layout.html", "uses": [ "composition" ] + }, + { + "key": "fixed", + "name": "Fixed Position", + "glyph": "3", + "type": "telemetry.panel", + "templateUrl": "templates/fixed.html", + "uses": [ "composition" ] } ], "representations": [ diff --git a/platform/features/layout/res/templates/fixed.html b/platform/features/layout/res/templates/fixed.html new file mode 100644 index 0000000000..206ce97954 --- /dev/null +++ b/platform/features/layout/res/templates/fixed.html @@ -0,0 +1,26 @@ +
+ + + +
+ +
+ + +
+ + + + + + + +
+ +
\ No newline at end of file From 9d25359aa35dab9c5efd1365ea3a859e2ecbddd0 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 15 Jan 2015 17:04:03 -0800 Subject: [PATCH 02/10] [Fixed Position] Allow views to populate toolbar Add a toolbar representer to share enough scope that views become capable of populating toolbars. Needed for toolbar of fixed position view, WTD-615. --- .../edit/res/templates/edit-object.html | 13 +++++-- .../commonUI/edit/src/ToolbarRepresenter.js | 37 +++++++++++++++++++ 2 files changed, 47 insertions(+), 3 deletions(-) create mode 100644 platform/commonUI/edit/src/ToolbarRepresenter.js diff --git a/platform/commonUI/edit/res/templates/edit-object.html b/platform/commonUI/edit/res/templates/edit-object.html index a27016a3a4..c7339d0c4e 100644 --- a/platform/commonUI/edit/res/templates/edit-object.html +++ b/platform/commonUI/edit/res/templates/edit-object.html @@ -2,13 +2,20 @@ mct-object="domainObject" ng-model="representation"> -
- +
+ + + +
+ toolbar="toolbar" + mct-object="representation.selected.key && domainObject">
diff --git a/platform/commonUI/edit/src/ToolbarRepresenter.js b/platform/commonUI/edit/src/ToolbarRepresenter.js new file mode 100644 index 0000000000..97a424fc83 --- /dev/null +++ b/platform/commonUI/edit/src/ToolbarRepresenter.js @@ -0,0 +1,37 @@ +/*global define*/ + +define( + [], + function () { + + function ToolbarRepresenter(scope, element, attrs) { + var parent = scope.$parent; + + function represent(domainObject, representation) { + // New domain object, clear out the tool bar + parent.toolbar = {}; + scope.toolbar = parent.toolbar; + } + + return { + /** + * Set the current representation in use, and the domain + * object being represented. + * + * @param {RepresentationDefinition} representation the + * definition of the representation in use + * @param {DomainObject} domainObject the domain object + * being represented + */ + represent: represent, + /** + * Release any resources associated with this representer. + */ + destroy: function () {} + }; + } + + return ToolbarRepresenter; + + } +); \ No newline at end of file From 1b2ebf125078c94fc9febbfe722db89289dea611 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 15 Jan 2015 18:29:31 -0800 Subject: [PATCH 03/10] [Fixed] Add Fixed Position controller Add controller for fixed position view (initially, as copied from Layout view.) WTD-615. --- .../features/layout/res/templates/fixed.html | 2 - .../features/layout/src/FixedController.js | 172 ++++++++++++++++++ 2 files changed, 172 insertions(+), 2 deletions(-) create mode 100644 platform/features/layout/src/FixedController.js diff --git a/platform/features/layout/res/templates/fixed.html b/platform/features/layout/res/templates/fixed.html index 206ce97954..af63b80b68 100644 --- a/platform/features/layout/res/templates/fixed.html +++ b/platform/features/layout/res/templates/fixed.html @@ -1,8 +1,6 @@
- -
diff --git a/platform/features/layout/src/FixedController.js b/platform/features/layout/src/FixedController.js new file mode 100644 index 0000000000..10c19eb3e7 --- /dev/null +++ b/platform/features/layout/src/FixedController.js @@ -0,0 +1,172 @@ +/*global define*/ + +define( + ['./LayoutDrag'], + function (LayoutDrag) { + "use strict"; + + var DEFAULT_DIMENSIONS = [ 12, 8 ], + DEFAULT_GRID_SIZE = [32, 32]; + + /** + * The FixedController is responsible for supporting the + * Fixed Position view. It arranges frames according to saved + * configuration and provides methods for updating these based on + * mouse movement. + * @constructor + * @param {Scope} $scope the controller's Angular scope + */ + function FixedController($scope) { + var gridSize = DEFAULT_GRID_SIZE, + activeDrag, + activeDragId, + rawPositions = {}, + positions = {}; + + // Utility function to copy raw positions from configuration, + // without writing directly to configuration (to avoid triggering + // persistence from watchers during drags). + function shallowCopy(obj, keys) { + var copy = {}; + keys.forEach(function (k) { + copy[k] = obj[k]; + }); + return copy; + } + + // Convert from { positions: ..., dimensions: ... } to an + // apropriate ng-style argument, to position frames. + function convertPosition(raw) { + // Multiply position/dimensions by grid size + return { + left: (gridSize[0] * raw.position[0]) + 'px', + top: (gridSize[1] * raw.position[1]) + 'px', + width: (gridSize[0] * raw.dimensions[0]) + 'px', + height: (gridSize[1] * raw.dimensions[1]) + 'px' + }; + } + + // Generate a default position (in its raw format) for a frame. + // Use an index to ensure that default positions are unique. + function defaultPosition(index) { + return { + position: [index, index], + dimensions: DEFAULT_DIMENSIONS + }; + } + + // Store a computed position for a contained frame by its + // domain object id. Called in a forEach loop, so arguments + // are as expected there. + function populatePosition(id, index) { + rawPositions[id] = + rawPositions[id] || defaultPosition(index || 0); + positions[id] = + convertPosition(rawPositions[id]); + } + + // Compute panel positions based on the layout's object model + function lookupPanels(model) { + var configuration = $scope.configuration || {}, + ids = (model || {}).composition || []; + + // Pull panel positions from configuration + rawPositions = shallowCopy(configuration.panels || {}, ids); + + // Clear prior computed positions + positions = {}; + + // Update width/height that we are tracking + gridSize = (model || {}).layoutGrid || DEFAULT_GRID_SIZE; + + // Compute positions and add defaults where needed + ids.forEach(populatePosition); + } + + // Position panes when the model field changes + $scope.$watch("model", lookupPanels); + + return { + /** + * Get a style object for a frame with the specified domain + * object identifier, suitable for use in an `ng-style` + * directive to position a frame as configured for this layout. + * @param {string} id the object identifier + * @returns {Object.} an object with + * appropriate left, width, etc fields for positioning + */ + getStyle: function (id) { + // Called in a loop, so just look up; the "positions" + // object is kept up to date by a watch. + return positions[id]; + }, + /** + * Start a drag gesture to move/resize a frame. + * + * The provided position and dimensions factors will determine + * whether this is a move or a resize, and what type it + * will be. For instance, a position factor of [1, 1] + * will move a frame along with the mouse as the drag + * proceeds, while a dimension factor of [0, 0] will leave + * dimensions unchanged. Combining these in different + * ways results in different handles; a position factor of + * [1, 0] and a dimensions factor of [-1, 0] will implement + * a left-edge resize, as the horizontal position will move + * with the mouse while the horizontal dimensions shrink in + * kind (and vertical properties remain unmodified.) + * + * @param {string} id the identifier of the domain object + * in the frame being manipulated + * @param {number[]} posFactor the position factor + * @param {number[]} dimFactor the dimensions factor + */ + startDrag: function (id, posFactor, dimFactor) { + activeDragId = id; + activeDrag = new LayoutDrag( + rawPositions[id], + posFactor, + dimFactor, + gridSize + ); + }, + /** + * Continue an active drag gesture. + * @param {number[]} delta the offset, in pixels, + * of the current pointer position, relative + * to its position when the drag started + */ + continueDrag: function (delta) { + if (activeDrag) { + rawPositions[activeDragId] = + activeDrag.getAdjustedPosition(delta); + populatePosition(activeDragId); + } + }, + /** + * End the active drag gesture. This will update the + * view configuration. + */ + endDrag: function () { + // Write to configuration; this is watched and + // saved by the EditRepresenter. + $scope.configuration = + $scope.configuration || {}; + // Make sure there is a "panels" field in the + // view configuration. + $scope.configuration.panels = + $scope.configuration.panels || {}; + // Store the position of this panel. + $scope.configuration.panels[activeDragId] = + rawPositions[activeDragId]; + // Mark this object as dirty to encourage persistence + if ($scope.commit) { + $scope.commit("Moved frame."); + } + } + }; + + } + + return FixedController; + } +); \ No newline at end of file From d453e593086e73360e93e8dacf597e01c15de7ed Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 15 Jan 2015 18:36:48 -0800 Subject: [PATCH 04/10] [Fixed Position] Expose controller Expose Fixed Position controller in order to begin implementing Fixed Position view and editing behavior. WTD-615. --- platform/features/layout/bundle.json | 5 +++++ platform/features/layout/res/templates/fixed.html | 9 +++++---- platform/features/layout/src/FixedController.js | 12 ++++++------ 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/platform/features/layout/bundle.json b/platform/features/layout/bundle.json index 80de35aacd..5d073da347 100644 --- a/platform/features/layout/bundle.json +++ b/platform/features/layout/bundle.json @@ -31,6 +31,11 @@ "key": "LayoutController", "implementation": "LayoutController.js", "depends": [ "$scope" ] + }, + { + "key": "FixedController", + "implementation": "FixedController.js", + "depends": [ "$scope" ] } ], "types": [ diff --git a/platform/features/layout/res/templates/fixed.html b/platform/features/layout/res/templates/fixed.html index af63b80b68..3f480c72e8 100644 --- a/platform/features/layout/res/templates/fixed.html +++ b/platform/features/layout/res/templates/fixed.html @@ -4,10 +4,11 @@
-
- - +
+ {{childObject.getModel().name}} +
+
+ {{controller.getValue(childObject.getId())}}
diff --git a/platform/features/layout/src/FixedController.js b/platform/features/layout/src/FixedController.js index 10c19eb3e7..ff43e6c4b0 100644 --- a/platform/features/layout/src/FixedController.js +++ b/platform/features/layout/src/FixedController.js @@ -5,8 +5,8 @@ define( function (LayoutDrag) { "use strict"; - var DEFAULT_DIMENSIONS = [ 12, 8 ], - DEFAULT_GRID_SIZE = [32, 32]; + var DEFAULT_DIMENSIONS = [ 2, 1 ], + DEFAULT_GRID_SIZE = [64, 16]; /** * The FixedController is responsible for supporting the @@ -153,14 +153,14 @@ define( $scope.configuration || {}; // Make sure there is a "panels" field in the // view configuration. - $scope.configuration.panels = - $scope.configuration.panels || {}; + $scope.configuration.elements = + $scope.configuration.elements || {}; // Store the position of this panel. - $scope.configuration.panels[activeDragId] = + $scope.configuration.elements[activeDragId] = rawPositions[activeDragId]; // Mark this object as dirty to encourage persistence if ($scope.commit) { - $scope.commit("Moved frame."); + $scope.commit("Moved element."); } } }; From b2bfa2b09b156adfd4006ee97f08e5986d7b2c25 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 15 Jan 2015 18:48:11 -0800 Subject: [PATCH 05/10] [Fixed Position] Populate background grid Add a background grid to fixed position view, WTD-615. --- .../features/layout/res/templates/fixed.html | 14 +++++++- .../features/layout/src/FixedController.js | 35 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/platform/features/layout/res/templates/fixed.html b/platform/features/layout/res/templates/fixed.html index 3f480c72e8..1675cd2cde 100644 --- a/platform/features/layout/res/templates/fixed.html +++ b/platform/features/layout/res/templates/fixed.html @@ -1,7 +1,19 @@ -
+ +
+
+ + + +
diff --git a/platform/features/layout/src/FixedController.js b/platform/features/layout/src/FixedController.js index ff43e6c4b0..a959775120 100644 --- a/platform/features/layout/src/FixedController.js +++ b/platform/features/layout/src/FixedController.js @@ -6,7 +6,8 @@ define( "use strict"; var DEFAULT_DIMENSIONS = [ 2, 1 ], - DEFAULT_GRID_SIZE = [64, 16]; + DEFAULT_GRID_SIZE = [64, 16], + DEFAULT_GRID_EXTENT = [4, 4]; /** * The FixedController is responsible for supporting the @@ -18,8 +19,10 @@ define( */ function FixedController($scope) { var gridSize = DEFAULT_GRID_SIZE, + gridExtent = DEFAULT_GRID_EXTENT, activeDrag, activeDragId, + cellStyles = [], rawPositions = {}, positions = {}; @@ -34,6 +37,25 @@ define( return copy; } + // Refresh cell styles (e.g. because grid extent changed) + function refreshCellStyles() { + var x, y; + + cellStyles = []; + + for (x = 0; x < gridExtent[0]; x += 1) { + for (y = 0; y < gridExtent[1]; y += 1) { + // Position blocks; subtract out border size from w/h + cellStyles.push({ + left: x * gridSize[0] + 'px', + top: y * gridSize[1] + 'px', + width: gridSize[0] - 2 + 'px', + height: gridSize[1] - 2 + 'px' + }); + } + } + } + // Convert from { positions: ..., dimensions: ... } to an // apropriate ng-style argument, to position frames. function convertPosition(raw) { @@ -86,7 +108,18 @@ define( // Position panes when the model field changes $scope.$watch("model", lookupPanels); + refreshCellStyles(); + return { + /** + * Get styles for all background cells, as will populate the + * ng-style tag. + * @memberof FixedController# + * @returns {Array} cell styles + */ + getCellStyles: function () { + return cellStyles; + }, /** * Get a style object for a frame with the specified domain * object identifier, suitable for use in an `ng-style` From bd068f31c5a4d220f90723804c73cc4c3d2b08eb Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 15 Jan 2015 18:53:59 -0800 Subject: [PATCH 06/10] [Fixed Position] Fill available area with grid Fill available space with background grid for fixed position view, WTD-615. --- .../features/layout/res/templates/fixed.html | 3 ++- platform/features/layout/src/FixedController.js | 17 +++++++++++++++-- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/platform/features/layout/res/templates/fixed.html b/platform/features/layout/res/templates/fixed.html index 1675cd2cde..95af6c0c05 100644 --- a/platform/features/layout/res/templates/fixed.html +++ b/platform/features/layout/res/templates/fixed.html @@ -1,7 +1,8 @@
+ ng-controller="FixedController as controller" + mct-resize="controller.setBounds(bounds)">
Date: Thu, 15 Jan 2015 19:03:34 -0800 Subject: [PATCH 07/10] [Fixed Position] Position/style telemetry cells Position telemetry elements in fixed position view appropriately. WTD-615. --- platform/features/layout/res/templates/fixed.html | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/platform/features/layout/res/templates/fixed.html b/platform/features/layout/res/templates/fixed.html index 95af6c0c05..b7b99ec21c 100644 --- a/platform/features/layout/res/templates/fixed.html +++ b/platform/features/layout/res/templates/fixed.html @@ -10,18 +10,16 @@ ng-style="cell">
- - - +
-
+
{{childObject.getModel().name}}
-
- {{controller.getValue(childObject.getId())}} +
+ X{{controller.getValue(childObject.getId())}}
From 2960d4cdc26e9d09aac0bf6de89138010b8921e6 Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 15 Jan 2015 19:07:49 -0800 Subject: [PATCH 08/10] [Fixed Position] All subscription callback to be undefined Allow callback provided when subscribing to telemetry using telemetrySubscriber to be omitted; this permits usage of the resulting subscription more directly from controllers, such as for fixed position view, WTD-615. --- platform/telemetry/src/TelemetrySubscription.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/platform/telemetry/src/TelemetrySubscription.js b/platform/telemetry/src/TelemetrySubscription.js index 5e929d8ee4..c8d3914726 100644 --- a/platform/telemetry/src/TelemetrySubscription.js +++ b/platform/telemetry/src/TelemetrySubscription.js @@ -58,7 +58,10 @@ define( // Invoke the observer callback to notify that new streaming // data has become available. function fireCallback() { - callback(); + // Fire callback, if one was provided + if (callback) { + callback(); + } // Clear the pending flag so that future updates will // schedule this callback. updatePending = false; From ec211a067ac220aa009b062a79b94053eb96cfca Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Thu, 15 Jan 2015 19:16:15 -0800 Subject: [PATCH 09/10] [Fixed Position] Show telemetry values Show telemetry values in cells in fixed position views. WTD-615. --- platform/features/layout/bundle.json | 2 +- .../features/layout/src/FixedController.js | 47 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/platform/features/layout/bundle.json b/platform/features/layout/bundle.json index 5d073da347..760cd2a686 100644 --- a/platform/features/layout/bundle.json +++ b/platform/features/layout/bundle.json @@ -35,7 +35,7 @@ { "key": "FixedController", "implementation": "FixedController.js", - "depends": [ "$scope" ] + "depends": [ "$scope", "telemetrySubscriber", "telemetryFormatter" ] } ], "types": [ diff --git a/platform/features/layout/src/FixedController.js b/platform/features/layout/src/FixedController.js index 9ddf68d3fc..70a1ecc170 100644 --- a/platform/features/layout/src/FixedController.js +++ b/platform/features/layout/src/FixedController.js @@ -17,11 +17,13 @@ define( * @constructor * @param {Scope} $scope the controller's Angular scope */ - function FixedController($scope) { + function FixedController($scope, telemetrySubscriber, telemetryFormatter) { var gridSize = DEFAULT_GRID_SIZE, gridExtent = DEFAULT_GRID_EXTENT, activeDrag, activeDragId, + subscription, + values = {}, cellStyles = [], rawPositions = {}, positions = {}; @@ -105,9 +107,43 @@ define( ids.forEach(populatePosition); } + function updateValue(telemetryObject) { + var id = telemetryObject && telemetryObject.getId(); + if (id) { + values[id] = telemetryFormatter.formatRangeValue( + subscription.getRangeValue(telemetryObject) + ); + } + } + + // Update telemetry values based on new data available + function updateValues() { + if (subscription) { + subscription.getTelemetryObjects().forEach(updateValue); + } + } + + // Subscribe to telemetry updates for this domain object + function subscribe(domainObject) { + // Clear any old values + values = {}; + + // Release existing subscription (if any) + if (subscription) { + subscription.unsubscribe(); + } + + // Make a new subscription + subscription = domainObject && + telemetrySubscriber.subscribe(domainObject, updateValues); + } + // Position panes when the model field changes $scope.$watch("model", lookupPanels); + // Subscribe to telemetry when an object is available + $scope.$watch("domainObject", subscribe); + refreshCellStyles(); return { @@ -120,6 +156,15 @@ define( getCellStyles: function () { return cellStyles; }, + /** + * Get the current data value for the specified domain object. + * @memberof FixedController# + * @param {string} id the domain object identifier + * @returns {string} the displayable data value + */ + getValue: function (id) { + return values[id]; + }, /** * Set the size of the viewable fixed position area. * @memberof FixedController# From 082b55564478eb08e0dd40d23e924006da45a94d Mon Sep 17 00:00:00 2001 From: Victor Woeltjen Date: Fri, 16 Jan 2015 09:47:29 -0800 Subject: [PATCH 10/10] [Fixed Position] Persist drag positions Persist element positions after drag in fixed position view, WTD-615. --- platform/features/layout/res/templates/fixed.html | 2 +- platform/features/layout/src/FixedController.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/platform/features/layout/res/templates/fixed.html b/platform/features/layout/res/templates/fixed.html index b7b99ec21c..b91f3e524b 100644 --- a/platform/features/layout/res/templates/fixed.html +++ b/platform/features/layout/res/templates/fixed.html @@ -19,7 +19,7 @@ {{childObject.getModel().name}}
- X{{controller.getValue(childObject.getId())}} + {{controller.getValue(childObject.getId())}}
diff --git a/platform/features/layout/src/FixedController.js b/platform/features/layout/src/FixedController.js index 70a1ecc170..6eb93e9fc2 100644 --- a/platform/features/layout/src/FixedController.js +++ b/platform/features/layout/src/FixedController.js @@ -95,7 +95,7 @@ define( ids = (model || {}).composition || []; // Pull panel positions from configuration - rawPositions = shallowCopy(configuration.panels || {}, ids); + rawPositions = shallowCopy(configuration.elements || {}, ids); // Clear prior computed positions positions = {};