mirror of
https://github.com/nasa/openmct.git
synced 2025-06-14 13:18:15 +00:00
[Representation] Initial representation bundle
Initial transition of bundle platform/representation from sandbox branch. WTD-521.
This commit is contained in:
33
platform/representation/bundle.json
Normal file
33
platform/representation/bundle.json
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"extensions": {
|
||||||
|
"directives": [
|
||||||
|
{
|
||||||
|
"key": "mctInclude",
|
||||||
|
"implementation": "MCTInclude.js",
|
||||||
|
"depends": [ "templates[]" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "mctRepresentation",
|
||||||
|
"implementation": "MCTRepresentation.js",
|
||||||
|
"depends": [ "representations[]", "views[]", "gestures[]", "$q", "$log" ]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"gestures": [
|
||||||
|
{
|
||||||
|
"key": "drag",
|
||||||
|
"implementation": "gestures/DragGesture.js",
|
||||||
|
"depends": [ "$log" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "drop",
|
||||||
|
"implementation": "gestures/DropGesture.js",
|
||||||
|
"depends": [ "$q" ]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "menu",
|
||||||
|
"implementation": "gestures/ContextMenuGesture.js",
|
||||||
|
"depends": [ "$compile", "$document", "$window", "$rootScope" ]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
43
platform/representation/src/MCTInclude.js
Normal file
43
platform/representation/src/MCTInclude.js
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
/*global define,Promise*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module defining MCTInclude. Created by vwoeltje on 11/7/14.
|
||||||
|
*/
|
||||||
|
define(
|
||||||
|
[],
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Defines the mct-include directive. This acts like the
|
||||||
|
* ng-include directive, except it accepts a symbolic
|
||||||
|
* key which can be exposed by bundles.
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function MCTInclude(templates) {
|
||||||
|
var templateMap = {};
|
||||||
|
|
||||||
|
templates.forEach(function (template) {
|
||||||
|
var path = [
|
||||||
|
template.bundle.path,
|
||||||
|
template.bundle.resources,
|
||||||
|
template.templateUrl
|
||||||
|
].join("/");
|
||||||
|
templateMap[template.key] = path;
|
||||||
|
});
|
||||||
|
|
||||||
|
function controller($scope) {
|
||||||
|
$scope.inclusion = templateMap[$scope.key];
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
restrict: "E",
|
||||||
|
controller: controller,
|
||||||
|
template: '<ng-include src="inclusion"></ng-include>',
|
||||||
|
scope: { key: "=", ngModel: "=", parameters: "=" }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return MCTInclude;
|
||||||
|
}
|
||||||
|
);
|
122
platform/representation/src/MCTRepresentation.js
Normal file
122
platform/representation/src/MCTRepresentation.js
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
/*global define,Promise*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module defining MCTRepresentation. Created by vwoeltje on 11/7/14.
|
||||||
|
*/
|
||||||
|
define(
|
||||||
|
[],
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function MCTRepresentation(representations, views, gestures, $q, $log) {
|
||||||
|
var pathMap = {},
|
||||||
|
representationMap = {},
|
||||||
|
gestureMap = {};
|
||||||
|
|
||||||
|
// Assemble all representations and views
|
||||||
|
// The distinction between views and representations is
|
||||||
|
// not important her (view is-a representation)
|
||||||
|
representations.concat(views).forEach(function (representation) {
|
||||||
|
var path = [
|
||||||
|
representation.bundle.path,
|
||||||
|
representation.bundle.resources,
|
||||||
|
representation.templateUrl
|
||||||
|
].join("/");
|
||||||
|
|
||||||
|
// Consider allowing multiple templates with the same key
|
||||||
|
pathMap[representation.key] = path;
|
||||||
|
representationMap[representation.key] = representation;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assemble all gestures into a map, similarly
|
||||||
|
gestures.forEach(function (gesture) {
|
||||||
|
gestureMap[gesture.key] = gesture;
|
||||||
|
});
|
||||||
|
|
||||||
|
function findRepresentation(key, domainObject) {
|
||||||
|
return representationMap[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
function createGestures(element, domainObject, gestureKeys) {
|
||||||
|
return gestureKeys.map(function (key) {
|
||||||
|
return gestureMap[key];
|
||||||
|
}).filter(function (Gesture) {
|
||||||
|
return Gesture !== undefined && (Gesture.appliesTo ?
|
||||||
|
Gesture.appliesTo(domainObject) :
|
||||||
|
true);
|
||||||
|
}).map(function (Gesture) {
|
||||||
|
return new Gesture(element, domainObject);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function releaseGestures(gestures) {
|
||||||
|
gestures.forEach(function (gesture) {
|
||||||
|
if (gesture && gesture.destroy) {
|
||||||
|
gesture.destroy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function link($scope, element) {
|
||||||
|
var linkedGestures = [];
|
||||||
|
|
||||||
|
function refresh() {
|
||||||
|
var representation = representationMap[$scope.key],
|
||||||
|
domainObject = $scope.domainObject,
|
||||||
|
uses = ((representation || {}).uses || []),
|
||||||
|
gestureKeys = ((representation || {}).gestures || []);
|
||||||
|
|
||||||
|
$scope.representation = {};
|
||||||
|
$scope.inclusion = pathMap[$scope.key];
|
||||||
|
|
||||||
|
// Any existing gestures are no longer valid; release them.
|
||||||
|
releaseGestures(linkedGestures);
|
||||||
|
|
||||||
|
if (!representation && $scope.key) {
|
||||||
|
$log.warn("No representation found for " + $scope.key);
|
||||||
|
}
|
||||||
|
if (domainObject) {
|
||||||
|
$scope.model = domainObject.getModel();
|
||||||
|
|
||||||
|
uses.forEach(function (used) {
|
||||||
|
$log.debug([
|
||||||
|
"Requesting capability ",
|
||||||
|
used,
|
||||||
|
" for representation ",
|
||||||
|
$scope.key
|
||||||
|
].join(""));
|
||||||
|
$q.when(
|
||||||
|
domainObject.useCapability(used)
|
||||||
|
).then(function (c) {
|
||||||
|
$scope[used] = c;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
linkedGestures = createGestures(
|
||||||
|
element,
|
||||||
|
domainObject,
|
||||||
|
gestureKeys
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$scope.$watch("key", refresh);
|
||||||
|
$scope.$watch("domainObject", refresh);
|
||||||
|
$scope.$watch("domainObject.getModel().modified", refresh);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
restrict: "E",
|
||||||
|
link: link,
|
||||||
|
template: '<ng-include src="inclusion"></ng-include>',
|
||||||
|
scope: { key: "=", domainObject: "=mctObject", parameters: "=" }
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return MCTRepresentation;
|
||||||
|
}
|
||||||
|
);
|
86
platform/representation/src/gestures/ContextMenuGesture.js
Normal file
86
platform/representation/src/gestures/ContextMenuGesture.js
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
/*global define,Promise*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module defining ContextMenuGesture. Created by vwoeltje on 11/17/14.
|
||||||
|
*/
|
||||||
|
define(
|
||||||
|
[],
|
||||||
|
function () {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
var MENU_TEMPLATE = "<mct-representation key=\"'context-menu'\" " +
|
||||||
|
"mct-object=\"domainObject\" " +
|
||||||
|
"ng-class=\"menuClass\"" +
|
||||||
|
"ng-style=\"menuStyle\">" +
|
||||||
|
"</mct-representation>";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add listeners to a view such that it launches a context menu for the
|
||||||
|
* object it contains.
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
function ContextMenuGesture($compile, $document, $window, $rootScope, element, domainObject) {
|
||||||
|
function showMenu(event) {
|
||||||
|
var winDim = [$window.innerWidth, $window.innerHeight],
|
||||||
|
eventCoors = [event.pageX, event.pageY],
|
||||||
|
menuDim = [170, 200],
|
||||||
|
body = $document.find('body'),
|
||||||
|
scope = $rootScope.$new(),
|
||||||
|
goLeft = eventCoors[0] + menuDim[0] > winDim[0],
|
||||||
|
goUp = eventCoors[1] + menuDim[1] > winDim[1],
|
||||||
|
menu;
|
||||||
|
|
||||||
|
// Remove the context menu
|
||||||
|
function dismiss() {
|
||||||
|
menu.remove();
|
||||||
|
body.off("click", dismiss);
|
||||||
|
ContextMenuGesture.dismissExistingMenu = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Dismiss any menu which was already showing
|
||||||
|
if (ContextMenuGesture.dismissExistingMenu) {
|
||||||
|
ContextMenuGesture.dismissExistingMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
// ...and record the presence of this menu.
|
||||||
|
ContextMenuGesture.dismissExistingMenu = dismiss;
|
||||||
|
|
||||||
|
// Set up the scope, including menu positioning
|
||||||
|
scope.domainObject = domainObject;
|
||||||
|
scope.menuStyle = {};
|
||||||
|
scope.menuStyle[goLeft ? "right" : "left"] =
|
||||||
|
eventCoors[0] + 'px';
|
||||||
|
scope.menuStyle[goUp ? "bottom" : "top"] =
|
||||||
|
eventCoors[1] + 'px';
|
||||||
|
scope.menuClass = { "go-left": goLeft, "go-up": goUp, "context-menu-holder": true };
|
||||||
|
|
||||||
|
// Create the context menu
|
||||||
|
menu = $compile(MENU_TEMPLATE)(scope);
|
||||||
|
|
||||||
|
// Add the menu to the body
|
||||||
|
body.append(menu);
|
||||||
|
|
||||||
|
// Dismiss the menu when body is clicked elsewhere
|
||||||
|
body.on('click', dismiss);
|
||||||
|
|
||||||
|
// Don't launch browser's context menu
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
// When context menu event occurs, show object actions instead
|
||||||
|
element.on('contextmenu', showMenu);
|
||||||
|
|
||||||
|
return {
|
||||||
|
destroy: function () {
|
||||||
|
if (ContextMenuGesture.dismissExistingMenu) {
|
||||||
|
ContextMenuGesture.dismissExistingMenu();
|
||||||
|
}
|
||||||
|
element.off('contextmenu', showMenu);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return ContextMenuGesture;
|
||||||
|
}
|
||||||
|
);
|
61
platform/representation/src/gestures/DragGesture.js
Normal file
61
platform/representation/src/gestures/DragGesture.js
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*global define,Promise*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module defining DragGesture. Created by vwoeltje on 11/17/14.
|
||||||
|
*/
|
||||||
|
define(
|
||||||
|
['./GestureConstants'],
|
||||||
|
function (GestureConstants) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
|
||||||
|
function DragGesture($log, element, domainObject) {
|
||||||
|
function startDrag(e) {
|
||||||
|
var event = (e || {}).originalEvent || e;
|
||||||
|
|
||||||
|
$log.debug("Initiating drag");
|
||||||
|
|
||||||
|
try {
|
||||||
|
event.dataTransfer.effectAllowed = 'move';
|
||||||
|
event.dataTransfer.setData(
|
||||||
|
'text/plain',
|
||||||
|
JSON.stringify({
|
||||||
|
id: domainObject.getId(),
|
||||||
|
model: domainObject.getModel()
|
||||||
|
})
|
||||||
|
);
|
||||||
|
event.dataTransfer.setData(
|
||||||
|
GestureConstants.MCT_DRAG_TYPE,
|
||||||
|
domainObject.getId()
|
||||||
|
);
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
$log.warn([
|
||||||
|
"Could not initiate drag due to ",
|
||||||
|
err.message
|
||||||
|
].join(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$log.debug("Attaching drag gesture");
|
||||||
|
element.attr('draggable', 'true');
|
||||||
|
element.on('dragstart', startDrag);
|
||||||
|
|
||||||
|
return {
|
||||||
|
destroy: function () {
|
||||||
|
// Detach listener
|
||||||
|
element.attr('draggable', false);
|
||||||
|
element.off('dragstart', startDrag);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return DragGesture;
|
||||||
|
}
|
||||||
|
);
|
74
platform/representation/src/gestures/DropGesture.js
Normal file
74
platform/representation/src/gestures/DropGesture.js
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
/*global define,Promise*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module defining DropGesture. Created by vwoeltje on 11/17/14.
|
||||||
|
*/
|
||||||
|
define(
|
||||||
|
['./GestureConstants'],
|
||||||
|
function (GestureConstants) {
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @constructor
|
||||||
|
*/
|
||||||
|
|
||||||
|
function DropGesture($q, element, domainObject) {
|
||||||
|
|
||||||
|
function doPersist() {
|
||||||
|
var persistence = domainObject.getCapability("persistence");
|
||||||
|
return $q.when(persistence && peristence.persist());
|
||||||
|
}
|
||||||
|
|
||||||
|
function dragOver(e) {
|
||||||
|
var event = (e || {}).originalEvent || e;
|
||||||
|
//event.stopPropagation();
|
||||||
|
|
||||||
|
// TODO: Vary this based on modifier keys
|
||||||
|
event.dataTransfer.dropEffect = 'move';
|
||||||
|
event.preventDefault(); // Required in Chrome?
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function drop(e) {
|
||||||
|
var event = (e || {}).originalEvent || e,
|
||||||
|
id = event.dataTransfer.getData(GestureConstants.MCT_DRAG_TYPE);
|
||||||
|
|
||||||
|
if (id) {
|
||||||
|
$q.when(domainObject.useCapability(
|
||||||
|
'mutation',
|
||||||
|
function (model) {
|
||||||
|
var composition = model.composition;
|
||||||
|
if (composition && // not-contains
|
||||||
|
!(composition.map(function (i) {
|
||||||
|
return i === id;
|
||||||
|
}).reduce(function (a, b) {
|
||||||
|
return a || b;
|
||||||
|
}, false))) {
|
||||||
|
model.composition.push(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)).then(function (result) {
|
||||||
|
return result && doPersist();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
element.on('dragover', dragOver);
|
||||||
|
element.on('drop', drop);
|
||||||
|
|
||||||
|
return {
|
||||||
|
destroy: function () {
|
||||||
|
element.off('dragover', dragOver);
|
||||||
|
element.off('drop', drop);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return DropGesture;
|
||||||
|
}
|
||||||
|
);
|
8
platform/representation/src/gestures/GestureConstants.js
Normal file
8
platform/representation/src/gestures/GestureConstants.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
/*global define,Promise*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Module defining GestureConstants. Created by vwoeltje on 11/17/14.
|
||||||
|
*/
|
||||||
|
define({
|
||||||
|
MCT_DRAG_TYPE: 'mct-domain-object-id'
|
||||||
|
});
|
Reference in New Issue
Block a user