[Layout] Support sub-object selection in layout (#1811)

Updates to sub object selection, first cut of selection APIs.

* [API] Add inspector view registry to register inspector view providers and show a view in the inspector.

[API] Modify the selection API to register the click event and handle the event. The API will add a class to the selected object and the immediate parent of the selected object.

[Directive] Implemenet mct-selectable directive for making an element selectable.

[Layout] Update the layout controller to use the Selection API. Also, add double click gesture to allow drilling into a selected object.

Populate the Elements pool with contained elements of the selected object. Update toolbar and inspector to listen for the changes in selection.

* [Frontend] Mods to markup and CSS for sub-object selection

* MCTSelectable allows selection in initialization, use to select on navigation

[Frontend] Show grid in first nested layout, hide from deeper nesting. Only show grids when applicable to relative selection.

* Fix checkstyle and lint errors

* Bring back the change that made mct-init-select work

* [Inspector] Make sure the right content is displayed based on whether a view provider exists or not.

* Only show table options when editing

* Make reviewers' requested changes

* Fix broken tests

* [Frontend] Cleanups and tweaks

Fixes #1811
- Cleanups between frame, editor and selecting.scss;
- Hover and selected borders visually pumped up a bit;
- Solid borders on hover and selecting when browsing;
- Dashed borders for layouts when editing;
- Fixed cursor to only show move capability when
element is selected;

* [Frontend] Tweaks to frame.no-frame layout

Fixes #1811
- Margin set to 0;
- Overflow set to hidden;

* [Frontend] Fixed position items border width fixed

Fixes #1811
- Set to 1px;

* Add tests for inspector controller and fix broken tests. Clean up code.

* [Fixed Position] Stop event propagation on click handlers in fixed position to avoid the event reaching the selection click handlers which caused issues with toolbar and selection."

* Fix tests

* Add tests

* Add test

* Remove element from document
This commit is contained in:
Pegah Sarram
2017-12-07 13:04:46 -08:00
committed by Pete Richards
parent 50b4d5cb28
commit 425655bae0
34 changed files with 944 additions and 360 deletions

View File

@@ -121,7 +121,8 @@ define([
"key": "ElementsController",
"implementation": ElementsController,
"depends": [
"$scope"
"$scope",
"openmct"
]
},
{
@@ -299,9 +300,6 @@ define([
{
"key": "edit-elements",
"template": elementsTemplate,
"uses": [
"composition"
],
"gestures": [
"drop"
]
@@ -385,7 +383,10 @@ define([
]
},
{
"implementation": EditToolbarRepresenter
"implementation": EditToolbarRepresenter,
"depends": [
"openmct"
]
}
],
"constants": [

View File

@@ -61,7 +61,12 @@
<mct-representation key="representation.selected.key"
mct-object="representation.selected.key && domainObject"
class="abs flex-elem grows object-holder-main scroll"
toolbar="toolbar">
toolbar="toolbar"
mct-selectable="{
item: domainObject.useCapability('adapter'),
oldItem: domainObject
}"
mct-init-select>
</mct-representation>
</div><!--/ l-object-wrapper-inner -->
</div>

View File

@@ -25,7 +25,7 @@
ng-model="filterBy">
</mct-include>
<div class="flex-elem grows vscroll">
<ul class="tree">
<ul class="tree" ng-if="composition.length > 0">
<li ng-repeat="containedObject in composition | filter:searchElements">
<span class="tree-item">
<mct-representation
@@ -36,5 +36,6 @@
</span>
</li>
</ul>
<div ng-if="composition.length === 0">No contained elements</div>
</div>
</div>

View File

@@ -29,7 +29,11 @@ define(
*
* @constructor
*/
function ElementsController($scope) {
function ElementsController($scope, openmct) {
this.scope = $scope;
this.scope.composition = [];
var self = this;
function filterBy(text) {
if (typeof text === 'undefined') {
return $scope.searchText;
@@ -47,10 +51,44 @@ define(
}
}
function setSelection(selection) {
self.scope.selection = selection;
self.refreshComposition(selection);
}
$scope.filterBy = filterBy;
$scope.searchElements = searchElements;
openmct.selection.on('change', setSelection);
setSelection(openmct.selection.get());
$scope.$on("$destroy", function () {
openmct.selection.off("change", setSelection);
});
}
/**
* Gets the composition for the selected object and populates the scope with it.
*
* @param selection the selection object
* @private
*/
ElementsController.prototype.refreshComposition = function (selection) {
if (!selection[0]) {
return;
}
var selectedObjectComposition = selection[0].context.oldItem.useCapability('composition');
if (selectedObjectComposition) {
selectedObjectComposition.then(function (composition) {
this.scope.composition = composition;
}.bind(this));
} else {
this.scope.composition = [];
}
};
return ElementsController;
}
);

View File

@@ -38,7 +38,7 @@ define(
* @constructor
* @implements {Representer}
*/
function EditToolbarRepresenter(scope, element, attrs) {
function EditToolbarRepresenter(openmct, scope, element, attrs) {
var self = this;
// Mark changes as ready to persist
@@ -109,6 +109,7 @@ define(
this.updateSelection = updateSelection;
this.toolbar = undefined;
this.toolbarObject = {};
this.openmct = openmct;
// If this representation exposes a toolbar, set up watches
// to synchronize with it.
@@ -146,7 +147,7 @@ define(
// Expose the toolbar object to the parent scope
initialize(definition);
// Create a selection scope
this.setSelection(new EditToolbarSelection());
this.setSelection(new EditToolbarSelection(this.openmct));
// Initialize toolbar to an empty selection
this.updateSelection([]);
};

View File

@@ -38,10 +38,18 @@ define(
* @memberof platform/commonUI/edit
* @constructor
*/
function EditToolbarSelection() {
function EditToolbarSelection(openmct) {
this.selection = [{}];
this.selecting = false;
this.selectedObj = undefined;
openmct.selection.on('change', function (selection) {
if (selection[0] && selection[0].context.toolbar) {
this.select(selection[0].context.toolbar);
} else {
this.deselect();
}
}.bind(this));
}
/**

View File

@@ -27,11 +27,23 @@ define(
describe("The Elements Pane controller", function () {
var mockScope,
mockOpenMCT,
mockSelection,
controller;
beforeEach(function () {
mockScope = jasmine.createSpy("$scope");
controller = new ElementsController(mockScope);
mockScope = jasmine.createSpyObj("$scope", ['$on']);
mockSelection = jasmine.createSpyObj("selection", [
'on',
'off',
'get'
]);
mockSelection.get.andReturn([]);
mockOpenMCT = {
selection: mockSelection
};
controller = new ElementsController(mockScope, mockOpenMCT);
});
function getModel(model) {

View File

@@ -29,7 +29,9 @@ define(
mockElement,
testAttrs,
mockUnwatch,
representer;
representer,
mockOpenMCT,
mockSelection;
beforeEach(function () {
mockScope = jasmine.createSpyObj(
@@ -46,7 +48,18 @@ define(
mockScope.$parent.$watchCollection.andReturn(mockUnwatch);
mockSelection = jasmine.createSpyObj("selection", [
'on',
'off',
'get'
]);
mockSelection.get.andReturn([]);
mockOpenMCT = {
selection: mockSelection
};
representer = new EditToolbarRepresenter(
mockOpenMCT,
mockScope,
mockElement,
testAttrs

View File

@@ -28,13 +28,25 @@ define(
var testProxy,
testElement,
otherElement,
selection;
selection,
mockSelection,
mockOpenMCT;
beforeEach(function () {
testProxy = { someKey: "some value" };
testElement = { someOtherKey: "some other value" };
otherElement = { yetAnotherKey: 42 };
selection = new EditToolbarSelection();
mockSelection = jasmine.createSpyObj("selection", [
// 'select',
'on',
'off',
'get'
]);
mockSelection.get.andReturn([]);
mockOpenMCT = {
selection: mockSelection
};
selection = new EditToolbarSelection(mockOpenMCT);
selection.proxy(testProxy);
});