mirror of
https://github.com/nasa/openmct.git
synced 2025-06-25 18:50:11 +00:00
Compare commits
40 Commits
tables-rem
...
tcr-fixes-
Author | SHA1 | Date | |
---|---|---|---|
07c2b0820a | |||
a0d2cd5711 | |||
2d8f58573d | |||
e4e7ecd74e | |||
f148583318 | |||
514896884f | |||
fc024e583e | |||
7f2f060417 | |||
a94d50226a | |||
6eda100af8 | |||
782ee9aa37 | |||
29e94befe8 | |||
24a1e9ba75 | |||
edeefe8f2f | |||
d263723a0c | |||
666bb41697 | |||
b74c14b334 | |||
d8f733d424 | |||
b39f3fab3f | |||
4912188fe4 | |||
e254fafb5c | |||
1dc1cc6c24 | |||
baa5d10009 | |||
58048d44b2 | |||
775e93484e | |||
0e27234389 | |||
ac2b9acccb | |||
075d4deecb | |||
ac11f898d4 | |||
dd31de6935 | |||
15d4b1a8e5 | |||
9e811e722f | |||
8ef53d85c4 | |||
abcc5cb023 | |||
931871ff95 | |||
6b1e8862ef | |||
00ce246fc5 | |||
c0c7d96429 | |||
92b2582d0d | |||
4084a1ac86 |
@ -43,15 +43,14 @@ define([
|
|||||||
form: [
|
form: [
|
||||||
{
|
{
|
||||||
name: "State Duration (seconds)",
|
name: "State Duration (seconds)",
|
||||||
control: "textfield",
|
control: "numberfield",
|
||||||
cssClass: "l-input-sm l-numeric",
|
cssClass: "l-input-sm l-numeric",
|
||||||
key: "duration",
|
key: "duration",
|
||||||
required: true,
|
required: true,
|
||||||
property: [
|
property: [
|
||||||
"telemetry",
|
"telemetry",
|
||||||
"duration"
|
"duration"
|
||||||
],
|
]
|
||||||
pattern: "^\\d*(\\.\\d*)?$"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
initialize: function (object) {
|
initialize: function (object) {
|
||||||
|
@ -49,7 +49,6 @@
|
|||||||
openmct.install(openmct.plugins.ExampleImagery());
|
openmct.install(openmct.plugins.ExampleImagery());
|
||||||
openmct.install(openmct.plugins.UTCTimeSystem());
|
openmct.install(openmct.plugins.UTCTimeSystem());
|
||||||
openmct.install(openmct.plugins.ImportExport());
|
openmct.install(openmct.plugins.ImportExport());
|
||||||
openmct.install(openmct.plugins.FixedView());
|
|
||||||
openmct.install(openmct.plugins.AutoflowView({
|
openmct.install(openmct.plugins.AutoflowView({
|
||||||
type: "telemetry.panel"
|
type: "telemetry.panel"
|
||||||
}));
|
}));
|
||||||
|
@ -25,7 +25,7 @@
|
|||||||
"eventemitter3": "^1.2.0",
|
"eventemitter3": "^1.2.0",
|
||||||
"exports-loader": "^0.7.0",
|
"exports-loader": "^0.7.0",
|
||||||
"express": "^4.13.1",
|
"express": "^4.13.1",
|
||||||
"fast-sass-loader": "^1.4.5",
|
"fast-sass-loader": "1.4.6",
|
||||||
"file-loader": "^1.1.11",
|
"file-loader": "^1.1.11",
|
||||||
"file-saver": "^1.3.8",
|
"file-saver": "^1.3.8",
|
||||||
"git-rev-sync": "^1.4.0",
|
"git-rev-sync": "^1.4.0",
|
||||||
|
@ -92,16 +92,7 @@ function (
|
|||||||
* @memberof platform/commonUI/edit.SaveAction#
|
* @memberof platform/commonUI/edit.SaveAction#
|
||||||
*/
|
*/
|
||||||
SaveAsAction.prototype.perform = function () {
|
SaveAsAction.prototype.perform = function () {
|
||||||
// Discard the current root view (which will be the editing
|
return this.save();
|
||||||
// UI, which will have been pushed atop the Browse UI.)
|
|
||||||
function returnToBrowse(object) {
|
|
||||||
if (object) {
|
|
||||||
object.getCapability("action").perform("navigate");
|
|
||||||
}
|
|
||||||
return object;
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.save().then(returnToBrowse);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -169,15 +160,17 @@ function (
|
|||||||
}
|
}
|
||||||
|
|
||||||
function saveAfterClone(clonedObject) {
|
function saveAfterClone(clonedObject) {
|
||||||
return domainObject.getCapability("editor").save()
|
return this.openmct.editor.save().then(() => {
|
||||||
.then(resolveWith(clonedObject));
|
// Force mutation for search indexing
|
||||||
|
clonedObject.useCapability('mutation', (model) => {
|
||||||
|
return model;
|
||||||
|
});
|
||||||
|
return clonedObject;
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishEditing(clonedObject) {
|
function finishEditing(clonedObject) {
|
||||||
return domainObject.getCapability("editor").finish()
|
return fetchObject(clonedObject.getId())
|
||||||
.then(function () {
|
|
||||||
return fetchObject(clonedObject.getId());
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onSuccess(object) {
|
function onSuccess(object) {
|
||||||
@ -190,7 +183,7 @@ function (
|
|||||||
if (reason !== "user canceled") {
|
if (reason !== "user canceled") {
|
||||||
self.notificationService.error("Save Failed");
|
self.notificationService.error("Save Failed");
|
||||||
}
|
}
|
||||||
return false;
|
throw reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
return getParent(domainObject)
|
return getParent(domainObject)
|
||||||
|
@ -65,24 +65,33 @@ define(
|
|||||||
CreateAction.prototype.perform = function () {
|
CreateAction.prototype.perform = function () {
|
||||||
var newModel = this.type.getInitialModel(),
|
var newModel = this.type.getInitialModel(),
|
||||||
openmct = this.openmct,
|
openmct = this.openmct,
|
||||||
newObject,
|
newObject;
|
||||||
editAction;
|
|
||||||
|
|
||||||
function onSave() {
|
|
||||||
openmct.editor.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
function onCancel() {
|
function onCancel() {
|
||||||
openmct.editor.cancel();
|
openmct.editor.cancel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function navigateAndEdit(object) {
|
||||||
|
let objectPath = object.getCapability('context').getPath(),
|
||||||
|
url = '#/browse/' + objectPath
|
||||||
|
.map(function (o) {
|
||||||
|
return o && openmct.objects.makeKeyString(o.getId())
|
||||||
|
})
|
||||||
|
.join('/');
|
||||||
|
|
||||||
|
window.location.href = url;
|
||||||
|
|
||||||
|
openmct.editor.edit();
|
||||||
|
}
|
||||||
|
|
||||||
newModel.type = this.type.getKey();
|
newModel.type = this.type.getKey();
|
||||||
newModel.location = this.parent.getId();
|
newModel.location = this.parent.getId();
|
||||||
newObject = this.parent.useCapability('instantiation', newModel);
|
newObject = this.parent.useCapability('instantiation', newModel);
|
||||||
|
|
||||||
openmct.editor.edit();
|
openmct.editor.edit();
|
||||||
editAction = newObject.getCapability("action").getActions("edit")[0];
|
newObject.getCapability("action").perform("save-as")
|
||||||
newObject.getCapability("action").perform("save-as").then(onSave, onCancel);
|
.then(navigateAndEdit, onCancel)
|
||||||
|
|
||||||
// TODO: support editing object without saving object first.
|
// TODO: support editing object without saving object first.
|
||||||
// Which means we have to toggle createwizard afterwards. For now,
|
// Which means we have to toggle createwizard afterwards. For now,
|
||||||
// We will disable this.
|
// We will disable this.
|
||||||
|
@ -1,475 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define([
|
|
||||||
"./src/FixedController",
|
|
||||||
"./templates/fixed.html",
|
|
||||||
"./templates/frame.html",
|
|
||||||
"./templates/elements/telemetry.html",
|
|
||||||
"./templates/elements/box.html",
|
|
||||||
"./templates/elements/line.html",
|
|
||||||
"./templates/elements/text.html",
|
|
||||||
"./templates/elements/image.html",
|
|
||||||
"legacyRegistry"
|
|
||||||
], function (
|
|
||||||
FixedController,
|
|
||||||
fixedTemplate,
|
|
||||||
frameTemplate,
|
|
||||||
telemetryTemplate,
|
|
||||||
boxTemplate,
|
|
||||||
lineTemplate,
|
|
||||||
textTemplate,
|
|
||||||
imageTemplate,
|
|
||||||
legacyRegistry
|
|
||||||
) {
|
|
||||||
return function() {
|
|
||||||
return function (openmct) {
|
|
||||||
openmct.legacyRegistry.register("platform/features/fixed", {
|
|
||||||
"name": "Fixed position components.",
|
|
||||||
"description": "Plug in adding Fixed Position object type.",
|
|
||||||
"extensions": {
|
|
||||||
"views": [
|
|
||||||
{
|
|
||||||
"key": "fixed-display",
|
|
||||||
"name": "Fixed Position Display",
|
|
||||||
"cssClass": "icon-box-with-dashed-lines",
|
|
||||||
"type": "telemetry.fixed",
|
|
||||||
"template": fixedTemplate,
|
|
||||||
"uses": ["composition"],
|
|
||||||
"editable": true
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"templates": [
|
|
||||||
{
|
|
||||||
"key": "fixed.telemetry",
|
|
||||||
"template": telemetryTemplate
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "fixed.box",
|
|
||||||
"template": boxTemplate
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "fixed.line",
|
|
||||||
"template": lineTemplate
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "fixed.text",
|
|
||||||
"template": textTemplate
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "fixed.image",
|
|
||||||
"template": imageTemplate
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"controllers": [
|
|
||||||
{
|
|
||||||
"key": "FixedController",
|
|
||||||
"implementation": FixedController,
|
|
||||||
"depends": [
|
|
||||||
"$scope",
|
|
||||||
"$q",
|
|
||||||
"dialogService",
|
|
||||||
"openmct",
|
|
||||||
"$element"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"toolbars": [
|
|
||||||
{
|
|
||||||
name: "Fixed Position Toolbar",
|
|
||||||
key: "fixed.position",
|
|
||||||
description: "Toolbar for the selected element inside a fixed position display.",
|
|
||||||
forSelection: function (selection) {
|
|
||||||
if (!selection) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (openmct.editor.isEditing() &&
|
|
||||||
selection[0] && selection[0].context.elementProxy &&
|
|
||||||
((selection[1] && selection[1].context.item.type === 'telemetry.fixed') ||
|
|
||||||
(selection[0] && selection[0].context.item && selection[0].context.item.type === 'telemetry.fixed')));
|
|
||||||
},
|
|
||||||
toolbar: function (selection) {
|
|
||||||
var imageProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "height", "width", "url"];
|
|
||||||
var boxProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "height", "width", "fill"];
|
|
||||||
var textProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "height", "width", "fill", "color", "size", "text"];
|
|
||||||
var lineProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "x2", "y2"];
|
|
||||||
var telemetryProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "height", "width", "fill", "color", "size", "titled"];
|
|
||||||
var fixedPageProperties = ["add"];
|
|
||||||
|
|
||||||
var properties = [],
|
|
||||||
fixedItem = selection[0] && selection[0].context.item,
|
|
||||||
elementProxy = selection[0] && selection[0].context.elementProxy,
|
|
||||||
domainObject = selection[1] && selection[1].context.item,
|
|
||||||
path;
|
|
||||||
|
|
||||||
if (elementProxy) {
|
|
||||||
var type = elementProxy.element.type;
|
|
||||||
path = "configuration['fixed-display'].elements[" + elementProxy.index + "]";
|
|
||||||
properties =
|
|
||||||
type === 'fixed.image' ? imageProperties :
|
|
||||||
type === 'fixed.text' ? textProperties :
|
|
||||||
type === 'fixed.box' ? boxProperties :
|
|
||||||
type === 'fixed.line' ? lineProperties :
|
|
||||||
type === 'fixed.telemetry' ? telemetryProperties : [];
|
|
||||||
} else if (fixedItem) {
|
|
||||||
properties = domainObject && domainObject.type === 'layout' ? [] : fixedPageProperties;
|
|
||||||
}
|
|
||||||
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
control: "menu",
|
|
||||||
domainObject: domainObject || selection[0].context.item,
|
|
||||||
method: function (option) {
|
|
||||||
selection[0].context.fixedController.add(option.key);
|
|
||||||
},
|
|
||||||
key: "add",
|
|
||||||
icon: "icon-plus",
|
|
||||||
label: "Add",
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
"name": "Box",
|
|
||||||
"class": "icon-box",
|
|
||||||
"key": "fixed.box"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Line",
|
|
||||||
"class": "icon-line-horz",
|
|
||||||
"key": "fixed.line"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Text",
|
|
||||||
"class": "icon-T",
|
|
||||||
"key": "fixed.text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Image",
|
|
||||||
"class": "icon-image",
|
|
||||||
"key": "fixed.image"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "menu",
|
|
||||||
domainObject: domainObject,
|
|
||||||
method: function (option) {
|
|
||||||
console.log('option', option)
|
|
||||||
selection[0].context.fixedController.order(
|
|
||||||
selection[0].context.elementProxy,
|
|
||||||
option.key
|
|
||||||
);
|
|
||||||
},
|
|
||||||
key: "order",
|
|
||||||
icon: "icon-layers",
|
|
||||||
title: "Move the selected object above or below other objects",
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
"name": "Move to Top",
|
|
||||||
"class": "icon-arrow-double-up",
|
|
||||||
"key": "top"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Move Up",
|
|
||||||
"class": "icon-arrow-up",
|
|
||||||
"key": "up"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Move Down",
|
|
||||||
"class": "icon-arrow-down",
|
|
||||||
"key": "down"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Move to Bottom",
|
|
||||||
"class": "icon-arrow-double-down",
|
|
||||||
"key": "bottom"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "color-picker",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".fill",
|
|
||||||
icon: "icon-paint-bucket",
|
|
||||||
title: "Set fill color",
|
|
||||||
key: 'fill'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "color-picker",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".stroke",
|
|
||||||
icon: "icon-line-horz",
|
|
||||||
title: "Set border color",
|
|
||||||
key: 'stroke'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "button",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".url",
|
|
||||||
icon: "icon-image",
|
|
||||||
title: "Edit image properties",
|
|
||||||
key: 'url',
|
|
||||||
dialog: {
|
|
||||||
control: "input",
|
|
||||||
type: "text",
|
|
||||||
name: "Image URL",
|
|
||||||
class: "l-input-lg",
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "color-picker",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".color",
|
|
||||||
icon: "icon-T",
|
|
||||||
mandatory: true,
|
|
||||||
title: "Set text color",
|
|
||||||
key: 'color'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "select-menu",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".size",
|
|
||||||
title: "Set text size",
|
|
||||||
key: 'size',
|
|
||||||
options: [9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 30, 36, 48, 72, 96].map(function (size) {
|
|
||||||
return { "value": size + "px"};
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".x",
|
|
||||||
label: "X",
|
|
||||||
title: "X position",
|
|
||||||
key: "x",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".y",
|
|
||||||
label: "Y",
|
|
||||||
title: "Y position",
|
|
||||||
key: "y",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".x",
|
|
||||||
label: "X1",
|
|
||||||
title: "X1 position",
|
|
||||||
key: "x1",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".y",
|
|
||||||
label: "Y1",
|
|
||||||
title: "Y1 position",
|
|
||||||
key: "y1",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".x2",
|
|
||||||
label: "X2",
|
|
||||||
title: "X2 position",
|
|
||||||
key: "x2",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".y2",
|
|
||||||
label: "Y2",
|
|
||||||
title: "Y2 position",
|
|
||||||
key: "y2",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "0"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".height",
|
|
||||||
label: "H",
|
|
||||||
title: "Resize object height",
|
|
||||||
key: "height",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".width",
|
|
||||||
label: "W",
|
|
||||||
title: "Resize object width",
|
|
||||||
key: "width",
|
|
||||||
class: "l-input-sm",
|
|
||||||
min: "1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "toggle-button",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".useGrid",
|
|
||||||
key: "useGrid",
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
value: true,
|
|
||||||
icon: 'icon-grid-snap-to',
|
|
||||||
title: 'Snap to grid'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: false,
|
|
||||||
icon: 'icon-grid-snap-no',
|
|
||||||
title: "Do not snap to grid"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "button",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".text",
|
|
||||||
icon: "icon-gear",
|
|
||||||
title: "Edit text properties",
|
|
||||||
key: "text",
|
|
||||||
dialog: {
|
|
||||||
control: "input",
|
|
||||||
type: "text",
|
|
||||||
name: "Text",
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "toggle-button",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".titled",
|
|
||||||
key: "titled",
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
value: true,
|
|
||||||
icon: 'icon-two-parts-both',
|
|
||||||
title: 'Show label'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
value: false,
|
|
||||||
icon: 'icon-two-parts-one-only',
|
|
||||||
title: "Hide label"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "button",
|
|
||||||
domainObject: domainObject,
|
|
||||||
method: function () {
|
|
||||||
selection[0].context.fixedController.remove(
|
|
||||||
selection[0].context.elementProxy
|
|
||||||
);
|
|
||||||
},
|
|
||||||
key: "remove",
|
|
||||||
icon: "icon-trash"
|
|
||||||
}
|
|
||||||
].filter(function (item) {
|
|
||||||
var filtered;
|
|
||||||
|
|
||||||
properties.forEach(function (property) {
|
|
||||||
if (item.property && item.key === property ||
|
|
||||||
item.method && item.key === property) {
|
|
||||||
filtered = item;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return filtered;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"key": "telemetry.fixed",
|
|
||||||
"name": "Fixed Position Display",
|
|
||||||
"cssClass": "icon-box-with-dashed-lines",
|
|
||||||
"description": "Collect and display telemetry elements in " +
|
|
||||||
"alphanumeric format in a simple canvas workspace. " +
|
|
||||||
"Elements can be positioned and sized. " +
|
|
||||||
"Lines, boxes and images can be added as well.",
|
|
||||||
"priority": 899,
|
|
||||||
"delegates": [
|
|
||||||
"telemetry"
|
|
||||||
],
|
|
||||||
"features": "creation",
|
|
||||||
"contains": [
|
|
||||||
{
|
|
||||||
"has": "telemetry"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"model": {
|
|
||||||
"layoutGrid": [64, 16],
|
|
||||||
"composition": []
|
|
||||||
},
|
|
||||||
"properties": [
|
|
||||||
{
|
|
||||||
"name": "Layout Grid",
|
|
||||||
"control": "composite",
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"name": "Horizontal grid (px)",
|
|
||||||
"control": "textfield",
|
|
||||||
"cssClass": "l-input-sm l-numeric"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Vertical grid (px)",
|
|
||||||
"control": "textfield",
|
|
||||||
"cssClass": "l-input-sm l-numeric"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"pattern": "^(\\d*[1-9]\\d*)?$",
|
|
||||||
"property": "layoutGrid",
|
|
||||||
"conversion": "number[]"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"views": [
|
|
||||||
"fixed-display"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
openmct.legacyRegistry.enable("platform/features/fixed");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
@ -1,720 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
[
|
|
||||||
'lodash',
|
|
||||||
'./FixedProxy',
|
|
||||||
'./elements/ElementProxies',
|
|
||||||
'./FixedDragHandle',
|
|
||||||
'../../../../src/api/objects/object-utils'
|
|
||||||
],
|
|
||||||
function (
|
|
||||||
_,
|
|
||||||
FixedProxy,
|
|
||||||
ElementProxies,
|
|
||||||
FixedDragHandle,
|
|
||||||
objectUtils
|
|
||||||
) {
|
|
||||||
|
|
||||||
var DEFAULT_DIMENSIONS = [2, 1];
|
|
||||||
|
|
||||||
// Convert from element x/y/width/height to an
|
|
||||||
// appropriate ng-style argument, to position elements.
|
|
||||||
function convertPosition(elementProxy) {
|
|
||||||
if (elementProxy.getStyle) {
|
|
||||||
return elementProxy.getStyle();
|
|
||||||
}
|
|
||||||
|
|
||||||
var gridSize = elementProxy.getGridSize();
|
|
||||||
|
|
||||||
// Multiply position/dimensions by grid size
|
|
||||||
return {
|
|
||||||
left: (gridSize[0] * elementProxy.element.x) + 'px',
|
|
||||||
top: (gridSize[1] * elementProxy.element.y) + 'px',
|
|
||||||
width: (gridSize[0] * elementProxy.element.width) + 'px',
|
|
||||||
height: (gridSize[1] * elementProxy.element.height) + 'px'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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.
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param {Scope} $scope the controller's Angular scope
|
|
||||||
*/
|
|
||||||
function FixedController($scope, $q, dialogService, openmct, $element) {
|
|
||||||
this.names = {}; // Cache names by ID
|
|
||||||
this.values = {}; // Cache values by ID
|
|
||||||
this.elementProxiesById = {};
|
|
||||||
this.telemetryObjects = {};
|
|
||||||
this.subscriptions = {};
|
|
||||||
this.openmct = openmct;
|
|
||||||
this.$element = $element;
|
|
||||||
this.$scope = $scope;
|
|
||||||
this.dialogService = dialogService;
|
|
||||||
this.$q = $q;
|
|
||||||
this.newDomainObject = $scope.domainObject.useCapability('adapter');
|
|
||||||
this.fixedViewSelectable = false;
|
|
||||||
|
|
||||||
var self = this;
|
|
||||||
[
|
|
||||||
'digest',
|
|
||||||
'fetchHistoricalData',
|
|
||||||
'getTelemetry',
|
|
||||||
'setDisplayedValue',
|
|
||||||
'subscribeToObject',
|
|
||||||
'unsubscribe',
|
|
||||||
'updateView'
|
|
||||||
].forEach(function (name) {
|
|
||||||
self[name] = self[name].bind(self);
|
|
||||||
});
|
|
||||||
|
|
||||||
// Decorate an element for display
|
|
||||||
function makeProxyElement(element, index, elements) {
|
|
||||||
var ElementProxy = ElementProxies[element.type],
|
|
||||||
e = ElementProxy && new ElementProxy(element, index, elements, self.gridSize);
|
|
||||||
|
|
||||||
if (e) {
|
|
||||||
// Provide a displayable position (convert from grid to px)
|
|
||||||
e.style = convertPosition(e);
|
|
||||||
// Template names are same as type names, presently
|
|
||||||
e.template = element.type;
|
|
||||||
}
|
|
||||||
|
|
||||||
return e;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decorate elements in the current configuration
|
|
||||||
function refreshElements() {
|
|
||||||
var elements = (((self.newDomainObject.configuration || {})['fixed-display'] || {}).elements || []);
|
|
||||||
|
|
||||||
// Create the new proxies...
|
|
||||||
self.elementProxies = elements.map(makeProxyElement);
|
|
||||||
|
|
||||||
if (self.selectedElementProxy) {
|
|
||||||
// If selection is not in array, select parent.
|
|
||||||
// Otherwise, set the element to select after refresh.
|
|
||||||
var index = elements.indexOf(self.selectedElementProxy.element);
|
|
||||||
if (index === -1) {
|
|
||||||
self.$element[0].click();
|
|
||||||
} else if (!self.elementToSelectAfterRefresh) {
|
|
||||||
self.elementToSelectAfterRefresh = self.elementProxies[index].element;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, rebuild lists of elements by id to
|
|
||||||
// facilitate faster update when new telemetry comes in.
|
|
||||||
self.elementProxiesById = {};
|
|
||||||
self.elementProxies.forEach(function (elementProxy) {
|
|
||||||
var id = elementProxy.id;
|
|
||||||
if (elementProxy.element.type === 'fixed.telemetry') {
|
|
||||||
// Provide it a cached name/value to avoid flashing
|
|
||||||
elementProxy.name = self.names[id];
|
|
||||||
elementProxy.value = self.values[id];
|
|
||||||
self.elementProxiesById[id] = self.elementProxiesById[id] || [];
|
|
||||||
self.elementProxiesById[id].push(elementProxy);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Trigger a new query for telemetry data
|
|
||||||
function updateDisplayBounds(bounds, isTick) {
|
|
||||||
if (!isTick) {
|
|
||||||
//Reset values
|
|
||||||
self.values = {};
|
|
||||||
refreshElements();
|
|
||||||
|
|
||||||
//Fetch new data
|
|
||||||
Object.values(self.telemetryObjects).forEach(function (object) {
|
|
||||||
self.fetchHistoricalData(object);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add an element to this view
|
|
||||||
function addElement(element) {
|
|
||||||
var index;
|
|
||||||
var elements = (((self.newDomainObject.configuration || {})['fixed-display'] || {}).elements || []);
|
|
||||||
elements.push(element);
|
|
||||||
|
|
||||||
if (self.selectedElementProxy) {
|
|
||||||
index = elements.indexOf(self.selectedElementProxy.element);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.mutate("configuration['fixed-display'].elements", elements);
|
|
||||||
elements = (self.newDomainObject.configuration)['fixed-display'].elements || [];
|
|
||||||
self.elementToSelectAfterRefresh = elements[elements.length - 1];
|
|
||||||
|
|
||||||
if (self.selectedElementProxy) {
|
|
||||||
// Update the selected element with the new
|
|
||||||
// value since newDomainOject is mutated.
|
|
||||||
self.selectedElementProxy.element = elements[index];
|
|
||||||
}
|
|
||||||
refreshElements();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Position a panel after a drop event
|
|
||||||
function handleDrop(e, id, position) {
|
|
||||||
// Don't handle this event if it has already been handled
|
|
||||||
if (e.defaultPrevented) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
// Store the position of this element.
|
|
||||||
// color is set to "" to let the CSS theme determine the default color
|
|
||||||
addElement({
|
|
||||||
type: "fixed.telemetry",
|
|
||||||
x: Math.floor(position.x / self.gridSize[0]),
|
|
||||||
y: Math.floor(position.y / self.gridSize[1]),
|
|
||||||
id: id,
|
|
||||||
stroke: "transparent",
|
|
||||||
color: "",
|
|
||||||
titled: true,
|
|
||||||
width: DEFAULT_DIMENSIONS[0],
|
|
||||||
height: DEFAULT_DIMENSIONS[1],
|
|
||||||
useGrid: true
|
|
||||||
});
|
|
||||||
|
|
||||||
// Subscribe to the new object to get telemetry
|
|
||||||
self.openmct.objects.get(id).then(function (object) {
|
|
||||||
self.getTelemetry(object);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.elementProxies = [];
|
|
||||||
this.addElement = addElement;
|
|
||||||
this.refreshElements = refreshElements;
|
|
||||||
this.fixedProxy = new FixedProxy(this.addElement, this.$q, this.dialogService);
|
|
||||||
|
|
||||||
this.composition = this.openmct.composition.get(this.newDomainObject);
|
|
||||||
this.composition.on('add', this.onCompositionAdd, this);
|
|
||||||
this.composition.on('remove', this.onCompositionRemove, this);
|
|
||||||
this.composition.load();
|
|
||||||
|
|
||||||
// Position panes where they are dropped
|
|
||||||
$scope.$on("mctDrop", handleDrop);
|
|
||||||
|
|
||||||
$scope.$on("$destroy", this.destroy.bind(this));
|
|
||||||
|
|
||||||
// Respond to external bounds changes
|
|
||||||
this.openmct.time.on("bounds", updateDisplayBounds);
|
|
||||||
|
|
||||||
this.openmct.selection.on('change', this.setSelection.bind(this));
|
|
||||||
this.openmct.editor.on('isEditing', this.handleEditing.bind(this));
|
|
||||||
|
|
||||||
this.$element.on('click', this.bypassSelection.bind(this));
|
|
||||||
this.unlisten = this.openmct.objects.observe(this.newDomainObject, '*', function (obj) {
|
|
||||||
this.newDomainObject = JSON.parse(JSON.stringify(obj));
|
|
||||||
this.updateElementPositions(this.newDomainObject.layoutGrid);
|
|
||||||
}.bind(this));
|
|
||||||
|
|
||||||
this.updateElementPositions(this.newDomainObject.layoutGrid);
|
|
||||||
refreshElements();
|
|
||||||
}
|
|
||||||
|
|
||||||
FixedController.prototype.updateElementPositions = function (layoutGrid) {
|
|
||||||
this.gridSize = layoutGrid;
|
|
||||||
|
|
||||||
this.elementProxies.forEach(function (elementProxy) {
|
|
||||||
elementProxy.setGridSize(this.gridSize);
|
|
||||||
elementProxy.style = convertPosition(elementProxy);
|
|
||||||
}.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.onCompositionAdd = function (object) {
|
|
||||||
this.getTelemetry(object);
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.onCompositionRemove = function (identifier) {
|
|
||||||
// Defer mutation of newDomainObject to prevent mutating an
|
|
||||||
// outdated version since this is triggered by a composition change.
|
|
||||||
setTimeout(function () {
|
|
||||||
var id = objectUtils.makeKeyString(identifier);
|
|
||||||
var elements = this.newDomainObject.configuration['fixed-display'].elements || [];
|
|
||||||
var newElements = elements.filter(function (proxy) {
|
|
||||||
return proxy.id !== id;
|
|
||||||
});
|
|
||||||
this.mutate("configuration['fixed-display'].elements", newElements);
|
|
||||||
|
|
||||||
if (this.subscriptions[id]) {
|
|
||||||
this.subscriptions[id]();
|
|
||||||
delete this.subscriptions[id];
|
|
||||||
}
|
|
||||||
|
|
||||||
delete this.telemetryObjects[id];
|
|
||||||
this.refreshElements();
|
|
||||||
}.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes an element from the view.
|
|
||||||
*
|
|
||||||
* @param {Object} elementProxy the element proxy to remove.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.remove = function (elementProxy) {
|
|
||||||
var element = elementProxy.element;
|
|
||||||
var elements = this.newDomainObject.configuration['fixed-display'].elements || [];
|
|
||||||
elements.splice(elements.indexOf(element), 1);
|
|
||||||
|
|
||||||
if (element.type === 'fixed.telemetry') {
|
|
||||||
this.newDomainObject.composition = this.newDomainObject.composition.filter(function (identifier) {
|
|
||||||
return objectUtils.makeKeyString(identifier) !== element.id;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.mutate("configuration['fixed-display'].elements", elements);
|
|
||||||
this.refreshElements();
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a new element to the view.
|
|
||||||
*
|
|
||||||
* @param {string} type the type of element to add. Supported types are:
|
|
||||||
* `fixed.image`
|
|
||||||
* `fixed.box`
|
|
||||||
* `fixed.text`
|
|
||||||
* `fixed.line`
|
|
||||||
*/
|
|
||||||
FixedController.prototype.add = function (type) {
|
|
||||||
this.fixedProxy.add(type);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change the display order of the element proxy.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.order = function (elementProxy, position) {
|
|
||||||
var elements = elementProxy.order(position);
|
|
||||||
|
|
||||||
// Find the selected element index in the updated array.
|
|
||||||
var selectedElemenetIndex = elements.indexOf(this.selectedElementProxy.element);
|
|
||||||
|
|
||||||
this.mutate("configuration['fixed-display'].elements", elements);
|
|
||||||
elements = (this.newDomainObject.configuration)['fixed-display'].elements || [];
|
|
||||||
|
|
||||||
// Update the selected element with the new
|
|
||||||
// value since newDomainOject is mutated.
|
|
||||||
this.selectedElementProxy.element = elements[selectedElemenetIndex];
|
|
||||||
this.refreshElements();
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.generateDragHandle = function (elementProxy, elementHandle) {
|
|
||||||
var index = this.elementProxies.indexOf(elementProxy);
|
|
||||||
|
|
||||||
if (elementHandle) {
|
|
||||||
elementHandle.element = elementProxy.element;
|
|
||||||
elementProxy = elementHandle;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new FixedDragHandle(
|
|
||||||
elementProxy,
|
|
||||||
"configuration['fixed-display'].elements[" + index + "]",
|
|
||||||
this
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.generateDragHandles = function (elementProxy) {
|
|
||||||
return elementProxy.handles().map(function (handle) {
|
|
||||||
return this.generateDragHandle(elementProxy, handle);
|
|
||||||
}, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.updateSelectionStyle = function () {
|
|
||||||
this.selectedElementProxy.style = convertPosition(this.selectedElementProxy);
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.setSelection = function (selectable) {
|
|
||||||
var selection = selectable[0];
|
|
||||||
|
|
||||||
if (this.selectionListeners) {
|
|
||||||
this.selectionListeners.forEach(function (l) {
|
|
||||||
l();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.selectionListeners = [];
|
|
||||||
|
|
||||||
if (!selection) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selection.context.elementProxy) {
|
|
||||||
this.selectedElementProxy = selection.context.elementProxy;
|
|
||||||
this.attachSelectionListeners();
|
|
||||||
this.mvHandle = this.generateDragHandle(this.selectedElementProxy);
|
|
||||||
this.resizeHandles = this.generateDragHandles(this.selectedElementProxy);
|
|
||||||
} else {
|
|
||||||
// Make fixed view selectable if it's not already.
|
|
||||||
if (!this.fixedViewSelectable && selectable.length === 1) {
|
|
||||||
this.fixedViewSelectable = true;
|
|
||||||
selection.context.fixedController = this;
|
|
||||||
this.openmct.selection.select(selection);
|
|
||||||
}
|
|
||||||
|
|
||||||
this.resizeHandles = [];
|
|
||||||
this.mvHandle = undefined;
|
|
||||||
this.selectedElementProxy = undefined;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.attachSelectionListeners = function () {
|
|
||||||
var index = this.elementProxies.indexOf(this.selectedElementProxy);
|
|
||||||
var path = "configuration['fixed-display'].elements[" + index + "]";
|
|
||||||
|
|
||||||
this.selectionListeners.push(this.openmct.objects.observe(this.newDomainObject, path + ".useGrid", function (newValue) {
|
|
||||||
if (this.selectedElementProxy.useGrid() !== newValue) {
|
|
||||||
this.selectedElementProxy.useGrid(newValue);
|
|
||||||
this.updateSelectionStyle();
|
|
||||||
this.openmct.objects.mutate(this.newDomainObject, path, this.selectedElementProxy.element);
|
|
||||||
}
|
|
||||||
}.bind(this)));
|
|
||||||
[
|
|
||||||
"width",
|
|
||||||
"height",
|
|
||||||
"stroke",
|
|
||||||
"fill",
|
|
||||||
"x",
|
|
||||||
"y",
|
|
||||||
"x1",
|
|
||||||
"y1",
|
|
||||||
"x2",
|
|
||||||
"y2",
|
|
||||||
"color",
|
|
||||||
"size",
|
|
||||||
"text",
|
|
||||||
"titled"
|
|
||||||
].forEach(function (property) {
|
|
||||||
this.selectionListeners.push(this.openmct.objects.observe(this.newDomainObject, path + "." + property, function (newValue) {
|
|
||||||
this.selectedElementProxy.element[property] = newValue;
|
|
||||||
this.updateSelectionStyle();
|
|
||||||
}.bind(this)));
|
|
||||||
}.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.destroy = function () {
|
|
||||||
this.unsubscribe();
|
|
||||||
this.unlisten();
|
|
||||||
this.openmct.time.off("bounds", this.updateDisplayBounds);
|
|
||||||
this.openmct.selection.off("change", this.setSelection);
|
|
||||||
this.composition.off('add', this.onCompositionAdd, this);
|
|
||||||
this.composition.off('remove', this.onCompositionRemove, this);
|
|
||||||
this.openmct.editor.off('isEditing', this.handleEditing, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A rate-limited digest function. Caps digests at 60Hz
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
FixedController.prototype.digest = function () {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
if (!this.digesting) {
|
|
||||||
this.digesting = true;
|
|
||||||
requestAnimationFrame(function () {
|
|
||||||
self.$scope.$digest();
|
|
||||||
self.digesting = false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Unsubscribe all listeners
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
FixedController.prototype.unsubscribe = function () {
|
|
||||||
Object.values(this.subscriptions).forEach(function (unsubscribeFunc) {
|
|
||||||
unsubscribeFunc();
|
|
||||||
});
|
|
||||||
this.subscriptions = {};
|
|
||||||
this.telemetryObjects = {};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Subscribe to the given domain object
|
|
||||||
* @private
|
|
||||||
* @param {object} object Domain object to subscribe to
|
|
||||||
* @returns {object} The provided object, for chaining.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.subscribeToObject = function (object) {
|
|
||||||
var self = this;
|
|
||||||
var timeAPI = this.openmct.time;
|
|
||||||
var id = objectUtils.makeKeyString(object.identifier);
|
|
||||||
this.subscriptions[id] = self.openmct.telemetry.subscribe(object, function (datum) {
|
|
||||||
if (timeAPI.clock() !== undefined) {
|
|
||||||
self.updateView(object, datum);
|
|
||||||
}
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
return object;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print the values from the given datum against the provided object in the view.
|
|
||||||
* @private
|
|
||||||
* @param {object} telemetryObject The domain object associated with the given telemetry data
|
|
||||||
* @param {object} datum The telemetry datum containing the values to print
|
|
||||||
*/
|
|
||||||
FixedController.prototype.updateView = function (telemetryObject, datum) {
|
|
||||||
var metadata = this.openmct.telemetry.getMetadata(telemetryObject);
|
|
||||||
var valueMetadata = this.chooseValueMetadataToDisplay(metadata);
|
|
||||||
var formattedTelemetryValue = this.getFormattedTelemetryValueForKey(valueMetadata, datum);
|
|
||||||
var limitEvaluator = this.openmct.telemetry.limitEvaluator(telemetryObject);
|
|
||||||
var alarm = limitEvaluator && limitEvaluator.evaluate(datum, valueMetadata);
|
|
||||||
|
|
||||||
this.setDisplayedValue(
|
|
||||||
telemetryObject,
|
|
||||||
formattedTelemetryValue,
|
|
||||||
alarm && alarm.cssClass
|
|
||||||
);
|
|
||||||
this.digest();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
FixedController.prototype.getFormattedTelemetryValueForKey = function (valueMetadata, datum) {
|
|
||||||
var formatter = this.openmct.telemetry.getValueFormatter(valueMetadata);
|
|
||||||
|
|
||||||
return formatter.format(datum);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
FixedController.prototype.chooseValueMetadataToDisplay = function (metadata) {
|
|
||||||
// If there is a range value, show that preferentially
|
|
||||||
var valueMetadata = metadata.valuesForHints(['range'])[0];
|
|
||||||
|
|
||||||
// If no range is defined, default to the highest priority non time-domain data.
|
|
||||||
if (valueMetadata === undefined) {
|
|
||||||
var valuesOrderedByPriority = metadata.values();
|
|
||||||
valueMetadata = valuesOrderedByPriority.filter(function (values) {
|
|
||||||
return !(values.hints.domain);
|
|
||||||
})[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return valueMetadata;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Request the last historical data point for the given domain object
|
|
||||||
* @param {object} object
|
|
||||||
* @returns {object} the provided object for chaining.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.fetchHistoricalData = function (object) {
|
|
||||||
var bounds = this.openmct.time.bounds();
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
self.openmct.telemetry.request(object, {start: bounds.start, end: bounds.end, size: 1})
|
|
||||||
.then(function (data) {
|
|
||||||
if (data.length > 0) {
|
|
||||||
self.updateView(object, data[data.length - 1]);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return object;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Print a value to the onscreen element associated with a given telemetry object.
|
|
||||||
* @private
|
|
||||||
* @param {object} telemetryObject The telemetry object associated with the value
|
|
||||||
* @param {string | number} value The value to print to screen
|
|
||||||
* @param {string} [cssClass] an optional CSS class to apply to the onscreen element.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.setDisplayedValue = function (telemetryObject, value, cssClass) {
|
|
||||||
var id = objectUtils.makeKeyString(telemetryObject.identifier);
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
(self.elementProxiesById[id] || []).forEach(function (element) {
|
|
||||||
self.names[id] = telemetryObject.name;
|
|
||||||
self.values[id] = value;
|
|
||||||
element.name = self.names[id];
|
|
||||||
element.value = self.values[id];
|
|
||||||
element.cssClass = cssClass;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.getTelemetry = function (domainObject) {
|
|
||||||
var id = objectUtils.makeKeyString(domainObject.identifier);
|
|
||||||
|
|
||||||
if (this.subscriptions[id]) {
|
|
||||||
this.subscriptions[id]();
|
|
||||||
delete this.subscriptions[id];
|
|
||||||
}
|
|
||||||
delete this.telemetryObjects[id];
|
|
||||||
|
|
||||||
if (!this.openmct.telemetry.isTelemetryObject(domainObject)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize display
|
|
||||||
this.telemetryObjects[id] = domainObject;
|
|
||||||
this.setDisplayedValue(domainObject, "");
|
|
||||||
|
|
||||||
return Promise.resolve(domainObject)
|
|
||||||
.then(this.fetchHistoricalData)
|
|
||||||
.then(this.subscribeToObject);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the size of the grid, in pixels. The returned array
|
|
||||||
* is in the form `[x, y]`.
|
|
||||||
* @returns {number[]} the grid size
|
|
||||||
* @memberof platform/features/layout.FixedController#
|
|
||||||
*/
|
|
||||||
FixedController.prototype.getGridSize = function () {
|
|
||||||
return this.gridSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get an array of elements in this panel; these are
|
|
||||||
* decorated proxies for both selection and display.
|
|
||||||
* @returns {Array} elements in this panel
|
|
||||||
*/
|
|
||||||
FixedController.prototype.getElements = function () {
|
|
||||||
return this.elementProxies;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if the element should be selected or not.
|
|
||||||
*
|
|
||||||
* @param elementProxy the element to check
|
|
||||||
* @returns {boolean} true if the element should be selected.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.shouldSelect = function (elementProxy) {
|
|
||||||
if (elementProxy.element === this.elementToSelectAfterRefresh) {
|
|
||||||
delete this.elementToSelectAfterRefresh;
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks if an element is currently selected.
|
|
||||||
*
|
|
||||||
* @returns {boolean} true if an element is selected.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.isElementSelected = function () {
|
|
||||||
return (this.selectedElementProxy) ? true : false;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the style for the selected element.
|
|
||||||
*
|
|
||||||
* @returns {string} element style
|
|
||||||
*/
|
|
||||||
FixedController.prototype.getSelectedElementStyle = function () {
|
|
||||||
return (this.selectedElementProxy) ? this.selectedElementProxy.style : undefined;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the selected element.
|
|
||||||
*
|
|
||||||
* @returns the selected element
|
|
||||||
*/
|
|
||||||
FixedController.prototype.getSelectedElement = function () {
|
|
||||||
return this.selectedElementProxy;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Prevents the event from bubbling up if drag is in progress.
|
|
||||||
*/
|
|
||||||
FixedController.prototype.bypassSelection = function ($event) {
|
|
||||||
if (this.dragInProgress) {
|
|
||||||
if ($event) {
|
|
||||||
$event.stopPropagation();
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get drag handles.
|
|
||||||
* @returns {platform/features/layout.FixedDragHandle[]}
|
|
||||||
* drag handles for the current selection
|
|
||||||
*/
|
|
||||||
FixedController.prototype.handles = function () {
|
|
||||||
return this.resizeHandles;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the handle to handle dragging to reposition an element.
|
|
||||||
* @returns {platform/features/layout.FixedDragHandle} the drag handle
|
|
||||||
*/
|
|
||||||
FixedController.prototype.moveHandle = function () {
|
|
||||||
return this.mvHandle;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the selection context.
|
|
||||||
*
|
|
||||||
* @param elementProxy the element proxy
|
|
||||||
* @returns {object} the context object which includes elementProxy
|
|
||||||
*/
|
|
||||||
FixedController.prototype.getContext = function (elementProxy) {
|
|
||||||
return {
|
|
||||||
elementProxy: elementProxy,
|
|
||||||
fixedController: this
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* End drag.
|
|
||||||
*
|
|
||||||
* @param handle the resize handle
|
|
||||||
*/
|
|
||||||
FixedController.prototype.endDrag = function (handle) {
|
|
||||||
this.dragInProgress = true;
|
|
||||||
|
|
||||||
setTimeout(function () {
|
|
||||||
this.dragInProgress = false;
|
|
||||||
}.bind(this), 0);
|
|
||||||
|
|
||||||
if (handle) {
|
|
||||||
handle.endDrag();
|
|
||||||
} else {
|
|
||||||
this.moveHandle().endDrag();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.mutate = function (path, value) {
|
|
||||||
this.openmct.objects.mutate(this.newDomainObject, path, value);
|
|
||||||
};
|
|
||||||
|
|
||||||
FixedController.prototype.handleEditing = function (isEditing) {
|
|
||||||
// Listen for edit mode changes and update selection if necessary.
|
|
||||||
// Mainly to ensure fixedController is on the selection context when editing.
|
|
||||||
this.setSelection(this.openmct.selection.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
return FixedController;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,110 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
[],
|
|
||||||
function () {
|
|
||||||
|
|
||||||
// Drag handle dimensions
|
|
||||||
var DRAG_HANDLE_SIZE = [6, 6];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Template-displayable drag handle for an element in fixed
|
|
||||||
* position mode.
|
|
||||||
*
|
|
||||||
* @param elementHandle the element handle
|
|
||||||
* @param configPath the configuration path of an element
|
|
||||||
* @param {Object} fixedControl the fixed controller
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function FixedDragHandle(elementHandle, configPath, fixedControl) {
|
|
||||||
this.elementHandle = elementHandle;
|
|
||||||
this.configPath = configPath;
|
|
||||||
this.fixedControl = fixedControl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a CSS style to position this drag handle.
|
|
||||||
*
|
|
||||||
* @returns CSS style object (for `ng-style`)
|
|
||||||
* @memberof platform/features/layout.FixedDragHandle#
|
|
||||||
*/
|
|
||||||
FixedDragHandle.prototype.style = function () {
|
|
||||||
var gridSize = this.elementHandle.getGridSize();
|
|
||||||
|
|
||||||
// Adjust from grid to pixel coordinates
|
|
||||||
var x = this.elementHandle.x() * gridSize[0],
|
|
||||||
y = this.elementHandle.y() * gridSize[1];
|
|
||||||
|
|
||||||
// Convert to a CSS style centered on that point
|
|
||||||
return {
|
|
||||||
left: (x - DRAG_HANDLE_SIZE[0] / 2) + 'px',
|
|
||||||
top: (y - DRAG_HANDLE_SIZE[1] / 2) + 'px',
|
|
||||||
width: DRAG_HANDLE_SIZE[0] + 'px',
|
|
||||||
height: DRAG_HANDLE_SIZE[1] + 'px'
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Start a drag gesture. This should be called when a drag
|
|
||||||
* begins to track initial state.
|
|
||||||
*/
|
|
||||||
FixedDragHandle.prototype.startDrag = function () {
|
|
||||||
// Cache initial x/y positions
|
|
||||||
this.dragging = {
|
|
||||||
x: this.elementHandle.x(),
|
|
||||||
y: this.elementHandle.y()
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Continue a drag gesture; update x/y positions.
|
|
||||||
*
|
|
||||||
* @param {number[]} delta x/y pixel difference since drag started
|
|
||||||
*/
|
|
||||||
FixedDragHandle.prototype.continueDrag = function (delta) {
|
|
||||||
var gridSize = this.elementHandle.getGridSize();
|
|
||||||
|
|
||||||
if (this.dragging) {
|
|
||||||
// Update x/y positions (snapping to grid)
|
|
||||||
var newX = this.dragging.x + Math.round(delta[0] / gridSize[0]);
|
|
||||||
var newY = this.dragging.y + Math.round(delta[1] / gridSize[1]);
|
|
||||||
|
|
||||||
this.elementHandle.x(Math.max(0, newX));
|
|
||||||
this.elementHandle.y(Math.max(0, newY));
|
|
||||||
this.fixedControl.updateSelectionStyle();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* End a drag gesture. This should be called when a drag
|
|
||||||
* concludes to trigger commit of changes.
|
|
||||||
*/
|
|
||||||
FixedDragHandle.prototype.endDrag = function () {
|
|
||||||
this.dragging = undefined;
|
|
||||||
this.fixedControl.mutate(this.configPath, this.elementHandle.element);
|
|
||||||
};
|
|
||||||
|
|
||||||
return FixedDragHandle;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,76 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['./elements/ElementFactory'],
|
|
||||||
function (ElementFactory) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Proxy for configuring a fixed position view via the toolbar.
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @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(addElementCallback, $q, dialogService) {
|
|
||||||
this.factory = new ElementFactory(dialogService);
|
|
||||||
this.$q = $q;
|
|
||||||
this.addElementCallback = addElementCallback;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a new visual element to this view. Supported types are:
|
|
||||||
*
|
|
||||||
* * `fixed.image`
|
|
||||||
* * `fixed.box`
|
|
||||||
* * `fixed.text`
|
|
||||||
* * `fixed.line`
|
|
||||||
*
|
|
||||||
* @param {string} type the type of element to add
|
|
||||||
*/
|
|
||||||
FixedProxy.prototype.add = function (type) {
|
|
||||||
var addElementCallback = this.addElementCallback;
|
|
||||||
|
|
||||||
// Place a configured element into the view configuration
|
|
||||||
function addElement(element) {
|
|
||||||
// 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;
|
|
||||||
element.useGrid = true;
|
|
||||||
|
|
||||||
// Finally, add it to the view's configuration
|
|
||||||
addElementCallback(element);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Defer creation to the factory
|
|
||||||
this.$q.when(this.factory.createElement(type)).then(addElement);
|
|
||||||
};
|
|
||||||
|
|
||||||
return FixedProxy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,115 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
[],
|
|
||||||
function () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles drag interactions on frames in layouts. This will
|
|
||||||
* provides new positions/dimensions for frames based on
|
|
||||||
* relative pixel positions provided; these will take into account
|
|
||||||
* the grid size (in a snap-to sense) and will enforce some minimums
|
|
||||||
* on both position and dimensions.
|
|
||||||
*
|
|
||||||
* The provided position and dimensions factors will determine
|
|
||||||
* whether this is a move or a resize, and what type of resize 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 {object} rawPosition the initial position/dimensions
|
|
||||||
* of the frame being interacted with
|
|
||||||
* @param {number[]} posFactor the position factor
|
|
||||||
* @param {number[]} dimFactor the dimensions factor
|
|
||||||
* @param {number[]} the size of each grid element, in pixels
|
|
||||||
* @constructor
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
*/
|
|
||||||
function LayoutDrag(rawPosition, posFactor, dimFactor, gridSize) {
|
|
||||||
this.rawPosition = rawPosition;
|
|
||||||
this.posFactor = posFactor;
|
|
||||||
this.dimFactor = dimFactor;
|
|
||||||
this.gridSize = gridSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert a delta from pixel coordinates to grid coordinates,
|
|
||||||
// rounding to whole-number grid coordinates.
|
|
||||||
function toGridDelta(gridSize, pixelDelta) {
|
|
||||||
return pixelDelta.map(function (v, i) {
|
|
||||||
return Math.round(v / gridSize[i]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utility function to perform element-by-element multiplication
|
|
||||||
function multiply(array, factors) {
|
|
||||||
return array.map(function (v, i) {
|
|
||||||
return v * factors[i];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utility function to perform element-by-element addition
|
|
||||||
function add(array, other) {
|
|
||||||
return array.map(function (v, i) {
|
|
||||||
return v + other[i];
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Utility function to perform element-by-element max-choosing
|
|
||||||
function max(array, other) {
|
|
||||||
return array.map(function (v, i) {
|
|
||||||
return Math.max(v, other[i]);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a new position object in grid coordinates, with
|
|
||||||
* position and dimensions both offset appropriately
|
|
||||||
* according to the factors supplied in the constructor.
|
|
||||||
* @param {number[]} pixelDelta the offset from the
|
|
||||||
* original position, in pixels
|
|
||||||
*/
|
|
||||||
LayoutDrag.prototype.getAdjustedPosition = function (pixelDelta) {
|
|
||||||
var gridDelta = toGridDelta(this.gridSize, pixelDelta);
|
|
||||||
return {
|
|
||||||
position: max(add(
|
|
||||||
this.rawPosition.position,
|
|
||||||
multiply(gridDelta, this.posFactor)
|
|
||||||
), [0, 0]),
|
|
||||||
dimensions: max(add(
|
|
||||||
this.rawPosition.dimensions,
|
|
||||||
multiply(gridDelta, this.dimFactor)
|
|
||||||
), [1, 1])
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
return LayoutDrag;
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,105 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2016, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define([
|
|
||||||
'zepto',
|
|
||||||
'../../../commonUI/general/src/services/Overlay'
|
|
||||||
], function (
|
|
||||||
$,
|
|
||||||
Overlay
|
|
||||||
) {
|
|
||||||
/**
|
|
||||||
* MCT Trigger Modal is intended for use in only one location: inside the
|
|
||||||
* object-header to allow views in a layout to be popped out in a modal.
|
|
||||||
* Users can close the modal and go back to normal, and everything generally
|
|
||||||
* just works fine.
|
|
||||||
*
|
|
||||||
* This code is sensitive to how our html is constructed-- particularly with
|
|
||||||
* how it locates the the container of an element in a layout. However, it
|
|
||||||
* should be able to handle slight relocations so long as it is always a
|
|
||||||
* descendent of a `.frame` element.
|
|
||||||
*/
|
|
||||||
function MCTTriggerModal($document) {
|
|
||||||
|
|
||||||
function link($scope, $element) {
|
|
||||||
var actions = $scope.domainObject.getCapability('action'),
|
|
||||||
notebookAction = actions.getActions({key: 'notebook-new-entry'})[0];
|
|
||||||
|
|
||||||
var frame = $element.parent();
|
|
||||||
|
|
||||||
for (var i = 0; i < 10; i++) {
|
|
||||||
if (frame.hasClass('frame')) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
frame = frame.parent();
|
|
||||||
}
|
|
||||||
if (!frame.hasClass('frame')) {
|
|
||||||
$element.remove();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
frame = frame[0];
|
|
||||||
|
|
||||||
var layoutContainer = frame.parentElement;
|
|
||||||
|
|
||||||
var notebookButton = notebookAction ?
|
|
||||||
[
|
|
||||||
{
|
|
||||||
class: 'icon-notebook new-notebook-entry',
|
|
||||||
title: 'New Notebook Entry',
|
|
||||||
clickHandler: function (event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
notebookAction.perform();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
] : [];
|
|
||||||
|
|
||||||
var overlayService = new Overlay ({
|
|
||||||
$document: $document,
|
|
||||||
$scope: $scope,
|
|
||||||
$element: frame,
|
|
||||||
overlayWillMount: function () {
|
|
||||||
$(frame).removeClass('frame frame-template');
|
|
||||||
layoutContainer.removeChild(frame);
|
|
||||||
},
|
|
||||||
overlayDidUnmount: function () {
|
|
||||||
$(frame).addClass('frame frame-template');
|
|
||||||
layoutContainer.appendChild(frame);
|
|
||||||
},
|
|
||||||
browseBarButtons: notebookButton
|
|
||||||
});
|
|
||||||
|
|
||||||
$element.on('click', overlayService.toggleOverlay);
|
|
||||||
$scope.$on('$destroy', function () {
|
|
||||||
$element.off('click', overlayService.toggleOverlay);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
restrict: 'A',
|
|
||||||
link: link
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return MCTTriggerModal;
|
|
||||||
|
|
||||||
});
|
|
@ -1,58 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
[],
|
|
||||||
function () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Utility function for creating getter-setter functions,
|
|
||||||
* since these are frequently useful for element proxies.
|
|
||||||
*
|
|
||||||
* An optional third argument may be supplied in order to
|
|
||||||
* constrain or modify arguments when using as a setter;
|
|
||||||
* this argument is a function which takes two arguments
|
|
||||||
* (the current value for the property, and the requested
|
|
||||||
* new value.) This is useful when values need to be kept
|
|
||||||
* in certain ranges; specifically, to keep x/y positions
|
|
||||||
* non-negative in a fixed position view.
|
|
||||||
*
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param {Object} object the object to get/set values upon
|
|
||||||
* @param {string} key the property to get/set
|
|
||||||
* @param {function} [updater] function used to process updates
|
|
||||||
*/
|
|
||||||
function AccessorMutator(object, key, updater) {
|
|
||||||
return function (value) {
|
|
||||||
if (arguments.length > 0) {
|
|
||||||
object[key] = updater ?
|
|
||||||
updater(value, object[key]) :
|
|
||||||
value;
|
|
||||||
}
|
|
||||||
return object[key];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return AccessorMutator;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,61 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['./ElementProxy', './AccessorMutator'],
|
|
||||||
function (ElementProxy, AccessorMutator) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selection proxy for Box elements in a fixed position view.
|
|
||||||
* Also serves as a superclass for Text elements, since those
|
|
||||||
* elements have a superset of Box properties.
|
|
||||||
*
|
|
||||||
* Note that arguments here are meant to match those expected
|
|
||||||
* by `Array.prototype.map`
|
|
||||||
*
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param element the fixed position element, as stored in its
|
|
||||||
* configuration
|
|
||||||
* @param index the element's index within its array
|
|
||||||
* @param {number[]} gridSize the current layout grid size in [x,y] from
|
|
||||||
* @param {Array} elements the full array of elements
|
|
||||||
*/
|
|
||||||
function BoxProxy(element, index, elements, gridSize) {
|
|
||||||
var proxy = new ElementProxy(element, index, elements, gridSize);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get/set this element's fill color. (Omitting the
|
|
||||||
* argument makes this act as a getter.)
|
|
||||||
* @method
|
|
||||||
* @param {string} fill the new fill color
|
|
||||||
* @returns {string} the fill color
|
|
||||||
* @memberof platform/features/layout.BoxProxy#
|
|
||||||
*/
|
|
||||||
proxy.fill = new AccessorMutator(element, 'fill');
|
|
||||||
|
|
||||||
return proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
return BoxProxy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,115 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
[],
|
|
||||||
function () {
|
|
||||||
|
|
||||||
var INITIAL_STATES = {
|
|
||||||
"fixed.image": {
|
|
||||||
stroke: "transparent"
|
|
||||||
},
|
|
||||||
"fixed.box": {
|
|
||||||
fill: "#717171",
|
|
||||||
border: "transparent",
|
|
||||||
stroke: "transparent"
|
|
||||||
},
|
|
||||||
"fixed.line": {
|
|
||||||
x: 5,
|
|
||||||
y: 9,
|
|
||||||
x2: 6,
|
|
||||||
y2: 6,
|
|
||||||
stroke: "#717171"
|
|
||||||
},
|
|
||||||
"fixed.text": {
|
|
||||||
fill: "transparent",
|
|
||||||
stroke: "transparent",
|
|
||||||
size: "13px"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
DIALOGS = {
|
|
||||||
"fixed.image": {
|
|
||||||
name: "Image Properties",
|
|
||||||
sections: [
|
|
||||||
{
|
|
||||||
rows: [
|
|
||||||
{
|
|
||||||
key: "url",
|
|
||||||
control: "textfield",
|
|
||||||
name: "Image URL",
|
|
||||||
"cssClass": "l-input-lg",
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"fixed.text": {
|
|
||||||
name: "Text Element Properties",
|
|
||||||
sections: [
|
|
||||||
{
|
|
||||||
rows: [
|
|
||||||
{
|
|
||||||
key: "text",
|
|
||||||
control: "textfield",
|
|
||||||
name: "Text",
|
|
||||||
required: true
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function ElementFactory(dialogService) {
|
|
||||||
this.dialogService = dialogService;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*/
|
|
||||||
ElementFactory.prototype.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] ? this.dialogService.getUserInput(
|
|
||||||
DIALOGS[type],
|
|
||||||
initialState
|
|
||||||
) : initialState;
|
|
||||||
};
|
|
||||||
|
|
||||||
return ElementFactory;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,35 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['./TelemetryProxy', './ImageProxy', './LineProxy', './BoxProxy', './TextProxy'],
|
|
||||||
function (TelemetryProxy, ImageProxy, LineProxy, BoxProxy, TextProxy) {
|
|
||||||
|
|
||||||
return {
|
|
||||||
"fixed.telemetry": TelemetryProxy,
|
|
||||||
"fixed.line": LineProxy,
|
|
||||||
"fixed.box": BoxProxy,
|
|
||||||
"fixed.image": ImageProxy,
|
|
||||||
"fixed.text": TextProxy
|
|
||||||
};
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,209 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['./AccessorMutator', './ResizeHandle', './UnitAccessorMutator'],
|
|
||||||
function (AccessorMutator, ResizeHandle, UnitAccessorMutator) {
|
|
||||||
|
|
||||||
// Index deltas for changes in order
|
|
||||||
var ORDERS = {
|
|
||||||
top: Number.POSITIVE_INFINITY,
|
|
||||||
up: 1,
|
|
||||||
down: -1,
|
|
||||||
bottom: Number.NEGATIVE_INFINITY
|
|
||||||
};
|
|
||||||
|
|
||||||
// Mininmum pixel height and width for objects
|
|
||||||
var MIN_WIDTH = 10;
|
|
||||||
var MIN_HEIGHT = 10;
|
|
||||||
|
|
||||||
// Ensure a value is non-negative (for x/y setters)
|
|
||||||
function clamp(value) {
|
|
||||||
return Math.max(value, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstract superclass for other classes which provide useful
|
|
||||||
* interfaces upon an elements in a fixed position view.
|
|
||||||
* This handles the generic operations (e.g. remove) so that
|
|
||||||
* subclasses only need to implement element-specific behaviors.
|
|
||||||
*
|
|
||||||
* Note that arguments here are meant to match those expected
|
|
||||||
* by `Array.prototype.map`
|
|
||||||
*
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @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
|
|
||||||
* @param {number[]} gridSize the current layout grid size in [x,y] from
|
|
||||||
*/
|
|
||||||
function ElementProxy(element, index, elements, gridSize) {
|
|
||||||
/**
|
|
||||||
* The element as stored in the view configuration.
|
|
||||||
* @memberof platform/features/layout.ElementProxy#
|
|
||||||
*/
|
|
||||||
this.element = element;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The current grid size of the layout.
|
|
||||||
* @memberof platform/features/layout.ElementProxy#
|
|
||||||
*/
|
|
||||||
this.gridSize = gridSize || [1,1]; //Ensure a reasonable default
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
* @memberof platform/features/layout.ElementProxy#
|
|
||||||
*/
|
|
||||||
this.x = new AccessorMutator(element, 'x', clamp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
* @memberof platform/features/layout.ElementProxy#
|
|
||||||
*/
|
|
||||||
this.y = new AccessorMutator(element, 'y', clamp);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get and/or set the stroke color of this element.
|
|
||||||
* @param {string} [stroke] the new stroke color (if setting)
|
|
||||||
* @returns {string} the stroke color
|
|
||||||
* @memberof platform/features/layout.ElementProxy#
|
|
||||||
*/
|
|
||||||
this.stroke = new AccessorMutator(element, 'stroke');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
* @memberof platform/features/layout.ElementProxy#
|
|
||||||
*/
|
|
||||||
this.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
|
|
||||||
* @memberof platform/features/layout.ElementProxy#
|
|
||||||
*/
|
|
||||||
this.height = new AccessorMutator(element, 'height');
|
|
||||||
|
|
||||||
this.useGrid = new UnitAccessorMutator(this);
|
|
||||||
this.index = index;
|
|
||||||
this.elements = elements;
|
|
||||||
this.resizeHandles = [new ResizeHandle(this, this.element)];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Change the display order of this element.
|
|
||||||
* @param {string} o where to move this element;
|
|
||||||
* one of "top", "up", "down", or "bottom"
|
|
||||||
* @return {Array} the full array of elements
|
|
||||||
*/
|
|
||||||
ElementProxy.prototype.order = function (o) {
|
|
||||||
var index = this.index,
|
|
||||||
elements = this.elements,
|
|
||||||
element = this.element,
|
|
||||||
delta = ORDERS[o] || 0,
|
|
||||||
desired = Math.max(
|
|
||||||
Math.min(index + delta, elements.length - 1),
|
|
||||||
0
|
|
||||||
);
|
|
||||||
// Move to the desired index, if this is a change
|
|
||||||
if ((desired !== index) && (elements[index] === element)) {
|
|
||||||
// Splice out the current element
|
|
||||||
elements.splice(index, 1);
|
|
||||||
// Splice it back in at the correct index
|
|
||||||
elements.splice(desired, 0, element);
|
|
||||||
// Track change in index (proxy should be recreated
|
|
||||||
// anyway, but be consistent)
|
|
||||||
this.index = desired;
|
|
||||||
}
|
|
||||||
|
|
||||||
return elements;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get handles to control specific features of this element,
|
|
||||||
* e.g. corner size.
|
|
||||||
* @return {platform/features/layout.ElementHandle[]} handles
|
|
||||||
* for moving/resizing this element
|
|
||||||
*/
|
|
||||||
ElementProxy.prototype.handles = function () {
|
|
||||||
return this.resizeHandles;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns which grid size the element is currently using.
|
|
||||||
* @return {number[]} The current grid size in [x,y] form if the element
|
|
||||||
* is currently using the grid, [1,1] if it is using
|
|
||||||
* pixels.
|
|
||||||
*/
|
|
||||||
ElementProxy.prototype.getGridSize = function () {
|
|
||||||
var gridSize;
|
|
||||||
// Default to using the grid if useGrid was not defined
|
|
||||||
if (typeof this.element.useGrid === 'undefined') {
|
|
||||||
this.element.useGrid = true;
|
|
||||||
}
|
|
||||||
if (this.element.useGrid) {
|
|
||||||
gridSize = this.gridSize;
|
|
||||||
} else {
|
|
||||||
gridSize = [1,1];
|
|
||||||
}
|
|
||||||
return gridSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set the current grid size stored by this element proxy
|
|
||||||
* @param {number[]} gridSize The current layout grid size in [x,y] form
|
|
||||||
*/
|
|
||||||
ElementProxy.prototype.setGridSize = function (gridSize) {
|
|
||||||
this.gridSize = gridSize;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current minimum element width in grid units
|
|
||||||
* @return {number} The current minimum element width
|
|
||||||
*/
|
|
||||||
ElementProxy.prototype.getMinWidth = function () {
|
|
||||||
return Math.ceil(MIN_WIDTH / this.getGridSize()[0]);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the current minimum element height in grid units
|
|
||||||
* @return {number} The current minimum element height
|
|
||||||
*/
|
|
||||||
ElementProxy.prototype.getMinHeight = function () {
|
|
||||||
return Math.ceil(MIN_HEIGHT / this.getGridSize()[1]);
|
|
||||||
};
|
|
||||||
|
|
||||||
return ElementProxy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,58 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['./ElementProxy', './AccessorMutator'],
|
|
||||||
function (ElementProxy, AccessorMutator) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selection proxy for Image elements in a fixed position view.
|
|
||||||
*
|
|
||||||
* Note that arguments here are meant to match those expected
|
|
||||||
* by `Array.prototype.map`
|
|
||||||
*
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @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
|
|
||||||
* @param {number[]} gridSize the current layout grid size in [x,y] from
|
|
||||||
* @augments {platform/features/layout.ElementProxy}
|
|
||||||
*/
|
|
||||||
function ImageProxy(element, index, elements, gridSize) {
|
|
||||||
var proxy = new ElementProxy(element, index, elements, gridSize);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get and/or set the displayed text of this element.
|
|
||||||
* @param {string} [text] the new text (if setting)
|
|
||||||
* @returns {string} the text
|
|
||||||
* @memberof platform/features/layout.ImageProxy#
|
|
||||||
*/
|
|
||||||
proxy.url = new AccessorMutator(element, 'url');
|
|
||||||
|
|
||||||
return proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
return ImageProxy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,94 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
define(
|
|
||||||
[],
|
|
||||||
function () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle for changing x/y position of a line's end point.
|
|
||||||
* This is used to support drag handles for line elements
|
|
||||||
* in a fixed position view. Field names for opposite ends
|
|
||||||
* are provided to avoid zero-length lines.
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param element the line element
|
|
||||||
* @param {string} xProperty field which stores x position
|
|
||||||
* @param {string} yProperty field which stores y position
|
|
||||||
* @param {string} xOther field which stores x of other end
|
|
||||||
* @param {string} yOther field which stores y of other end
|
|
||||||
* @implements {platform/features/layout.ElementHandle}
|
|
||||||
*/
|
|
||||||
function LineHandle(element, elementProxy, xProperty, yProperty, xOther, yOther) {
|
|
||||||
this.elementProxy = elementProxy;
|
|
||||||
this.element = element;
|
|
||||||
this.xProperty = xProperty;
|
|
||||||
this.yProperty = yProperty;
|
|
||||||
this.xOther = xOther;
|
|
||||||
this.yOther = yOther;
|
|
||||||
}
|
|
||||||
|
|
||||||
LineHandle.prototype.x = function (value) {
|
|
||||||
var element = this.element,
|
|
||||||
xProperty = this.xProperty,
|
|
||||||
yProperty = this.yProperty,
|
|
||||||
xOther = this.xOther,
|
|
||||||
yOther = this.yOther;
|
|
||||||
|
|
||||||
if (arguments.length > 0) {
|
|
||||||
// Ensure we stay in view
|
|
||||||
value = Math.max(value, 0);
|
|
||||||
// Make sure end points will still be different
|
|
||||||
if (element[yOther] !== element[yProperty] ||
|
|
||||||
element[xOther] !== value) {
|
|
||||||
element[xProperty] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return element[xProperty];
|
|
||||||
};
|
|
||||||
|
|
||||||
LineHandle.prototype.y = function (value) {
|
|
||||||
var element = this.element,
|
|
||||||
xProperty = this.xProperty,
|
|
||||||
yProperty = this.yProperty,
|
|
||||||
xOther = this.xOther,
|
|
||||||
yOther = this.yOther;
|
|
||||||
|
|
||||||
if (arguments.length > 0) {
|
|
||||||
// Ensure we stay in view
|
|
||||||
value = Math.max(value, 0);
|
|
||||||
// Make sure end points will still be different
|
|
||||||
if (element[xOther] !== element[xProperty] ||
|
|
||||||
element[yOther] !== value) {
|
|
||||||
element[yProperty] = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return element[yProperty];
|
|
||||||
};
|
|
||||||
|
|
||||||
LineHandle.prototype.getGridSize = function () {
|
|
||||||
return this.elementProxy.getGridSize();
|
|
||||||
};
|
|
||||||
|
|
||||||
return LineHandle;
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,171 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['./ElementProxy', './LineHandle', './AccessorMutator'],
|
|
||||||
function (ElementProxy, LineHandle, AccessorMutator) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selection/diplay proxy for line elements of a fixed position
|
|
||||||
* view.
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @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
|
|
||||||
* @param {number[]} gridSize the current layout grid size in [x,y] from
|
|
||||||
* @augments {platform/features/layout.ElementProxy}
|
|
||||||
*/
|
|
||||||
function LineProxy(element, index, elements, gridSize) {
|
|
||||||
var proxy = new ElementProxy(element, index, elements, gridSize),
|
|
||||||
handles = [
|
|
||||||
new LineHandle(element, proxy, 'x', 'y', 'x2', 'y2'),
|
|
||||||
new LineHandle(element, proxy, 'x2', 'y2', 'x', 'y')
|
|
||||||
];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets style specific to line proxy.
|
|
||||||
*/
|
|
||||||
proxy.getStyle = function () {
|
|
||||||
var layoutGridSize = proxy.getGridSize();
|
|
||||||
|
|
||||||
return {
|
|
||||||
left: (layoutGridSize[0] * proxy.x()) + 'px',
|
|
||||||
top: (layoutGridSize[1] * proxy.y()) + 'px',
|
|
||||||
width: (layoutGridSize[0] * proxy.width()) + 'px',
|
|
||||||
height: (layoutGridSize[1] * proxy.height()) + 'px'
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the top-left x coordinate, in grid space, of
|
|
||||||
* this line's bounding box.
|
|
||||||
* @returns {number} the x coordinate
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
proxy.x = function (v) {
|
|
||||||
var x = Math.min(element.x, element.x2),
|
|
||||||
delta = Math.max(v, 0) - x;
|
|
||||||
if (arguments.length > 0 && delta) {
|
|
||||||
element.x += delta;
|
|
||||||
element.x2 += delta;
|
|
||||||
}
|
|
||||||
return x;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the top-left y coordinate, in grid space, of
|
|
||||||
* this line's bounding box.
|
|
||||||
* @returns {number} the y coordinate
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
proxy.y = function (v) {
|
|
||||||
var y = Math.min(element.y, element.y2),
|
|
||||||
delta = Math.max(v, 0) - y;
|
|
||||||
if (arguments.length > 0 && delta) {
|
|
||||||
element.y += delta;
|
|
||||||
element.y2 += delta;
|
|
||||||
}
|
|
||||||
return y;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the width, in grid space, of
|
|
||||||
* this line's bounding box.
|
|
||||||
* @returns {number} the width
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
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
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
proxy.y2 = function () {
|
|
||||||
return element.y2 - proxy.y();
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get element handles for changing the position of end
|
|
||||||
* points of this line.
|
|
||||||
* @returns {LineHandle[]} line handles for both end points
|
|
||||||
* @memberof platform/features/layout.LineProxy#
|
|
||||||
*/
|
|
||||||
proxy.handles = function () {
|
|
||||||
return handles;
|
|
||||||
};
|
|
||||||
|
|
||||||
return proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
return LineProxy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,72 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
define(
|
|
||||||
[],
|
|
||||||
function () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @interface platform/features/layout.ElementHandle
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle for changing width/height properties of an element.
|
|
||||||
* This is used to support drag handles for different
|
|
||||||
* element types in a fixed position view.
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function ResizeHandle(elementProxy, element) {
|
|
||||||
this.elementProxy = elementProxy;
|
|
||||||
this.element = element;
|
|
||||||
}
|
|
||||||
|
|
||||||
ResizeHandle.prototype.x = function (value) {
|
|
||||||
var element = this.element;
|
|
||||||
if (arguments.length > 0) {
|
|
||||||
element.width = Math.max(
|
|
||||||
this.elementProxy.getMinWidth(),
|
|
||||||
value - element.x
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return element.x + element.width;
|
|
||||||
};
|
|
||||||
|
|
||||||
ResizeHandle.prototype.y = function (value) {
|
|
||||||
var element = this.element;
|
|
||||||
if (arguments.length > 0) {
|
|
||||||
element.height = Math.max(
|
|
||||||
this.elementProxy.getMinHeight(),
|
|
||||||
value - element.y
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return element.y + element.height;
|
|
||||||
};
|
|
||||||
|
|
||||||
ResizeHandle.prototype.getGridSize = function () {
|
|
||||||
return this.elementProxy.getGridSize();
|
|
||||||
};
|
|
||||||
|
|
||||||
return ResizeHandle;
|
|
||||||
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,56 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['./TextProxy'],
|
|
||||||
function (TextProxy) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selection proxy for telemetry elements in a fixed position view.
|
|
||||||
*
|
|
||||||
* Note that arguments here are meant to match those expected
|
|
||||||
* by `Array.prototype.map`
|
|
||||||
*
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @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
|
|
||||||
* @param {number[]} gridSize the current layout grid size in [x,y] form
|
|
||||||
* @augments {platform/features/layout.ElementProxy}
|
|
||||||
*/
|
|
||||||
function TelemetryProxy(element, index, elements, gridSize) {
|
|
||||||
var proxy = new TextProxy(element, index, elements, gridSize);
|
|
||||||
|
|
||||||
// Expose the domain object identifier
|
|
||||||
proxy.id = element.id;
|
|
||||||
|
|
||||||
// Don't expose text configuration
|
|
||||||
delete proxy.text;
|
|
||||||
|
|
||||||
return proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TelemetryProxy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,75 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['./BoxProxy', './AccessorMutator'],
|
|
||||||
function (BoxProxy, AccessorMutator) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Selection proxy for Text elements in a fixed position view.
|
|
||||||
*
|
|
||||||
* Note that arguments here are meant to match those expected
|
|
||||||
* by `Array.prototype.map`
|
|
||||||
*
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @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
|
|
||||||
* @param {number[]} gridSize the current layout grid size in [x,y] from
|
|
||||||
* @augments {platform/features/layout.ElementProxy}
|
|
||||||
*/
|
|
||||||
function TextProxy(element, index, elements, gridSize) {
|
|
||||||
var proxy = new BoxProxy(element, index, elements, gridSize);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get and/or set the text color of this element.
|
|
||||||
* @param {string} [color] the new text color (if setting)
|
|
||||||
* @returns {string} the text color
|
|
||||||
* @memberof platform/features/layout.TextProxy#
|
|
||||||
*/
|
|
||||||
proxy.color = new AccessorMutator(element, 'color');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get and/or set the displayed text of this element.
|
|
||||||
* @param {string} [text] the new text (if setting)
|
|
||||||
* @returns {string} the text
|
|
||||||
* @memberof platform/features/layout.TextProxy#
|
|
||||||
*/
|
|
||||||
proxy.text = new AccessorMutator(element, 'text');
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get and/or set the text size of this element.
|
|
||||||
*
|
|
||||||
* @param {string} [size] the new text size (if setting)
|
|
||||||
* @returns {string} the text size
|
|
||||||
* @memberof platform/features/layout.TextProxy#
|
|
||||||
*/
|
|
||||||
proxy.size = new AccessorMutator(element, 'size');
|
|
||||||
|
|
||||||
return proxy;
|
|
||||||
}
|
|
||||||
|
|
||||||
return TextProxy;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,92 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
[],
|
|
||||||
function () {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Variant of AccessorMutator to handle the specific case of updating
|
|
||||||
* useGrid, in order update the positions appropriately from within
|
|
||||||
* the scope of UnitAccessorMutator
|
|
||||||
*
|
|
||||||
* @memberof platform/features/layout
|
|
||||||
* @constructor
|
|
||||||
* @param {ElementProxy} proxy ElementProxy object to perform the update
|
|
||||||
* upon
|
|
||||||
*/
|
|
||||||
function UnitAccessorMutator(elementProxy) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
this.elementProxy = elementProxy;
|
|
||||||
return function (useGrid) {
|
|
||||||
var current = elementProxy.element.useGrid;
|
|
||||||
if (arguments.length > 0) {
|
|
||||||
elementProxy.element.useGrid = useGrid;
|
|
||||||
if (useGrid && !current) {
|
|
||||||
self.convertCoordsTo('grid');
|
|
||||||
} else if (!useGrid && current) {
|
|
||||||
self.convertCoordsTo('px');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return elementProxy.element.useGrid;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* For the elementProxy object called upon, convert its element's
|
|
||||||
* coordinates and size from pixels to grid units, or vice-versa.
|
|
||||||
* @param {string} unit When called with 'px', converts grid units to
|
|
||||||
* pixels; when called with 'grid', snaps element
|
|
||||||
* to grid units
|
|
||||||
*/
|
|
||||||
UnitAccessorMutator.prototype.convertCoordsTo = function (unit) {
|
|
||||||
var proxy = this.elementProxy,
|
|
||||||
gridSize = proxy.gridSize,
|
|
||||||
element = proxy.element,
|
|
||||||
minWidth = proxy.getMinWidth(),
|
|
||||||
minHeight = proxy.getMinHeight();
|
|
||||||
if (unit === 'px') {
|
|
||||||
element.x = element.x * gridSize[0];
|
|
||||||
element.y = element.y * gridSize[1];
|
|
||||||
element.width = element.width * gridSize[0];
|
|
||||||
element.height = element.height * gridSize[1];
|
|
||||||
if (element.x2 && element.y2) {
|
|
||||||
element.x2 = element.x2 * gridSize[0];
|
|
||||||
element.y2 = element.y2 * gridSize[1];
|
|
||||||
}
|
|
||||||
} else if (unit === 'grid') {
|
|
||||||
element.x = Math.round(element.x / gridSize[0]);
|
|
||||||
element.y = Math.round(element.y / gridSize[1]);
|
|
||||||
element.width = Math.max(Math.round(element.width / gridSize[0]), minWidth);
|
|
||||||
element.height = Math.max(Math.round(element.height / gridSize[1]), minHeight);
|
|
||||||
if (element.x2 && element.y2) {
|
|
||||||
element.x2 = Math.round(element.x2 / gridSize[0]);
|
|
||||||
element.y2 = Math.round(element.y2 / gridSize[1]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return UnitAccessorMutator;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,26 +0,0 @@
|
|||||||
<!--
|
|
||||||
Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
Administration. All rights reserved.
|
|
||||||
|
|
||||||
Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
License for the specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
|
|
||||||
Open MCT includes source code licensed under additional open source
|
|
||||||
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
this source code distribution or the Licensing information page available
|
|
||||||
at runtime from the About dialog for additional information.
|
|
||||||
-->
|
|
||||||
<div
|
|
||||||
class="l-fixed-position-box"
|
|
||||||
ng-style="{ background: ngModel.fill(), border: '1px ' + ngModel.stroke() + ' solid' }"
|
|
||||||
>
|
|
||||||
</div>
|
|
@ -1,26 +0,0 @@
|
|||||||
<!--
|
|
||||||
Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
Administration. All rights reserved.
|
|
||||||
|
|
||||||
Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
License for the specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
|
|
||||||
Open MCT includes source code licensed under additional open source
|
|
||||||
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
this source code distribution or the Licensing information page available
|
|
||||||
at runtime from the About dialog for additional information.
|
|
||||||
-->
|
|
||||||
<div
|
|
||||||
ng-style="{ 'background-image': 'url(' + ngModel.element.url + ')', border: '1px solid ' + ngModel.stroke() }"
|
|
||||||
class="l-fixed-position-image"
|
|
||||||
>
|
|
||||||
</div>
|
|
@ -1,31 +0,0 @@
|
|||||||
<!--
|
|
||||||
Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
Administration. All rights reserved.
|
|
||||||
|
|
||||||
Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
License for the specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
|
|
||||||
Open MCT includes source code licensed under additional open source
|
|
||||||
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
this source code distribution or the Licensing information page available
|
|
||||||
at runtime from the About dialog for additional information.
|
|
||||||
-->
|
|
||||||
<svg ng-attr-width="{{ngModel.getGridSize()[0] * ngModel.width()}}"
|
|
||||||
ng-attr-height="{{ngModel.getGridSize()[1] * ngModel.height()}}">
|
|
||||||
<line ng-attr-x1="{{ngModel.getGridSize()[0] * ngModel.x1() + 1}}"
|
|
||||||
ng-attr-y1="{{ngModel.getGridSize()[1] * ngModel.y1() + 1}}"
|
|
||||||
ng-attr-x2="{{ngModel.getGridSize()[0] * ngModel.x2() + 1}}"
|
|
||||||
ng-attr-y2="{{ngModel.getGridSize()[1] * ngModel.y2() + 1}}"
|
|
||||||
ng-attr-stroke="{{ngModel.stroke()}}"
|
|
||||||
stroke-width="2">
|
|
||||||
</line>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 1.5 KiB |
@ -1,39 +0,0 @@
|
|||||||
<!--
|
|
||||||
Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
Administration. All rights reserved.
|
|
||||||
|
|
||||||
Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
License for the specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
|
|
||||||
Open MCT includes source code licensed under additional open source
|
|
||||||
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
this source code distribution or the Licensing information page available
|
|
||||||
at runtime from the About dialog for additional information.
|
|
||||||
-->
|
|
||||||
<div
|
|
||||||
class="l-fixed-position-text l-telemetry"
|
|
||||||
ng-style="{ background: ngModel.fill(), 'border-color': ngModel.stroke(), color: ngModel.color(), 'font-size': ngModel.size() }"
|
|
||||||
>
|
|
||||||
<span
|
|
||||||
class="l-elem l-value l-obj-val-format"
|
|
||||||
data-value="{{ngModel.value}}"
|
|
||||||
ng-class="ngModel.cssClass"
|
|
||||||
>
|
|
||||||
{{ngModel.value}}
|
|
||||||
</span>
|
|
||||||
<span
|
|
||||||
class="l-elem l-title"
|
|
||||||
ng-show="ngModel.element.titled"
|
|
||||||
>
|
|
||||||
{{ngModel.name}}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
@ -1,27 +0,0 @@
|
|||||||
<!--
|
|
||||||
Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
Administration. All rights reserved.
|
|
||||||
|
|
||||||
Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
License for the specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
|
|
||||||
Open MCT includes source code licensed under additional open source
|
|
||||||
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
this source code distribution or the Licensing information page available
|
|
||||||
at runtime from the About dialog for additional information.
|
|
||||||
-->
|
|
||||||
<div
|
|
||||||
class="l-fixed-position-text l-static-text"
|
|
||||||
ng-style="{ background: ngModel.fill(), 'border-color': ngModel.stroke(), color: ngModel.color(), 'font-size': ngModel.size() }"
|
|
||||||
>
|
|
||||||
{{ngModel.element.text}}
|
|
||||||
</div>
|
|
@ -1,62 +0,0 @@
|
|||||||
<!--
|
|
||||||
Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
Administration. All rights reserved.
|
|
||||||
|
|
||||||
Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
License for the specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
|
|
||||||
Open MCT includes source code licensed under additional open source
|
|
||||||
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
this source code distribution or the Licensing information page available
|
|
||||||
at runtime from the About dialog for additional information.
|
|
||||||
-->
|
|
||||||
<div class="t-fixed-position l-fixed-position"
|
|
||||||
ng-controller="FixedController as controller">
|
|
||||||
|
|
||||||
<!-- Background grid -->
|
|
||||||
<div class="l-fixed-position__grid-holder l-grid-holder c-grid" ng-click="controller.bypassSelection($event)">
|
|
||||||
<div class="c-grid__x l-grid l-grid-x"
|
|
||||||
ng-if="!controller.getGridSize()[0] < 3"
|
|
||||||
ng-style="{ 'background-size': controller.getGridSize() [0] + 'px 100%' }"></div>
|
|
||||||
<div class="c-grid__y l-grid l-grid-y"
|
|
||||||
ng-if="!controller.getGridSize()[1] < 3"
|
|
||||||
ng-style="{ 'background-size': '100% ' + controller.getGridSize() [1] + 'px' }"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Fixed position elements -->
|
|
||||||
<div ng-repeat="element in controller.getElements()"
|
|
||||||
class="l-fixed-position-item s-selectable s-moveable is-selectable is-moveable"
|
|
||||||
ng-style="element.style"
|
|
||||||
mct-selectable="controller.getContext(element)"
|
|
||||||
mct-init-select="controller.shouldSelect(element)">
|
|
||||||
<mct-include key="element.template"
|
|
||||||
parameters="{ gridSize: controller.getGridSize() }"
|
|
||||||
ng-model="element">
|
|
||||||
</mct-include>
|
|
||||||
</div>
|
|
||||||
<!-- Selection highlight, handles -->
|
|
||||||
<span class="c-frame-edit" ng-if="controller.isElementSelected()">
|
|
||||||
<div class="c-frame-edit__move"
|
|
||||||
mct-drag-down="controller.moveHandle().startDrag()"
|
|
||||||
mct-drag="controller.moveHandle().continueDrag(delta)"
|
|
||||||
mct-drag-up="controller.endDrag()"
|
|
||||||
ng-style="controller.getSelectedElementStyle()">
|
|
||||||
</div>
|
|
||||||
<div ng-repeat="handle in controller.handles()"
|
|
||||||
class="c-frame-edit__handle c-frame-edit__handle--nwse"
|
|
||||||
ng-style="handle.style()"
|
|
||||||
mct-drag-down="handle.startDrag()"
|
|
||||||
mct-drag="handle.continueDrag(delta)"
|
|
||||||
mct-drag-up="controller.endDrag(handle)">
|
|
||||||
</div>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
@ -1,49 +0,0 @@
|
|||||||
<!--
|
|
||||||
Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
Administration. All rights reserved.
|
|
||||||
|
|
||||||
Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
"License"); you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
License for the specific language governing permissions and limitations
|
|
||||||
under the License.
|
|
||||||
|
|
||||||
Open MCT includes source code licensed under additional open source
|
|
||||||
licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
this source code distribution or the Licensing information page available
|
|
||||||
at runtime from the About dialog for additional information.
|
|
||||||
-->
|
|
||||||
<div class="frame frame-template t-frame-inner abs has-local-controls t-object-type-{{ domainObject.getModel().type }}">
|
|
||||||
<div class="abs object-browse-bar l-flex-row">
|
|
||||||
<div class="left flex-elem l-flex-row grows">
|
|
||||||
<mct-representation
|
|
||||||
key="'object-header-frame'"
|
|
||||||
mct-object="domainObject"
|
|
||||||
class="l-flex-row flex-elem object-header grows">
|
|
||||||
</mct-representation>
|
|
||||||
</div>
|
|
||||||
<div class="btn-bar right l-flex-row flex-elem flex-justify-end flex-fixed h-local-controls local-controls-hidden">
|
|
||||||
<mct-representation
|
|
||||||
key="'switcher'"
|
|
||||||
ng-model="representation"
|
|
||||||
mct-object="domainObject">
|
|
||||||
</mct-representation>
|
|
||||||
<a class="s-button icon-expand t-btn-view-large"
|
|
||||||
title="View large"
|
|
||||||
mct-trigger-modal>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="abs object-holder">
|
|
||||||
<mct-representation
|
|
||||||
key="representation.selected.key"
|
|
||||||
mct-object="representation.selected.key && domainObject">
|
|
||||||
</mct-representation>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
@ -1,641 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
[
|
|
||||||
"../src/FixedController",
|
|
||||||
"zepto"
|
|
||||||
],
|
|
||||||
function (
|
|
||||||
FixedController,
|
|
||||||
$
|
|
||||||
) {
|
|
||||||
|
|
||||||
describe("The Fixed Position controller", function () {
|
|
||||||
var mockScope,
|
|
||||||
mockQ,
|
|
||||||
mockDialogService,
|
|
||||||
mockFormatter,
|
|
||||||
mockDomainObject,
|
|
||||||
mockEvent,
|
|
||||||
testGrid,
|
|
||||||
testModel,
|
|
||||||
testConfiguration,
|
|
||||||
mockOpenMCT,
|
|
||||||
mockTelemetryAPI,
|
|
||||||
mockCompositionAPI,
|
|
||||||
mockCompositionCollection,
|
|
||||||
mockChildren,
|
|
||||||
mockConductor,
|
|
||||||
mockMetadata,
|
|
||||||
mockTimeSystem,
|
|
||||||
mockLimitEvaluator,
|
|
||||||
mockSelection,
|
|
||||||
mockObjects,
|
|
||||||
mockNewDomainObject,
|
|
||||||
unlistenFunc,
|
|
||||||
$element = [],
|
|
||||||
selectable = [],
|
|
||||||
controller;
|
|
||||||
|
|
||||||
// Utility function; find a $on calls for a given expression.
|
|
||||||
function findOn(expr) {
|
|
||||||
var on;
|
|
||||||
mockScope.$on.calls.all().forEach(function (call) {
|
|
||||||
if (call.args[0] === expr) {
|
|
||||||
on = call.args[1];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return on;
|
|
||||||
}
|
|
||||||
|
|
||||||
function makeMockDomainObject(id) {
|
|
||||||
return {
|
|
||||||
identifier: {
|
|
||||||
key: "domainObject-" + id,
|
|
||||||
namespace: ""
|
|
||||||
},
|
|
||||||
name: "Point " + id
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockScope = jasmine.createSpyObj(
|
|
||||||
'$scope',
|
|
||||||
["$on", "$watch", "$digest", "commit"]
|
|
||||||
);
|
|
||||||
mockQ = jasmine.createSpyObj('$q', ['when']);
|
|
||||||
mockDialogService = jasmine.createSpyObj(
|
|
||||||
'dialogService',
|
|
||||||
['getUserInput']
|
|
||||||
);
|
|
||||||
mockFormatter = jasmine.createSpyObj(
|
|
||||||
'telemetryFormatter',
|
|
||||||
['format']
|
|
||||||
);
|
|
||||||
mockFormatter.format.and.callFake(function (valueMetadata) {
|
|
||||||
return "Formatted " + valueMetadata.value;
|
|
||||||
});
|
|
||||||
|
|
||||||
mockConductor = jasmine.createSpyObj('conductor', [
|
|
||||||
'on',
|
|
||||||
'off',
|
|
||||||
'bounds',
|
|
||||||
'timeSystem',
|
|
||||||
'clock'
|
|
||||||
]);
|
|
||||||
mockConductor.bounds.and.returnValue({});
|
|
||||||
mockTimeSystem = {
|
|
||||||
metadata: {
|
|
||||||
key: 'key'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mockConductor.timeSystem.and.returnValue(mockTimeSystem);
|
|
||||||
|
|
||||||
mockEvent = jasmine.createSpyObj(
|
|
||||||
'event',
|
|
||||||
['preventDefault']
|
|
||||||
);
|
|
||||||
|
|
||||||
mockTelemetryAPI = jasmine.createSpyObj('telemetry',
|
|
||||||
[
|
|
||||||
'subscribe',
|
|
||||||
'request',
|
|
||||||
'isTelemetryObject',
|
|
||||||
'getMetadata',
|
|
||||||
'limitEvaluator',
|
|
||||||
'getValueFormatter'
|
|
||||||
]
|
|
||||||
);
|
|
||||||
mockTelemetryAPI.isTelemetryObject.and.returnValue(true);
|
|
||||||
mockTelemetryAPI.request.and.returnValue(Promise.resolve([]));
|
|
||||||
|
|
||||||
testGrid = [123, 456];
|
|
||||||
testModel = {
|
|
||||||
composition: ['a', 'b', 'c'],
|
|
||||||
layoutGrid: testGrid
|
|
||||||
};
|
|
||||||
testConfiguration = { elements: [
|
|
||||||
{ type: "fixed.telemetry", id: 'a', x: 1, y: 1, useGrid: true},
|
|
||||||
{ type: "fixed.telemetry", id: 'b', x: 1, y: 1, useGrid: true},
|
|
||||||
{ type: "fixed.telemetry", id: 'c', x: 1, y: 1, useGrid: true}
|
|
||||||
]};
|
|
||||||
|
|
||||||
mockChildren = testModel.composition.map(makeMockDomainObject);
|
|
||||||
mockCompositionCollection = jasmine.createSpyObj('compositionCollection', [
|
|
||||||
'load',
|
|
||||||
'on',
|
|
||||||
'off'
|
|
||||||
]);
|
|
||||||
mockCompositionAPI = jasmine.createSpyObj('composition', [
|
|
||||||
'get'
|
|
||||||
]);
|
|
||||||
mockCompositionAPI.get.and.returnValue(mockCompositionCollection);
|
|
||||||
mockCompositionCollection.load.and.returnValue(
|
|
||||||
Promise.resolve(mockChildren)
|
|
||||||
);
|
|
||||||
|
|
||||||
mockScope.model = testModel;
|
|
||||||
mockScope.configuration = testConfiguration;
|
|
||||||
|
|
||||||
mockNewDomainObject = jasmine.createSpyObj("newDomainObject", [
|
|
||||||
'layoutGrid',
|
|
||||||
'configuration',
|
|
||||||
'composition'
|
|
||||||
]);
|
|
||||||
mockNewDomainObject.layoutGrid = testGrid;
|
|
||||||
mockNewDomainObject.configuration = {
|
|
||||||
'fixed-display': testConfiguration
|
|
||||||
};
|
|
||||||
mockNewDomainObject.composition = ['a', 'b', 'c'];
|
|
||||||
|
|
||||||
mockDomainObject = jasmine.createSpyObj(
|
|
||||||
'domainObject',
|
|
||||||
['getId', 'getModel', 'getCapability', 'useCapability']
|
|
||||||
);
|
|
||||||
mockDomainObject.useCapability.and.returnValue(mockNewDomainObject);
|
|
||||||
mockScope.domainObject = mockDomainObject;
|
|
||||||
|
|
||||||
selectable[0] = {
|
|
||||||
context: {
|
|
||||||
oldItem: mockDomainObject
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mockSelection = jasmine.createSpyObj("selection", [
|
|
||||||
'select',
|
|
||||||
'on',
|
|
||||||
'off',
|
|
||||||
'get'
|
|
||||||
]);
|
|
||||||
mockSelection.get.and.returnValue([]);
|
|
||||||
|
|
||||||
unlistenFunc = jasmine.createSpy("unlisten");
|
|
||||||
mockObjects = jasmine.createSpyObj('objects', [
|
|
||||||
'observe',
|
|
||||||
'get'
|
|
||||||
]);
|
|
||||||
mockObjects.observe.and.returnValue(unlistenFunc);
|
|
||||||
|
|
||||||
mockOpenMCT = {
|
|
||||||
time: mockConductor,
|
|
||||||
telemetry: mockTelemetryAPI,
|
|
||||||
composition: mockCompositionAPI,
|
|
||||||
selection: mockSelection,
|
|
||||||
objects: mockObjects
|
|
||||||
};
|
|
||||||
|
|
||||||
$element = $('<div></div>');
|
|
||||||
spyOn($element[0], 'click');
|
|
||||||
|
|
||||||
mockMetadata = jasmine.createSpyObj('mockMetadata', [
|
|
||||||
'valuesForHints',
|
|
||||||
'value',
|
|
||||||
'values'
|
|
||||||
]);
|
|
||||||
mockMetadata.value.and.returnValue({
|
|
||||||
key: 'value'
|
|
||||||
});
|
|
||||||
|
|
||||||
mockMetadata.valuesForHints.and.callFake(function (hints) {
|
|
||||||
if (hints === ['domain']) {
|
|
||||||
return [{
|
|
||||||
key: 'time'
|
|
||||||
}];
|
|
||||||
} else {
|
|
||||||
return [{
|
|
||||||
key: 'value'
|
|
||||||
}];
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mockLimitEvaluator = jasmine.createSpyObj('limitEvaluator', [
|
|
||||||
'evaluate'
|
|
||||||
]);
|
|
||||||
|
|
||||||
mockLimitEvaluator.evaluate.and.returnValue({});
|
|
||||||
|
|
||||||
mockTelemetryAPI.getMetadata.and.returnValue(mockMetadata);
|
|
||||||
mockTelemetryAPI.limitEvaluator.and.returnValue(mockLimitEvaluator);
|
|
||||||
mockTelemetryAPI.getValueFormatter.and.returnValue(mockFormatter);
|
|
||||||
|
|
||||||
controller = new FixedController(
|
|
||||||
mockScope,
|
|
||||||
mockQ,
|
|
||||||
mockDialogService,
|
|
||||||
mockOpenMCT,
|
|
||||||
$element
|
|
||||||
);
|
|
||||||
spyOn(controller, "mutate");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("subscribes a domain object", function () {
|
|
||||||
var object = makeMockDomainObject("mock");
|
|
||||||
|
|
||||||
return controller.getTelemetry(object).then(function () {
|
|
||||||
expect(mockTelemetryAPI.subscribe).toHaveBeenCalledWith(
|
|
||||||
object,
|
|
||||||
jasmine.any(Function),
|
|
||||||
jasmine.any(Object)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("releases subscription when a domain objects is removed", function () {
|
|
||||||
var unsubscribe = jasmine.createSpy('unsubscribe');
|
|
||||||
var unsubscribePromise = new Promise(function (resolve) {
|
|
||||||
unsubscribe.and.callFake(resolve);
|
|
||||||
});
|
|
||||||
var object = makeMockDomainObject("mock");
|
|
||||||
|
|
||||||
mockTelemetryAPI.subscribe.and.returnValue(unsubscribe);
|
|
||||||
return controller.getTelemetry(object).then(function () {
|
|
||||||
controller.onCompositionRemove(object.identifier);
|
|
||||||
return unsubscribePromise;
|
|
||||||
}).then(function () {
|
|
||||||
expect(unsubscribe).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("exposes visible elements based on configuration", function () {
|
|
||||||
var elements = controller.getElements();
|
|
||||||
|
|
||||||
expect(elements.length).toEqual(3);
|
|
||||||
expect(elements[0].id).toEqual('a');
|
|
||||||
expect(elements[1].id).toEqual('b');
|
|
||||||
expect(elements[2].id).toEqual('c');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows elements to be selected", function () {
|
|
||||||
selectable[0].context.elementProxy = controller.getElements()[1];
|
|
||||||
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
|
|
||||||
|
|
||||||
expect(controller.isElementSelected()).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows selection retrieval", function () {
|
|
||||||
var elements = controller.getElements();
|
|
||||||
selectable[0].context.elementProxy = elements[1];
|
|
||||||
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
|
|
||||||
|
|
||||||
expect(controller.getSelectedElement()).toEqual(elements[1]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("selects the parent view when selected element is removed", function () {
|
|
||||||
var elements = controller.getElements();
|
|
||||||
selectable[0].context.elementProxy = elements[1];
|
|
||||||
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
|
|
||||||
controller.remove(elements[1]);
|
|
||||||
|
|
||||||
expect($element[0].click).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("retains selections during refresh", function () {
|
|
||||||
// Get elements; remove one of them; trigger refresh.
|
|
||||||
// Same element (at least by index) should still be selected.
|
|
||||||
var elements = controller.getElements();
|
|
||||||
selectable[0].context.elementProxy = elements[1];
|
|
||||||
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
|
|
||||||
|
|
||||||
expect(controller.getSelectedElement()).toEqual(elements[1]);
|
|
||||||
|
|
||||||
controller.remove(elements[2]);
|
|
||||||
elements = controller.getElements();
|
|
||||||
|
|
||||||
// Verify removal, as test assumes this
|
|
||||||
expect(elements.length).toEqual(2);
|
|
||||||
|
|
||||||
expect(controller.shouldSelect(elements[1])).toBe(true);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Displays received values for telemetry elements", function () {
|
|
||||||
var elements;
|
|
||||||
var mockTelemetry = {
|
|
||||||
time: 100,
|
|
||||||
value: 200
|
|
||||||
};
|
|
||||||
var testElement = {};
|
|
||||||
var telemetryObject = {
|
|
||||||
identifier: {
|
|
||||||
key: '12345'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
mockConductor.clock.and.returnValue({});
|
|
||||||
controller.elementProxiesById = {};
|
|
||||||
controller.elementProxiesById['12345'] = [testElement];
|
|
||||||
controller.elementProxies = [testElement];
|
|
||||||
|
|
||||||
controller.subscribeToObject(telemetryObject);
|
|
||||||
mockTelemetryAPI.subscribe.calls.mostRecent().args[1](mockTelemetry);
|
|
||||||
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
mockScope.$digest.and.callFake(resolve);
|
|
||||||
}).then(function () {
|
|
||||||
// Get elements that controller is now exposing
|
|
||||||
elements = controller.getElements();
|
|
||||||
|
|
||||||
// Formatted values should be available
|
|
||||||
expect(elements[0].value).toEqual("Formatted 200");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("updates elements styles when grid size changes", function () {
|
|
||||||
// Grid size is initially set to testGrid which is [123, 456]
|
|
||||||
var originalLeft = controller.getElements()[0].style.left;
|
|
||||||
|
|
||||||
// Change the grid size
|
|
||||||
controller.updateElementPositions([20, 20]);
|
|
||||||
|
|
||||||
expect(controller.getElements()[0].style.left).not.toEqual(originalLeft);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("listens for drop events", function () {
|
|
||||||
mockScope.domainObject = mockDomainObject;
|
|
||||||
mockScope.model = testModel;
|
|
||||||
|
|
||||||
// Layout should position panels according to
|
|
||||||
// where the user dropped them, so it needs to
|
|
||||||
// listen for drop events.
|
|
||||||
expect(mockScope.$on).toHaveBeenCalledWith(
|
|
||||||
'mctDrop',
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
|
|
||||||
// Verify precondition
|
|
||||||
expect(testConfiguration.elements.length).toEqual(3);
|
|
||||||
|
|
||||||
// Notify that a drop occurred
|
|
||||||
testModel.composition.push('d');
|
|
||||||
|
|
||||||
mockObjects.get.and.returnValue(Promise.resolve([]));
|
|
||||||
|
|
||||||
findOn('mctDrop')(
|
|
||||||
mockEvent,
|
|
||||||
'd',
|
|
||||||
{ x: 300, y: 100 }
|
|
||||||
);
|
|
||||||
|
|
||||||
// Should have added an element
|
|
||||||
expect(testConfiguration.elements.length).toEqual(4);
|
|
||||||
|
|
||||||
// ...and prevented default...
|
|
||||||
expect(mockEvent.preventDefault).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("ignores drops when default has been prevented", function () {
|
|
||||||
// Avoids redundant drop-handling, WTD-1233
|
|
||||||
mockEvent.defaultPrevented = true;
|
|
||||||
|
|
||||||
// Notify that a drop occurred
|
|
||||||
testModel.composition.push('d');
|
|
||||||
findOn('mctDrop')(
|
|
||||||
mockEvent,
|
|
||||||
'd',
|
|
||||||
{ x: 300, y: 100 }
|
|
||||||
);
|
|
||||||
|
|
||||||
// Should NOT have added an element
|
|
||||||
expect(testConfiguration.elements.length).toEqual(3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("unsubscribes when destroyed", function () {
|
|
||||||
var unsubscribe = jasmine.createSpy('unsubscribe');
|
|
||||||
var object = makeMockDomainObject("mock");
|
|
||||||
|
|
||||||
mockTelemetryAPI.subscribe.and.returnValue(unsubscribe);
|
|
||||||
|
|
||||||
return controller.getTelemetry(object).then(function () {
|
|
||||||
expect(unsubscribe).not.toHaveBeenCalled();
|
|
||||||
// Destroy the scope
|
|
||||||
findOn('$destroy')();
|
|
||||||
|
|
||||||
expect(unsubscribe).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("exposes its grid size", function () {
|
|
||||||
expect(controller.getGridSize()).toEqual(testGrid);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("exposes drag handles", function () {
|
|
||||||
var handles;
|
|
||||||
selectable[0].context.elementProxy = controller.getElements()[1];
|
|
||||||
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
|
|
||||||
|
|
||||||
// Should have a non-empty array of handles
|
|
||||||
handles = controller.handles();
|
|
||||||
|
|
||||||
expect(handles).toEqual(jasmine.any(Array));
|
|
||||||
expect(handles.length).not.toEqual(0);
|
|
||||||
|
|
||||||
// And they should have start/continue/end drag methods
|
|
||||||
handles.forEach(function (handle) {
|
|
||||||
expect(handle.startDrag).toEqual(jasmine.any(Function));
|
|
||||||
expect(handle.continueDrag).toEqual(jasmine.any(Function));
|
|
||||||
expect(handle.endDrag).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("exposes a move handle", function () {
|
|
||||||
selectable[0].context.elementProxy = controller.getElements()[1];
|
|
||||||
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
|
|
||||||
|
|
||||||
// Should have a move handle
|
|
||||||
var handle = controller.moveHandle();
|
|
||||||
|
|
||||||
// And it should have start/continue/end drag methods
|
|
||||||
expect(handle.startDrag).toEqual(jasmine.any(Function));
|
|
||||||
expect(handle.continueDrag).toEqual(jasmine.any(Function));
|
|
||||||
expect(handle.endDrag).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
it("updates selection style during drag", function () {
|
|
||||||
var oldStyle;
|
|
||||||
selectable[0].context.elementProxy = controller.getElements()[1];
|
|
||||||
mockOpenMCT.selection.on.calls.mostRecent().args[1](selectable);
|
|
||||||
|
|
||||||
// Get style
|
|
||||||
oldStyle = controller.getSelectedElementStyle();
|
|
||||||
|
|
||||||
// Start a drag gesture
|
|
||||||
controller.moveHandle().startDrag();
|
|
||||||
|
|
||||||
// Haven't moved yet; style shouldn't have updated yet
|
|
||||||
expect(controller.getSelectedElementStyle()).toEqual(oldStyle);
|
|
||||||
|
|
||||||
// Drag a little
|
|
||||||
controller.moveHandle().continueDrag([1000, 100]);
|
|
||||||
|
|
||||||
// Style should have been updated
|
|
||||||
expect(controller.getSelectedElementStyle()).not.toEqual(oldStyle);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("cleans up selection on scope destroy", function () {
|
|
||||||
expect(mockScope.$on).toHaveBeenCalledWith(
|
|
||||||
'$destroy',
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
|
|
||||||
mockScope.$on.calls.mostRecent().args[1]();
|
|
||||||
|
|
||||||
expect(mockOpenMCT.selection.off).toHaveBeenCalledWith(
|
|
||||||
'change',
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("on display bounds changes", function () {
|
|
||||||
var testBounds;
|
|
||||||
var boundsChangeCallback;
|
|
||||||
var objectOne;
|
|
||||||
var objectTwo;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testBounds = { start: 123, end: 321 };
|
|
||||||
boundsChangeCallback = mockConductor.on.calls.mostRecent().args[1];
|
|
||||||
objectOne = {};
|
|
||||||
objectTwo = {};
|
|
||||||
controller.telemetryObjects = [
|
|
||||||
objectOne,
|
|
||||||
objectTwo
|
|
||||||
];
|
|
||||||
spyOn(controller, "fetchHistoricalData");
|
|
||||||
controller.fetchHistoricalData.and.callThrough();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("registers a bounds change listener", function () {
|
|
||||||
expect(mockConductor.on).toHaveBeenCalledWith("bounds", jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
it("requests only a single point", function () {
|
|
||||||
mockConductor.clock.and.returnValue(undefined);
|
|
||||||
boundsChangeCallback(testBounds);
|
|
||||||
expect(mockTelemetryAPI.request.calls.count()).toBe(2);
|
|
||||||
|
|
||||||
mockTelemetryAPI.request.calls.all().forEach(function (call) {
|
|
||||||
expect(call.args[1].size).toBe(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("Does not fetch historical data on tick", function () {
|
|
||||||
boundsChangeCallback(testBounds, true);
|
|
||||||
expect(mockTelemetryAPI.request.calls.count()).toBe(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
describe("on receipt of telemetry", function () {
|
|
||||||
var mockTelemetryObject;
|
|
||||||
var testValue;
|
|
||||||
var testElement;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockTelemetryObject = {
|
|
||||||
identifier: {
|
|
||||||
key: '12345'
|
|
||||||
}
|
|
||||||
};
|
|
||||||
testValue = 30;
|
|
||||||
testElement = {};
|
|
||||||
|
|
||||||
controller.elementProxiesById = {};
|
|
||||||
controller.elementProxiesById['12345'] = [testElement];
|
|
||||||
controller.elementProxies = [testElement];
|
|
||||||
});
|
|
||||||
|
|
||||||
it("updates displayed values from historical telemetry", function () {
|
|
||||||
spyOn(controller, "updateView");
|
|
||||||
controller.updateView.and.callThrough();
|
|
||||||
|
|
||||||
mockTelemetryAPI.request.and.returnValue(Promise.resolve([{
|
|
||||||
time: 100,
|
|
||||||
value: testValue
|
|
||||||
}]));
|
|
||||||
|
|
||||||
controller.fetchHistoricalData(mockTelemetryObject);
|
|
||||||
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
mockScope.$digest.and.callFake(resolve);
|
|
||||||
}).then(function () {
|
|
||||||
expect(controller.updateView).toHaveBeenCalled();
|
|
||||||
expect(controller.getElements()[0].value)
|
|
||||||
.toEqual("Formatted " + testValue);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("selects an range value to display, if available", function () {
|
|
||||||
mockMetadata.valuesForHints.and.returnValue([
|
|
||||||
{
|
|
||||||
key: 'range',
|
|
||||||
source: 'range'
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
var key = controller.chooseValueMetadataToDisplay(mockMetadata).source;
|
|
||||||
expect(key).toEqual('range');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("selects the first non-domain value to display, if no range available", function () {
|
|
||||||
mockMetadata.valuesForHints.and.returnValue([]);
|
|
||||||
mockMetadata.values.and.returnValue([
|
|
||||||
{
|
|
||||||
key: 'domain',
|
|
||||||
source: 'domain',
|
|
||||||
hints: {
|
|
||||||
domain: 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
key: 'image',
|
|
||||||
source: 'image',
|
|
||||||
hints: {
|
|
||||||
image: 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]);
|
|
||||||
var key = controller.chooseValueMetadataToDisplay(mockMetadata).source;
|
|
||||||
expect(key).toEqual('image');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("reflects limit status", function () {
|
|
||||||
mockLimitEvaluator.evaluate.and.returnValue({cssClass: "alarm-a"});
|
|
||||||
controller.updateView(mockTelemetryObject, [{
|
|
||||||
time: 100,
|
|
||||||
value: testValue
|
|
||||||
}]);
|
|
||||||
|
|
||||||
return new Promise(function (resolve) {
|
|
||||||
mockScope.$digest.and.callFake(resolve);
|
|
||||||
}).then(function () {
|
|
||||||
// Limit-based CSS classes should be available
|
|
||||||
expect(controller.getElements()[0].cssClass).toEqual("alarm-a");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("listens for selection change events", function () {
|
|
||||||
expect(mockOpenMCT.selection.on).toHaveBeenCalledWith(
|
|
||||||
'change',
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,92 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['../src/FixedDragHandle'],
|
|
||||||
function (FixedDragHandle) {
|
|
||||||
|
|
||||||
var TEST_GRID_SIZE = [13, 33];
|
|
||||||
|
|
||||||
describe("A fixed position drag handle", function () {
|
|
||||||
var mockElementHandle,
|
|
||||||
mockConfigPath,
|
|
||||||
mockFixedControl,
|
|
||||||
handle;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockElementHandle = jasmine.createSpyObj(
|
|
||||||
'elementHandle',
|
|
||||||
['x', 'y','getGridSize']
|
|
||||||
);
|
|
||||||
mockElementHandle.x.and.returnValue(6);
|
|
||||||
mockElementHandle.y.and.returnValue(8);
|
|
||||||
mockElementHandle.getGridSize.and.returnValue(TEST_GRID_SIZE);
|
|
||||||
|
|
||||||
mockFixedControl = jasmine.createSpyObj(
|
|
||||||
'fixedControl',
|
|
||||||
['updateSelectionStyle', 'mutate']
|
|
||||||
);
|
|
||||||
mockFixedControl.updateSelectionStyle.and.returnValue();
|
|
||||||
mockFixedControl.mutate.and.returnValue();
|
|
||||||
|
|
||||||
mockConfigPath = jasmine.createSpy('configPath');
|
|
||||||
|
|
||||||
handle = new FixedDragHandle(
|
|
||||||
mockElementHandle,
|
|
||||||
mockConfigPath,
|
|
||||||
mockFixedControl
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides a style for positioning", function () {
|
|
||||||
var style = handle.style();
|
|
||||||
// 6 grid coords * 13 pixels - 3 pixels for centering
|
|
||||||
expect(style.left).toEqual('75px');
|
|
||||||
// 8 grid coords * 33 pixels - 3 pixels for centering
|
|
||||||
expect(style.top).toEqual('261px');
|
|
||||||
});
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
// Should have called updateSelectionStyle once per continueDrag
|
|
||||||
expect(mockFixedControl.updateSelectionStyle.calls.count()).toEqual(2);
|
|
||||||
|
|
||||||
// Finally, ending drag should mutate
|
|
||||||
handle.endDrag();
|
|
||||||
expect(mockFixedControl.mutate).toHaveBeenCalled();
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,71 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['../src/FixedProxy'],
|
|
||||||
function (FixedProxy) {
|
|
||||||
|
|
||||||
describe("Fixed Position view's selection proxy", function () {
|
|
||||||
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.and.returnValue(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();
|
|
||||||
});
|
|
||||||
|
|
||||||
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.calls.mostRecent().args[0]({});
|
|
||||||
// Should have fired the callback
|
|
||||||
expect(mockCallback).toHaveBeenCalledWith({
|
|
||||||
type: "fixed.box",
|
|
||||||
x: 0,
|
|
||||||
y: 0,
|
|
||||||
width: 1,
|
|
||||||
height: 1,
|
|
||||||
useGrid: true
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,81 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
["../src/LayoutDrag"],
|
|
||||||
function (LayoutDrag) {
|
|
||||||
|
|
||||||
describe("A Layout drag handler", function () {
|
|
||||||
var testPosition = {
|
|
||||||
position: [8, 11],
|
|
||||||
dimensions: [3, 2]
|
|
||||||
};
|
|
||||||
|
|
||||||
it("changes position by a supplied factor, rounding by grid size", function () {
|
|
||||||
var handler = new LayoutDrag(
|
|
||||||
testPosition,
|
|
||||||
[1, 1],
|
|
||||||
[0, 0],
|
|
||||||
[10, 20]
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(handler.getAdjustedPosition([37, 84])).toEqual({
|
|
||||||
position: [12, 15],
|
|
||||||
dimensions: [3, 2]
|
|
||||||
});
|
|
||||||
expect(handler.getAdjustedPosition([-37, 84])).toEqual({
|
|
||||||
position: [4, 15],
|
|
||||||
dimensions: [3, 2]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("changes dimensions by a supplied factor, rounding by grid size", function () {
|
|
||||||
var handler = new LayoutDrag(
|
|
||||||
testPosition,
|
|
||||||
[0, 0],
|
|
||||||
[1, 1],
|
|
||||||
[10, 20]
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(handler.getAdjustedPosition([37, 84])).toEqual({
|
|
||||||
position: [8, 11],
|
|
||||||
dimensions: [7, 6]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows mixing dimension and position factors", function () {
|
|
||||||
var handler = new LayoutDrag(
|
|
||||||
testPosition,
|
|
||||||
[0, 1],
|
|
||||||
[-1, 0],
|
|
||||||
[10, 20]
|
|
||||||
);
|
|
||||||
|
|
||||||
expect(handler.getAdjustedPosition([11, 84])).toEqual({
|
|
||||||
position: [8, 15],
|
|
||||||
dimensions: [2, 2]
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,128 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2016, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define([
|
|
||||||
'../src/MCTTriggerModal'
|
|
||||||
], function (
|
|
||||||
MCTTriggerModal
|
|
||||||
) {
|
|
||||||
describe('MCTTriggerModal', function () {
|
|
||||||
var $scope,
|
|
||||||
$element,
|
|
||||||
frame,
|
|
||||||
layoutContainer,
|
|
||||||
$document,
|
|
||||||
mctTriggerModal;
|
|
||||||
|
|
||||||
function makeElement(classes, parentEl) {
|
|
||||||
var elem = jasmine.createSpyObj('element.' + classes.join('.'), [
|
|
||||||
'hasClass',
|
|
||||||
'parent'
|
|
||||||
]);
|
|
||||||
elem.hasClass.and.callFake(function (className) {
|
|
||||||
return classes.indexOf(className) !== -1;
|
|
||||||
});
|
|
||||||
elem.parent.and.returnValue(parentEl);
|
|
||||||
var div = document.createElement('div');
|
|
||||||
div.className = classes.join(' ');
|
|
||||||
parentEl[0].appendChild(div);
|
|
||||||
elem[0] = div;
|
|
||||||
return elem;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
$scope = jasmine.createSpyObj('$scope', ['$on']);
|
|
||||||
$scope.domainObject = { getCapability: function () {
|
|
||||||
return { getActions: function () {
|
|
||||||
return [];
|
|
||||||
}};
|
|
||||||
}};
|
|
||||||
|
|
||||||
$element = jasmine.createSpyObj('$element', [
|
|
||||||
'parent',
|
|
||||||
'remove',
|
|
||||||
'on',
|
|
||||||
'off'
|
|
||||||
]);
|
|
||||||
layoutContainer = document.createElement('div');
|
|
||||||
frame = makeElement(['frame'], [layoutContainer]);
|
|
||||||
var child = makeElement([], frame);
|
|
||||||
for (var i = 0; i < 5; i++) {
|
|
||||||
child = makeElement([], child);
|
|
||||||
}
|
|
||||||
$element.parent.and.returnValue(child);
|
|
||||||
$document = [jasmine.createSpyObj('document', ['createElement'])];
|
|
||||||
$document[0].body = document.createElement('div');
|
|
||||||
$document[0].createElement.and.callFake(function (tag) {
|
|
||||||
return document.createElement(tag);
|
|
||||||
});
|
|
||||||
|
|
||||||
mctTriggerModal = new MCTTriggerModal($document);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('is a directive definition', function () {
|
|
||||||
expect(mctTriggerModal.restrict).toBe('A');
|
|
||||||
expect(mctTriggerModal.link).toEqual(jasmine.any(Function));
|
|
||||||
});
|
|
||||||
|
|
||||||
describe('link', function () {
|
|
||||||
beforeEach(function () {
|
|
||||||
mctTriggerModal.link($scope, $element);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('attaches handlers to $element', function () {
|
|
||||||
expect($element.on).toHaveBeenCalledWith(
|
|
||||||
'click',
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('cleans up on $scope $destroy', function () {
|
|
||||||
expect($scope.$on).toHaveBeenCalledWith(
|
|
||||||
'$destroy',
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
$scope.$on.calls.mostRecent().args[1]();
|
|
||||||
expect($element.off).toHaveBeenCalledWith(
|
|
||||||
'click',
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('opens and closes overlays', function () {
|
|
||||||
[
|
|
||||||
'a.close', 'a.t-done', '.abs.blocker'
|
|
||||||
].forEach(function (selector) {
|
|
||||||
$element.on.calls.mostRecent().args[1]();
|
|
||||||
var container = $document[0].body.querySelector('.t-contents');
|
|
||||||
expect(container.children[0]).toBe(frame[0]);
|
|
||||||
expect(layoutContainer.children[0]).not.toBe(frame[0]);
|
|
||||||
$document[0].body.querySelector(selector)
|
|
||||||
.dispatchEvent(new Event('click'));
|
|
||||||
expect(container.children[0]).not.toBe(frame[0]);
|
|
||||||
expect(layoutContainer.children[0]).toBe(frame[0]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
@ -1,50 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['../../src/elements/AccessorMutator'],
|
|
||||||
function (AccessorMutator) {
|
|
||||||
|
|
||||||
describe("An accessor-mutator", function () {
|
|
||||||
var testObject,
|
|
||||||
am;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testObject = { t: 42, other: 100 };
|
|
||||||
am = new AccessorMutator(testObject, 't');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows access to a property", function () {
|
|
||||||
expect(am()).toEqual(42);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows mutation of a property", function () {
|
|
||||||
expect(am("some other value")).toEqual("some other value");
|
|
||||||
expect(testObject).toEqual({
|
|
||||||
t: "some other value",
|
|
||||||
other: 100
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,55 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['../../src/elements/BoxProxy'],
|
|
||||||
function (BoxProxy) {
|
|
||||||
|
|
||||||
describe("A fixed position box proxy", function () {
|
|
||||||
var testElement,
|
|
||||||
testElements,
|
|
||||||
proxy;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 1,
|
|
||||||
y: 2,
|
|
||||||
width: 42,
|
|
||||||
height: 24,
|
|
||||||
fill: "transparent"
|
|
||||||
};
|
|
||||||
testElements = [{}, {}, testElement, {}];
|
|
||||||
proxy = new BoxProxy(
|
|
||||||
testElement,
|
|
||||||
testElements.indexOf(testElement),
|
|
||||||
testElements
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides getter/setter for fill color", function () {
|
|
||||||
expect(proxy.fill()).toEqual('transparent');
|
|
||||||
expect(proxy.fill('#FFF')).toEqual('#FFF');
|
|
||||||
expect(proxy.fill()).toEqual('#FFF');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,69 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['../../src/elements/ElementFactory'],
|
|
||||||
function (ElementFactory) {
|
|
||||||
|
|
||||||
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.and.returnValue(mockPromise);
|
|
||||||
mockPromise.then.and.returnValue(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();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,51 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['../../src/elements/ElementProxies'],
|
|
||||||
function (ElementProxies) {
|
|
||||||
|
|
||||||
// Expect these element types to have proxies
|
|
||||||
var ELEMENT_TYPES = [
|
|
||||||
"fixed.telemetry",
|
|
||||||
"fixed.line",
|
|
||||||
"fixed.box",
|
|
||||||
"fixed.text",
|
|
||||||
"fixed.image"
|
|
||||||
];
|
|
||||||
|
|
||||||
// Verify that the set of proxies exposed matches the specific
|
|
||||||
// list above.
|
|
||||||
describe("The set of element proxies", function () {
|
|
||||||
ELEMENT_TYPES.forEach(function (t) {
|
|
||||||
it("exposes a proxy wrapper for " + t + " elements", function () {
|
|
||||||
expect(typeof ElementProxies[t]).toEqual('function');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("exposes no additional wrappers", function () {
|
|
||||||
expect(Object.keys(ElementProxies).length)
|
|
||||||
.toEqual(ELEMENT_TYPES.length);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,98 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['../../src/elements/ElementProxy'],
|
|
||||||
function (ElementProxy) {
|
|
||||||
|
|
||||||
describe("A fixed position element proxy", function () {
|
|
||||||
var testElement,
|
|
||||||
testElements,
|
|
||||||
proxy;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 1,
|
|
||||||
y: 2,
|
|
||||||
stroke: '#717171',
|
|
||||||
width: 42,
|
|
||||||
height: 24,
|
|
||||||
useGrid: true
|
|
||||||
};
|
|
||||||
testElements = [{}, {}, testElement, {}];
|
|
||||||
proxy = new ElementProxy(
|
|
||||||
testElement,
|
|
||||||
testElements.indexOf(testElement),
|
|
||||||
testElements,
|
|
||||||
[13,21]
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("exposes element properties", function () {
|
|
||||||
Object.keys(testElement).forEach(function (k) {
|
|
||||||
expect(proxy[k]()).toEqual(testElement[k]);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows order to be changed", function () {
|
|
||||||
proxy.order("down");
|
|
||||||
expect(testElements).toEqual([{}, testElement, {}, {}]);
|
|
||||||
proxy.order("up");
|
|
||||||
expect(testElements).toEqual([{}, {}, testElement, {}]);
|
|
||||||
proxy.order("bottom");
|
|
||||||
expect(testElements).toEqual([testElement, {}, {}, {}]);
|
|
||||||
proxy.order("top");
|
|
||||||
expect(testElements).toEqual([{}, {}, {}, testElement]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("ensures x/y values are non-negative", function () {
|
|
||||||
proxy.x(-1);
|
|
||||||
proxy.y(-400);
|
|
||||||
expect(proxy.x()).toEqual(0);
|
|
||||||
expect(proxy.y()).toEqual(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows modifying the current grid size", function () {
|
|
||||||
proxy.setGridSize([112,420]);
|
|
||||||
expect(proxy.gridSize).toEqual([112,420]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("returns the current grid size only if the element snaps to grid", function () {
|
|
||||||
expect(proxy.getGridSize()).toEqual([13,21]);
|
|
||||||
proxy.useGrid(false);
|
|
||||||
expect(proxy.getGridSize()).toEqual([1,1]);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("returns the mininum height and width of an element currently used units", function () {
|
|
||||||
// Assumes mininum height and width are 10, in pixels
|
|
||||||
expect(proxy.getMinWidth()).toEqual(1);
|
|
||||||
expect(proxy.getMinHeight()).toEqual(1);
|
|
||||||
proxy.setGridSize([7,4]);
|
|
||||||
expect(proxy.getMinWidth()).toEqual(2);
|
|
||||||
expect(proxy.getMinHeight()).toEqual(3);
|
|
||||||
proxy.useGrid(false);
|
|
||||||
expect(proxy.getMinWidth()).toEqual(10);
|
|
||||||
expect(proxy.getMinHeight()).toEqual(10);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,56 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['../../src/elements/ImageProxy'],
|
|
||||||
function (ImageProxy) {
|
|
||||||
|
|
||||||
describe("A fixed position image proxy", function () {
|
|
||||||
var testElement,
|
|
||||||
testElements,
|
|
||||||
proxy;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 1,
|
|
||||||
y: 2,
|
|
||||||
width: 42,
|
|
||||||
height: 24,
|
|
||||||
url: "http://www.nasa.gov"
|
|
||||||
};
|
|
||||||
testElements = [{}, {}, testElement, {}];
|
|
||||||
proxy = new ImageProxy(
|
|
||||||
testElement,
|
|
||||||
testElements.indexOf(testElement),
|
|
||||||
testElements
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides getter/setter for image URL", function () {
|
|
||||||
expect(proxy.url()).toEqual("http://www.nasa.gov");
|
|
||||||
expect(proxy.url("http://www.nasa.gov/some.jpg"))
|
|
||||||
.toEqual("http://www.nasa.gov/some.jpg");
|
|
||||||
expect(proxy.url()).toEqual("http://www.nasa.gov/some.jpg");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,81 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['../../src/elements/LineHandle'],
|
|
||||||
function (LineHandle) {
|
|
||||||
|
|
||||||
describe("A fixed position drag handle", function () {
|
|
||||||
var testElement,
|
|
||||||
mockElementProxy,
|
|
||||||
handle,
|
|
||||||
TEST_GRID_SIZE = [45, 21];
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 3,
|
|
||||||
y: 42,
|
|
||||||
x2: 8,
|
|
||||||
y2: 11,
|
|
||||||
useGrid: true
|
|
||||||
};
|
|
||||||
mockElementProxy = jasmine.createSpyObj('elementProxy', ['getGridSize']);
|
|
||||||
mockElementProxy.getGridSize.and.returnValue(TEST_GRID_SIZE);
|
|
||||||
|
|
||||||
handle = new LineHandle(testElement, mockElementProxy, 'x', 'y', 'x2', 'y2');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides x/y grid coordinates for its corner", function () {
|
|
||||||
expect(handle.x()).toEqual(3);
|
|
||||||
expect(handle.y()).toEqual(42);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("changes x and y positions", function () {
|
|
||||||
handle.x(30);
|
|
||||||
expect(testElement.x).toEqual(30);
|
|
||||||
handle.y(40);
|
|
||||||
expect(testElement.y).toEqual(40);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("disallows values less than zero", function () {
|
|
||||||
handle.x(-1);
|
|
||||||
handle.y(-400);
|
|
||||||
expect(testElement.x).toEqual(0);
|
|
||||||
expect(testElement.y).toEqual(0);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("ensures that end points remain different", function () {
|
|
||||||
handle.x(testElement.x2);
|
|
||||||
handle.y(testElement.y2);
|
|
||||||
// First change should have been fine, because y was different
|
|
||||||
expect(testElement.x).toEqual(testElement.x2);
|
|
||||||
// Second change should have been rejected
|
|
||||||
expect(testElement.y).not.toEqual(testElement.y2);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("returns the correct grid size", function () {
|
|
||||||
expect(handle.getGridSize()).toEqual(TEST_GRID_SIZE);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,95 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['../../src/elements/LineProxy'],
|
|
||||||
function (LineProxy) {
|
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides handles for both ends", function () {
|
|
||||||
expect(new LineProxy(diagonal).handles().length).toEqual(2);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,93 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['../../src/elements/ResizeHandle'],
|
|
||||||
function (ResizeHandle) {
|
|
||||||
|
|
||||||
var TEST_MIN_WIDTH = 4,
|
|
||||||
TEST_MIN_HEIGHT = 2,
|
|
||||||
TEST_GRID_SIZE = [34, 81];
|
|
||||||
|
|
||||||
describe("A fixed position drag handle", function () {
|
|
||||||
var testElement,
|
|
||||||
mockElementProxy,
|
|
||||||
handle;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 3,
|
|
||||||
y: 42,
|
|
||||||
width: 30,
|
|
||||||
height: 36,
|
|
||||||
useGrid: true
|
|
||||||
};
|
|
||||||
mockElementProxy = jasmine.createSpyObj('elementProxy', [
|
|
||||||
'getGridSize',
|
|
||||||
'getMinWidth',
|
|
||||||
'getMinHeight'
|
|
||||||
]);
|
|
||||||
mockElementProxy.getGridSize.and.returnValue(TEST_GRID_SIZE);
|
|
||||||
mockElementProxy.getMinWidth.and.returnValue(TEST_MIN_WIDTH);
|
|
||||||
mockElementProxy.getMinHeight.and.returnValue(TEST_MIN_HEIGHT);
|
|
||||||
|
|
||||||
handle = new ResizeHandle(
|
|
||||||
mockElementProxy,
|
|
||||||
testElement
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("returns the correct grid size", function () {
|
|
||||||
expect(handle.getGridSize()).toEqual(TEST_GRID_SIZE);
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,54 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['../../src/elements/TelemetryProxy'],
|
|
||||||
function (TelemetryProxy) {
|
|
||||||
|
|
||||||
describe("A fixed position telemetry proxy", function () {
|
|
||||||
var testElement,
|
|
||||||
testElements,
|
|
||||||
proxy;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 1,
|
|
||||||
y: 2,
|
|
||||||
z: 3,
|
|
||||||
width: 42,
|
|
||||||
height: 24,
|
|
||||||
id: "test-id"
|
|
||||||
};
|
|
||||||
testElements = [{}, {}, testElement, {}];
|
|
||||||
proxy = new TelemetryProxy(
|
|
||||||
testElement,
|
|
||||||
testElements.indexOf(testElement),
|
|
||||||
testElements
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("exposes the element's id", function () {
|
|
||||||
expect(proxy.id).toEqual('test-id');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,70 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['../../src/elements/TextProxy'],
|
|
||||||
function (TextProxy) {
|
|
||||||
|
|
||||||
describe("A fixed position text proxy", function () {
|
|
||||||
var testElement,
|
|
||||||
testElements,
|
|
||||||
proxy;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 1,
|
|
||||||
y: 2,
|
|
||||||
width: 42,
|
|
||||||
height: 24,
|
|
||||||
fill: "transparent",
|
|
||||||
size: "20px"
|
|
||||||
};
|
|
||||||
testElements = [{}, {}, testElement, {}];
|
|
||||||
proxy = new TextProxy(
|
|
||||||
testElement,
|
|
||||||
testElements.indexOf(testElement),
|
|
||||||
testElements
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides getter/setter for fill color", function () {
|
|
||||||
expect(proxy.fill()).toEqual('transparent');
|
|
||||||
expect(proxy.fill('#FFF')).toEqual('#FFF');
|
|
||||||
expect(proxy.fill()).toEqual('#FFF');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("provides getter/setter for text size", function () {
|
|
||||||
expect(proxy.size()).toEqual('20px');
|
|
||||||
expect(proxy.size('12px')).toEqual('12px');
|
|
||||||
expect(proxy.size()).toEqual('12px');
|
|
||||||
});
|
|
||||||
|
|
||||||
it("defaults to 13px for unspecified text size", function () {
|
|
||||||
testElement = {x: 1, y: 2};
|
|
||||||
proxy = new TextProxy(testElement, 0, [testElement]);
|
|
||||||
|
|
||||||
expect(proxy.size()).toEqual('13px');
|
|
||||||
});
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,157 +0,0 @@
|
|||||||
/*****************************************************************************
|
|
||||||
* Open MCT, Copyright (c) 2014-2018, United States Government
|
|
||||||
* as represented by the Administrator of the National Aeronautics and Space
|
|
||||||
* Administration. All rights reserved.
|
|
||||||
*
|
|
||||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
|
||||||
* "License"); you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
|
||||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
|
||||||
* License for the specific language governing permissions and limitations
|
|
||||||
* under the License.
|
|
||||||
*
|
|
||||||
* Open MCT includes source code licensed under additional open source
|
|
||||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
|
||||||
* this source code distribution or the Licensing information page available
|
|
||||||
* at runtime from the About dialog for additional information.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
define(
|
|
||||||
['../../src/elements/UnitAccessorMutator'],
|
|
||||||
function (UnitAccessorMutator) {
|
|
||||||
|
|
||||||
var GRID_SIZE = [13,17];
|
|
||||||
|
|
||||||
describe("An elementProxy.gridSize accessor-mutator", function () {
|
|
||||||
var mockElementProxy,
|
|
||||||
testElement,
|
|
||||||
mockLineProxy,
|
|
||||||
testLine,
|
|
||||||
uAM,
|
|
||||||
uAMLine;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
testElement = {
|
|
||||||
x: 2,
|
|
||||||
y: 3,
|
|
||||||
width: 4,
|
|
||||||
height: 5,
|
|
||||||
useGrid: true
|
|
||||||
};
|
|
||||||
|
|
||||||
mockElementProxy = {
|
|
||||||
element: testElement,
|
|
||||||
gridSize: GRID_SIZE,
|
|
||||||
getMinHeight: jasmine.createSpy('minHeight'),
|
|
||||||
getMinWidth: jasmine.createSpy('minWidth')
|
|
||||||
};
|
|
||||||
|
|
||||||
testLine = {
|
|
||||||
x: 7,
|
|
||||||
y: 8,
|
|
||||||
x2: 9,
|
|
||||||
y2: 10,
|
|
||||||
width: 11,
|
|
||||||
height: 12,
|
|
||||||
useGrid: true
|
|
||||||
};
|
|
||||||
|
|
||||||
mockLineProxy = {
|
|
||||||
element: testLine,
|
|
||||||
gridSize: GRID_SIZE,
|
|
||||||
getMinHeight: jasmine.createSpy('minHeight'),
|
|
||||||
getMinWidth: jasmine.createSpy('minWidth')
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
uAM = new UnitAccessorMutator(mockElementProxy);
|
|
||||||
uAMLine = new UnitAccessorMutator(mockLineProxy);
|
|
||||||
|
|
||||||
mockElementProxy.getMinWidth.and.returnValue(1);
|
|
||||||
mockElementProxy.getMinHeight.and.returnValue(1);
|
|
||||||
|
|
||||||
mockLineProxy.getMinWidth.and.returnValue(1);
|
|
||||||
mockLineProxy.getMinHeight.and.returnValue(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows access to useGrid", function () {
|
|
||||||
expect(uAM()).toEqual(mockElementProxy.element.useGrid);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows mutation of useGrid", function () {
|
|
||||||
uAM(false);
|
|
||||||
expect(mockElementProxy.element.useGrid).toEqual(false);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("converts coordinates appropriately for a box", function () {
|
|
||||||
uAM(false);
|
|
||||||
expect(mockElementProxy.element.x).toEqual(26);
|
|
||||||
expect(mockElementProxy.element.y).toEqual(51);
|
|
||||||
expect(mockElementProxy.element.width).toEqual(52);
|
|
||||||
expect(mockElementProxy.element.height).toEqual(85);
|
|
||||||
uAM(true);
|
|
||||||
expect(mockElementProxy.element.x).toEqual(2);
|
|
||||||
expect(mockElementProxy.element.y).toEqual(3);
|
|
||||||
expect(mockElementProxy.element.width).toEqual(4);
|
|
||||||
expect(mockElementProxy.element.height).toEqual(5);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("converts coordinates appropriately for a line", function () {
|
|
||||||
uAMLine(false);
|
|
||||||
expect(mockLineProxy.element.x).toEqual(91);
|
|
||||||
expect(mockLineProxy.element.y).toEqual(136);
|
|
||||||
expect(mockLineProxy.element.x2).toEqual(117);
|
|
||||||
expect(mockLineProxy.element.y2).toEqual(170);
|
|
||||||
expect(mockLineProxy.element.width).toEqual(143);
|
|
||||||
expect(mockLineProxy.element.height).toEqual(204);
|
|
||||||
uAMLine(true);
|
|
||||||
expect(mockLineProxy.element.x).toEqual(7);
|
|
||||||
expect(mockLineProxy.element.y).toEqual(8);
|
|
||||||
expect(mockLineProxy.element.x2).toEqual(9);
|
|
||||||
expect(mockLineProxy.element.y2).toEqual(10);
|
|
||||||
expect(mockLineProxy.element.width).toEqual(11);
|
|
||||||
expect(mockLineProxy.element.height).toEqual(12);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("doesn't covert coordinates unecessarily", function () {
|
|
||||||
uAM(false);
|
|
||||||
expect(mockElementProxy.element.x).toEqual(26);
|
|
||||||
expect(mockElementProxy.element.y).toEqual(51);
|
|
||||||
expect(mockElementProxy.element.width).toEqual(52);
|
|
||||||
expect(mockElementProxy.element.height).toEqual(85);
|
|
||||||
uAM(false);
|
|
||||||
expect(mockElementProxy.element.x).toEqual(26);
|
|
||||||
expect(mockElementProxy.element.y).toEqual(51);
|
|
||||||
expect(mockElementProxy.element.width).toEqual(52);
|
|
||||||
expect(mockElementProxy.element.height).toEqual(85);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("snaps coordinates onto the grid", function () {
|
|
||||||
uAM(false);
|
|
||||||
mockElementProxy.element.x += 11;
|
|
||||||
mockElementProxy.element.y -= 27;
|
|
||||||
mockElementProxy.element.width -= 14;
|
|
||||||
mockElementProxy.element.height += 4;
|
|
||||||
uAM(true);
|
|
||||||
expect(mockElementProxy.element.x).toEqual(3);
|
|
||||||
expect(mockElementProxy.element.y).toEqual(1);
|
|
||||||
expect(mockElementProxy.element.width).toEqual(3);
|
|
||||||
expect(mockElementProxy.element.height).toEqual(5);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("enforces a minimum height and width", function () {
|
|
||||||
uAM(false);
|
|
||||||
mockElementProxy.element.width = 4;
|
|
||||||
mockElementProxy.element.height = 4;
|
|
||||||
uAM(true);
|
|
||||||
expect(mockElementProxy.element.width).toEqual(1);
|
|
||||||
expect(mockElementProxy.element.height).toEqual(1);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -29,13 +29,22 @@ define(
|
|||||||
function SnapshotPreviewController($scope, openmct) {
|
function SnapshotPreviewController($scope, openmct) {
|
||||||
|
|
||||||
$scope.previewImage = function (imageUrl) {
|
$scope.previewImage = function (imageUrl) {
|
||||||
var image = document.createElement('img');
|
let imageDiv = document.createElement('div');
|
||||||
image.src = imageUrl;
|
imageDiv.classList = 'image-main s-image-main';
|
||||||
|
imageDiv.style.backgroundImage = `url(${imageUrl})`;
|
||||||
|
|
||||||
openmct.overlays.overlay(
|
let previewImageOverlay = openmct.overlays.overlay(
|
||||||
{
|
{
|
||||||
element: image,
|
element: imageDiv,
|
||||||
size: 'large'
|
size: 'large',
|
||||||
|
buttons: [
|
||||||
|
{
|
||||||
|
label: 'Done',
|
||||||
|
callback: function () {
|
||||||
|
previewImageOverlay.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -43,13 +52,13 @@ define(
|
|||||||
$scope.annotateImage = function (ngModel, field, imageUrl) {
|
$scope.annotateImage = function (ngModel, field, imageUrl) {
|
||||||
$scope.imageUrl = imageUrl;
|
$scope.imageUrl = imageUrl;
|
||||||
|
|
||||||
var div = document.createElement('div'),
|
let div = document.createElement('div'),
|
||||||
painterroInstance = {},
|
painterroInstance = {},
|
||||||
save = false;
|
save = false;
|
||||||
|
|
||||||
div.id = 'snap-annotation';
|
div.id = 'snap-annotation';
|
||||||
|
|
||||||
openmct.overlays.overlay(
|
let annotateImageOverlay = openmct.overlays.overlay(
|
||||||
{
|
{
|
||||||
element: div,
|
element: div,
|
||||||
size: 'large',
|
size: 'large',
|
||||||
@ -59,6 +68,7 @@ define(
|
|||||||
callback: function () {
|
callback: function () {
|
||||||
save = false;
|
save = false;
|
||||||
painterroInstance.save();
|
painterroInstance.save();
|
||||||
|
annotateImageOverlay.dismiss();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -66,6 +76,7 @@ define(
|
|||||||
callback: function () {
|
callback: function () {
|
||||||
save = true;
|
save = true;
|
||||||
painterroInstance.save();
|
painterroInstance.save();
|
||||||
|
annotateImageOverlay.dismiss();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -97,7 +108,7 @@ define(
|
|||||||
},
|
},
|
||||||
saveHandler: function (image, done) {
|
saveHandler: function (image, done) {
|
||||||
if (save) {
|
if (save) {
|
||||||
var url = image.asBlob(),
|
let url = image.asBlob(),
|
||||||
reader = new window.FileReader();
|
reader = new window.FileReader();
|
||||||
|
|
||||||
reader.readAsDataURL(url);
|
reader.readAsDataURL(url);
|
||||||
|
@ -43,6 +43,7 @@ define([
|
|||||||
'./ui/layout/Layout.vue',
|
'./ui/layout/Layout.vue',
|
||||||
'../platform/core/src/objects/DomainObjectImpl',
|
'../platform/core/src/objects/DomainObjectImpl',
|
||||||
'../platform/core/src/capabilities/ContextualDomainObject',
|
'../platform/core/src/capabilities/ContextualDomainObject',
|
||||||
|
'./ui/preview/plugin',
|
||||||
'vue'
|
'vue'
|
||||||
], function (
|
], function (
|
||||||
EventEmitter,
|
EventEmitter,
|
||||||
@ -67,6 +68,7 @@ define([
|
|||||||
Layout,
|
Layout,
|
||||||
DomainObjectImpl,
|
DomainObjectImpl,
|
||||||
ContextualDomainObject,
|
ContextualDomainObject,
|
||||||
|
PreviewPlugin,
|
||||||
Vue
|
Vue
|
||||||
) {
|
) {
|
||||||
/**
|
/**
|
||||||
@ -230,7 +232,7 @@ define([
|
|||||||
this.install(this.plugins.Plot());
|
this.install(this.plugins.Plot());
|
||||||
this.install(this.plugins.TelemetryTable());
|
this.install(this.plugins.TelemetryTable());
|
||||||
this.install(this.plugins.DisplayLayout());
|
this.install(this.plugins.DisplayLayout());
|
||||||
this.install(this.plugins.Preview());
|
this.install(PreviewPlugin.default());
|
||||||
|
|
||||||
if (typeof BUILD_CONSTANTS !== 'undefined') {
|
if (typeof BUILD_CONSTANTS !== 'undefined') {
|
||||||
this.install(buildInfoPlugin(BUILD_CONSTANTS));
|
this.install(buildInfoPlugin(BUILD_CONSTANTS));
|
||||||
|
@ -58,11 +58,8 @@ define([
|
|||||||
|
|
||||||
handleLegacyMutation = function (legacyObject) {
|
handleLegacyMutation = function (legacyObject) {
|
||||||
var newStyleObject = utils.toNewFormat(legacyObject.getModel(), legacyObject.getId());
|
var newStyleObject = utils.toNewFormat(legacyObject.getModel(), legacyObject.getId());
|
||||||
|
|
||||||
//Don't trigger self
|
|
||||||
this.eventEmitter.off('mutation', handleMutation);
|
|
||||||
this.eventEmitter.emit(newStyleObject.identifier.key + ":*", newStyleObject);
|
this.eventEmitter.emit(newStyleObject.identifier.key + ":*", newStyleObject);
|
||||||
this.eventEmitter.on('mutation', handleMutation);
|
this.eventEmitter.emit('mutation', newStyleObject);
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
|
||||||
this.eventEmitter.on('mutation', handleMutation);
|
this.eventEmitter.on('mutation', handleMutation);
|
||||||
|
@ -28,6 +28,11 @@ export default class Editor extends EventEmitter {
|
|||||||
super();
|
super();
|
||||||
this.editing = false;
|
this.editing = false;
|
||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
|
document.addEventListener('drop', (event) => {
|
||||||
|
if (!this.isEditing()) {
|
||||||
|
this.edit();
|
||||||
|
}
|
||||||
|
}, {capture: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -46,6 +46,7 @@ define([
|
|||||||
function DefaultCompositionProvider(publicAPI, compositionAPI) {
|
function DefaultCompositionProvider(publicAPI, compositionAPI) {
|
||||||
this.publicAPI = publicAPI;
|
this.publicAPI = publicAPI;
|
||||||
this.listeningTo = {};
|
this.listeningTo = {};
|
||||||
|
this.onMutation = this.onMutation.bind(this);
|
||||||
|
|
||||||
this.cannotContainDuplicates = this.cannotContainDuplicates.bind(this);
|
this.cannotContainDuplicates = this.cannotContainDuplicates.bind(this);
|
||||||
this.cannotContainItself = this.cannotContainItself.bind(this);
|
this.cannotContainItself = this.cannotContainItself.bind(this);
|
||||||
@ -177,8 +178,12 @@ define([
|
|||||||
* @method remove
|
* @method remove
|
||||||
*/
|
*/
|
||||||
DefaultCompositionProvider.prototype.remove = function (domainObject, childId) {
|
DefaultCompositionProvider.prototype.remove = function (domainObject, childId) {
|
||||||
// TODO: this needs to be synchronized via mutation.
|
let composition = domainObject.composition.filter(function (child) {
|
||||||
throw new Error('Default Provider does not implement removal.');
|
return !(childId.namespace === child.namespace &&
|
||||||
|
childId.key === child.key);
|
||||||
|
});
|
||||||
|
|
||||||
|
this.publicAPI.objects.mutate(domainObject, 'composition', composition);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -208,9 +213,10 @@ define([
|
|||||||
if (this.topicListener) {
|
if (this.topicListener) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var topic = this.publicAPI.$injector.get('topic');
|
this.publicAPI.objects.eventEmitter.on('mutation', this.onMutation);
|
||||||
var mutation = topic('mutation');
|
this.topicListener = () => {
|
||||||
this.topicListener = mutation.listen(this.onMutation.bind(this));
|
this.publicAPI.objects.eventEmitter.off('mutation', this.onMutation)
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -220,7 +226,7 @@ define([
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
DefaultCompositionProvider.prototype.onMutation = function (oldDomainObject) {
|
DefaultCompositionProvider.prototype.onMutation = function (oldDomainObject) {
|
||||||
var id = oldDomainObject.getId();
|
var id = objectUtils.makeKeyString(oldDomainObject.identifier);
|
||||||
var listeners = this.listeningTo[id];
|
var listeners = this.listeningTo[id];
|
||||||
|
|
||||||
if (!listeners) {
|
if (!listeners) {
|
||||||
@ -228,7 +234,7 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
var oldComposition = listeners.composition.map(objectUtils.makeKeyString);
|
var oldComposition = listeners.composition.map(objectUtils.makeKeyString);
|
||||||
var newComposition = oldDomainObject.getModel().composition.map(objectUtils.makeKeyString);
|
var newComposition = oldDomainObject.composition.map(objectUtils.makeKeyString);
|
||||||
|
|
||||||
var added = _.difference(newComposition, oldComposition).map(objectUtils.parseKeyString);
|
var added = _.difference(newComposition, oldComposition).map(objectUtils.parseKeyString);
|
||||||
var removed = _.difference(oldComposition, newComposition).map(objectUtils.parseKeyString);
|
var removed = _.difference(oldComposition, newComposition).map(objectUtils.parseKeyString);
|
||||||
|
@ -83,18 +83,15 @@ define([
|
|||||||
this.object = newObject;
|
this.object = newObject;
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
|
||||||
this.eventEmitter.on(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
|
//Emit wildcard event
|
||||||
|
|
||||||
//Emit event specific to property
|
|
||||||
this.eventEmitter.emit(qualifiedEventName(this.object, path), value);
|
|
||||||
|
|
||||||
this.eventEmitter.off(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
|
|
||||||
|
|
||||||
//Emit wildcare event
|
|
||||||
this.eventEmitter.emit(qualifiedEventName(this.object, '*'), this.object);
|
this.eventEmitter.emit(qualifiedEventName(this.object, '*'), this.object);
|
||||||
|
|
||||||
//Emit a general "any object" event
|
//Emit a general "any object" event
|
||||||
this.eventEmitter.emit(ANY_OBJECT_EVENT, this.object);
|
this.eventEmitter.emit(ANY_OBJECT_EVENT, this.object);
|
||||||
|
|
||||||
|
this.eventEmitter.on(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
|
||||||
|
//Emit event specific to property
|
||||||
|
this.eventEmitter.emit(qualifiedEventName(this.object, path), value);
|
||||||
|
this.eventEmitter.off(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
|
||||||
};
|
};
|
||||||
|
|
||||||
return MutableObject;
|
return MutableObject;
|
||||||
|
@ -22,7 +22,7 @@ class Dialog extends Overlay {
|
|||||||
super({
|
super({
|
||||||
element: component.$el,
|
element: component.$el,
|
||||||
size: 'fit',
|
size: 'fit',
|
||||||
notDismissable: true,
|
dismissable: false,
|
||||||
...options
|
...options
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -12,6 +12,7 @@ class Overlay extends EventEmitter {
|
|||||||
constructor(options) {
|
constructor(options) {
|
||||||
super();
|
super();
|
||||||
|
|
||||||
|
this.dismissable = options.dismissable !== false ? true : false;
|
||||||
this.container = document.createElement('div');
|
this.container = document.createElement('div');
|
||||||
this.container.classList.add('l-overlay-wrapper', cssClasses[options.size]);
|
this.container.classList.add('l-overlay-wrapper', cssClasses[options.size]);
|
||||||
|
|
||||||
@ -20,7 +21,7 @@ class Overlay extends EventEmitter {
|
|||||||
dismiss: this.dismiss.bind(this),
|
dismiss: this.dismiss.bind(this),
|
||||||
element: options.element,
|
element: options.element,
|
||||||
buttons: options.buttons,
|
buttons: options.buttons,
|
||||||
notDismissable: options.notDismissable ? true : false
|
dismissable: this.dismissable
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
OverlayComponent: OverlayComponent
|
OverlayComponent: OverlayComponent
|
||||||
@ -35,8 +36,8 @@ class Overlay extends EventEmitter {
|
|||||||
|
|
||||||
dismiss() {
|
dismiss() {
|
||||||
this.emit('destroy');
|
this.emit('destroy');
|
||||||
this.component.$destroy();
|
|
||||||
document.body.removeChild(this.container);
|
document.body.removeChild(this.container);
|
||||||
|
this.component.$destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -14,6 +14,14 @@ import ProgressDialog from './ProgressDialog';
|
|||||||
class OverlayAPI {
|
class OverlayAPI {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.activeOverlays = [];
|
this.activeOverlays = [];
|
||||||
|
|
||||||
|
this.dismissLastOverlay = this.dismissLastOverlay.bind(this);
|
||||||
|
|
||||||
|
document.addEventListener('keyup', (event) => {
|
||||||
|
if (event.key === 'Escape') {
|
||||||
|
this.dismissLastOverlay();
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -38,14 +46,24 @@ class OverlayAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
] * A description of option properties that can be passed into the overlay
|
* private
|
||||||
* @typedef options
|
*/
|
||||||
|
dismissLastOverlay() {
|
||||||
|
let lastOverlay = this.activeOverlays[this.activeOverlays.length - 1];
|
||||||
|
if (lastOverlay && lastOverlay.dismissable) {
|
||||||
|
lastOverlay.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A description of option properties that can be passed into the overlay
|
||||||
|
* @typedef options
|
||||||
* @property {object} element DOMElement that is to be inserted/shown on the overlay
|
* @property {object} element DOMElement that is to be inserted/shown on the overlay
|
||||||
* @property {string} size prefered size of the overlay (large, small, fit)
|
* @property {string} size prefered size of the overlay (large, small, fit)
|
||||||
* @property {array} buttons optional button objects with label and callback properties
|
* @property {array} buttons optional button objects with label and callback properties
|
||||||
* @property {function} onDestroy callback to be called when overlay is destroyed
|
* @property {function} onDestroy callback to be called when overlay is destroyed
|
||||||
* @property {boolean} notDismissable to prevent user from dismissing the overlay, calling code
|
* @property {boolean} dismissable allow user to dismiss overlay by using esc, and clicking away
|
||||||
* will need to explicitly dismiss the overlay.
|
* from overlay. Unless set to false, all overlays will be dismissable by default.
|
||||||
*/
|
*/
|
||||||
overlay(options) {
|
overlay(options) {
|
||||||
let overlay = new Overlay(options);
|
let overlay = new Overlay(options);
|
||||||
|
@ -25,7 +25,7 @@ class ProgressDialog extends Overlay {
|
|||||||
super({
|
super({
|
||||||
element: component.$el,
|
element: component.$el,
|
||||||
size: 'fit',
|
size: 'fit',
|
||||||
notDismissable: true,
|
dismissable: false,
|
||||||
...options
|
...options
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="c-overlay__outer">
|
<div class="c-overlay__outer">
|
||||||
<button class="c-click-icon c-overlay__close-button icon-x-in-circle"
|
<button class="c-click-icon c-overlay__close-button icon-x-in-circle"
|
||||||
v-if="!notDismissable"
|
v-if="dismissable"
|
||||||
@click="destroy">
|
@click="destroy">
|
||||||
</button>
|
</button>
|
||||||
<div class="c-overlay__contents" ref="element"></div>
|
<div class="c-overlay__contents" ref="element"></div>
|
||||||
@ -129,19 +129,19 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
inject: ['dismiss', 'element', 'buttons', 'notDismissable'],
|
inject: ['dismiss', 'element', 'buttons', 'dismissable'],
|
||||||
mounted() {
|
mounted() {
|
||||||
this.$refs.element.appendChild(this.element);
|
this.$refs.element.appendChild(this.element);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
destroy: function () {
|
destroy: function () {
|
||||||
if (!this.notDismissable) {
|
if (this.dismissable) {
|
||||||
this.dismiss();
|
this.dismiss();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
buttonClickHandler: function (method) {
|
buttonClickHandler: function (method) {
|
||||||
method();
|
method();
|
||||||
this.destroy();
|
this.$emit('destroy');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -32,7 +32,7 @@ define([], function () {
|
|||||||
// is inside a layout, or the main layout is selected.
|
// is inside a layout, or the main layout is selected.
|
||||||
return (openmct.editor.isEditing() && selection &&
|
return (openmct.editor.isEditing() && selection &&
|
||||||
((selection[1] && selection[1].context.item && selection[1].context.item.type === 'layout') ||
|
((selection[1] && selection[1].context.item && selection[1].context.item.type === 'layout') ||
|
||||||
(selection[0].context.item && selection[0].context.item.type === 'layout')));
|
(selection[0].context.item && selection[0].context.item.type === 'layout')));
|
||||||
},
|
},
|
||||||
toolbar: function (selection) {
|
toolbar: function (selection) {
|
||||||
const DIALOG_FORM = {
|
const DIALOG_FORM = {
|
||||||
@ -73,10 +73,13 @@ define([], function () {
|
|||||||
return openmct.$injector.get('dialogService').getUserInput(form, {});
|
return openmct.$injector.get('dialogService').getUserInput(form, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getPath() {
|
||||||
|
return `configuration.items[${selection[0].context.index}]`;
|
||||||
|
}
|
||||||
|
|
||||||
let selectedParent = selection[1] && selection[1].context.item,
|
let selectedParent = selection[1] && selection[1].context.item,
|
||||||
selectedObject = selection[0].context.item,
|
selectedObject = selection[0].context.item,
|
||||||
layoutItem = selection[0].context.layoutItem,
|
layoutItem = selection[0].context.layoutItem,
|
||||||
layoutItemIndex = selection[0].context.index,
|
|
||||||
toolbar = [];
|
toolbar = [];
|
||||||
|
|
||||||
if (selectedObject && selectedObject.type === 'layout') {
|
if (selectedObject && selectedObject.type === 'layout') {
|
||||||
@ -121,7 +124,6 @@ define([], function () {
|
|||||||
return toolbar;
|
return toolbar;
|
||||||
}
|
}
|
||||||
|
|
||||||
let path = `configuration.items[${layoutItemIndex}]`;
|
|
||||||
let separator = {
|
let separator = {
|
||||||
control: "separator"
|
control: "separator"
|
||||||
};
|
};
|
||||||
@ -140,7 +142,7 @@ define([], function () {
|
|||||||
label: 'Ok',
|
label: 'Ok',
|
||||||
emphasis: 'true',
|
emphasis: 'true',
|
||||||
callback: function () {
|
callback: function () {
|
||||||
removeItem(layoutItem, layoutItemIndex);
|
removeItem(layoutItem, selection[0].context.index);
|
||||||
prompt.dismiss();
|
prompt.dismiss();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -154,6 +156,96 @@ define([], function () {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let stackOrder = {
|
||||||
|
control: "menu",
|
||||||
|
domainObject: selectedParent,
|
||||||
|
icon: "icon-layers",
|
||||||
|
title: "Move the selected object above or below other objects",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: "Move to Top",
|
||||||
|
value: "top",
|
||||||
|
class: "icon-arrow-double-up"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Move Up",
|
||||||
|
value: "up",
|
||||||
|
class: "icon-arrow-up"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Move Down",
|
||||||
|
value: "down",
|
||||||
|
class: "icon-arrow-down"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Move to Bottom",
|
||||||
|
value: "bottom",
|
||||||
|
class: "icon-arrow-double-down"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
method: function (option) {
|
||||||
|
selection[1].context.orderItem(option.value, selection[0].context.index);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let useGrid = {
|
||||||
|
control: "toggle-button",
|
||||||
|
domainObject: selectedParent,
|
||||||
|
property: function () {
|
||||||
|
return getPath() + ".useGrid";
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: false,
|
||||||
|
icon: "icon-grid-snap-to",
|
||||||
|
title: "Grid snapping enabled"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: true,
|
||||||
|
icon: "icon-grid-snap-no",
|
||||||
|
title: "Grid snapping disabled"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
let x = {
|
||||||
|
control: "input",
|
||||||
|
type: "number",
|
||||||
|
domainObject: selectedParent,
|
||||||
|
property: function () {
|
||||||
|
return getPath() + ".x";
|
||||||
|
},
|
||||||
|
label: "X:",
|
||||||
|
title: "X position"
|
||||||
|
},
|
||||||
|
y = {
|
||||||
|
control: "input",
|
||||||
|
type: "number",
|
||||||
|
domainObject: selectedParent,
|
||||||
|
property: function () {
|
||||||
|
return getPath() + ".y";
|
||||||
|
},
|
||||||
|
label: "Y:",
|
||||||
|
title: "Y position",
|
||||||
|
},
|
||||||
|
width = {
|
||||||
|
control: 'input',
|
||||||
|
type: 'number',
|
||||||
|
domainObject: selectedParent,
|
||||||
|
property: function () {
|
||||||
|
return getPath() + ".width";
|
||||||
|
},
|
||||||
|
label: 'W:',
|
||||||
|
title: 'Resize object width'
|
||||||
|
},
|
||||||
|
height = {
|
||||||
|
control: 'input',
|
||||||
|
type: 'number',
|
||||||
|
domainObject: selectedParent,
|
||||||
|
property: function () {
|
||||||
|
return getPath() + ".height";
|
||||||
|
},
|
||||||
|
label: 'H:',
|
||||||
|
title: 'Resize object height'
|
||||||
|
};
|
||||||
|
|
||||||
if (layoutItem.type === 'subobject-view') {
|
if (layoutItem.type === 'subobject-view') {
|
||||||
if (toolbar.length > 0) {
|
if (toolbar.length > 0) {
|
||||||
@ -163,124 +255,113 @@ define([], function () {
|
|||||||
toolbar.push({
|
toolbar.push({
|
||||||
control: "toggle-button",
|
control: "toggle-button",
|
||||||
domainObject: selectedParent,
|
domainObject: selectedParent,
|
||||||
property: path + ".hasFrame",
|
property: function () {
|
||||||
|
return getPath() + ".hasFrame";
|
||||||
|
},
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
value: false,
|
value: false,
|
||||||
icon: 'icon-frame-hide',
|
icon: 'icon-frame-show',
|
||||||
title: "Hide frame"
|
title: "Frame visible"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: true,
|
value: true,
|
||||||
icon: 'icon-frame-show',
|
icon: 'icon-frame-hide',
|
||||||
title: "Show frame"
|
title: "Frame hidden"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
toolbar.push(separator);
|
toolbar.push(separator);
|
||||||
|
toolbar.push(stackOrder);
|
||||||
|
toolbar.push(x);
|
||||||
|
toolbar.push(y);
|
||||||
|
toolbar.push(width);
|
||||||
|
toolbar.push(height);
|
||||||
|
toolbar.push(useGrid);
|
||||||
|
toolbar.push(separator);
|
||||||
toolbar.push(remove);
|
toolbar.push(remove);
|
||||||
} else {
|
} else {
|
||||||
const TEXT_SIZE = [9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 30, 36, 48, 72, 96];
|
const TEXT_SIZE = [8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 30, 36, 48, 72, 96, 128];
|
||||||
let fill = {
|
let fill = {
|
||||||
control: "color-picker",
|
control: "color-picker",
|
||||||
domainObject: selectedParent,
|
domainObject: selectedParent,
|
||||||
property: path + ".fill",
|
property: function () {
|
||||||
icon: "icon-paint-bucket",
|
return getPath() + ".fill";
|
||||||
title: "Set fill color"
|
|
||||||
},
|
},
|
||||||
stroke = {
|
icon: "icon-paint-bucket",
|
||||||
control: "color-picker",
|
title: "Set fill color"
|
||||||
domainObject: selectedParent,
|
},
|
||||||
property: path + ".stroke",
|
stroke = {
|
||||||
icon: "icon-line-horz",
|
control: "color-picker",
|
||||||
title: "Set border color"
|
domainObject: selectedParent,
|
||||||
|
property: function () {
|
||||||
|
return getPath() + ".stroke";
|
||||||
},
|
},
|
||||||
color = {
|
icon: "icon-line-horz",
|
||||||
control: "color-picker",
|
title: "Set border color"
|
||||||
domainObject: selectedParent,
|
},
|
||||||
property: path + ".color",
|
color = {
|
||||||
icon: "icon-font",
|
control: "color-picker",
|
||||||
mandatory: true,
|
domainObject: selectedParent,
|
||||||
title: "Set text color",
|
property: function () {
|
||||||
preventNone: true
|
return getPath() + ".color";
|
||||||
},
|
},
|
||||||
size = {
|
icon: "icon-font",
|
||||||
control: "select-menu",
|
mandatory: true,
|
||||||
domainObject: selectedParent,
|
title: "Set text color",
|
||||||
property: path + ".size",
|
preventNone: true
|
||||||
title: "Set text size",
|
},
|
||||||
options: TEXT_SIZE.map(size => {
|
size = {
|
||||||
return {
|
control: "select-menu",
|
||||||
value: size + "px"
|
domainObject: selectedParent,
|
||||||
};
|
property: function () {
|
||||||
})
|
return getPath() + ".size";
|
||||||
},
|
},
|
||||||
x = {
|
title: "Set text size",
|
||||||
control: "input",
|
options: TEXT_SIZE.map(size => {
|
||||||
type: "number",
|
return {
|
||||||
domainObject: selectedParent,
|
value: size + "px"
|
||||||
property: path + ".x",
|
};
|
||||||
label: "X:",
|
})
|
||||||
title: "X position"
|
};
|
||||||
},
|
|
||||||
y = {
|
|
||||||
control: "input",
|
|
||||||
type: "number",
|
|
||||||
domainObject: selectedParent,
|
|
||||||
property: path + ".y",
|
|
||||||
label: "Y:",
|
|
||||||
title: "Y position",
|
|
||||||
},
|
|
||||||
width = {
|
|
||||||
control: 'input',
|
|
||||||
type: 'number',
|
|
||||||
domainObject: selectedParent,
|
|
||||||
property: path + ".width",
|
|
||||||
label: 'W:',
|
|
||||||
title: 'Resize object width'
|
|
||||||
},
|
|
||||||
height = {
|
|
||||||
control: 'input',
|
|
||||||
type: 'number',
|
|
||||||
domainObject: selectedParent,
|
|
||||||
property: path + ".height",
|
|
||||||
label: 'H:',
|
|
||||||
title: 'Resize object height'
|
|
||||||
};
|
|
||||||
|
|
||||||
if (layoutItem.type === 'telemetry-view') {
|
if (layoutItem.type === 'telemetry-view') {
|
||||||
let displayMode = {
|
let displayMode = {
|
||||||
control: "select-menu",
|
control: "select-menu",
|
||||||
domainObject: selectedParent,
|
domainObject: selectedParent,
|
||||||
property: path + ".displayMode",
|
property: function () {
|
||||||
title: "Set display mode",
|
return getPath() + ".displayMode";
|
||||||
options: [
|
|
||||||
{
|
|
||||||
name: 'Label + Value',
|
|
||||||
value: 'all'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Label only",
|
|
||||||
value: "label"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Value only",
|
|
||||||
value: "value"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
value = {
|
title: "Set display mode",
|
||||||
control: "select-menu",
|
options: [
|
||||||
domainObject: selectedParent,
|
{
|
||||||
property: path + ".value",
|
name: 'Label + Value',
|
||||||
title: "Set value",
|
value: 'all'
|
||||||
options: openmct.telemetry.getMetadata(selectedObject).values().map(value => {
|
},
|
||||||
return {
|
{
|
||||||
name: value.name,
|
name: "Label only",
|
||||||
value: value.key
|
value: "label"
|
||||||
}
|
},
|
||||||
})
|
{
|
||||||
};
|
name: "Value only",
|
||||||
|
value: "value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
value = {
|
||||||
|
control: "select-menu",
|
||||||
|
domainObject: selectedParent,
|
||||||
|
property: function () {
|
||||||
|
return getPath() + ".value";
|
||||||
|
},
|
||||||
|
title: "Set value",
|
||||||
|
options: openmct.telemetry.getMetadata(selectedObject).values().map(value => {
|
||||||
|
return {
|
||||||
|
name: value.name,
|
||||||
|
value: value.key
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
toolbar = [
|
toolbar = [
|
||||||
displayMode,
|
displayMode,
|
||||||
separator,
|
separator,
|
||||||
@ -292,18 +373,22 @@ define([], function () {
|
|||||||
separator,
|
separator,
|
||||||
size,
|
size,
|
||||||
separator,
|
separator,
|
||||||
|
stackOrder,
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
height,
|
height,
|
||||||
width,
|
width,
|
||||||
|
useGrid,
|
||||||
separator,
|
separator,
|
||||||
remove
|
remove
|
||||||
];
|
];
|
||||||
} else if (layoutItem.type === 'text-view' ) {
|
} else if (layoutItem.type === 'text-view') {
|
||||||
let text = {
|
let text = {
|
||||||
control: "button",
|
control: "button",
|
||||||
domainObject: selectedParent,
|
domainObject: selectedParent,
|
||||||
property: path,
|
property: function () {
|
||||||
|
return getPath();
|
||||||
|
},
|
||||||
icon: "icon-gear",
|
icon: "icon-gear",
|
||||||
title: "Edit text properties",
|
title: "Edit text properties",
|
||||||
dialog: DIALOG_FORM['text']
|
dialog: DIALOG_FORM['text']
|
||||||
@ -311,14 +396,16 @@ define([], function () {
|
|||||||
toolbar = [
|
toolbar = [
|
||||||
fill,
|
fill,
|
||||||
stroke,
|
stroke,
|
||||||
color,
|
|
||||||
separator,
|
separator,
|
||||||
|
color,
|
||||||
size,
|
size,
|
||||||
separator,
|
separator,
|
||||||
|
stackOrder,
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
height,
|
height,
|
||||||
width,
|
width,
|
||||||
|
useGrid,
|
||||||
separator,
|
separator,
|
||||||
text,
|
text,
|
||||||
separator,
|
separator,
|
||||||
@ -329,10 +416,12 @@ define([], function () {
|
|||||||
fill,
|
fill,
|
||||||
stroke,
|
stroke,
|
||||||
separator,
|
separator,
|
||||||
|
stackOrder,
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
height,
|
height,
|
||||||
width,
|
width,
|
||||||
|
useGrid,
|
||||||
separator,
|
separator,
|
||||||
remove
|
remove
|
||||||
];
|
];
|
||||||
@ -340,7 +429,9 @@ define([], function () {
|
|||||||
let url = {
|
let url = {
|
||||||
control: "button",
|
control: "button",
|
||||||
domainObject: selectedParent,
|
domainObject: selectedParent,
|
||||||
property: path,
|
property: function () {
|
||||||
|
return getPath();
|
||||||
|
},
|
||||||
icon: "icon-image",
|
icon: "icon-image",
|
||||||
title: "Edit image properties",
|
title: "Edit image properties",
|
||||||
dialog: DIALOG_FORM['image']
|
dialog: DIALOG_FORM['image']
|
||||||
@ -348,10 +439,12 @@ define([], function () {
|
|||||||
toolbar = [
|
toolbar = [
|
||||||
stroke,
|
stroke,
|
||||||
separator,
|
separator,
|
||||||
|
stackOrder,
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
height,
|
height,
|
||||||
width,
|
width,
|
||||||
|
useGrid,
|
||||||
separator,
|
separator,
|
||||||
url,
|
url,
|
||||||
separator,
|
separator,
|
||||||
@ -362,7 +455,9 @@ define([], function () {
|
|||||||
control: "input",
|
control: "input",
|
||||||
type: "number",
|
type: "number",
|
||||||
domainObject: selectedParent,
|
domainObject: selectedParent,
|
||||||
property: path + ".x2",
|
property: function () {
|
||||||
|
return getPath() + ".x2";
|
||||||
|
},
|
||||||
label: "X2:",
|
label: "X2:",
|
||||||
title: "X2 position"
|
title: "X2 position"
|
||||||
},
|
},
|
||||||
@ -370,17 +465,21 @@ define([], function () {
|
|||||||
control: "input",
|
control: "input",
|
||||||
type: "number",
|
type: "number",
|
||||||
domainObject: selectedParent,
|
domainObject: selectedParent,
|
||||||
property: path + ".y2",
|
property: function () {
|
||||||
|
return getPath() + ".y2";
|
||||||
|
},
|
||||||
label: "Y2:",
|
label: "Y2:",
|
||||||
title: "Y2 position",
|
title: "Y2 position",
|
||||||
};
|
};
|
||||||
toolbar = [
|
toolbar = [
|
||||||
stroke,
|
stroke,
|
||||||
separator,
|
separator,
|
||||||
|
stackOrder,
|
||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
x2,
|
x2,
|
||||||
y2,
|
y2,
|
||||||
|
useGrid,
|
||||||
separator,
|
separator,
|
||||||
remove
|
remove
|
||||||
];
|
];
|
||||||
|
@ -25,6 +25,7 @@ define(function () {
|
|||||||
return {
|
return {
|
||||||
name: "Display Layout",
|
name: "Display Layout",
|
||||||
creatable: true,
|
creatable: true,
|
||||||
|
description: 'Assemble other objects and components together into a reusable screen layout. Simply drag in the objects you want, position and size them. Save your design and view or edit it at any time.',
|
||||||
cssClass: 'icon-layout',
|
cssClass: 'icon-layout',
|
||||||
initialize(domainObject) {
|
initialize(domainObject) {
|
||||||
domainObject.composition = [];
|
domainObject.composition = [];
|
||||||
@ -32,7 +33,31 @@ define(function () {
|
|||||||
items: [],
|
items: [],
|
||||||
layoutGrid: [10, 10],
|
layoutGrid: [10, 10],
|
||||||
};
|
};
|
||||||
}
|
},
|
||||||
|
form: [
|
||||||
|
{
|
||||||
|
name: "Horizontal grid (px)",
|
||||||
|
control: "numberfield",
|
||||||
|
cssClass: "l-input-sm l-numeric",
|
||||||
|
property: [
|
||||||
|
"configuration",
|
||||||
|
"layoutGrid",
|
||||||
|
0
|
||||||
|
],
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Vertical grid (px)",
|
||||||
|
control: "numberfield",
|
||||||
|
cssClass: "l-input-sm l-numeric",
|
||||||
|
property: [
|
||||||
|
"configuration",
|
||||||
|
"layoutGrid",
|
||||||
|
1
|
||||||
|
],
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,7 +54,8 @@
|
|||||||
x: 1,
|
x: 1,
|
||||||
y: 1,
|
y: 1,
|
||||||
width: 10,
|
width: 10,
|
||||||
height: 5
|
height: 5,
|
||||||
|
useGrid: true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
inject: ['openmct'],
|
inject: ['openmct'],
|
||||||
|
@ -25,30 +25,26 @@
|
|||||||
@dragover="handleDragOver"
|
@dragover="handleDragOver"
|
||||||
@click="bypassSelection"
|
@click="bypassSelection"
|
||||||
@drop="handleDrop">
|
@drop="handleDrop">
|
||||||
<div class="l-layout__object">
|
<!-- Background grid -->
|
||||||
<!-- Background grid -->
|
<div class="l-layout__grid-holder c-grid">
|
||||||
<div class="l-layout__grid-holder c-grid"
|
<div class="c-grid__x l-grid l-grid-x"
|
||||||
v-if="!drilledIn">
|
v-if="gridSize[0] >= 3"
|
||||||
<div class="c-grid__x l-grid l-grid-x"
|
:style="[{ backgroundSize: gridSize[0] + 'px 100%' }]">
|
||||||
v-if="gridSize[0] >= 3"
|
|
||||||
:style="[{ backgroundSize: gridSize[0] + 'px 100%' }]">
|
|
||||||
</div>
|
|
||||||
<div class="c-grid__y l-grid l-grid-y"
|
|
||||||
v-if="gridSize[1] >= 3"
|
|
||||||
:style="[{ backgroundSize: '100%' + gridSize[1] + 'px' }]"></div>
|
|
||||||
</div>
|
</div>
|
||||||
<component v-for="(item, index) in layoutItems"
|
<div class="c-grid__y l-grid l-grid-y"
|
||||||
:is="item.type"
|
v-if="gridSize[1] >= 3"
|
||||||
:item="item"
|
:style="[{ backgroundSize: '100%' + gridSize[1] + 'px' }]"></div>
|
||||||
:key="item.id"
|
|
||||||
:gridSize="gridSize"
|
|
||||||
:initSelect="initSelectIndex === index"
|
|
||||||
:index="index"
|
|
||||||
@drilledIn="updateDrilledIn"
|
|
||||||
@endDrag="endDrag"
|
|
||||||
>
|
|
||||||
</component>
|
|
||||||
</div>
|
</div>
|
||||||
|
<component v-for="(item, index) in layoutItems"
|
||||||
|
:is="item.type"
|
||||||
|
:item="item"
|
||||||
|
:key="item.id"
|
||||||
|
:gridSize="item.useGrid ? gridSize : [1, 1]"
|
||||||
|
:initSelect="initSelectIndex === index"
|
||||||
|
:index="index"
|
||||||
|
@endDrag="endDrag"
|
||||||
|
>
|
||||||
|
</component>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -59,30 +55,47 @@
|
|||||||
@include abs();
|
@include abs();
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
&__grid-holder {
|
&__grid-holder {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__object {
|
|
||||||
flex: 1 1 auto;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__frame {
|
&__frame {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.l-shell__main-container {
|
.is-editing {
|
||||||
> .l-layout {
|
.l-shell__main-container {
|
||||||
[s-selected] {
|
&[s-selected],
|
||||||
border: $browseSelectedBorder;
|
&[s-selected-parent] {
|
||||||
|
// Display grid in main layout holder when editing
|
||||||
|
> .l-layout {
|
||||||
|
background: $editUIGridColorBg;
|
||||||
|
|
||||||
|
> [class*="__grid-holder"] {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.l-layout__frame {
|
||||||
|
&[s-selected],
|
||||||
|
&[s-selected-parent] {
|
||||||
|
// Display grid in nested layouts when editing
|
||||||
|
> * > * > .l-layout {
|
||||||
|
background: $editUIGridColorBg;
|
||||||
|
box-shadow: inset $editUIGridColorFg 0 0 2px 1px;
|
||||||
|
|
||||||
|
> [class*='grid-holder'] {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Styles moved to _global.scss;
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
|
||||||
@ -104,6 +117,12 @@
|
|||||||
'text-view': TextView,
|
'text-view': TextView,
|
||||||
'image-view': ImageView
|
'image-view': ImageView
|
||||||
};
|
};
|
||||||
|
const ORDERS = {
|
||||||
|
top: Number.POSITIVE_INFINITY,
|
||||||
|
up: 1,
|
||||||
|
down: -1,
|
||||||
|
bottom: Number.NEGATIVE_INFINITY
|
||||||
|
};
|
||||||
|
|
||||||
function getItemDefinition(itemType, ...options) {
|
function getItemDefinition(itemType, ...options) {
|
||||||
let itemView = ITEM_TYPE_VIEW_MAP[itemType];
|
let itemView = ITEM_TYPE_VIEW_MAP[itemType];
|
||||||
@ -119,7 +138,6 @@
|
|||||||
data() {
|
data() {
|
||||||
let domainObject = JSON.parse(JSON.stringify(this.domainObject));
|
let domainObject = JSON.parse(JSON.stringify(this.domainObject));
|
||||||
return {
|
return {
|
||||||
drilledIn: undefined,
|
|
||||||
internalDomainObject: domainObject,
|
internalDomainObject: domainObject,
|
||||||
initSelectIndex: undefined
|
initSelectIndex: undefined
|
||||||
};
|
};
|
||||||
@ -144,16 +162,49 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateDrilledIn();
|
if (this.removeSelectionListener) {
|
||||||
|
this.removeSelectionListener();
|
||||||
|
}
|
||||||
|
|
||||||
|
let itemIndex = selection[0].context.index;
|
||||||
|
|
||||||
|
if (itemIndex !== undefined) {
|
||||||
|
this.attachSelectionListener(itemIndex);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
updateDrilledIn(drilledInItem) {
|
attachSelectionListener(index) {
|
||||||
let identifier = drilledInItem && this.openmct.objects.makeKeyString(drilledInItem.identifier);
|
let path = `configuration.items[${index}].useGrid`;
|
||||||
this.drilledIn = identifier;
|
this.removeSelectionListener = this.openmct.objects.observe(this.internalDomainObject, path, function (value) {
|
||||||
this.layoutItems.forEach(item => {
|
let item = this.layoutItems[index];
|
||||||
if (item.type === 'subobject-view') {
|
|
||||||
item.drilledIn = this.openmct.objects.makeKeyString(item.identifier) === identifier;
|
if (value) {
|
||||||
|
item.x = Math.round(item.x / this.gridSize[0]);
|
||||||
|
item.y = Math.round(item.y / this.gridSize[1]);
|
||||||
|
item.width = Math.round(item.width / this.gridSize[0]);
|
||||||
|
item.height = Math.round(item.height / this.gridSize[1]);
|
||||||
|
|
||||||
|
if (item.x2) {
|
||||||
|
item.x2 = Math.round(item.x2 / this.gridSize[0]);
|
||||||
|
}
|
||||||
|
if (item.y2) {
|
||||||
|
item.y2 = Math.round(item.y2 / this.gridSize[1]);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
item.x = this.gridSize[0] * item.x;
|
||||||
|
item.y = this.gridSize[1] * item.y;
|
||||||
|
item.width = this.gridSize[0] * item.width;
|
||||||
|
item.height = this.gridSize[1] * item.height;
|
||||||
|
|
||||||
|
if (item.x2) {
|
||||||
|
item.x2 = this.gridSize[0] * item.x2;
|
||||||
|
}
|
||||||
|
if (item.y2) {
|
||||||
|
item.y2 = this.gridSize[1] * item.y2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
item.useGrid = value;
|
||||||
|
this.mutate(`configuration.items[${index}]`, item);
|
||||||
|
}.bind(this));
|
||||||
},
|
},
|
||||||
bypassSelection($event) {
|
bypassSelection($event) {
|
||||||
if (this.dragInProgress) {
|
if (this.dragInProgress) {
|
||||||
@ -177,13 +228,13 @@
|
|||||||
this.openmct.objects.mutate(this.internalDomainObject, path, value);
|
this.openmct.objects.mutate(this.internalDomainObject, path, value);
|
||||||
},
|
},
|
||||||
handleDrop($event) {
|
handleDrop($event) {
|
||||||
if (!$event.dataTransfer.types.includes('domainobject')) {
|
if (!$event.dataTransfer.types.includes('openmct/domain-object-path')) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$event.preventDefault();
|
$event.preventDefault();
|
||||||
|
|
||||||
let domainObject = JSON.parse($event.dataTransfer.getData('domainobject'));
|
let domainObject = JSON.parse($event.dataTransfer.getData('openmct/domain-object-path'))[0];
|
||||||
let elementRect = this.$el.getBoundingClientRect();
|
let elementRect = this.$el.getBoundingClientRect();
|
||||||
let droppedObjectPosition = [
|
let droppedObjectPosition = [
|
||||||
Math.floor(($event.pageX - elementRect.left) / this.gridSize[0]),
|
Math.floor(($event.pageX - elementRect.left) / this.gridSize[0]),
|
||||||
@ -234,12 +285,17 @@
|
|||||||
this.initSelectIndex = this.layoutItems.length - 1;
|
this.initSelectIndex = this.layoutItems.length - 1;
|
||||||
},
|
},
|
||||||
trackItem(item) {
|
trackItem(item) {
|
||||||
|
if (!item.identifier) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let keyString = this.openmct.objects.makeKeyString(item.identifier);
|
||||||
|
|
||||||
if (item.type === "telemetry-view") {
|
if (item.type === "telemetry-view") {
|
||||||
let keyString = this.openmct.objects.makeKeyString(item.identifier);
|
|
||||||
let count = this.telemetryViewMap[keyString] || 0;
|
let count = this.telemetryViewMap[keyString] || 0;
|
||||||
this.telemetryViewMap[keyString] = ++count;
|
this.telemetryViewMap[keyString] = ++count;
|
||||||
} else if (item.type === "subobject-view") {
|
} else if (item.type === "subobject-view") {
|
||||||
this.objectViewMap[this.openmct.objects.makeKeyString(item.identifier)] = true;
|
this.objectViewMap[keyString] = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeItem(item, index) {
|
removeItem(item, index) {
|
||||||
@ -311,13 +367,28 @@
|
|||||||
});
|
});
|
||||||
this.mutate("configuration.items", layoutItems);
|
this.mutate("configuration.items", layoutItems);
|
||||||
this.$el.click();
|
this.$el.click();
|
||||||
|
},
|
||||||
|
orderItem(position, index) {
|
||||||
|
let delta = ORDERS[position];
|
||||||
|
let newIndex = Math.max(Math.min(index + delta, this.layoutItems.length - 1), 0);
|
||||||
|
let item = this.layoutItems[index];
|
||||||
|
|
||||||
|
if (newIndex !== index) {
|
||||||
|
this.layoutItems.splice(index, 1);
|
||||||
|
this.layoutItems.splice(newIndex, 0, item);
|
||||||
|
this.mutate('configuration.items', this.layoutItems);
|
||||||
|
|
||||||
|
if (this.removeSelectionListener) {
|
||||||
|
this.removeSelectionListener();
|
||||||
|
this.attachSelectionListener(newIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.unlisten = this.openmct.objects.observe(this.internalDomainObject, '*', function (obj) {
|
this.unlisten = this.openmct.objects.observe(this.internalDomainObject, '*', function (obj) {
|
||||||
this.internalDomainObject = JSON.parse(JSON.stringify(obj));
|
this.internalDomainObject = JSON.parse(JSON.stringify(obj));
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
|
|
||||||
this.openmct.selection.on('change', this.setSelection);
|
this.openmct.selection.on('change', this.setSelection);
|
||||||
this.initializeItems();
|
this.initializeItems();
|
||||||
this.composition = this.openmct.composition.get(this.internalDomainObject);
|
this.composition = this.openmct.composition.get(this.internalDomainObject);
|
||||||
@ -330,7 +401,10 @@
|
|||||||
this.composition.off('add', this.addChild);
|
this.composition.off('add', this.addChild);
|
||||||
this.composition.off('remove', this.removeChild);
|
this.composition.off('remove', this.removeChild);
|
||||||
this.unlisten();
|
this.unlisten();
|
||||||
|
|
||||||
|
if (this.removeSelectionListener) {
|
||||||
|
this.removeSelectionListener();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -56,7 +56,8 @@
|
|||||||
y: 1,
|
y: 1,
|
||||||
width: 10,
|
width: 10,
|
||||||
height: 5,
|
height: 5,
|
||||||
url: element.url
|
url: element.url,
|
||||||
|
useGrid: true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
inject: ['openmct'],
|
inject: ['openmct'],
|
||||||
|
@ -25,25 +25,24 @@
|
|||||||
:class="{
|
:class="{
|
||||||
'no-frame': !item.hasFrame,
|
'no-frame': !item.hasFrame,
|
||||||
'u-inspectable': inspectable,
|
'u-inspectable': inspectable,
|
||||||
'is-drilled-in': item.drilledIn
|
'is-resizing': isResizing
|
||||||
}"
|
}"
|
||||||
:style="style"
|
:style="style">
|
||||||
@dblclick="drill($event)">
|
|
||||||
|
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
|
|
||||||
<!-- Drag handles -->
|
<!-- Drag handles -->
|
||||||
<div class="c-frame-edit">
|
<div class="c-frame-edit">
|
||||||
<div class="c-frame-edit__move"
|
<div class="c-frame-edit__move"
|
||||||
@mousedown="startDrag([1,1], [0,0], $event)"></div>
|
@mousedown="startDrag([1,1], [0,0], $event, 'move')"></div>
|
||||||
<div class="c-frame-edit__handle c-frame-edit__handle--nw"
|
<div class="c-frame-edit__handle c-frame-edit__handle--nw"
|
||||||
@mousedown="startDrag([1,1], [-1,-1], $event)"></div>
|
@mousedown="startDrag([1,1], [-1,-1], $event, 'resize')"></div>
|
||||||
<div class="c-frame-edit__handle c-frame-edit__handle--ne"
|
<div class="c-frame-edit__handle c-frame-edit__handle--ne"
|
||||||
@mousedown="startDrag([0,1], [1,-1], $event)"></div>
|
@mousedown="startDrag([0,1], [1,-1], $event, 'resize')"></div>
|
||||||
<div class="c-frame-edit__handle c-frame-edit__handle--sw"
|
<div class="c-frame-edit__handle c-frame-edit__handle--sw"
|
||||||
@mousedown="startDrag([1,0], [-1,1], $event)"></div>
|
@mousedown="startDrag([1,0], [-1,1], $event, 'resize')"></div>
|
||||||
<div class="c-frame-edit__handle c-frame-edit__handle--se"
|
<div class="c-frame-edit__handle c-frame-edit__handle--se"
|
||||||
@mousedown="startDrag([0,0], [1,1], $event)"></div>
|
@mousedown="startDrag([0,0], [1,1], $event, 'resize')"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -55,20 +54,167 @@
|
|||||||
.c-frame {
|
.c-frame {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
border: 1px solid transparent;
|
|
||||||
|
|
||||||
/*************************** NO-FRAME */
|
// Whatever is placed into the slot, make it fill the entirety of the space, obeying padding
|
||||||
&.no-frame {
|
> *:first-child {
|
||||||
> [class*="contents"] > [class*="__header"] {
|
flex: 1 1 auto;
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.no-frame) {
|
&:not(.no-frame) {
|
||||||
background: $colorBodyBg;
|
background: $colorBodyBg;
|
||||||
border: 1px solid $colorInteriorBorder;
|
border: $browseFrameBorder;
|
||||||
padding: $interiorMargin;
|
padding: $interiorMargin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-frame-edit {
|
||||||
|
// In Layouts, this is the editing rect and handles
|
||||||
|
// In Fixed Position, this is a wrapper element
|
||||||
|
@include abs();
|
||||||
|
display: none;
|
||||||
|
|
||||||
|
&__move {
|
||||||
|
@include abs();
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__handle {
|
||||||
|
$d: 6px;
|
||||||
|
$o: floor($d * -0.5);
|
||||||
|
background: $editFrameColorHandleFg;
|
||||||
|
box-shadow: $editFrameColorHandleBg 0 0 0 2px;
|
||||||
|
display: none; // Set to block via s-selected selector
|
||||||
|
position: absolute;
|
||||||
|
width: $d; height: $d;
|
||||||
|
top: auto; right: auto; bottom: auto; left: auto;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
// Extended hit area
|
||||||
|
@include abs(-10px);
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
z-index: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $editUIColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--nwse {
|
||||||
|
cursor: nwse-resize;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--nw {
|
||||||
|
cursor: nw-resize;
|
||||||
|
left: $o; top: $o;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--ne {
|
||||||
|
cursor: ne-resize;
|
||||||
|
right: $o; top: $o;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--se {
|
||||||
|
cursor: se-resize;
|
||||||
|
right: $o; bottom: $o;
|
||||||
|
}
|
||||||
|
|
||||||
|
&--sw {
|
||||||
|
cursor: sw-resize;
|
||||||
|
left: $o; bottom: $o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.c-so-view.has-complex-content + .c-frame-edit {
|
||||||
|
// Target frames that hold domain objects that include header elements, as opposed to drawing and alpha objects
|
||||||
|
// Make the __move element a more affordable drag UI element
|
||||||
|
.c-frame-edit__move {
|
||||||
|
@include userSelectNone();
|
||||||
|
background: $editFrameMovebarColorBg;
|
||||||
|
box-shadow: rgba(black, 0.2) 0 1px;
|
||||||
|
bottom: auto;
|
||||||
|
height: 0; // Height is set on hover on s-selected.c-frame
|
||||||
|
opacity: 0.8;
|
||||||
|
max-height: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
// Grippy
|
||||||
|
$h: 4px;
|
||||||
|
$tbOffset: ($editFrameMovebarH - $h) / 2;
|
||||||
|
$lrOffset: 25%;
|
||||||
|
@include grippy($editFrameMovebarColorFg);
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
top: $tbOffset; right: $lrOffset; bottom: $tbOffset; left: $lrOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $editFrameHovMovebarColorBg;
|
||||||
|
&:before { @include grippy($editFrameHovMovebarColorFg); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.is-editing {
|
||||||
|
.c-frame {
|
||||||
|
$moveBarOutDelay: 500ms;
|
||||||
|
&.no-frame {
|
||||||
|
border: $editFrameBorder; // Base border style for a frame element while editing.
|
||||||
|
}
|
||||||
|
|
||||||
|
&-edit {
|
||||||
|
display: contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
&-edit__move,
|
||||||
|
.c-so-view {
|
||||||
|
transition: $transOut;
|
||||||
|
transition-delay: $moveBarOutDelay;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not([s-selected]) {
|
||||||
|
&:hover {
|
||||||
|
border: $editFrameBorderHov;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&[s-selected] {
|
||||||
|
// All frames selected while editing
|
||||||
|
border: $editFrameSelectedBorder;
|
||||||
|
box-shadow: $editFrameSelectedShdw;
|
||||||
|
|
||||||
|
> .c-frame-edit {
|
||||||
|
[class*='__handle'] {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.l-layout__frame:not(.is-resizing) {
|
||||||
|
// Show and animate the __move bar for sub-object views with complex content
|
||||||
|
&:hover > .c-so-view.has-complex-content {
|
||||||
|
// Move content down so the __move bar doesn't cover it.
|
||||||
|
padding-top: $editFrameMovebarH;
|
||||||
|
transition: $transIn;
|
||||||
|
|
||||||
|
&.c-so-view--no-frame {
|
||||||
|
// Move content down with a bit more space
|
||||||
|
padding-top: $editFrameMovebarH + $interiorMarginSm;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Show the move bar
|
||||||
|
+ .c-frame-edit .c-frame-edit__move {
|
||||||
|
height: $editFrameMovebarH;
|
||||||
|
transition: $transIn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
@ -84,7 +230,8 @@
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
dragPosition: undefined
|
dragPosition: undefined,
|
||||||
|
isResizing: undefined
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -110,24 +257,6 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
drill($event) {
|
|
||||||
if ($event) {
|
|
||||||
$event.stopPropagation();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!this.openmct.editor.isEditing() || !this.item.identifier) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.openmct.objects.get(this.item.identifier)
|
|
||||||
.then(domainObject => {
|
|
||||||
if (this.openmct.composition.get(domainObject) === undefined) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$emit('drilledIn', this.item);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
updatePosition(event) {
|
updatePosition(event) {
|
||||||
let currentPosition = [event.pageX, event.pageY];
|
let currentPosition = [event.pageX, event.pageY];
|
||||||
this.initialPosition = this.initialPosition || currentPosition;
|
this.initialPosition = this.initialPosition || currentPosition;
|
||||||
@ -135,7 +264,7 @@
|
|||||||
return value - this.initialPosition[index];
|
return value - this.initialPosition[index];
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
},
|
},
|
||||||
startDrag(posFactor, dimFactor, event) {
|
startDrag(posFactor, dimFactor, event, type) {
|
||||||
document.body.addEventListener('mousemove', this.continueDrag);
|
document.body.addEventListener('mousemove', this.continueDrag);
|
||||||
document.body.addEventListener('mouseup', this.endDrag);
|
document.body.addEventListener('mouseup', this.endDrag);
|
||||||
|
|
||||||
@ -145,6 +274,7 @@
|
|||||||
};
|
};
|
||||||
this.updatePosition(event);
|
this.updatePosition(event);
|
||||||
this.activeDrag = new LayoutDrag(this.dragPosition, posFactor, dimFactor, this.gridSize);
|
this.activeDrag = new LayoutDrag(this.dragPosition, posFactor, dimFactor, this.gridSize);
|
||||||
|
this.isResizing = type === 'resize';
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
},
|
},
|
||||||
continueDrag(event) {
|
continueDrag(event) {
|
||||||
@ -162,6 +292,7 @@
|
|||||||
this.dragPosition = undefined;
|
this.dragPosition = undefined;
|
||||||
this.initialPosition = undefined;
|
this.initialPosition = undefined;
|
||||||
this.delta = undefined;
|
this.delta = undefined;
|
||||||
|
this.isResizing = undefined;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,8 @@
|
|||||||
y: 10,
|
y: 10,
|
||||||
x2: 10,
|
x2: 10,
|
||||||
y2: 5,
|
y2: 5,
|
||||||
stroke: '#717171'
|
stroke: '#717171',
|
||||||
|
useGrid: true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
inject: ['openmct'],
|
inject: ['openmct'],
|
||||||
|
@ -22,12 +22,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<layout-frame :item="item"
|
<layout-frame :item="item"
|
||||||
:grid-size="gridSize"
|
:grid-size="gridSize"
|
||||||
@endDrag="(item, updates) => $emit('endDrag', item, updates)"
|
@endDrag="(item, updates) => $emit('endDrag', item, updates)">
|
||||||
@drilledIn="item => $emit('drilledIn', item)">
|
|
||||||
<object-frame v-if="domainObject"
|
<object-frame v-if="domainObject"
|
||||||
:domain-object="domainObject"
|
:domain-object="domainObject"
|
||||||
:object-path="objectPath"
|
:object-path="objectPath"
|
||||||
:has-frame="item.hasFrame">
|
:has-frame="item.hasFrame"
|
||||||
|
ref="objectFrame">
|
||||||
</object-frame>
|
</object-frame>
|
||||||
</layout-frame>
|
</layout-frame>
|
||||||
</template>
|
</template>
|
||||||
@ -65,7 +65,8 @@
|
|||||||
x: position[0],
|
x: position[0],
|
||||||
y: position[1],
|
y: position[1],
|
||||||
identifier: domainObject.identifier,
|
identifier: domainObject.identifier,
|
||||||
hasFrame: hasFrameByDefault(domainObject.type)
|
hasFrame: hasFrameByDefault(domainObject.type),
|
||||||
|
useGrid: true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
inject: ['openmct'],
|
inject: ['openmct'],
|
||||||
@ -98,13 +99,15 @@
|
|||||||
setObject(domainObject) {
|
setObject(domainObject) {
|
||||||
this.domainObject = domainObject;
|
this.domainObject = domainObject;
|
||||||
this.objectPath = [this.domainObject].concat(this.openmct.router.path);
|
this.objectPath = [this.domainObject].concat(this.openmct.router.path);
|
||||||
this.context = {
|
this.$nextTick(function () {
|
||||||
item: domainObject,
|
let childContext = this.$refs.objectFrame.getSelectionContext();
|
||||||
layoutItem: this.item,
|
childContext.item = domainObject;
|
||||||
index: this.index
|
childContext.layoutItem = this.item;
|
||||||
};
|
childContext.index = this.index;
|
||||||
this.removeSelectable = this.openmct.selection.selectable(
|
this.context = childContext;
|
||||||
this.$el, this.context, this.initSelect);
|
this.removeSelectable = this.openmct.selection.selectable(
|
||||||
|
this.$el, this.context, this.initSelect);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -99,6 +99,7 @@
|
|||||||
fill: "",
|
fill: "",
|
||||||
color: "",
|
color: "",
|
||||||
size: "13px",
|
size: "13px",
|
||||||
|
useGrid: true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
inject: ['openmct'],
|
inject: ['openmct'],
|
||||||
|
@ -59,7 +59,8 @@
|
|||||||
y: 1,
|
y: 1,
|
||||||
width: 10,
|
width: 10,
|
||||||
height: 5,
|
height: 5,
|
||||||
text: element.text
|
text: element.text,
|
||||||
|
useGrid: true
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
inject: ['openmct'],
|
inject: ['openmct'],
|
||||||
|
@ -61,7 +61,8 @@ export default function () {
|
|||||||
return {
|
return {
|
||||||
item: domainObject,
|
item: domainObject,
|
||||||
addElement: component && component.$refs.displayLayout.addElement,
|
addElement: component && component.$refs.displayLayout.addElement,
|
||||||
removeItem: component && component.$refs.displayLayout.removeItem
|
removeItem: component && component.$refs.displayLayout.removeItem,
|
||||||
|
orderItem: component && component.$refs.displayLayout.orderItem
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
destroy() {
|
destroy() {
|
||||||
|
@ -24,7 +24,7 @@
|
|||||||
<div class="c-fl-container"
|
<div class="c-fl-container"
|
||||||
:style="[{'flex-basis': sizeString}]"
|
:style="[{'flex-basis': sizeString}]"
|
||||||
:class="{'is-empty': !frames.length}">
|
:class="{'is-empty': !frames.length}">
|
||||||
<div class="c-fl-container__header icon-grippy-ew"
|
<div class="c-fl-container__header"
|
||||||
v-show="isEditing"
|
v-show="isEditing"
|
||||||
draggable="true"
|
draggable="true"
|
||||||
@dragstart="startContainerDrag">
|
@dragstart="startContainerDrag">
|
||||||
@ -35,7 +35,7 @@
|
|||||||
class="c-fl-frame__drop-hint"
|
class="c-fl-frame__drop-hint"
|
||||||
:index="-1"
|
:index="-1"
|
||||||
:allow-drop="allowDrop"
|
:allow-drop="allowDrop"
|
||||||
@object-drop-to="moveOrCreateFrame">
|
@object-drop-to="moveOrCreateNewFrame">
|
||||||
</drop-hint>
|
</drop-hint>
|
||||||
|
|
||||||
<div class="c-fl-container__frames-holder">
|
<div class="c-fl-container__frames-holder">
|
||||||
@ -55,7 +55,7 @@
|
|||||||
:key="i"
|
:key="i"
|
||||||
:index="i"
|
:index="i"
|
||||||
:allowDrop="allowDrop"
|
:allowDrop="allowDrop"
|
||||||
@object-drop-to="moveOrCreateFrame">
|
@object-drop-to="moveOrCreateNewFrame">
|
||||||
</drop-hint>
|
</drop-hint>
|
||||||
|
|
||||||
<resize-handle
|
<resize-handle
|
||||||
@ -100,7 +100,7 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
allowDrop(event, index) {
|
allowDrop(event, index) {
|
||||||
if (event.dataTransfer.getData('domainObject')) {
|
if (event.dataTransfer.types.includes('openmct/domain-object-path')) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
let frameId = event.dataTransfer.getData('frameid'),
|
let frameId = event.dataTransfer.getData('frameid'),
|
||||||
@ -123,15 +123,12 @@ export default {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
moveOrCreateFrame(insertIndex, event) {
|
moveOrCreateNewFrame(insertIndex, event) {
|
||||||
if (event.dataTransfer.types.includes('domainobject')) {
|
if (event.dataTransfer.types.includes('openmct/domain-object-path')) {
|
||||||
// create frame using domain object
|
|
||||||
let domainObject = JSON.parse(event.dataTransfer.getData('domainObject'));
|
|
||||||
this.$emit(
|
this.$emit(
|
||||||
'create-frame',
|
'new-frame',
|
||||||
this.index,
|
this.index,
|
||||||
insertIndex,
|
insertIndex
|
||||||
domainObject.identifier
|
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
@ -21,10 +21,10 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div v-if="isEditing"
|
<div v-show="isValidTarget">
|
||||||
v-show="isValidTarget">
|
|
||||||
<div class="c-drop-hint c-drop-hint--always-show"
|
<div class="c-drop-hint c-drop-hint--always-show"
|
||||||
:class="{'is-mouse-over': isMouseOver}"
|
:class="{'is-mouse-over': isMouseOver}"
|
||||||
|
@dragover.prevent
|
||||||
@dragenter="dragenter"
|
@dragenter="dragenter"
|
||||||
@dragleave="dragleave"
|
@dragleave="dragleave"
|
||||||
@drop="dropHandler">
|
@drop="dropHandler">
|
||||||
@ -37,8 +37,6 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import isEditingMixin from '../mixins/isEditing';
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props:{
|
props:{
|
||||||
index: Number,
|
index: Number,
|
||||||
@ -47,7 +45,6 @@ export default {
|
|||||||
required: true
|
required: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mixins: [isEditingMixin],
|
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
isMouseOver: false,
|
isMouseOver: false,
|
||||||
@ -75,10 +72,12 @@ export default {
|
|||||||
mounted() {
|
mounted() {
|
||||||
document.addEventListener('dragstart', this.dragstart);
|
document.addEventListener('dragstart', this.dragstart);
|
||||||
document.addEventListener('dragend', this.dragend);
|
document.addEventListener('dragend', this.dragend);
|
||||||
|
document.addEventListener('drop', this.dragend);
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
document.removeEventListener('dragstart', this.dragstart);
|
document.removeEventListener('dragstart', this.dragstart);
|
||||||
document.removeEventListener('dragend', this.dragend);
|
document.removeEventListener('dragend', this.dragend);
|
||||||
|
document.removeEventListener('drop', this.dragend);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
@ -22,6 +22,11 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="c-fl">
|
<div class="c-fl">
|
||||||
|
<div
|
||||||
|
id="js-fl-drag-ghost"
|
||||||
|
class="c-fl__drag-ghost">
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="c-fl__empty"
|
<div class="c-fl__empty"
|
||||||
v-if="areAllContainersEmpty()">
|
v-if="areAllContainersEmpty()">
|
||||||
<span class="c-fl__empty-message">This Flexible Layout is currently empty</span>
|
<span class="c-fl__empty-message">This Flexible Layout is currently empty</span>
|
||||||
@ -50,7 +55,7 @@
|
|||||||
:container="container"
|
:container="container"
|
||||||
:rowsLayout="rowsLayout"
|
:rowsLayout="rowsLayout"
|
||||||
@move-frame="moveFrame"
|
@move-frame="moveFrame"
|
||||||
@create-frame="createFrame"
|
@new-frame="setFrameLocation"
|
||||||
@persist="persist">
|
@persist="persist">
|
||||||
</container-component>
|
</container-component>
|
||||||
|
|
||||||
@ -79,6 +84,22 @@
|
|||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import '~styles/sass-base';
|
@import '~styles/sass-base';
|
||||||
|
|
||||||
|
@mixin containerGrippy($headerSize, $dir) {
|
||||||
|
position: absolute;
|
||||||
|
$h: 6px;
|
||||||
|
$minorOffset: ($headerSize - $h) / 2;
|
||||||
|
$majorOffset: 35%;
|
||||||
|
content: '';
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
@include grippy($c: $editFrameSelectedMovebarColorFg, $dir: $dir);
|
||||||
|
@if $dir == 'x' {
|
||||||
|
top: $minorOffset; right: $majorOffset; bottom: $minorOffset; left: $majorOffset;
|
||||||
|
} @else {
|
||||||
|
top: $majorOffset; right: $minorOffset; bottom: $majorOffset; left: $minorOffset;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.c-fl {
|
.c-fl {
|
||||||
@include abs();
|
@include abs();
|
||||||
@ -100,7 +121,6 @@
|
|||||||
> * + * { margin-left: 1px; }
|
> * + * { margin-left: 1px; }
|
||||||
|
|
||||||
&[class*='--rows'] {
|
&[class*='--rows'] {
|
||||||
//@include test(blue, 0.1);
|
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
> * + * {
|
> * + * {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
@ -122,13 +142,29 @@
|
|||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__drag-ghost{
|
||||||
|
background: $colorItemTreeHoverBg;
|
||||||
|
color: $colorItemTreeHoverFg;
|
||||||
|
border-radius: $basicCr;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding: $interiorMarginLg $interiorMarginLg * 2;
|
||||||
|
position: absolute;
|
||||||
|
top: -10000px;
|
||||||
|
z-index: 2;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
color: $colorKey;
|
||||||
|
margin-right: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-fl-container {
|
.c-fl-container {
|
||||||
/***************************************************** CONTAINERS */
|
/***************************************************** CONTAINERS */
|
||||||
$headerSize: 16px;
|
$headerSize: 16px;
|
||||||
|
|
||||||
border: 1px solid transparent;
|
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
@ -138,9 +174,9 @@
|
|||||||
flex-shrink: 1;
|
flex-shrink: 1;
|
||||||
|
|
||||||
&__header {
|
&__header {
|
||||||
// Only displayed when editing
|
// Only displayed when editing, controlled via JS
|
||||||
background: $editSelectableColor;
|
background: $editFrameMovebarColorBg;
|
||||||
color: $editSelectableColorFg;
|
color: $editFrameMovebarColorFg;
|
||||||
cursor: move;
|
cursor: move;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
@ -148,12 +184,8 @@
|
|||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
// Drag grippy
|
// Drag grippy
|
||||||
font-size: 0.8em;
|
@include containerGrippy($headerSize, 'x');
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
position: absolute;
|
|
||||||
left: 50%; top: 50%;
|
|
||||||
transform-origin: center;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,19 +205,27 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.is-editing & {
|
.is-editing & {
|
||||||
//background: $editCanvasColorBg;
|
|
||||||
border-color: $editSelectableColor;
|
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: $editSelectableColorHov;
|
.c-fl-container__header {
|
||||||
|
background: $editFrameHovMovebarColorBg;
|
||||||
|
color: $editFrameHovMovebarColorFg;
|
||||||
|
|
||||||
|
&:before {
|
||||||
|
opacity: .75;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&[s-selected] {
|
&[s-selected] {
|
||||||
border-color: $editSelectableColorSelected;
|
border: $editFrameSelectedBorder;
|
||||||
|
|
||||||
.c-fl-container__header {
|
.c-fl-container__header {
|
||||||
background: $editSelectableColorSelected;
|
background:$editFrameSelectedMovebarColorBg;
|
||||||
color: $editSelectableColorSelectedFg;
|
color: $editFrameSelectedMovebarColorFg;
|
||||||
|
&:before {
|
||||||
|
// Grippy
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,11 +234,6 @@
|
|||||||
// Frames get styled here because this is particular to their presence in this layout type
|
// Frames get styled here because this is particular to their presence in this layout type
|
||||||
.c-fl-frame {
|
.c-fl-frame {
|
||||||
@include browserPrefix(margin-collapse, collapse);
|
@include browserPrefix(margin-collapse, collapse);
|
||||||
margin: 1px;
|
|
||||||
|
|
||||||
//&__drag-wrapper {
|
|
||||||
// border: 1px solid $colorInteriorBorder; // Now handled by is-selectable
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****** ROWS LAYOUT */
|
/****** ROWS LAYOUT */
|
||||||
@ -211,8 +246,8 @@
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
// Drag grippy
|
// Grippy
|
||||||
transform: rotate(90deg) translate(-50%, 50%);
|
@include containerGrippy($headerSize, 'y');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,8 +270,6 @@
|
|||||||
$dropHintSize: 15px;
|
$dropHintSize: 15px;
|
||||||
|
|
||||||
display: flex;
|
display: flex;
|
||||||
// justify-content: stretch;
|
|
||||||
// align-items: stretch;
|
|
||||||
flex: 1 1;
|
flex: 1 1;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
overflow: hidden; // Needed to allow frames to collapse when sized down
|
overflow: hidden; // Needed to allow frames to collapse when sized down
|
||||||
@ -275,7 +308,6 @@
|
|||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
width: $size;
|
width: $size;
|
||||||
z-index: 2;
|
|
||||||
|
|
||||||
// Changed when layout is different, see below
|
// Changed when layout is different, see below
|
||||||
border-top-right-radius: $controlCr;
|
border-top-right-radius: $controlCr;
|
||||||
@ -304,37 +336,16 @@
|
|||||||
|
|
||||||
&:before {
|
&:before {
|
||||||
// The visible resize line
|
// The visible resize line
|
||||||
background: $editColor;
|
background: $editUIColor;
|
||||||
content: '';
|
content: '';
|
||||||
display: block;
|
display: block;
|
||||||
flex: 1 1 auto;
|
flex: 1 1 auto;
|
||||||
min-height: $size; min-width: $size;
|
min-height: $size; min-width: $size;
|
||||||
}
|
}
|
||||||
|
|
||||||
&__grippy {
|
|
||||||
// Grippy element
|
|
||||||
$d: 4px;
|
|
||||||
$c: black;
|
|
||||||
$a: 0.9;
|
|
||||||
$d: 5px;
|
|
||||||
background: $editColor;
|
|
||||||
color: $editColorBg;
|
|
||||||
border-radius: $smallCr;
|
|
||||||
font-size: 0.8em;
|
|
||||||
height: $d;
|
|
||||||
width: $d * 10;
|
|
||||||
position: absolute;
|
|
||||||
left: 50%; top: 50%;
|
|
||||||
text-align: center;
|
|
||||||
transform-origin: center center;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.vertical {
|
&.vertical {
|
||||||
padding: $margin $size;
|
padding: $margin $size;
|
||||||
&:hover{
|
&:hover{
|
||||||
// padding: $marginHov 0;
|
|
||||||
cursor: row-resize;
|
cursor: row-resize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -342,20 +353,15 @@
|
|||||||
&.horizontal {
|
&.horizontal {
|
||||||
padding: $size $margin;
|
padding: $size $margin;
|
||||||
&:hover{
|
&:hover{
|
||||||
// padding: 0 $marginHov;
|
|
||||||
cursor: col-resize;
|
cursor: col-resize;
|
||||||
}
|
}
|
||||||
|
|
||||||
[class*='grippy'] {
|
|
||||||
transform: translate(-50%) rotate(90deg);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
transition: $transOut;
|
transition: $transOut;
|
||||||
&:before {
|
&:before {
|
||||||
// The visible resize line
|
// The visible resize line
|
||||||
background: $editColorHov;
|
background: $editUIColorHov;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -467,7 +473,8 @@ export default {
|
|||||||
},
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
domainObject: this.layoutObject
|
domainObject: this.layoutObject,
|
||||||
|
newFrameLocation: []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
@ -496,9 +503,27 @@ export default {
|
|||||||
this.persist();
|
this.persist();
|
||||||
},
|
},
|
||||||
deleteContainer(containerId) {
|
deleteContainer(containerId) {
|
||||||
let container = this.containers.filter(c => c.id === containerId)[0];
|
let container = this.containers.filter(c => c.id === containerId)[0],
|
||||||
let containerIndex = this.containers.indexOf(container);
|
containerIndex = this.containers.indexOf(container);
|
||||||
|
|
||||||
|
/*
|
||||||
|
remove associated domainObjects from composition
|
||||||
|
*/
|
||||||
|
container.frames.forEach(f => {
|
||||||
|
this.composition.remove({identifier: f.domainObjectIdentifier});
|
||||||
|
});
|
||||||
|
|
||||||
this.containers.splice(containerIndex, 1);
|
this.containers.splice(containerIndex, 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
add a container when there are no containers in the FL,
|
||||||
|
to prevent user from not being able to add a frame via
|
||||||
|
drag and drop.
|
||||||
|
*/
|
||||||
|
if (this.containers.length === 0) {
|
||||||
|
this.containers.push(new Container(100));
|
||||||
|
}
|
||||||
|
|
||||||
sizeToFill(this.containers);
|
sizeToFill(this.containers);
|
||||||
this.persist();
|
this.persist();
|
||||||
},
|
},
|
||||||
@ -513,12 +538,22 @@ export default {
|
|||||||
sizeItems(toContainer.frames, frame);
|
sizeItems(toContainer.frames, frame);
|
||||||
this.persist();
|
this.persist();
|
||||||
},
|
},
|
||||||
createFrame(containerIndex, insertFrameIndex, objectIdentifier) {
|
setFrameLocation(containerIndex, insertFrameIndex) {
|
||||||
let frame = new Frame(objectIdentifier);
|
this.newFrameLocation = [containerIndex, insertFrameIndex];
|
||||||
let container = this.containers[containerIndex];
|
},
|
||||||
container.frames.splice(insertFrameIndex + 1, 0, frame);
|
addFrame(domainObject) {
|
||||||
sizeItems(container.frames, frame);
|
if (this.newFrameLocation.length) {
|
||||||
this.persist();
|
let containerIndex = this.newFrameLocation[0],
|
||||||
|
frameIndex = this.newFrameLocation[1],
|
||||||
|
frame = new Frame(domainObject.identifier),
|
||||||
|
container = this.containers[containerIndex];
|
||||||
|
|
||||||
|
container.frames.splice(frameIndex + 1, 0, frame);
|
||||||
|
sizeItems(container.frames, frame);
|
||||||
|
|
||||||
|
this.newFrameLocation = [];
|
||||||
|
this.persist(containerIndex);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
deleteFrame(frameId) {
|
deleteFrame(frameId) {
|
||||||
let container = this.containers
|
let container = this.containers
|
||||||
@ -528,6 +563,12 @@ export default {
|
|||||||
.frames
|
.frames
|
||||||
.filter((f => f.id === frameId))[0];
|
.filter((f => f.id === frameId))[0];
|
||||||
let frameIndex = container.frames.indexOf(frame);
|
let frameIndex = container.frames.indexOf(frame);
|
||||||
|
|
||||||
|
/*
|
||||||
|
remove associated domainObject from composition
|
||||||
|
*/
|
||||||
|
this.composition.remove({identifier: frame.domainObjectIdentifier});
|
||||||
|
|
||||||
container.frames.splice(frameIndex, 1);
|
container.frames.splice(frameIndex, 1);
|
||||||
sizeToFill(container.frames);
|
sizeToFill(container.frames);
|
||||||
this.persist(containerIndex);
|
this.persist(containerIndex);
|
||||||
@ -600,24 +641,33 @@ export default {
|
|||||||
} else {
|
} else {
|
||||||
this.containers.splice(toIndex, 0, container);
|
this.containers.splice(toIndex, 0, container);
|
||||||
}
|
}
|
||||||
|
this.persist();
|
||||||
|
},
|
||||||
|
removeChildObject(identifier) {
|
||||||
|
let removeIdentifier = this.openmct.objects.makeKeyString(identifier);
|
||||||
|
|
||||||
|
this.containers.forEach(container => {
|
||||||
|
container.frames = container.frames.filter(frame => {
|
||||||
|
let frameIdentifier = this.openmct.objects.makeKeyString(frame.domainObjectIdentifier);
|
||||||
|
|
||||||
|
return removeIdentifier !== frameIdentifier;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
this.persist();
|
this.persist();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
this.composition = this.openmct.composition.get(this.domainObject);
|
||||||
|
this.composition.on('remove', this.removeChildObject);
|
||||||
|
this.composition.on('add', this.addFrame);
|
||||||
|
|
||||||
let context = {
|
|
||||||
item: this.domainObject,
|
|
||||||
addContainer: this.addContainer,
|
|
||||||
deleteContainer: this.deleteContainer,
|
|
||||||
deleteFrame: this.deleteFrame,
|
|
||||||
type: 'flexible-layout'
|
|
||||||
}
|
|
||||||
|
|
||||||
this.unsubscribeSelection = this.openmct.selection.selectable(this.$el, context, true);
|
|
||||||
this.unobserve = this.openmct.objects.observe(this.domainObject, '*', this.updateDomainObject);
|
this.unobserve = this.openmct.objects.observe(this.domainObject, '*', this.updateDomainObject);
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
this.unsubscribeSelection();
|
this.composition.off('remove', this.removeChildObject);
|
||||||
|
this.composition.off('add', this.addFrame);
|
||||||
|
|
||||||
this.unobserve();
|
this.unobserve();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
'flex-basis': `${frame.size}%`
|
'flex-basis': `${frame.size}%`
|
||||||
}">
|
}">
|
||||||
|
|
||||||
<div class="c-frame c-fl-frame__drag-wrapper is-selectable is-moveable"
|
<div class="c-frame c-fl-frame__drag-wrapper is-selectable u-inspectable is-moveable"
|
||||||
draggable="true"
|
draggable="true"
|
||||||
@dragstart="initDrag"
|
@dragstart="initDrag"
|
||||||
ref="frame">
|
ref="frame">
|
||||||
@ -35,7 +35,8 @@
|
|||||||
v-if="domainObject"
|
v-if="domainObject"
|
||||||
:domain-object="domainObject"
|
:domain-object="domainObject"
|
||||||
:object-path="objectPath"
|
:object-path="objectPath"
|
||||||
:has-frame="hasFrame">
|
:has-frame="hasFrame"
|
||||||
|
ref="objectFrame">
|
||||||
</object-frame>
|
</object-frame>
|
||||||
|
|
||||||
<div class="c-fl-frame__size-indicator"
|
<div class="c-fl-frame__size-indicator"
|
||||||
@ -73,22 +74,33 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
setDomainObject(object) {
|
setDomainObject(object) {
|
||||||
console.log('setting object!');
|
|
||||||
this.domainObject = object;
|
this.domainObject = object;
|
||||||
this.objectPath = [object];
|
this.objectPath = [object];
|
||||||
this.setSelection();
|
this.setSelection();
|
||||||
},
|
},
|
||||||
setSelection() {
|
setSelection() {
|
||||||
let context = {
|
this.$nextTick(function () {
|
||||||
item: this.domainObject,
|
let childContext = this.$refs.objectFrame.getSelectionContext();
|
||||||
addContainer: this.addContainer,
|
childContext.item = this.domainObject;
|
||||||
type: 'frame',
|
childContext.type = 'frame';
|
||||||
frameId: this.frame.id
|
childContext.frameId = this.frame.id;
|
||||||
};
|
this.unsubscribeSelection = this.openmct.selection.selectable(
|
||||||
|
this.$refs.frame, childContext, false);
|
||||||
this.unsubscribeSelection = this.openmct.selection.selectable(this.$refs.frame, context, false);
|
});
|
||||||
},
|
},
|
||||||
initDrag(event) {
|
initDrag(event) {
|
||||||
|
let type = this.openmct.types.get(this.domainObject.type),
|
||||||
|
iconClass = type.definition ? type.definition.cssClass : 'icon-object-unknown';
|
||||||
|
|
||||||
|
if (this.dragGhost) {
|
||||||
|
let originalClassName = this.dragGhost.classList[0];
|
||||||
|
this.dragGhost.className = '';
|
||||||
|
this.dragGhost.classList.add(originalClassName, iconClass);
|
||||||
|
|
||||||
|
this.dragGhost.innerHTML = `<span>${this.domainObject.name}</span>`;
|
||||||
|
event.dataTransfer.setDragImage(this.dragGhost, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
event.dataTransfer.setData('frameid', this.frame.id);
|
event.dataTransfer.setData('frameid', this.frame.id);
|
||||||
event.dataTransfer.setData('containerIndex', this.containerIndex);
|
event.dataTransfer.setData('containerIndex', this.containerIndex);
|
||||||
}
|
}
|
||||||
@ -99,6 +111,8 @@ export default {
|
|||||||
this.setDomainObject(object);
|
this.setDomainObject(object);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.dragGhost = document.getElementById('js-fl-drag-ghost');
|
||||||
},
|
},
|
||||||
beforeDestroy() {
|
beforeDestroy() {
|
||||||
if (this.unsubscribeSelection) {
|
if (this.unsubscribeSelection) {
|
||||||
|
@ -52,9 +52,18 @@ define([
|
|||||||
layoutObject: domainObject
|
layoutObject: domainObject
|
||||||
},
|
},
|
||||||
el: element,
|
el: element,
|
||||||
template: '<flexible-layout-component></flexible-layout-component>'
|
template: '<flexible-layout-component ref="flexibleLayout"></flexible-layout-component>'
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
getSelectionContext: function () {
|
||||||
|
return {
|
||||||
|
item: domainObject,
|
||||||
|
addContainer: component.$refs.flexibleLayout.addContainer,
|
||||||
|
deleteContainer: component.$refs.flexibleLayout.deleteContainer,
|
||||||
|
deleteFrame: component.$refs.flexibleLayout.deleteFrame,
|
||||||
|
type: 'flexible-layout'
|
||||||
|
};
|
||||||
|
},
|
||||||
destroy: function (element) {
|
destroy: function (element) {
|
||||||
component.$destroy();
|
component.$destroy();
|
||||||
component = undefined;
|
component = undefined;
|
||||||
|
@ -44,6 +44,7 @@ define([
|
|||||||
containers: [new Container.default(50), new Container.default(50)],
|
containers: [new Container.default(50), new Container.default(50)],
|
||||||
rowsLayout: false
|
rowsLayout: false
|
||||||
};
|
};
|
||||||
|
domainObject.composition = [];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -53,18 +53,18 @@ function ToolbarProvider(openmct) {
|
|||||||
toggleContainer = {
|
toggleContainer = {
|
||||||
control: 'toggle-button',
|
control: 'toggle-button',
|
||||||
key: 'toggle-layout',
|
key: 'toggle-layout',
|
||||||
domainObject: secondary ? secondary.context.item : primary.context.item,
|
domainObject: primary.context.item,
|
||||||
property: 'configuration.rowsLayout',
|
property: 'configuration.rowsLayout',
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
value: false,
|
value: true,
|
||||||
icon: 'icon-columns',
|
icon: 'icon-columns',
|
||||||
title: 'Columns'
|
title: 'Columns layout'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: true,
|
value: false,
|
||||||
icon: 'icon-rows',
|
icon: 'icon-rows',
|
||||||
title: 'Rows'
|
title: 'Rows layout'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@ -120,14 +120,14 @@ function ToolbarProvider(openmct) {
|
|||||||
property: `configuration.containers[${containerIndex}].frames[${frameIndex}].noFrame`,
|
property: `configuration.containers[${containerIndex}].frames[${frameIndex}].noFrame`,
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
value: true,
|
value: false,
|
||||||
icon: 'icon-frame-hide',
|
icon: 'icon-frame-hide',
|
||||||
title: "Hide frame"
|
title: "Frame hidden"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
value: false,
|
value: true,
|
||||||
icon: 'icon-frame-show',
|
icon: 'icon-frame-show',
|
||||||
title: "Show frame"
|
title: "Frame visible"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
@ -140,6 +140,8 @@ function ToolbarProvider(openmct) {
|
|||||||
title: 'Add Container'
|
title: 'Add Container'
|
||||||
};
|
};
|
||||||
|
|
||||||
|
toggleContainer.domainObject = secondary.context.item;
|
||||||
|
|
||||||
} else if (primary.context.type === 'container') {
|
} else if (primary.context.type === 'container') {
|
||||||
|
|
||||||
deleteContainer = {
|
deleteContainer = {
|
||||||
@ -151,7 +153,7 @@ function ToolbarProvider(openmct) {
|
|||||||
|
|
||||||
let prompt = openmct.overlays.dialog({
|
let prompt = openmct.overlays.dialog({
|
||||||
iconClass: 'alert',
|
iconClass: 'alert',
|
||||||
message: `This action will permanently delete container ${containerIndex + 1} from this Flexible Layout`,
|
message: 'This action will permanently delete this container from this Flexible Layout',
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
label: 'Ok',
|
label: 'Ok',
|
||||||
@ -202,7 +204,7 @@ function ToolbarProvider(openmct) {
|
|||||||
addContainer,
|
addContainer,
|
||||||
toggleFrame ? separator: undefined,
|
toggleFrame ? separator: undefined,
|
||||||
toggleFrame,
|
toggleFrame,
|
||||||
deleteFrame || deleteContainer ? separator: undefined,
|
deleteFrame || deleteContainer ? separator : undefined,
|
||||||
deleteFrame,
|
deleteFrame,
|
||||||
deleteContainer
|
deleteContainer
|
||||||
];
|
];
|
||||||
|
@ -4,9 +4,8 @@
|
|||||||
@click="navigate">
|
@click="navigate">
|
||||||
<td class="c-list-item__name">
|
<td class="c-list-item__name">
|
||||||
<a :href="objectLink" ref="objectLink">
|
<a :href="objectLink" ref="objectLink">
|
||||||
<div class="c-list-item__type-icon"
|
<div class="c-list-item__type-icon" :class="item.type.cssClass"></div>
|
||||||
:class="item.type.cssClass"></div>
|
<div class="c-list-item__name-value">{{item.model.name}}</div>
|
||||||
{{item.model.name}}
|
|
||||||
</a>
|
</a>
|
||||||
</td>
|
</td>
|
||||||
<td class="c-list-item__type">{{ item.type.name }}</td>
|
<td class="c-list-item__type">{{ item.type.name }}</td>
|
||||||
@ -20,17 +19,24 @@
|
|||||||
|
|
||||||
/******************************* LIST ITEM */
|
/******************************* LIST ITEM */
|
||||||
.c-list-item {
|
.c-list-item {
|
||||||
&__name {
|
&__name a {
|
||||||
@include ellipsize();
|
display: flex;
|
||||||
|
|
||||||
|
> * + * { margin-left: $interiorMarginSm; }
|
||||||
}
|
}
|
||||||
|
|
||||||
&__type-icon {
|
&__type-icon {
|
||||||
|
// Have to do it this way instead of using icon-* class, due to need to apply alias to the icon
|
||||||
color: $colorKey;
|
color: $colorKey;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 1em;
|
width: 1em;
|
||||||
margin-right:$interiorMarginSm;
|
margin-right:$interiorMarginSm;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&__name-value {
|
||||||
|
@include ellipsize();
|
||||||
|
}
|
||||||
|
|
||||||
&.is-alias {
|
&.is-alias {
|
||||||
// Object is an alias to an original.
|
// Object is an alias to an original.
|
||||||
[class*='__type-icon'] {
|
[class*='__type-icon'] {
|
||||||
@ -48,7 +54,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
@ -78,9 +78,12 @@
|
|||||||
|
|
||||||
td {
|
td {
|
||||||
$p: floor($interiorMargin * 1.5);
|
$p: floor($interiorMargin * 1.5);
|
||||||
font-size: 1.1em;
|
@include ellipsize();
|
||||||
|
line-height: 120%; // Needed for icon alignment
|
||||||
|
max-width: 0;
|
||||||
padding-top: $p;
|
padding-top: $p;
|
||||||
padding-bottom: $p;
|
padding-bottom: $p;
|
||||||
|
width: 25%;
|
||||||
|
|
||||||
&:not(.c-list-item__name) {
|
&:not(.c-list-item__name) {
|
||||||
color: $colorItemFgDetails;
|
color: $colorItemFgDetails;
|
||||||
|
@ -7,18 +7,19 @@
|
|||||||
<div class="c-ne__embed__info">
|
<div class="c-ne__embed__info">
|
||||||
<div class="c-ne__embed__name">
|
<div class="c-ne__embed__name">
|
||||||
<a class="c-ne__embed__link"
|
<a class="c-ne__embed__link"
|
||||||
v-on:click="navigate(embed.type)"
|
:href="objectLink"
|
||||||
v-bind:class="[embed.cssClass]">{{embed.name}}</a>
|
:class="embed.cssClass">{{embed.name}}</a>
|
||||||
<a class="c-ne__embed__context-available icon-arrow-down"
|
<a class="c-ne__embed__context-available icon-arrow-down"
|
||||||
v-on:click="toggleActionMenu"></a>
|
@click="toggleActionMenu"></a>
|
||||||
</div>
|
</div>
|
||||||
<div class="hide-menu hidden">
|
<div class="hide-menu hidden">
|
||||||
<div class="menu-element context-menu-wrapper mobile-disable-select">
|
<div class="menu-element context-menu-wrapper mobile-disable-select">
|
||||||
<div class="menu context-menu">
|
<div class="c-menu">
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="action in actions"
|
<li v-for="action in actions"
|
||||||
v-bind:class="[action.cssClass]"
|
:key="action.name"
|
||||||
v-on:click="action.perform(embed, entry)">
|
:class="action.cssClass"
|
||||||
|
@click="action.perform(embed, entry)">
|
||||||
{{ action.name }}
|
{{ action.name }}
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
<li class="c-notebook__entry c-ne has-local-controls"
|
<li class="c-notebook__entry c-ne has-local-controls"
|
||||||
v-on:drop="dropOnEntry(entry.id, $event)"
|
@drop.prevent="dropOnEntry(entry.id, $event)">
|
||||||
v-on:dragover="dragoverOnEntry"
|
|
||||||
>
|
|
||||||
<div class="c-ne__time-and-content">
|
<div class="c-ne__time-and-content">
|
||||||
<div class="c-ne__time">
|
<div class="c-ne__time">
|
||||||
<span>{{formatTime(entry.createdOn, 'YYYY-MM-DD')}}</span>
|
<span>{{formatTime(entry.createdOn, 'YYYY-MM-DD')}}</span>
|
||||||
@ -11,18 +9,18 @@
|
|||||||
<div class="c-ne__text c-input-inline"
|
<div class="c-ne__text c-input-inline"
|
||||||
contenteditable="true"
|
contenteditable="true"
|
||||||
ref="contenteditable"
|
ref="contenteditable"
|
||||||
v-on:blur="textBlur($event, entry.id)"
|
@blur="textBlur($event, entry.id)"
|
||||||
v-on:focus="textFocus($event, entry.id)"
|
@focus="textFocus($event, entry.id)"
|
||||||
v-bind:key="entry.id"
|
|
||||||
v-html="entry.text">
|
v-html="entry.text">
|
||||||
</div>
|
</div>
|
||||||
<div class="c-ne__embeds">
|
<div class="c-ne__embeds">
|
||||||
<notebook-embed
|
<notebook-embed
|
||||||
v-for="(embed, index) in entry.embeds"
|
v-for="embed in entry.embeds"
|
||||||
:key="index"
|
:key="embed.id"
|
||||||
:embed="embed"
|
:embed="embed"
|
||||||
:entry="entry"
|
:objectPath="embed.objectPath"
|
||||||
></notebook-embed>
|
:entry="entry">
|
||||||
|
</notebook-embed>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -30,6 +28,7 @@
|
|||||||
<div class="c-ne__local-controls--hidden">
|
<div class="c-ne__local-controls--hidden">
|
||||||
<button class="c-click-icon c-click-icon--major icon-trash"
|
<button class="c-click-icon c-click-icon--major icon-trash"
|
||||||
title="Delete this entry"
|
title="Delete this entry"
|
||||||
v-on:click="deleteEntry"></button>
|
@click="deleteEntry">
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
@ -5,30 +5,25 @@
|
|||||||
@input="search"
|
@input="search"
|
||||||
@clear="search">
|
@clear="search">
|
||||||
</search>
|
</search>
|
||||||
<div class="c-notebook__controls">
|
<div class="c-notebook__controls ">
|
||||||
<div class="select c-notebook__controls__time">
|
<select class="c-notebook__controls__time" v-model="showTime">
|
||||||
<select v-model="showTime">
|
<option value="0" selected="selected">Show all</option>
|
||||||
<option value="0" selected="selected">Show all</option>
|
<option value="1">Last hour</option>
|
||||||
<option value="1">Last hour</option>
|
<option value="8">Last 8 hours</option>
|
||||||
<option value="8">Last 8 hours</option>
|
<option value="24">Last 24 hours</option>
|
||||||
<option value="24">Last 24 hours</option>
|
</select>
|
||||||
</select>
|
<select class="c-notebook__controls__time" v-model="sortEntries">
|
||||||
</div>
|
<option value="newest" :selected="sortEntries === 'newest'">Newest first</option>
|
||||||
<div class="select c-notebook__controls__sort">
|
<option value="oldest" :selected="sortEntries === 'oldest'">Oldest first</option>
|
||||||
<select v-model="sortEntries">
|
</select>
|
||||||
<option value="newest" :selected="sortEntries === 'newest'">Newest first</option>
|
|
||||||
<option value="oldest" :selected="sortEntries === 'oldest'">Oldest first</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="c-notebook__drag-area icon-plus"
|
<div class="c-notebook__drag-area icon-plus"
|
||||||
@click="newEntry($event)"
|
@click="newEntry($event)"
|
||||||
@drop="newEntry($event)"
|
@drop="newEntry($event)">
|
||||||
id="newEntry">
|
|
||||||
<span class="c-notebook__drag-area__label">To start a new entry, click here or drag and drop any object</span>
|
<span class="c-notebook__drag-area__label">To start a new entry, click here or drag and drop any object</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="c-notebook__entries" ng-mouseover="handleActive()">
|
<div class="c-notebook__entries">
|
||||||
<ul>
|
<ul>
|
||||||
<notebook-entry
|
<notebook-entry
|
||||||
v-for="(entry,index) in filteredAndSortedEntries"
|
v-for="(entry,index) in filteredAndSortedEntries"
|
||||||
|
@ -34,28 +34,17 @@ function (
|
|||||||
Vue,
|
Vue,
|
||||||
Painterro
|
Painterro
|
||||||
) {
|
) {
|
||||||
function EmbedController (openmct, domainObject) {
|
function EmbedController(openmct, domainObject) {
|
||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
this.domainObject = domainObject;
|
this.domainObject = domainObject;
|
||||||
this.objectService = openmct.$injector.get('objectService');
|
|
||||||
this.navigationService = openmct.$injector.get('navigationService');
|
|
||||||
this.popupService = openmct.$injector.get('popupService');
|
this.popupService = openmct.$injector.get('popupService');
|
||||||
this.agentService = openmct.$injector.get('agentService');
|
this.agentService = openmct.$injector.get('agentService');
|
||||||
this.dialogService = openmct.$injector.get('dialogService');
|
|
||||||
|
|
||||||
|
|
||||||
this.navigate = this.navigate.bind(this);
|
|
||||||
this.exposedData = this.exposedData.bind(this);
|
this.exposedData = this.exposedData.bind(this);
|
||||||
this.exposedMethods = this.exposedMethods.bind(this);
|
this.exposedMethods = this.exposedMethods.bind(this);
|
||||||
this.toggleActionMenu = this.toggleActionMenu.bind(this);
|
this.toggleActionMenu = this.toggleActionMenu.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
EmbedController.prototype.navigate = function (embedType) {
|
|
||||||
this.objectService.getObjects([embedType]).then(function (objects) {
|
|
||||||
this.navigationService.setNavigation(objects[embedType]);
|
|
||||||
}.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
EmbedController.prototype.openSnapshot = function (domainObject, entry, embed) {
|
EmbedController.prototype.openSnapshot = function (domainObject, entry, embed) {
|
||||||
|
|
||||||
function annotateSnapshot(openmct) {
|
function annotateSnapshot(openmct) {
|
||||||
@ -63,20 +52,22 @@ function (
|
|||||||
|
|
||||||
var save = false,
|
var save = false,
|
||||||
painterroInstance = {},
|
painterroInstance = {},
|
||||||
annotateOverlay = new Vue({
|
annotateVue = new Vue({
|
||||||
template: '<div id="snap-annotation"></div>'
|
template: '<div id="snap-annotation"></div>'
|
||||||
}),
|
}),
|
||||||
self = this;
|
self = this;
|
||||||
|
|
||||||
openmct.overlays.overlay({
|
let annotateOverlay = openmct.overlays.overlay({
|
||||||
element: annotateOverlay.$mount().$el,
|
element: annotateVue.$mount().$el,
|
||||||
size: 'large',
|
size: 'large',
|
||||||
|
dismissable: false,
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
label: 'Cancel',
|
label: 'Cancel',
|
||||||
callback: function () {
|
callback: function () {
|
||||||
save = false;
|
save = false;
|
||||||
painterroInstance.save();
|
painterroInstance.save();
|
||||||
|
annotateOverlay.dismiss();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -84,11 +75,12 @@ function (
|
|||||||
callback: function () {
|
callback: function () {
|
||||||
save = true;
|
save = true;
|
||||||
painterroInstance.save();
|
painterroInstance.save();
|
||||||
|
annotateOverlay.dismiss();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
onDestroy: function () {
|
onDestroy: function () {
|
||||||
annotateOverlay.$destroy(true);
|
annotateVue.$destroy(true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -162,14 +154,11 @@ function (
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function onDestroyCallback() {
|
|
||||||
snapshot.$destroy(true);
|
|
||||||
}
|
|
||||||
|
|
||||||
var snapshotOverlay = this.openmct.overlays.overlay({
|
var snapshotOverlay = this.openmct.overlays.overlay({
|
||||||
element: snapshot.$mount().$el,
|
element: snapshot.$mount().$el,
|
||||||
onDestroy: onDestroyCallback,
|
onDestroy: () => {snapshot.$destroy(true)},
|
||||||
size: 'large',
|
size: 'large',
|
||||||
|
dismissable: true,
|
||||||
buttons: [
|
buttons: [
|
||||||
{
|
{
|
||||||
label: 'Done',
|
label: 'Done',
|
||||||
@ -199,23 +188,20 @@ function (
|
|||||||
return foundId;
|
return foundId;
|
||||||
};
|
};
|
||||||
|
|
||||||
EmbedController.prototype.actionToMenuDecorator = function (action) {
|
EmbedController.prototype.populateActionMenu = function (openmct, actions) {
|
||||||
return {
|
|
||||||
name: action.getMetadata().name,
|
|
||||||
cssClass: action.getMetadata().cssClass,
|
|
||||||
perform: action.perform
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
EmbedController.prototype.populateActionMenu = function (objectService, actionService) {
|
|
||||||
return function () {
|
return function () {
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
objectService.getObjects([self.embed.type]).then(function (resp) {
|
openmct.objects.get(self.embed.type).then(function (domainObject) {
|
||||||
var domainObject = resp[self.embed.type],
|
actions.forEach((action) => {
|
||||||
previewAction = actionService.getActions({key: 'mct-preview-action', domainObject: domainObject})[0];
|
self.actions.push({
|
||||||
|
cssClass: action.cssClass,
|
||||||
self.actions.push(self.actionToMenuDecorator(previewAction));
|
name: action.name,
|
||||||
|
perform: () => {
|
||||||
|
action.invoke([domainObject].concat(openmct.router.path));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -268,13 +254,14 @@ function (
|
|||||||
// Remove the context menu
|
// Remove the context menu
|
||||||
function dismiss() {
|
function dismiss() {
|
||||||
container.find('.hide-menu').append(menu);
|
container.find('.hide-menu').append(menu);
|
||||||
body.off(initiatingEvent, dismiss);
|
body.off(initiatingEvent, menuClickHandler);
|
||||||
menu.off(initiatingEvent, menuClickHandler);
|
|
||||||
dismissExistingMenu = undefined;
|
dismissExistingMenu = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function menuClickHandler(e) {
|
function menuClickHandler(e) {
|
||||||
e.stopPropagation();
|
window.setTimeout(() => {
|
||||||
|
dismiss();
|
||||||
|
}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dismiss any menu which was already showing
|
// Dismiss any menu which was already showing
|
||||||
@ -290,11 +277,7 @@ function (
|
|||||||
marginY: -50
|
marginY: -50
|
||||||
});
|
});
|
||||||
|
|
||||||
// Stop propagation so that clicks or touches on the menu do not close the menu
|
body.on(initiatingEvent, menuClickHandler);
|
||||||
menu.on(initiatingEvent, menuClickHandler);
|
|
||||||
|
|
||||||
body.on(initiatingEvent, dismiss);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
EmbedController.prototype.exposedData = function () {
|
EmbedController.prototype.exposedData = function () {
|
||||||
@ -308,11 +291,9 @@ function (
|
|||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
return {
|
return {
|
||||||
navigate: self.navigate,
|
|
||||||
openSnapshot: self.openSnapshot,
|
openSnapshot: self.openSnapshot,
|
||||||
formatTime: self.formatTime,
|
formatTime: self.formatTime,
|
||||||
toggleActionMenu: self.toggleActionMenu,
|
toggleActionMenu: self.toggleActionMenu,
|
||||||
actionToMenuDecorator: self.actionToMenuDecorator,
|
|
||||||
findInArray: self.findInArray
|
findInArray: self.findInArray
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
@ -30,8 +30,6 @@ function (
|
|||||||
function EntryController (openmct, domainObject) {
|
function EntryController (openmct, domainObject) {
|
||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
this.domainObject = domainObject;
|
this.domainObject = domainObject;
|
||||||
this.dndService = this.openmct.$injector.get('dndService');
|
|
||||||
this.dialogService = this.openmct.$injector.get('dialogService');
|
|
||||||
|
|
||||||
this.currentEntryValue = '';
|
this.currentEntryValue = '';
|
||||||
|
|
||||||
@ -106,37 +104,35 @@ function (
|
|||||||
};
|
};
|
||||||
|
|
||||||
EntryController.prototype.dropOnEntry = function (entryid, event) {
|
EntryController.prototype.dropOnEntry = function (entryid, event) {
|
||||||
|
var data = event.dataTransfer.getData('openmct/domain-object-path');
|
||||||
var data = event.dataTransfer.getData('domainObject');
|
|
||||||
|
|
||||||
if (data) {
|
if (data) {
|
||||||
var selectedObject = JSON.parse(data),
|
var objectPath = JSON.parse(data),
|
||||||
selectedObjectId = selectedObject.identifier.key,
|
domainObject = objectPath[0],
|
||||||
cssClass = this.openmct.types.get(selectedObject.type),
|
domainObjectKey = domainObject.identifier.key,
|
||||||
|
domainObjectType = this.openmct.types.get(domainObject.type),
|
||||||
|
cssClass = domainObjectType && domainObjectType.definition ?
|
||||||
|
domainObjectType.definition.cssClass : 'icon-object-unknown',
|
||||||
entryPos = this.entryPosById(entryid),
|
entryPos = this.entryPosById(entryid),
|
||||||
currentEntryEmbeds = this.domainObject.entries[entryPos].embeds,
|
currentEntryEmbeds = this.domainObject.entries[entryPos].embeds,
|
||||||
newEmbed = {
|
newEmbed = {
|
||||||
type: selectedObjectId,
|
|
||||||
id: '' + Date.now(),
|
id: '' + Date.now(),
|
||||||
|
domainObject: domainObject,
|
||||||
|
objectPath: objectPath,
|
||||||
|
type: domainObjectKey,
|
||||||
cssClass: cssClass,
|
cssClass: cssClass,
|
||||||
name: selectedObject.name,
|
name: domainObject.name,
|
||||||
snapshot: ''
|
snapshot: ''
|
||||||
};
|
};
|
||||||
|
|
||||||
currentEntryEmbeds.push(newEmbed);
|
currentEntryEmbeds.push(newEmbed);
|
||||||
this.openmct.objects.mutate(this.domainObject, 'entries[' + entryPos + '].embeds', currentEntryEmbeds);
|
this.openmct.objects.mutate(this.domainObject, 'entries[' + entryPos + '].embeds', currentEntryEmbeds);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
EntryController.prototype.dragoverOnEntry = function () {
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
EntryController.prototype.exposedData = function () {
|
EntryController.prototype.exposedData = function () {
|
||||||
return {
|
return {
|
||||||
openmct: this.openmct,
|
openmct: this.openmct,
|
||||||
domainObject: this.domainObject,
|
domainObject: this.domainObject,
|
||||||
dialogService: this.dialogService,
|
|
||||||
currentEntryValue: this.currentEntryValue
|
currentEntryValue: this.currentEntryValue
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
@ -148,8 +144,7 @@ function (
|
|||||||
textBlur: this.textBlur,
|
textBlur: this.textBlur,
|
||||||
formatTime: this.formatTime,
|
formatTime: this.formatTime,
|
||||||
deleteEntry: this.deleteEntry,
|
deleteEntry: this.deleteEntry,
|
||||||
dropOnEntry: this.dropOnEntry,
|
dropOnEntry: this.dropOnEntry
|
||||||
dragoverOnEntry: this.dragoverOnEntry
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
return EntryController;
|
return EntryController;
|
||||||
|
@ -27,7 +27,9 @@ define([
|
|||||||
'../../res/templates/notebook.html',
|
'../../res/templates/notebook.html',
|
||||||
'../../res/templates/entry.html',
|
'../../res/templates/entry.html',
|
||||||
'../../res/templates/embed.html',
|
'../../res/templates/embed.html',
|
||||||
'../../../../ui/components/search.vue'
|
'../../../../ui/components/search.vue',
|
||||||
|
'../../../../ui/preview/PreviewAction',
|
||||||
|
'../../../../ui/mixins/object-link'
|
||||||
],
|
],
|
||||||
function (
|
function (
|
||||||
Vue,
|
Vue,
|
||||||
@ -36,15 +38,16 @@ function (
|
|||||||
NotebookTemplate,
|
NotebookTemplate,
|
||||||
EntryTemplate,
|
EntryTemplate,
|
||||||
EmbedTemplate,
|
EmbedTemplate,
|
||||||
search
|
search,
|
||||||
|
PreviewAction,
|
||||||
|
objectLinkMixin
|
||||||
) {
|
) {
|
||||||
|
|
||||||
function NotebookController(openmct, domainObject) {
|
function NotebookController(openmct, domainObject) {
|
||||||
this.openmct = openmct;
|
this.openmct = openmct;
|
||||||
this.domainObject = domainObject;
|
this.domainObject = domainObject;
|
||||||
this.entrySearch = '';
|
this.entrySearch = '';
|
||||||
this.objectService = openmct.$injector.get('objectService');
|
this.previewAction = new PreviewAction.default(openmct);
|
||||||
this.actionService = openmct.$injector.get('actionService');
|
|
||||||
|
|
||||||
this.show = this.show.bind(this);
|
this.show = this.show.bind(this);
|
||||||
this.destroy = this.destroy.bind(this);
|
this.destroy = this.destroy.bind(this);
|
||||||
@ -61,11 +64,12 @@ function (
|
|||||||
|
|
||||||
var notebookEmbed = {
|
var notebookEmbed = {
|
||||||
inject:['openmct', 'domainObject'],
|
inject:['openmct', 'domainObject'],
|
||||||
|
mixins:[objectLinkMixin.default],
|
||||||
props:['embed', 'entry'],
|
props:['embed', 'entry'],
|
||||||
template: EmbedTemplate,
|
template: EmbedTemplate,
|
||||||
data: embedController.exposedData,
|
data: embedController.exposedData,
|
||||||
methods: embedController.exposedMethods(),
|
methods: embedController.exposedMethods(),
|
||||||
beforeMount: embedController.populateActionMenu(self.objectService, self.actionService)
|
beforeMount: embedController.populateActionMenu(self.openmct, [self.previewAction])
|
||||||
};
|
};
|
||||||
|
|
||||||
var entryComponent = {
|
var entryComponent = {
|
||||||
@ -120,8 +124,8 @@ function (
|
|||||||
var date = Date.now(),
|
var date = Date.now(),
|
||||||
embed;
|
embed;
|
||||||
|
|
||||||
if (event.dataTransfer && event.dataTransfer.getData('domainObject')) {
|
if (event.dataTransfer && event.dataTransfer.getData('openmct/domain-object-path')) {
|
||||||
var selectedObject = JSON.parse(event.dataTransfer.getData('domainObject')),
|
var selectedObject = JSON.parse(event.dataTransfer.getData('openmct/domain-object-path'))[0],
|
||||||
selectedObjectId = selectedObject.identifier.key,
|
selectedObjectId = selectedObject.identifier.key,
|
||||||
cssClass = this.openmct.types.get(selectedObject.type);
|
cssClass = this.openmct.types.get(selectedObject.type);
|
||||||
|
|
||||||
|
@ -41,28 +41,24 @@
|
|||||||
<div class="grid-cell label"
|
<div class="grid-cell label"
|
||||||
title="The field to be plotted as a value for this series.">Value</div>
|
title="The field to be plotted as a value for this series.">Value</div>
|
||||||
<div class="grid-cell value">
|
<div class="grid-cell value">
|
||||||
<div class="select">
|
<select ng-model="form.yKey">
|
||||||
<select ng-model="form.yKey">
|
<option ng-repeat="option in yKeyOptions"
|
||||||
<option ng-repeat="option in yKeyOptions"
|
value="{{option.value}}"
|
||||||
value="{{option.value}}"
|
ng-selected="option.value == form.yKey">
|
||||||
ng-selected="option.value == form.yKey">
|
{{option.name}}
|
||||||
{{option.name}}
|
</option>
|
||||||
</option>
|
</select>
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="grid-row">
|
<li class="grid-row">
|
||||||
<div class="grid-cell label"
|
<div class="grid-cell label"
|
||||||
title="The line rendering style for this series.">Line Style</div>
|
title="The line rendering style for this series.">Line Style</div>
|
||||||
<div class="grid-cell value">
|
<div class="grid-cell value">
|
||||||
<div class="select">
|
<select ng-model="form.interpolate">
|
||||||
<select ng-model="form.interpolate">
|
<option value="none">None</option>
|
||||||
<option value="none">None</option>
|
<option value="linear">Linear interpolate</option>
|
||||||
<option value="linear">Linear interpolate</option>
|
<option value="stepAfter">Step after</option>
|
||||||
<option value="stepAfter">Step after</option>
|
</select>
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="grid-row">
|
<li class="grid-row">
|
||||||
@ -160,15 +156,13 @@
|
|||||||
<div class="grid-cell label"
|
<div class="grid-cell label"
|
||||||
title="The position of the legend relative to the plot display area.">Position</div>
|
title="The position of the legend relative to the plot display area.">Position</div>
|
||||||
<div class="grid-cell value">
|
<div class="grid-cell value">
|
||||||
<div class="select">
|
<select ng-model="form.position">
|
||||||
<select ng-model="form.position">
|
<option value="hidden">Hidden</option>
|
||||||
<option value="hidden">Hidden</option>
|
<option value="top">Top</option>
|
||||||
<option value="top">Top</option>
|
<option value="right">Right</option>
|
||||||
<option value="right">Right</option>
|
<option value="bottom">Bottom</option>
|
||||||
<option value="bottom">Bottom</option>
|
<option value="left">Left</option>
|
||||||
<option value="left">Left</option>
|
</select>
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="grid-row">
|
<li class="grid-row">
|
||||||
@ -180,15 +174,13 @@
|
|||||||
<div class="grid-cell label"
|
<div class="grid-cell label"
|
||||||
title="What to display in the legend when it's collapsed.">When collapsed show</div>
|
title="What to display in the legend when it's collapsed.">When collapsed show</div>
|
||||||
<div class="grid-cell value">
|
<div class="grid-cell value">
|
||||||
<div class="select">
|
<select ng-model="form.valueToShowWhenCollapsed">
|
||||||
<select ng-model="form.valueToShowWhenCollapsed">
|
<option value="none">Nothing</option>
|
||||||
<option value="none">nothing</option>
|
<option value="nearestTimestamp">Nearest timestamp</option>
|
||||||
<option value="nearestTimestamp">nearest timestamp</option>
|
<option value="nearestValue">Nearest value</option>
|
||||||
<option value="nearestValue">nearest Value</option>
|
<option value="min">Minimum value</option>
|
||||||
<option value="min">minimum value</option>
|
<option value="max">Maximum value</option>
|
||||||
<option value="max">maximum value</option>
|
</select>
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
<li class="grid-row">
|
<li class="grid-row">
|
||||||
|
@ -30,7 +30,7 @@ define(
|
|||||||
],
|
],
|
||||||
function (
|
function (
|
||||||
html2canvas,
|
html2canvas,
|
||||||
saveAs
|
{ saveAs }
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,9 +39,7 @@ define([
|
|||||||
'./folderView/plugin',
|
'./folderView/plugin',
|
||||||
'./flexibleLayout/plugin',
|
'./flexibleLayout/plugin',
|
||||||
'./tabs/plugin',
|
'./tabs/plugin',
|
||||||
'../../platform/features/fixed/plugin',
|
'./LADTable/plugin'
|
||||||
'./LADTable/plugin',
|
|
||||||
'./preview/plugin'
|
|
||||||
], function (
|
], function (
|
||||||
_,
|
_,
|
||||||
UTCTimeSystem,
|
UTCTimeSystem,
|
||||||
@ -61,9 +59,7 @@ define([
|
|||||||
FolderView,
|
FolderView,
|
||||||
FlexibleLayout,
|
FlexibleLayout,
|
||||||
Tabs,
|
Tabs,
|
||||||
FixedView,
|
LADTable
|
||||||
LADTable,
|
|
||||||
PreviewPlugin
|
|
||||||
) {
|
) {
|
||||||
var bundleMap = {
|
var bundleMap = {
|
||||||
LocalStorage: 'platform/persistence/local',
|
LocalStorage: 'platform/persistence/local',
|
||||||
@ -176,10 +172,8 @@ define([
|
|||||||
plugins.DisplayLayout = DisplayLayoutPlugin.default;
|
plugins.DisplayLayout = DisplayLayoutPlugin.default;
|
||||||
plugins.FolderView = FolderView;
|
plugins.FolderView = FolderView;
|
||||||
plugins.Tabs = Tabs;
|
plugins.Tabs = Tabs;
|
||||||
plugins.FixedView = FixedView;
|
|
||||||
plugins.FlexibleLayout = FlexibleLayout;
|
plugins.FlexibleLayout = FlexibleLayout;
|
||||||
plugins.LADTable = LADTable;
|
plugins.LADTable = LADTable;
|
||||||
plugins.Preview = PreviewPlugin.default;
|
|
||||||
|
|
||||||
return plugins;
|
return plugins;
|
||||||
});
|
});
|
||||||
|
@ -15,25 +15,25 @@
|
|||||||
v-for="(tab,index) in tabsList"
|
v-for="(tab,index) in tabsList"
|
||||||
:key="index"
|
:key="index"
|
||||||
:class="[
|
:class="[
|
||||||
{'is-current': tab=== currentTab},
|
{'is-current': isCurrent(tab)},
|
||||||
tab.type.definition.cssClass
|
tab.type.definition.cssClass
|
||||||
]"
|
]"
|
||||||
@click="showTab(tab)">
|
@click="showTab(tab)">
|
||||||
<span class="c-button__label">{{tab.model.name}}</span>
|
<span class="c-button__label">{{tab.domainObject.name}}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="c-tabs-view__object-holder"
|
<div class="c-tabs-view__object-holder"
|
||||||
v-for="(object, index) in tabsList"
|
v-for="(tab, index) in tabsList"
|
||||||
:key="index"
|
:key="index"
|
||||||
:class="{'invisible': object !== currentTab}">
|
:class="{'invisible': !isCurrent(tab)}">
|
||||||
<div class="c-tabs-view__object-name l-browse-bar__object-name--w"
|
<div class="c-tabs-view__object-name l-browse-bar__object-name--w"
|
||||||
:class="currentTab.type.definition.cssClass">
|
:class="currentTab.type.definition.cssClass">
|
||||||
<div class="l-browse-bar__object-name">
|
<div class="l-browse-bar__object-name">
|
||||||
{{currentTab.model.name}}
|
{{currentTab.domainObject.name}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<object-view class="c-tabs-view__object"
|
<object-view class="c-tabs-view__object"
|
||||||
:object="object.model">
|
:object="tab.domainObject">
|
||||||
</object-view>
|
</object-view>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -87,6 +87,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import ObjectView from '../../../ui/components/ObjectView.vue';
|
import ObjectView from '../../../ui/components/ObjectView.vue';
|
||||||
|
import _ from 'lodash';
|
||||||
|
|
||||||
var unknownObjectType = {
|
var unknownObjectType = {
|
||||||
definition: {
|
definition: {
|
||||||
@ -100,9 +101,71 @@ export default {
|
|||||||
components: {
|
components: {
|
||||||
ObjectView
|
ObjectView
|
||||||
},
|
},
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
currentTab: {},
|
||||||
|
tabsList: [],
|
||||||
|
setCurrentTab: true,
|
||||||
|
isDragging: false,
|
||||||
|
allowDrop: false
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
showTab(tab) {
|
||||||
|
this.currentTab = tab;
|
||||||
|
},
|
||||||
|
addItem(domainObject) {
|
||||||
|
let type = this.openmct.types.get(domainObject.type) || unknownObjectType,
|
||||||
|
tabItem = {
|
||||||
|
domainObject,
|
||||||
|
type: type
|
||||||
|
};
|
||||||
|
|
||||||
|
this.tabsList.push(tabItem);
|
||||||
|
|
||||||
|
if (this.setCurrentTab) {
|
||||||
|
this.currentTab = tabItem;
|
||||||
|
this.setCurrentTab = false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
removeItem(identifier) {
|
||||||
|
let pos = this.tabsList.findIndex(tab =>
|
||||||
|
tab.domainObject.identifier.namespace === identifier.namespace && tab.domainObject.identifier.key === identifier.key
|
||||||
|
),
|
||||||
|
tabToBeRemoved = this.tabsList[pos];
|
||||||
|
|
||||||
|
this.tabsList.splice(pos, 1);
|
||||||
|
|
||||||
|
if (this.isCurrent(tabToBeRemoved)) {
|
||||||
|
this.showTab(this.tabsList[this.tabsList.length - 1]);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onDrop(e) {
|
||||||
|
this.setCurrentTab = true;
|
||||||
|
},
|
||||||
|
dragstart (e) {
|
||||||
|
if (e.dataTransfer.types.includes('openmct/domain-object-path')) {
|
||||||
|
this.isDragging = true;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
dragend(e) {
|
||||||
|
this.isDragging = false;
|
||||||
|
this.allowDrop = false;
|
||||||
|
},
|
||||||
|
dragenter() {
|
||||||
|
this.allowDrop = true;
|
||||||
|
},
|
||||||
|
dragleave() {
|
||||||
|
this.allowDrop = false;
|
||||||
|
},
|
||||||
|
isCurrent(tab) {
|
||||||
|
return _.isEqual(this.currentTab, tab)
|
||||||
|
}
|
||||||
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
if (this.composition) {
|
if (this.composition) {
|
||||||
this.composition.on('add', this.addItem, this);
|
this.composition.on('add', this.addItem);
|
||||||
|
this.composition.on('remove', this.removeItem);
|
||||||
this.composition.load();
|
this.composition.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,54 +179,9 @@ export default {
|
|||||||
dropHint.addEventListener('dragleave', this.dragleave);
|
dropHint.addEventListener('dragleave', this.dragleave);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data: function () {
|
|
||||||
return {
|
|
||||||
currentTab: {},
|
|
||||||
tabsList: [],
|
|
||||||
setCurrentTab: true,
|
|
||||||
isDragging: false,
|
|
||||||
allowDrop: false
|
|
||||||
};
|
|
||||||
},
|
|
||||||
methods:{
|
|
||||||
showTab (tab) {
|
|
||||||
this.currentTab = tab;
|
|
||||||
},
|
|
||||||
addItem (model) {
|
|
||||||
let type = this.openmct.types.get(model.type) || unknownObjectType,
|
|
||||||
tabItem = {
|
|
||||||
model,
|
|
||||||
type: type
|
|
||||||
};
|
|
||||||
|
|
||||||
this.tabsList.push(tabItem);
|
|
||||||
|
|
||||||
if (this.setCurrentTab) {
|
|
||||||
this.currentTab = tabItem;
|
|
||||||
this.setCurrentTab = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
onDrop (e) {
|
|
||||||
this.setCurrentTab = true;
|
|
||||||
},
|
|
||||||
dragstart (e) {
|
|
||||||
if (e.dataTransfer.getData('domainObject')) {
|
|
||||||
this.isDragging = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
dragend (e) {
|
|
||||||
this.isDragging = false;
|
|
||||||
this.allowDrop = false;
|
|
||||||
},
|
|
||||||
dragenter () {
|
|
||||||
this.allowDrop = true;
|
|
||||||
},
|
|
||||||
dragleave() {
|
|
||||||
this.allowDrop = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
destroyed() {
|
destroyed() {
|
||||||
this.composition.off('add', this.addItem, this);
|
this.composition.off('add', this.addItem);
|
||||||
|
this.composition.off('remove', this.removeItem);
|
||||||
|
|
||||||
document.removeEventListener('dragstart', this.dragstart);
|
document.removeEventListener('dragstart', this.dragstart);
|
||||||
document.removeEventListener('dragend', this.dragend);
|
document.removeEventListener('dragend', this.dragend);
|
||||||
|
@ -79,8 +79,8 @@ define([
|
|||||||
|
|
||||||
loadComposition() {
|
loadComposition() {
|
||||||
this.tableComposition = this.openmct.composition.get(this.domainObject);
|
this.tableComposition = this.openmct.composition.get(this.domainObject);
|
||||||
if (this.tableComposition !== undefined){
|
if (this.tableComposition !== undefined) {
|
||||||
this.tableComposition.load().then((composition)=>{
|
this.tableComposition.load().then((composition) => {
|
||||||
composition = composition.filter(this.isTelemetryObject);
|
composition = composition.filter(this.isTelemetryObject);
|
||||||
|
|
||||||
this.configuration.addColumnsForAllObjects(composition);
|
this.configuration.addColumnsForAllObjects(composition);
|
||||||
@ -122,7 +122,6 @@ define([
|
|||||||
|
|
||||||
let telemetryRows = telemetryData.map(datum => new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator));
|
let telemetryRows = telemetryData.map(datum => new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator));
|
||||||
this.boundedRows.add(telemetryRows);
|
this.boundedRows.add(telemetryRows);
|
||||||
console.log('Loaded %i rows', telemetryRows.length);
|
|
||||||
this.decrementOutstandingRequests();
|
this.decrementOutstandingRequests();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -131,7 +130,7 @@ define([
|
|||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
incrementOutstandingRequests() {
|
incrementOutstandingRequests() {
|
||||||
if (this.outstandingRequests === 0){
|
if (this.outstandingRequests === 0) {
|
||||||
this.emit('outstanding-requests', true);
|
this.emit('outstanding-requests', true);
|
||||||
}
|
}
|
||||||
this.outstandingRequests++;
|
this.outstandingRequests++;
|
||||||
@ -143,7 +142,7 @@ define([
|
|||||||
decrementOutstandingRequests() {
|
decrementOutstandingRequests() {
|
||||||
this.outstandingRequests--;
|
this.outstandingRequests--;
|
||||||
|
|
||||||
if (this.outstandingRequests === 0){
|
if (this.outstandingRequests === 0) {
|
||||||
this.emit('outstanding-requests', false);
|
this.emit('outstanding-requests', false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,7 @@ define([
|
|||||||
objectMutated(object) {
|
objectMutated(object) {
|
||||||
//Synchronize domain object reference. Duplicate object otherwise change detection becomes impossible.
|
//Synchronize domain object reference. Duplicate object otherwise change detection becomes impossible.
|
||||||
this.domainObject = object;
|
this.domainObject = object;
|
||||||
|
//Was it the configuration that changed?
|
||||||
if (!_.eq(object.configuration, this.oldConfiguration)) {
|
if (!_.eq(object.configuration, this.oldConfiguration)) {
|
||||||
//Make copy of configuration, otherwise change detection is impossible if shared instance is being modified.
|
//Make copy of configuration, otherwise change detection is impossible if shared instance is being modified.
|
||||||
this.oldConfiguration = JSON.parse(JSON.stringify(this.getConfiguration()));
|
this.oldConfiguration = JSON.parse(JSON.stringify(this.getConfiguration()));
|
||||||
@ -91,16 +92,19 @@ define([
|
|||||||
let columnsToRemove = this.columns[objectKeyString];
|
let columnsToRemove = this.columns[objectKeyString];
|
||||||
|
|
||||||
delete this.columns[objectKeyString];
|
delete this.columns[objectKeyString];
|
||||||
|
|
||||||
|
let configuration = this.domainObject.configuration;
|
||||||
|
let configurationChanged = false;
|
||||||
columnsToRemove.forEach((column) => {
|
columnsToRemove.forEach((column) => {
|
||||||
//There may be more than one column with the same key (eg. time system columns)
|
//There may be more than one column with the same key (eg. time system columns)
|
||||||
if (!this.hasColumnWithKey(column.getKey())) {
|
if (!this.hasColumnWithKey(column.getKey())) {
|
||||||
let configuration = this.domainObject.configuration;
|
|
||||||
delete configuration.hiddenColumns[column.getKey()];
|
delete configuration.hiddenColumns[column.getKey()];
|
||||||
// If there are no more columns with this key, delete any configuration, and trigger
|
configurationChanged = true;
|
||||||
// a column refresh.
|
|
||||||
this.openmct.objects.mutate(this.domainObject, 'configuration', configuration);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
if (configurationChanged) {
|
||||||
|
this.updateConfiguration(configuration);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hasColumnWithKey(columnKey) {
|
hasColumnWithKey(columnKey) {
|
||||||
|
@ -34,7 +34,7 @@
|
|||||||
<div class="c-telemetry-table__headers-w js-table__headers-w" ref="headersTable" :style="{ 'max-width': widthWithScroll}">
|
<div class="c-telemetry-table__headers-w js-table__headers-w" ref="headersTable" :style="{ 'max-width': widthWithScroll}">
|
||||||
<table class="c-table__headers c-telemetry-table__headers">
|
<table class="c-table__headers c-telemetry-table__headers">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr class="c-telemetry-table__headers__name">
|
||||||
<table-column-header
|
<table-column-header
|
||||||
v-for="(title, key, headerIndex) in headers"
|
v-for="(title, key, headerIndex) in headers"
|
||||||
:key="key"
|
:key="key"
|
||||||
@ -50,7 +50,7 @@
|
|||||||
:sortOptions="sortOptions"
|
:sortOptions="sortOptions"
|
||||||
>{{title}}</table-column-header>
|
>{{title}}</table-column-header>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr class="c-telemetry-table__headers__filter">
|
||||||
<table-column-header
|
<table-column-header
|
||||||
v-for="(title, key, headerIndex) in headers"
|
v-for="(title, key, headerIndex) in headers"
|
||||||
:key="key"
|
:key="key"
|
||||||
@ -110,8 +110,8 @@
|
|||||||
.c-telemetry-table__drop-target {
|
.c-telemetry-table__drop-target {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 2px;
|
width: 2px;
|
||||||
background-color: $editColor;
|
background-color: $editUIColor;
|
||||||
box-shadow: rgba($editColor, 0.5) 0 0 10px;
|
box-shadow: rgba($editUIColor, 0.5) 0 0 10px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
@ -214,6 +214,22 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/******************************* EDITING */
|
||||||
|
.is-editing {
|
||||||
|
.c-telemetry-table__headers__name {
|
||||||
|
th[draggable],
|
||||||
|
th[draggable] > * {
|
||||||
|
cursor: move;
|
||||||
|
}
|
||||||
|
|
||||||
|
th[draggable]:hover {
|
||||||
|
$b: $editFrameHovMovebarColorBg;
|
||||||
|
background: $b;
|
||||||
|
> * { background: $b; }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/******************************* LEGACY */
|
/******************************* LEGACY */
|
||||||
.s-status-taking-snapshot,
|
.s-status-taking-snapshot,
|
||||||
.overlay.snapshot {
|
.overlay.snapshot {
|
||||||
|
@ -22,9 +22,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="c-conductor"
|
<div class="c-conductor"
|
||||||
:class="[isFixed ? 'is-fixed-mode' : 'is-realtime-mode']">
|
:class="[isFixed ? 'is-fixed-mode' : 'is-realtime-mode']">
|
||||||
<form class="u-contents" ref="conductorForm"
|
<form class="u-contents" ref="conductorForm" @submit.prevent="updateTimeFromConductor">
|
||||||
@submit="isFixed ? setBoundsFromView($event) : setOffsetsFromView($event)">
|
<button class="c-input--submit" type="submit" ref="submitButton"></button>
|
||||||
|
|
||||||
<ConductorModeIcon class="c-conductor__mode-icon"></ConductorModeIcon>
|
<ConductorModeIcon class="c-conductor__mode-icon"></ConductorModeIcon>
|
||||||
|
|
||||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__start-fixed"
|
<div class="c-ctrl-wrapper c-conductor-input c-conductor__start-fixed"
|
||||||
@ -35,7 +34,7 @@
|
|||||||
type="text" autocorrect="off" spellcheck="false"
|
type="text" autocorrect="off" spellcheck="false"
|
||||||
ref="startDate"
|
ref="startDate"
|
||||||
v-model="formattedBounds.start"
|
v-model="formattedBounds.start"
|
||||||
@change="validateBounds('start', $event.target); setBoundsFromView()" />
|
@change="validateAllBounds(); submitForm()" />
|
||||||
<date-picker
|
<date-picker
|
||||||
:default-date-time="formattedBounds.start"
|
:default-date-time="formattedBounds.start"
|
||||||
:formatter="timeFormatter"
|
:formatter="timeFormatter"
|
||||||
@ -48,9 +47,10 @@
|
|||||||
<div class="c-direction-indicator icon-minus"></div>
|
<div class="c-direction-indicator icon-minus"></div>
|
||||||
<input class="c-input--hrs-min-sec"
|
<input class="c-input--hrs-min-sec"
|
||||||
type="text" autocorrect="off"
|
type="text" autocorrect="off"
|
||||||
|
ref="startOffset"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
v-model="offsets.start"
|
v-model="offsets.start"
|
||||||
@change="validateOffsets($event); setOffsetsFromView()">
|
@change="validateAllOffsets(); submitForm()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__end-fixed">
|
<div class="c-ctrl-wrapper c-conductor-input c-conductor__end-fixed">
|
||||||
@ -63,7 +63,7 @@
|
|||||||
v-model="formattedBounds.end"
|
v-model="formattedBounds.end"
|
||||||
:disabled="!isFixed"
|
:disabled="!isFixed"
|
||||||
ref="endDate"
|
ref="endDate"
|
||||||
@change="validateBounds('end', $event.target); setBoundsFromView()">
|
@change="validateAllBounds(); submitForm()">
|
||||||
<date-picker
|
<date-picker
|
||||||
class="c-ctrl-wrapper--menus-left"
|
class="c-ctrl-wrapper--menus-left"
|
||||||
:default-date-time="formattedBounds.end"
|
:default-date-time="formattedBounds.end"
|
||||||
@ -80,8 +80,9 @@
|
|||||||
type="text"
|
type="text"
|
||||||
autocorrect="off"
|
autocorrect="off"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
|
ref="endOffset"
|
||||||
v-model="offsets.end"
|
v-model="offsets.end"
|
||||||
@change="validateOffsets($event); setOffsetsFromView()">
|
@change="validateAllOffsets(); submitForm()">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<conductor-axis
|
<conductor-axis
|
||||||
@ -101,6 +102,14 @@
|
|||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@import "~styles/sass-base";
|
@import "~styles/sass-base";
|
||||||
|
|
||||||
|
.c-input--submit {
|
||||||
|
// Can't use display: none because some browsers will pretend the input doesn't exist, and enter won't work
|
||||||
|
visibility: none;
|
||||||
|
height: 0;
|
||||||
|
width: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*********************************************** CONDUCTOR LAYOUT */
|
/*********************************************** CONDUCTOR LAYOUT */
|
||||||
.c-conductor {
|
.c-conductor {
|
||||||
display: grid;
|
display: grid;
|
||||||
@ -357,6 +366,7 @@ export default {
|
|||||||
},
|
},
|
||||||
setViewFromClock(clock) {
|
setViewFromClock(clock) {
|
||||||
this.isFixed = clock === undefined;
|
this.isFixed = clock === undefined;
|
||||||
|
this.clearAllValidation();
|
||||||
},
|
},
|
||||||
setViewFromBounds(bounds) {
|
setViewFromBounds(bounds) {
|
||||||
this.formattedBounds.start = this.timeFormatter.format(bounds.start);
|
this.formattedBounds.start = this.timeFormatter.format(bounds.start);
|
||||||
@ -368,45 +378,87 @@ export default {
|
|||||||
this.offsets.start = this.durationFormatter.format(Math.abs(offsets.start));
|
this.offsets.start = this.durationFormatter.format(Math.abs(offsets.start));
|
||||||
this.offsets.end = this.durationFormatter.format(Math.abs(offsets.end));
|
this.offsets.end = this.durationFormatter.format(Math.abs(offsets.end));
|
||||||
},
|
},
|
||||||
validateBounds(startOrEnd, input) {
|
updateTimeFromConductor() {
|
||||||
let validationResult = true;
|
if (this.isFixed) {
|
||||||
|
this.setBoundsFromView();
|
||||||
if (!this.timeFormatter.validate(input.value)){
|
|
||||||
validationResult = 'Invalid date value';
|
|
||||||
} else {
|
} else {
|
||||||
let boundsValues = {
|
this.setOffsetsFromView();
|
||||||
start: this.timeFormatter.parse(this.formattedBounds.start),
|
|
||||||
end: this.timeFormatter.parse(this.formattedBounds.end)
|
|
||||||
};
|
|
||||||
validationResult = this.openmct.time.validateBounds(boundsValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validationResult !== true){
|
|
||||||
input.setCustomValidity(validationResult);
|
|
||||||
} else {
|
|
||||||
input.setCustomValidity('');
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
validateOffsets(event) {
|
clearAllValidation() {
|
||||||
let input = event.target;
|
[this.$refs.startDate, this.$refs.endDate, this.$refs.startOffset, this.$refs.endOffset].forEach((input) => {
|
||||||
let validationResult = true;
|
|
||||||
|
|
||||||
if (!this.durationFormatter.validate(input.value)) {
|
|
||||||
validationResult = 'Invalid offset value';
|
|
||||||
} else {
|
|
||||||
let offsetValues = {
|
|
||||||
start: 0 - this.durationFormatter.parse(this.offsets.start),
|
|
||||||
end: this.durationFormatter.parse(this.offsets.end)
|
|
||||||
};
|
|
||||||
validationResult = this.openmct.time.validateOffsets(offsetValues);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (validationResult !== true){
|
|
||||||
input.setCustomValidity(validationResult);
|
|
||||||
} else {
|
|
||||||
input.setCustomValidity('');
|
input.setCustomValidity('');
|
||||||
}
|
input.title = '';
|
||||||
|
});
|
||||||
|
},
|
||||||
|
validateAllBounds() {
|
||||||
|
return [this.$refs.startDate, this.$refs.endDate].every((input) => {
|
||||||
|
let validationResult = true;
|
||||||
|
let formattedDate;
|
||||||
|
|
||||||
|
if (input === this.$refs.startDate) {
|
||||||
|
formattedDate = this.formattedBounds.start;
|
||||||
|
} else {
|
||||||
|
formattedDate = this.formattedBounds.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.timeFormatter.validate(formattedDate)){
|
||||||
|
validationResult = 'Invalid date';
|
||||||
|
} else {
|
||||||
|
let boundsValues = {
|
||||||
|
start: this.timeFormatter.parse(this.formattedBounds.start),
|
||||||
|
end: this.timeFormatter.parse(this.formattedBounds.end)
|
||||||
|
};
|
||||||
|
validationResult = this.openmct.time.validateBounds(boundsValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validationResult !== true){
|
||||||
|
input.setCustomValidity(validationResult);
|
||||||
|
input.title = validationResult;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
input.setCustomValidity('');
|
||||||
|
input.title = '';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
validateAllOffsets(event) {
|
||||||
|
return [this.$refs.startOffset, this.$refs.endOffset].every((input) => {
|
||||||
|
let validationResult = true;
|
||||||
|
let formattedOffset;
|
||||||
|
|
||||||
|
if (input === this.$refs.startOffset) {
|
||||||
|
formattedOffset = this.offsets.start;
|
||||||
|
} else {
|
||||||
|
formattedOffset = this.offsets.end;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.durationFormatter.validate(formattedOffset)) {
|
||||||
|
validationResult = 'Offsets must be in the format hh:mm:ss and less than 24 hours in duration';
|
||||||
|
} else {
|
||||||
|
let offsetValues = {
|
||||||
|
start: 0 - this.durationFormatter.parse(this.offsets.start),
|
||||||
|
end: this.durationFormatter.parse(this.offsets.end)
|
||||||
|
};
|
||||||
|
validationResult = this.openmct.time.validateOffsets(offsetValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (validationResult !== true){
|
||||||
|
input.setCustomValidity(validationResult);
|
||||||
|
input.title = validationResult;
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
input.setCustomValidity('');
|
||||||
|
input.title = '';
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
submitForm() {
|
||||||
|
// Allow Vue model to catch up to user input.
|
||||||
|
// Submitting form will cause validation messages to display (but only if triggered by button click)
|
||||||
|
this.$nextTick(() => this.$refs.submitButton.click());
|
||||||
},
|
},
|
||||||
getFormatter(key) {
|
getFormatter(key) {
|
||||||
return this.openmct.telemetry.getValueFormatter({
|
return this.openmct.telemetry.getValueFormatter({
|
||||||
@ -415,13 +467,13 @@ export default {
|
|||||||
},
|
},
|
||||||
startDateSelected(date){
|
startDateSelected(date){
|
||||||
this.formattedBounds.start = this.timeFormatter.format(date);
|
this.formattedBounds.start = this.timeFormatter.format(date);
|
||||||
this.validateBounds('start', this.$refs.startDate);
|
this.validateAllBounds();
|
||||||
this.setBoundsFromView();
|
this.submitForm();
|
||||||
},
|
},
|
||||||
endDateSelected(date){
|
endDateSelected(date){
|
||||||
this.formattedBounds.end = this.timeFormatter.format(date);
|
this.formattedBounds.end = this.timeFormatter.format(date);
|
||||||
this.validateBounds('end', this.$refs.endDate);
|
this.validateAllBounds();
|
||||||
this.setBoundsFromView();
|
this.submitForm();
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
@ -22,11 +22,11 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="c-ctrl-wrapper c-ctrl-wrapper--menus-up">
|
<div class="c-ctrl-wrapper c-ctrl-wrapper--menus-up">
|
||||||
<button class="c-button--menu c-mode-button"
|
<button class="c-button--menu c-mode-button"
|
||||||
@click="toggleMenu($event)">
|
@click.prevent="toggle">
|
||||||
<span class="c-button__label">{{selectedMode.name}}</span>
|
<span class="c-button__label">{{selectedMode.name}}</span>
|
||||||
</button>
|
</button>
|
||||||
<div class="c-menu c-super-menu c-conductor__mode-menu"
|
<div class="c-menu c-super-menu c-conductor__mode-menu"
|
||||||
v-if="showMenu">
|
v-if="open">
|
||||||
<div class="c-super-menu__menu">
|
<div class="c-super-menu__menu">
|
||||||
<ul>
|
<ul>
|
||||||
<li v-for="mode in modes"
|
<li v-for="mode in modes"
|
||||||
@ -69,8 +69,11 @@
|
|||||||
</style>
|
</style>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import toggleMixin from '../../ui/mixins/toggle-mixin';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['openmct', 'configuration'],
|
inject: ['openmct', 'configuration'],
|
||||||
|
mixins: [toggleMixin],
|
||||||
data: function () {
|
data: function () {
|
||||||
let activeClock = this.openmct.time.clock();
|
let activeClock = this.openmct.time.clock();
|
||||||
if (activeClock !== undefined) {
|
if (activeClock !== undefined) {
|
||||||
@ -81,8 +84,7 @@ export default {
|
|||||||
selectedMode: this.getModeOptionForClock(activeClock),
|
selectedMode: this.getModeOptionForClock(activeClock),
|
||||||
selectedTimeSystem: JSON.parse(JSON.stringify(this.openmct.time.timeSystem())),
|
selectedTimeSystem: JSON.parse(JSON.stringify(this.openmct.time.timeSystem())),
|
||||||
modes: [],
|
modes: [],
|
||||||
hoveredMode: {},
|
hoveredMode: {}
|
||||||
showMenu: false
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -177,17 +179,7 @@ export default {
|
|||||||
|
|
||||||
setViewFromClock(clock) {
|
setViewFromClock(clock) {
|
||||||
this.selectedMode = this.getModeOptionForClock(clock);
|
this.selectedMode = this.getModeOptionForClock(clock);
|
||||||
},
|
}
|
||||||
|
|
||||||
toggleMenu(event) {
|
|
||||||
this.showMenu = !this.showMenu;
|
|
||||||
|
|
||||||
if (this.showMenu) {
|
|
||||||
document.addEventListener('click', this.toggleMenu, true);
|
|
||||||
} else {
|
|
||||||
document.removeEventListener('click', this.toggleMenu, true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
this.loadClocksFromConfiguration();
|
this.loadClocksFromConfiguration();
|
||||||
|
@ -24,10 +24,10 @@
|
|||||||
v-if="selectedTimeSystem.name">
|
v-if="selectedTimeSystem.name">
|
||||||
<button class="c-button--menu c-time-system-button"
|
<button class="c-button--menu c-time-system-button"
|
||||||
:class="selectedTimeSystem.cssClass"
|
:class="selectedTimeSystem.cssClass"
|
||||||
@click="toggleMenu($event)">
|
@click.prevent="toggle">
|
||||||
<span class="c-button__label">{{selectedTimeSystem.name}}</span>
|
<span class="c-button__label">{{selectedTimeSystem.name}}</span>
|
||||||
</button>
|
</button>
|
||||||
<div class="c-menu" v-if="showMenu">
|
<div class="c-menu" v-if="open">
|
||||||
<ul>
|
<ul>
|
||||||
<li @click="setTimeSystemFromView(timeSystem)"
|
<li @click="setTimeSystemFromView(timeSystem)"
|
||||||
v-for="timeSystem in timeSystems"
|
v-for="timeSystem in timeSystems"
|
||||||
@ -41,15 +41,17 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
import toggleMixin from '../../ui/mixins/toggle-mixin';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['openmct', 'configuration'],
|
inject: ['openmct', 'configuration'],
|
||||||
|
mixins: [toggleMixin],
|
||||||
data: function () {
|
data: function () {
|
||||||
let activeClock = this.openmct.time.clock();
|
let activeClock = this.openmct.time.clock();
|
||||||
|
|
||||||
return {
|
return {
|
||||||
selectedTimeSystem: JSON.parse(JSON.stringify(this.openmct.time.timeSystem())),
|
selectedTimeSystem: JSON.parse(JSON.stringify(this.openmct.time.timeSystem())),
|
||||||
timeSystems: this.getValidTimesystemsForClock(activeClock),
|
timeSystems: this.getValidTimesystemsForClock(activeClock)
|
||||||
showMenu: false
|
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
@ -94,16 +96,6 @@ export default {
|
|||||||
return this.configuration.menuOptions.filter(configMatches)[0];
|
return this.configuration.menuOptions.filter(configMatches)[0];
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleMenu(event) {
|
|
||||||
this.showMenu = !this.showMenu;
|
|
||||||
|
|
||||||
if (this.showMenu) {
|
|
||||||
document.addEventListener('click', this.toggleMenu, true);
|
|
||||||
} else {
|
|
||||||
document.removeEventListener('click', this.toggleMenu, true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
setViewFromTimeSystem(timeSystem) {
|
setViewFromTimeSystem(timeSystem) {
|
||||||
this.selectedTimeSystem = timeSystem;
|
this.selectedTimeSystem = timeSystem;
|
||||||
},
|
},
|
||||||
|
@ -22,12 +22,12 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="c-ctrl-wrapper c-ctrl-wrapper--menus-up c-datetime-picker__wrapper" ref="calendarHolder">
|
<div class="c-ctrl-wrapper c-ctrl-wrapper--menus-up c-datetime-picker__wrapper" ref="calendarHolder">
|
||||||
<a class="c-click-icon icon-calendar"
|
<a class="c-click-icon icon-calendar"
|
||||||
@click="togglePicker()"></a>
|
@click="toggle"></a>
|
||||||
<div class="c-menu c-menu--mobile-modal c-datetime-picker"
|
<div class="c-menu c-menu--mobile-modal c-datetime-picker"
|
||||||
v-if="showPicker">
|
v-if="open">
|
||||||
<div class="c-datetime-picker__close-button">
|
<div class="c-datetime-picker__close-button">
|
||||||
<button class="c-click-icon icon-x-in-circle"
|
<button class="c-click-icon icon-x-in-circle"
|
||||||
@click="togglePicker()"></button>
|
@click="toggle"></button>
|
||||||
</div>
|
</div>
|
||||||
<div class="c-datetime-picker__pager c-pager l-month-year-pager">
|
<div class="c-datetime-picker__pager c-pager l-month-year-pager">
|
||||||
<div class="c-pager__prev c-click-icon icon-arrow-left"
|
<div class="c-pager__prev c-click-icon icon-arrow-left"
|
||||||
@ -160,6 +160,7 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
import moment from 'moment';
|
import moment from 'moment';
|
||||||
|
import toggleMixin from '../../ui/mixins/toggle-mixin';
|
||||||
|
|
||||||
const TIME_NAMES = {
|
const TIME_NAMES = {
|
||||||
'hours': "Hour",
|
'hours': "Hour",
|
||||||
@ -181,13 +182,13 @@ const TIME_OPTIONS = (function makeRanges() {
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
inject: ['openmct'],
|
inject: ['openmct'],
|
||||||
|
mixins: [toggleMixin],
|
||||||
props: {
|
props: {
|
||||||
defaultDateTime: String,
|
defaultDateTime: String,
|
||||||
formatter: Object
|
formatter: Object
|
||||||
},
|
},
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
showPicker: false,
|
|
||||||
picker: {
|
picker: {
|
||||||
year: undefined,
|
year: undefined,
|
||||||
month: undefined,
|
month: undefined,
|
||||||
@ -285,7 +286,6 @@ export default {
|
|||||||
this.date.year = cell.year;
|
this.date.year = cell.year;
|
||||||
this.date.day = cell.day;
|
this.date.day = cell.day;
|
||||||
this.updateFromView();
|
this.updateFromView();
|
||||||
this.showPicker = false;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
dateEquals(d1, d2) {
|
dateEquals(d1, d2) {
|
||||||
@ -315,23 +315,6 @@ export default {
|
|||||||
optionsFor(key) {
|
optionsFor(key) {
|
||||||
return TIME_OPTIONS[key];
|
return TIME_OPTIONS[key];
|
||||||
},
|
},
|
||||||
|
|
||||||
hidePicker(event) {
|
|
||||||
let path = event.composedPath();
|
|
||||||
if (path.indexOf(this.$refs.calendarHolder) === -1) {
|
|
||||||
this.showPicker = false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
togglePicker() {
|
|
||||||
this.showPicker = !this.showPicker;
|
|
||||||
|
|
||||||
if (this.showPicker) {
|
|
||||||
document.addEventListener('click', this.hidePicker, {
|
|
||||||
capture: true
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
mounted: function () {
|
mounted: function () {
|
||||||
this.updateFromModel(this.defaultDateTime);
|
this.updateFromModel(this.defaultDateTime);
|
||||||
|
@ -47,6 +47,14 @@ $bodyFont: $heroFont;
|
|||||||
@return linear-gradient(lighten($c, 5%), $c);
|
@return linear-gradient(lighten($c, 5%), $c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@function pullForward($val, $amt) {
|
||||||
|
@return lighten($val, $amt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@function pushBack($val, $amt) {
|
||||||
|
@return darken($val, $amt);
|
||||||
|
}
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
$fontBaseSize: 12px;
|
$fontBaseSize: 12px;
|
||||||
$smallCr: 2px;
|
$smallCr: 2px;
|
||||||
@ -55,7 +63,7 @@ $basicCr: 4px;
|
|||||||
|
|
||||||
// Base colors
|
// Base colors
|
||||||
$colorBodyBg: #393939;
|
$colorBodyBg: #393939;
|
||||||
$colorBodyFg: #aaa;
|
$colorBodyFg: #aaaaaa;
|
||||||
$colorBodyFgEm: #fff;
|
$colorBodyFgEm: #fff;
|
||||||
$colorGenBg: #222;
|
$colorGenBg: #222;
|
||||||
$colorHeadBg: #262626;
|
$colorHeadBg: #262626;
|
||||||
@ -65,10 +73,11 @@ $colorStatusBarFg: $colorBodyFg;
|
|||||||
$colorStatusBarFgHov: #aaa;
|
$colorStatusBarFgHov: #aaa;
|
||||||
$colorKey: #0099cc;
|
$colorKey: #0099cc;
|
||||||
$colorKeyFg: #fff;
|
$colorKeyFg: #fff;
|
||||||
$colorKeyHov: #00c0f6;
|
$colorKeyHov: #26d8ff;
|
||||||
$colorKeyFilter: invert(36%) sepia(76%) saturate(2514%) hue-rotate(170deg) brightness(99%) contrast(101%);
|
$colorKeyFilter: invert(36%) sepia(76%) saturate(2514%) hue-rotate(170deg) brightness(99%) contrast(101%);
|
||||||
$colorKeyFilterHov: invert(63%) sepia(88%) saturate(3029%) hue-rotate(154deg) brightness(101%) contrast(100%);
|
$colorKeyFilterHov: invert(63%) sepia(88%) saturate(3029%) hue-rotate(154deg) brightness(101%) contrast(100%);
|
||||||
$colorKeySelectedBg: $colorKey;
|
$colorKeySelectedBg: $colorKey;
|
||||||
|
$uiColor: #00b2ff; // Resize bars, splitter bars, etc.
|
||||||
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
|
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
|
||||||
$colorA: #ccc;
|
$colorA: #ccc;
|
||||||
$colorAHov: #fff;
|
$colorAHov: #fff;
|
||||||
@ -94,51 +103,52 @@ $colorPausedFg: #fff;
|
|||||||
$colorOk: #33cc33;
|
$colorOk: #33cc33;
|
||||||
|
|
||||||
// Base variations
|
// Base variations
|
||||||
$colorBodyBgSubtle: lighten($colorBodyBg, 5%);
|
$colorBodyBgSubtle: pullForward($colorBodyBg, 5%);
|
||||||
$colorBodyBgSubtleHov: darken($colorKey, 50%);
|
$colorBodyBgSubtleHov: pushBack($colorKey, 50%);
|
||||||
$colorKeySubtle: darken($colorKey, 10%);
|
$colorKeySubtle: pushBack($colorKey, 10%);
|
||||||
|
|
||||||
// Time Colors
|
// Time Colors
|
||||||
$colorTime: #618cff;
|
$colorTime: #618cff;
|
||||||
$colorTimeBg: $colorTime;
|
$colorTimeBg: $colorTime;
|
||||||
$colorTimeFg: lighten($colorTimeBg, 30%);
|
$colorTimeFg: pullForward($colorTimeBg, 30%);
|
||||||
$colorTimeHov: lighten($colorTime, 10%);
|
$colorTimeHov: pullForward($colorTime, 10%);
|
||||||
$colorTimeSubtle: darken($colorTime, 20%);
|
$colorTimeSubtle: pushBack($colorTime, 20%);
|
||||||
$colorTOI: $colorBodyFg; // was $timeControllerToiLineColor
|
$colorTOI: $colorBodyFg; // was $timeControllerToiLineColor
|
||||||
$colorTOIHov: $colorTime; // was $timeControllerToiLineColorHov
|
$colorTOIHov: $colorTime; // was $timeControllerToiLineColorHov
|
||||||
|
|
||||||
/************************************************** EDITING */
|
|
||||||
// Base Colors
|
|
||||||
$dlSpread: 20%;
|
|
||||||
$editColor: #00c7c3;
|
|
||||||
$editColorAlt: #9971ff;
|
|
||||||
$editColorBgBase: darken($editColor, $dlSpread);
|
|
||||||
$editColorBg: rgba($editColorBgBase, 0.2);
|
|
||||||
$editColorFg: lighten($editColor, $dlSpread);
|
|
||||||
$editColorHov: lighten($editColor, 20%);
|
|
||||||
// Canvas
|
|
||||||
$editCanvasColorBg: $editColorBg; //#002524;
|
|
||||||
$editCanvasColorGrid: rgba($editColorBgBase, 0.4); //lighten($editCanvasColorBg, 3%);
|
|
||||||
// Selectable
|
|
||||||
$editSelectableColor: #006563;
|
|
||||||
$editSelectableColorFg: lighten($editSelectableColor, 20%);
|
|
||||||
$editSelectableColorHov: lighten($editSelectableColor, 10%);
|
|
||||||
// Selectable selected
|
|
||||||
$editSelectableColorSelected: $editSelectableColorHov;
|
|
||||||
$editSelectableColorSelectedFg: lighten($editSelectableColorSelected, 30%);
|
|
||||||
$editSelectableColorFg: darken($editSelectableColor, 40%);
|
|
||||||
$editSelectableBorder: 1px dotted $editSelectableColor;
|
|
||||||
$editSelectableBorderHov: 1px dotted $editColorAlt;
|
|
||||||
$editSelectableBorderSelected: 1px solid $editColor;
|
|
||||||
$editSelectableShdwSelected: rgba($editColor, 0.75) 0 0 0 1px;
|
|
||||||
$editMoveableSelectedShdw: rgba($editColor, 0.5) 0 0 10px;
|
|
||||||
$editBorderDrilledIn: 1px dashed $editColorAlt;
|
|
||||||
$colorGridLines: rgba($editColor, 0.2);
|
|
||||||
|
|
||||||
/************************************************** BROWSING */
|
/************************************************** BROWSING */
|
||||||
$browseSelectableBorderHov: 1px dotted rgba($colorBodyFg, 0.2);
|
$browseFrameColor: pullForward($colorBodyBg, 10%);
|
||||||
$browseSelectableShdwHov: rgba($colorBodyFg, 0.2) 0 0 3px;
|
$browseFrameBorder: 1px solid $browseFrameColor; // Frames in Disp and Flex Layouts when frame is showing
|
||||||
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.6);
|
$browseSelectableShdwHov: rgba($colorBodyFg, 0.3) 0 0 3px;
|
||||||
|
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.4);
|
||||||
|
|
||||||
|
/************************************************** EDITING */
|
||||||
|
$editUIColor: $uiColor; // Base color
|
||||||
|
$editUIColorHov: pullForward(saturate($uiColor, 10%), 20%); // Hover color when $editUIColor is applied as a base color
|
||||||
|
$editUIBaseColor: #344b8d; // Base color, toolbar bg
|
||||||
|
$editUIBaseColorHov: pullForward($editUIBaseColor, 20%);
|
||||||
|
$editUIBaseColorFg: #ffffff; // Toolbar button icon colors, etc.
|
||||||
|
$editUIAreaBaseColor: pullForward(saturate($editUIBaseColor, 30%), 20%);
|
||||||
|
$editUIAreaShdw: $editUIAreaBaseColor 0 0 0 2px; // Edit area s-selected-parent
|
||||||
|
$editUIAreaShdwSelected: $editUIAreaBaseColor 0 0 0 3px; // Edit area s-selected
|
||||||
|
$editUIGridColorBg: rgba($editUIBaseColor, 0.2); // Background of layout editing area
|
||||||
|
$editUIGridColorFg: rgba(#000, 0.1); // Grid lines in layout editing area
|
||||||
|
$editFrameColor: $browseFrameColor; // Solid or dotted border applied to non-selected frames in a layout; move-bar on frame hover
|
||||||
|
$editFrameBorder: 1px dotted $editFrameColor;
|
||||||
|
$editFrameColorHov: $editUIColor; // Solid border hover on frames; hover should not be applied to selected objects
|
||||||
|
$editFrameBorderHov: 1px solid $editFrameColorHov; // Hover on selectable frames
|
||||||
|
$editFrameColorSelected: #ccc; // Border of selected frames
|
||||||
|
$editFrameColorHandleBg: $colorBodyBg; // Resize handle 'offset' color to make handle standout
|
||||||
|
$editFrameColorHandleFg: $editFrameColorSelected; // Resize handle main color
|
||||||
|
$editFrameSelectedShdw: rgba(black, 0.5) 0 1px 10px 1px;
|
||||||
|
$editFrameSelectedBorder: 1px dashed $editFrameColorSelected; // Selected frame element
|
||||||
|
$editFrameMovebarColorBg: $editFrameColor; // Movebar bg color
|
||||||
|
$editFrameMovebarColorFg: pullForward($editFrameMovebarColorBg, 20%); // Grippy lines, container size text
|
||||||
|
$editFrameHovMovebarColorBg: pullForward($editFrameMovebarColorBg, 10%); // Hover style
|
||||||
|
$editFrameHovMovebarColorFg: pullForward($editFrameMovebarColorFg, 10%);
|
||||||
|
$editFrameSelectedMovebarColorBg: pullForward($editFrameMovebarColorBg, 15%); // Selected style
|
||||||
|
$editFrameSelectedMovebarColorFg: pullForward($editFrameMovebarColorFg, 15%);
|
||||||
|
$editFrameMovebarH: 10px; // Height of move bar in layout frame
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
$colorIconAlias: #4af6f3;
|
$colorIconAlias: #4af6f3;
|
||||||
@ -148,16 +158,16 @@ $colorIconAliasForKeyFilter: #aaa;
|
|||||||
$colorTabsHolderBg: rgba(black, 0.2);
|
$colorTabsHolderBg: rgba(black, 0.2);
|
||||||
|
|
||||||
// Buttons and Controls
|
// Buttons and Controls
|
||||||
$colorBtnBg: lighten($colorBodyBg, 10%);
|
$colorBtnBg: pullForward($colorBodyBg, 10%);
|
||||||
$colorBtnBgHov: lighten($colorBtnBg, 10%);
|
$colorBtnBgHov: pullForward($colorBtnBg, 10%);
|
||||||
$colorBtnFg: lighten($colorBodyFg, 10%);
|
$colorBtnFg: pullForward($colorBodyFg, 10%);
|
||||||
$colorBtnReverseFg: lighten($colorBtnFg, 10%);
|
$colorBtnReverseFg: pullForward($colorBtnFg, 10%);
|
||||||
$colorBtnReverseBg: lighten($colorBtnBg, 10%);
|
$colorBtnReverseBg: pullForward($colorBtnBg, 10%);
|
||||||
$colorBtnFgHov: $colorBtnFg;
|
$colorBtnFgHov: $colorBtnFg;
|
||||||
$colorBtnMajorBg: $colorKey;
|
$colorBtnMajorBg: $colorKey;
|
||||||
$colorBtnMajorBgHov: $colorKeyHov;
|
$colorBtnMajorBgHov: $colorKeyHov;
|
||||||
$colorBtnMajorFg: $colorKeyFg;
|
$colorBtnMajorFg: $colorKeyFg;
|
||||||
$colorBtnMajorFgHov: darken($colorBtnMajorFg, 10%);
|
$colorBtnMajorFgHov: pushBack($colorBtnMajorFg, 10%);
|
||||||
$colorBtnCautionBg: #f16f6f;
|
$colorBtnCautionBg: #f16f6f;
|
||||||
$colorBtnCautionBgHov: #f1504e;
|
$colorBtnCautionBgHov: #f1504e;
|
||||||
$colorBtnCautionFg: $colorBtnFg;
|
$colorBtnCautionFg: $colorBtnFg;
|
||||||
@ -165,20 +175,20 @@ $colorClickIcon: $colorKey;
|
|||||||
$colorClickIconBgHov: rgba($colorKey, 0.6);
|
$colorClickIconBgHov: rgba($colorKey, 0.6);
|
||||||
$colorClickIconFgHov: $colorKeyHov;
|
$colorClickIconFgHov: $colorKeyHov;
|
||||||
$colorDropHint: $colorKey;
|
$colorDropHint: $colorKey;
|
||||||
$colorDropHintBg: darken($colorDropHint, 10%);
|
$colorDropHintBg: pushBack($colorDropHint, 10%);
|
||||||
$colorDropHintBgHov: $colorDropHint;
|
$colorDropHintBgHov: $colorDropHint;
|
||||||
$colorDropHintFg: lighten($colorDropHint, 40%);
|
$colorDropHintFg: pullForward($colorDropHint, 40%);
|
||||||
$colorDisclosureCtrl: rgba($colorBodyFg, 0.5);
|
$colorDisclosureCtrl: rgba($colorBodyFg, 0.5);
|
||||||
$colorDisclosureCtrlHov: rgba($colorBodyFg, 0.7);
|
$colorDisclosureCtrlHov: rgba($colorBodyFg, 0.7);
|
||||||
|
|
||||||
// Menus
|
// Menus
|
||||||
$colorMenuBg: lighten($colorBodyBg, 15%);
|
$colorMenuBg: pullForward($colorBodyBg, 15%);
|
||||||
$colorMenuFg: lighten($colorBodyFg, 30%);
|
$colorMenuFg: pullForward($colorBodyFg, 30%);
|
||||||
$colorMenuIc: lighten($colorKey, 15%);
|
$colorMenuIc: pullForward($colorKey, 15%);
|
||||||
$colorMenuHovBg: $colorMenuIc;
|
$colorMenuHovBg: $colorMenuIc;
|
||||||
$colorMenuHovFg: lighten($colorMenuFg, 10%);
|
$colorMenuHovFg: pullForward($colorMenuFg, 10%);
|
||||||
$colorMenuHovIc: $colorMenuHovFg;
|
$colorMenuHovIc: $colorMenuHovFg;
|
||||||
$colorMenuElementHilite: lighten($colorMenuBg, 10%);
|
$colorMenuElementHilite: pullForward($colorMenuBg, 10%);
|
||||||
$shdwMenu: rgba(black, 0.5) 0 1px 5px;
|
$shdwMenu: rgba(black, 0.5) 0 1px 5px;
|
||||||
$shdwMenuText: none;
|
$shdwMenuText: none;
|
||||||
$menuItemPad: $interiorMargin, floor($interiorMargin * 1.25);
|
$menuItemPad: $interiorMargin, floor($interiorMargin * 1.25);
|
||||||
@ -200,21 +210,21 @@ $colorFormLines: rgba(#000, 0.1);
|
|||||||
$colorFormSectionHeader: rgba(#000, 0.05);
|
$colorFormSectionHeader: rgba(#000, 0.05);
|
||||||
$colorInputBg: rgba(black, 0.2);
|
$colorInputBg: rgba(black, 0.2);
|
||||||
$colorInputFg: $colorBodyFg;
|
$colorInputFg: $colorBodyFg;
|
||||||
$colorInputPlaceholder: darken($colorBodyFg, 20%);
|
$colorInputPlaceholder: pushBack($colorBodyFg, 20%);
|
||||||
$colorFormText: darken($colorBodyFg, 10%);
|
$colorFormText: pushBack($colorBodyFg, 10%);
|
||||||
$colorInputIcon: darken($colorBodyFg, 25%);
|
$colorInputIcon: pushBack($colorBodyFg, 25%);
|
||||||
$colorFieldHint: lighten($colorBodyFg, 40%);
|
$colorFieldHint: pullForward($colorBodyFg, 40%);
|
||||||
$shdwInput: inset rgba(black, 0.4) 0 0 1px;
|
$shdwInput: inset rgba(black, 0.4) 0 0 1px;
|
||||||
$shdwInputHov: inset rgba(black, 0.7) 0 0 2px;
|
$shdwInputHov: inset rgba(black, 0.7) 0 0 2px;
|
||||||
$shdwInputFoc: inset rgba(black, 0.8) 0 0.25px 3px;
|
$shdwInputFoc: inset rgba(black, 0.8) 0 0.25px 3px;
|
||||||
|
|
||||||
// Inspector
|
// Inspector
|
||||||
$colorInspectorBg: lighten($colorBodyBg, 5%);
|
$colorInspectorBg: pullForward($colorBodyBg, 5%);
|
||||||
$colorInspectorFg: $colorBodyFg;
|
$colorInspectorFg: $colorBodyFg;
|
||||||
$colorInspectorPropName: darken($colorBodyFg, 20%);
|
$colorInspectorPropName: pushBack($colorBodyFg, 20%);
|
||||||
$colorInspectorPropVal: lighten($colorInspectorFg, 15%);
|
$colorInspectorPropVal: pullForward($colorInspectorFg, 15%);
|
||||||
$colorInspectorSectionHeaderBg: lighten($colorInspectorBg, 5%);
|
$colorInspectorSectionHeaderBg: pullForward($colorInspectorBg, 5%);
|
||||||
$colorInspectorSectionHeaderFg: lighten($colorInspectorBg, 40%);
|
$colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
|
||||||
|
|
||||||
// Overlay
|
// Overlay
|
||||||
$overlayColorBg: $colorMenuBg;
|
$overlayColorBg: $colorMenuBg;
|
||||||
@ -229,8 +239,8 @@ $colorIndicatorOn: $colorOk;
|
|||||||
$colorIndicatorOff: #777777;
|
$colorIndicatorOff: #777777;
|
||||||
|
|
||||||
// Staleness
|
// Staleness
|
||||||
$colorTelemFresh: lighten($colorBodyFg, 20%);
|
$colorTelemFresh: pullForward($colorBodyFg, 20%);
|
||||||
$colorTelemStale: darken($colorBodyFg, 20%);
|
$colorTelemStale: pushBack($colorBodyFg, 20%);
|
||||||
$styleTelemStale: italic;
|
$styleTelemStale: italic;
|
||||||
|
|
||||||
// Limits
|
// Limits
|
||||||
@ -256,22 +266,22 @@ $colorInfoBubbleFg: #666;
|
|||||||
|
|
||||||
// Items
|
// Items
|
||||||
$colorItemBg: buttonBg($colorBtnBg);
|
$colorItemBg: buttonBg($colorBtnBg);
|
||||||
$colorItemBgHov: buttonBg(lighten($colorBtnBg, 5%));
|
$colorItemBgHov: buttonBg(pullForward($colorBtnBg, 5%));
|
||||||
$colorListItemBg: transparent;
|
$colorListItemBg: transparent;
|
||||||
$colorListItemBgHov: rgba($colorKey, 0.1);
|
$colorListItemBgHov: rgba($colorKey, 0.1);
|
||||||
$colorItemFg: $colorBtnFg;
|
$colorItemFg: $colorBtnFg;
|
||||||
$colorItemFgDetails: darken($colorItemFg, 20%);
|
$colorItemFgDetails: pushBack($colorItemFg, 20%);
|
||||||
$shdwItemText: none;
|
$shdwItemText: none;
|
||||||
|
|
||||||
// Tabular
|
// Tabular
|
||||||
$colorTabBorder: lighten($colorBodyBg, 10%);
|
$colorTabBorder: pullForward($colorBodyBg, 10%);
|
||||||
$colorTabBodyBg: $colorBodyBg;
|
$colorTabBodyBg: $colorBodyBg;
|
||||||
$colorTabBodyFg: lighten($colorBodyFg, 20%);
|
$colorTabBodyFg: pullForward($colorBodyFg, 20%);
|
||||||
$colorTabHeaderBg: lighten($colorBodyBg, 10%);
|
$colorTabHeaderBg: pullForward($colorBodyBg, 10%);
|
||||||
$colorTabHeaderFg: $colorBodyFg;
|
$colorTabHeaderFg: $colorBodyFg;
|
||||||
$colorTabHeaderBorder: $colorBodyBg;
|
$colorTabHeaderBorder: $colorBodyBg;
|
||||||
$colorTabGroupHeaderBg: lighten($colorBodyBg, 5%);
|
$colorTabGroupHeaderBg: pullForward($colorBodyBg, 5%);
|
||||||
$colorTabGroupHeaderFg: darken($colorTabHeaderFg, 10%);
|
$colorTabGroupHeaderFg: pushBack($colorTabHeaderFg, 10%);
|
||||||
|
|
||||||
// Plot
|
// Plot
|
||||||
$colorPlotBg: rgba(black, 0.05);
|
$colorPlotBg: rgba(black, 0.05);
|
||||||
@ -280,22 +290,22 @@ $colorPlotHash: black;
|
|||||||
$opacityPlotHash: 0.2;
|
$opacityPlotHash: 0.2;
|
||||||
$stylePlotHash: dashed;
|
$stylePlotHash: dashed;
|
||||||
$colorPlotAreaBorder: $colorInteriorBorder;
|
$colorPlotAreaBorder: $colorInteriorBorder;
|
||||||
$colorPlotLabelFg: darken($colorPlotFg, 20%);
|
$colorPlotLabelFg: pushBack($colorPlotFg, 20%);
|
||||||
$legendHoverValueBg: rgba($colorBodyFg, 0.2);
|
$legendHoverValueBg: rgba($colorBodyFg, 0.2);
|
||||||
|
|
||||||
// Tree
|
// Tree
|
||||||
$colorTreeBg: transparent;
|
$colorTreeBg: transparent;
|
||||||
$colorItemTreeHoverBg: lighten($colorBodyBg, 10%);
|
$colorItemTreeHoverBg: pullForward($colorBodyBg, 10%);
|
||||||
$colorItemTreeHoverFg: lighten($colorBodyFg, 20%);
|
$colorItemTreeHoverFg: pullForward($colorBodyFg, 20%);
|
||||||
$colorItemTreeIcon: $colorKey; // Used
|
$colorItemTreeIcon: $colorKey; // Used
|
||||||
$colorItemTreeIconHover: $colorItemTreeIcon; // Used
|
$colorItemTreeIconHover: $colorItemTreeIcon; // Used
|
||||||
$colorItemTreeFg: $colorBodyFg;
|
$colorItemTreeFg: $colorBodyFg;
|
||||||
$colorItemTreeSelectedBg: darken($colorKey, 15%);
|
$colorItemTreeSelectedBg: pushBack($colorKey, 15%);
|
||||||
$colorItemTreeSelectedFg: $colorItemTreeHoverFg;
|
$colorItemTreeSelectedFg: $colorItemTreeHoverFg;
|
||||||
$colorItemTreeSelectedIcon: $colorItemTreeSelectedFg;
|
$colorItemTreeSelectedIcon: $colorItemTreeSelectedFg;
|
||||||
$colorItemTreeEditingBg: darken($editColor, 20%);
|
$colorItemTreeEditingBg: pushBack($editUIColor, 20%);
|
||||||
$colorItemTreeEditingFg: $editColorFg;
|
$colorItemTreeEditingFg: $editUIColor;
|
||||||
$colorItemTreeEditingIcon: $editColorFg;
|
$colorItemTreeEditingIcon: $editUIColor;
|
||||||
$colorItemTreeVC: $colorDisclosureCtrl;
|
$colorItemTreeVC: $colorDisclosureCtrl;
|
||||||
$colorItemTreeVCHover: $colorDisclosureCtrlHov;
|
$colorItemTreeVCHover: $colorDisclosureCtrlHov;
|
||||||
$shdwItemTreeIcon: none;
|
$shdwItemTreeIcon: none;
|
||||||
@ -307,18 +317,18 @@ $colorThumbHoverBg: $colorItemTreeHoverBg;
|
|||||||
$scrollbarTrackSize: 7px;
|
$scrollbarTrackSize: 7px;
|
||||||
$scrollbarTrackShdw: rgba(#000, 0.2) 0 1px 2px;
|
$scrollbarTrackShdw: rgba(#000, 0.2) 0 1px 2px;
|
||||||
$scrollbarTrackColorBg: rgba(#000, 0.2);
|
$scrollbarTrackColorBg: rgba(#000, 0.2);
|
||||||
$scrollbarThumbColor: darken($colorBodyBg, 50%);
|
$scrollbarThumbColor: pushBack($colorBodyBg, 50%);
|
||||||
$scrollbarThumbColorHov: $colorKey;
|
$scrollbarThumbColorHov: $colorKey;
|
||||||
$scrollbarThumbColorMenu: lighten($colorMenuBg, 10%);
|
$scrollbarThumbColorMenu: pullForward($colorMenuBg, 10%);
|
||||||
$scrollbarThumbColorMenuHov: lighten($scrollbarThumbColorMenu, 2%);
|
$scrollbarThumbColorMenuHov: pullForward($scrollbarThumbColorMenu, 2%);
|
||||||
|
|
||||||
// Splitter
|
// Splitter
|
||||||
$splitterHandleD: 2px;
|
$splitterHandleD: 2px;
|
||||||
$splitterHandleHitMargin: 4px;
|
$splitterHandleHitMargin: 4px;
|
||||||
$colorSplitterBaseBg: $colorBodyBg;
|
$colorSplitterBaseBg: $colorBodyBg;
|
||||||
$colorSplitterBg: lighten($colorSplitterBaseBg, 10%);
|
$colorSplitterBg: pullForward($colorBodyBg, 10%);
|
||||||
$colorSplitterFg: $colorBodyBg;
|
$colorSplitterFg: $colorBodyBg;
|
||||||
$colorSplitterHover: $colorKey;
|
$colorSplitterHover: $uiColor;
|
||||||
$colorSplitterActive: $colorKey;
|
$colorSplitterActive: $colorKey;
|
||||||
$splitterBtnD: (16px, 35px); // height, width
|
$splitterBtnD: (16px, 35px); // height, width
|
||||||
$splitterBtnColorBg: $colorBtnBg;
|
$splitterBtnColorBg: $colorBtnBg;
|
||||||
@ -330,7 +340,7 @@ $splitterCollapsedBtnColorBgHov: $colorKey;
|
|||||||
$splitterCollapsedBtnColorFgHov: $colorKeyFg;
|
$splitterCollapsedBtnColorFgHov: $colorKeyFg;
|
||||||
|
|
||||||
// Mobile
|
// Mobile
|
||||||
$colorMobilePaneLeft: darken($colorBodyBg, 2%);
|
$colorMobilePaneLeft: pushBack($colorBodyBg, 2%);
|
||||||
$colorMobilePaneLeftTreeItemBg: rgba($colorBodyFg, 0.1);
|
$colorMobilePaneLeftTreeItemBg: rgba($colorBodyFg, 0.1);
|
||||||
$colorMobilePaneLeftTreeItemFg: $colorItemTreeFg;
|
$colorMobilePaneLeftTreeItemFg: $colorItemTreeFg;
|
||||||
$colorMobileSelectListTreeItemBg: rgba(#000, 0.05);
|
$colorMobileSelectListTreeItemBg: rgba(#000, 0.05);
|
||||||
@ -367,21 +377,10 @@ $createBtnTextTransform: uppercase;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@mixin themedButton($c: $colorBtnBg) {
|
@mixin themedButton($c: $colorBtnBg) {
|
||||||
background: linear-gradient(lighten($c, 5%), $c);
|
background: linear-gradient(pullForward($c, 5%), $c);
|
||||||
box-shadow: rgba(black, 0.5) 0 0.5px 2px;
|
box-shadow: rgba(black, 0.5) 0 0.5px 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************** NOT USED, LEAVE FOR NOW */
|
@mixin themedSelect($bg: $colorBtnBg, $fg: $colorBtnFg) {
|
||||||
// Slider controls, not in use
|
@include cSelect(linear-gradient(lighten($bg, 5%), $bg), $fg, lighten($bg, 20%), rgba(black, 0.5) 0 0.5px 3px);
|
||||||
/*
|
}
|
||||||
$sliderColorBase: $colorKey;
|
|
||||||
$sliderColorRangeHolder: rgba(black, 0.07);
|
|
||||||
$sliderColorRange: rgba($sliderColorBase, 0.2);
|
|
||||||
$sliderColorRangeHov: rgba($sliderColorBase, 0.4);
|
|
||||||
$sliderColorKnob: darken($sliderColorBase, 20%);
|
|
||||||
$sliderColorKnobHov: rgba($sliderColorBase, 0.7);
|
|
||||||
$sliderColorRangeValHovBg: $sliderColorRange;
|
|
||||||
$sliderColorRangeValHovFg: $colorBodyFg;
|
|
||||||
$sliderKnobW: 15px;
|
|
||||||
$sliderKnobR: 2px;
|
|
||||||
*/
|
|
||||||
|
@ -51,6 +51,14 @@ $bodyFont: 'Chakra Petch', sans-serif;
|
|||||||
@return linear-gradient(lighten($c, 5%), $c);
|
@return linear-gradient(lighten($c, 5%), $c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@function pullForward($val, $amt) {
|
||||||
|
@return lighten($val, $amt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@function pushBack($val, $amt) {
|
||||||
|
@return darken($val, $amt);
|
||||||
|
}
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
$fontBaseSize: 12px;
|
$fontBaseSize: 12px;
|
||||||
$smallCr: 2px;
|
$smallCr: 2px;
|
||||||
@ -69,10 +77,11 @@ $colorStatusBarFg: $colorBodyFg;
|
|||||||
$colorStatusBarFgHov: #aaa;
|
$colorStatusBarFgHov: #aaa;
|
||||||
$colorKey: #0099cc;
|
$colorKey: #0099cc;
|
||||||
$colorKeyFg: #fff;
|
$colorKeyFg: #fff;
|
||||||
$colorKeyHov: #00c0f6;
|
$colorKeyHov: #26d8ff;
|
||||||
$colorKeyFilter: invert(36%) sepia(76%) saturate(2514%) hue-rotate(170deg) brightness(99%) contrast(101%);
|
$colorKeyFilter: invert(36%) sepia(76%) saturate(2514%) hue-rotate(170deg) brightness(99%) contrast(101%);
|
||||||
$colorKeyFilterHov: invert(63%) sepia(88%) saturate(3029%) hue-rotate(154deg) brightness(101%) contrast(100%);
|
$colorKeyFilterHov: invert(63%) sepia(88%) saturate(3029%) hue-rotate(154deg) brightness(101%) contrast(100%);
|
||||||
$colorKeySelectedBg: $colorKey;
|
$colorKeySelectedBg: $colorKey;
|
||||||
|
$uiColor: #00b2ff; // Resize bars, splitter bars, etc.
|
||||||
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
|
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
|
||||||
$colorA: #ccc;
|
$colorA: #ccc;
|
||||||
$colorAHov: #fff;
|
$colorAHov: #fff;
|
||||||
@ -98,51 +107,52 @@ $colorPausedFg: #fff;
|
|||||||
$colorOk: #33cc33;
|
$colorOk: #33cc33;
|
||||||
|
|
||||||
// Base variations
|
// Base variations
|
||||||
$colorBodyBgSubtle: lighten($colorBodyBg, 5%);
|
$colorBodyBgSubtle: pullForward($colorBodyBg, 5%);
|
||||||
$colorBodyBgSubtleHov: darken($colorKey, 50%);
|
$colorBodyBgSubtleHov: pushBack($colorKey, 50%);
|
||||||
$colorKeySubtle: darken($colorKey, 10%);
|
$colorKeySubtle: pushBack($colorKey, 10%);
|
||||||
|
|
||||||
// Time Colors
|
// Time Colors
|
||||||
$colorTime: #618cff;
|
$colorTime: #618cff;
|
||||||
$colorTimeBg: $colorTime;
|
$colorTimeBg: $colorTime;
|
||||||
$colorTimeFg: lighten($colorTimeBg, 30%);
|
$colorTimeFg: pullForward($colorTimeBg, 30%);
|
||||||
$colorTimeHov: lighten($colorTime, 10%);
|
$colorTimeHov: pullForward($colorTime, 10%);
|
||||||
$colorTimeSubtle: darken($colorTime, 20%);
|
$colorTimeSubtle: pushBack($colorTime, 20%);
|
||||||
$colorTOI: $colorBodyFg; // was $timeControllerToiLineColor
|
$colorTOI: $colorBodyFg; // was $timeControllerToiLineColor
|
||||||
$colorTOIHov: $colorTime; // was $timeControllerToiLineColorHov
|
$colorTOIHov: $colorTime; // was $timeControllerToiLineColorHov
|
||||||
|
|
||||||
/************************************************** EDITING */
|
|
||||||
// Base Colors
|
|
||||||
$dlSpread: 20%;
|
|
||||||
$editColor: #00c7c3;
|
|
||||||
$editColorAlt: #9971ff;
|
|
||||||
$editColorBgBase: darken($editColor, $dlSpread);
|
|
||||||
$editColorBg: rgba($editColorBgBase, 0.2);
|
|
||||||
$editColorFg: lighten($editColor, $dlSpread);
|
|
||||||
$editColorHov: lighten($editColor, 20%);
|
|
||||||
// Canvas
|
|
||||||
$editCanvasColorBg: $editColorBg; //#002524;
|
|
||||||
$editCanvasColorGrid: rgba($editColorBgBase, 0.4); //lighten($editCanvasColorBg, 3%);
|
|
||||||
// Selectable
|
|
||||||
$editSelectableColor: #006563;
|
|
||||||
$editSelectableColorFg: lighten($editSelectableColor, 20%);
|
|
||||||
$editSelectableColorHov: lighten($editSelectableColor, 10%);
|
|
||||||
// Selectable selected
|
|
||||||
$editSelectableColorSelected: $editSelectableColorHov;
|
|
||||||
$editSelectableColorSelectedFg: lighten($editSelectableColorSelected, 30%);
|
|
||||||
$editSelectableColorFg: darken($editSelectableColor, 40%);
|
|
||||||
$editSelectableBorder: 1px dotted $editSelectableColor;
|
|
||||||
$editSelectableBorderHov: 1px dotted $editColorAlt;
|
|
||||||
$editSelectableBorderSelected: 1px solid $editColor;
|
|
||||||
$editSelectableShdwSelected: rgba($editColor, 0.75) 0 0 0 1px;
|
|
||||||
$editMoveableSelectedShdw: rgba($editColor, 0.5) 0 0 10px;
|
|
||||||
$editBorderDrilledIn: 1px dashed $editColorAlt;
|
|
||||||
$colorGridLines: rgba($editColor, 0.2);
|
|
||||||
|
|
||||||
/************************************************** BROWSING */
|
/************************************************** BROWSING */
|
||||||
$browseSelectableBorderHov: 1px dotted rgba($colorBodyFg, 0.2);
|
$browseFrameColor: pullForward($colorBodyBg, 10%);
|
||||||
$browseSelectableShdwHov: rgba($colorBodyFg, 0.2) 0 0 3px;
|
$browseFrameBorder: 1px solid $browseFrameColor; // Frames in Disp and Flex Layouts when frame is showing
|
||||||
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.6);
|
$browseSelectableShdwHov: rgba($colorBodyFg, 0.3) 0 0 3px;
|
||||||
|
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.4);
|
||||||
|
|
||||||
|
/************************************************** EDITING */
|
||||||
|
$editUIColor: $uiColor; // Base color
|
||||||
|
$editUIColorHov: pullForward(saturate($uiColor, 10%), 20%); // Hover color when $editUIColor is applied as a base color
|
||||||
|
$editUIBaseColor: #344b8d; // Base color, toolbar bg
|
||||||
|
$editUIBaseColorHov: pullForward($editUIBaseColor, 20%);
|
||||||
|
$editUIBaseColorFg: #ffffff; // Toolbar button icon colors, etc.
|
||||||
|
$editUIAreaBaseColor: pullForward(saturate($editUIBaseColor, 30%), 20%);
|
||||||
|
$editUIAreaShdw: $editUIAreaBaseColor 0 0 0 2px; // Edit area s-selected-parent
|
||||||
|
$editUIAreaShdwSelected: $editUIAreaBaseColor 0 0 0 3px; // Edit area s-selected
|
||||||
|
$editUIGridColorBg: rgba($editUIBaseColor, 0.2); // Background of layout editing area
|
||||||
|
$editUIGridColorFg: rgba(#000, 0.1); // Grid lines in layout editing area
|
||||||
|
$editFrameColor: $browseFrameColor; // Solid or dotted border applied to non-selected frames in a layout; move-bar on frame hover
|
||||||
|
$editFrameBorder: 1px dotted $editFrameColor;
|
||||||
|
$editFrameColorHov: $editUIColor; // Solid border hover on frames; hover should not be applied to selected objects
|
||||||
|
$editFrameBorderHov: 1px solid $editFrameColorHov; // Hover on selectable frames
|
||||||
|
$editFrameColorSelected: #ccc; // Border of selected frames
|
||||||
|
$editFrameColorHandleBg: $colorBodyBg; // Resize handle 'offset' color to make handle standout
|
||||||
|
$editFrameColorHandleFg: $editFrameColorSelected; // Resize handle main color
|
||||||
|
$editFrameSelectedShdw: rgba(black, 0.5) 0 1px 10px 1px;
|
||||||
|
$editFrameSelectedBorder: 1px dashed $editFrameColorSelected; // Selected frame element
|
||||||
|
$editFrameMovebarColorBg: $editFrameColor; // Movebar bg color
|
||||||
|
$editFrameMovebarColorFg: pullForward($editFrameMovebarColorBg, 20%); // Grippy lines, container size text
|
||||||
|
$editFrameHovMovebarColorBg: pullForward($editFrameMovebarColorBg, 10%); // Hover style
|
||||||
|
$editFrameHovMovebarColorFg: pullForward($editFrameMovebarColorFg, 10%);
|
||||||
|
$editFrameSelectedMovebarColorBg: pullForward($editFrameMovebarColorBg, 15%); // Selected style
|
||||||
|
$editFrameSelectedMovebarColorFg: pullForward($editFrameMovebarColorFg, 15%);
|
||||||
|
$editFrameMovebarH: 10px; // Height of move bar in layout frame
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
$colorIconAlias: #4af6f3;
|
$colorIconAlias: #4af6f3;
|
||||||
@ -152,16 +162,16 @@ $colorIconAliasForKeyFilter: #aaa;
|
|||||||
$colorTabsHolderBg: rgba(black, 0.2);
|
$colorTabsHolderBg: rgba(black, 0.2);
|
||||||
|
|
||||||
// Buttons and Controls
|
// Buttons and Controls
|
||||||
$colorBtnBg: lighten($colorBodyBg, 10%);
|
$colorBtnBg: pullForward($colorBodyBg, 10%);
|
||||||
$colorBtnBgHov: lighten($colorBtnBg, 10%);
|
$colorBtnBgHov: pullForward($colorBtnBg, 10%);
|
||||||
$colorBtnFg: lighten($colorBodyFg, 10%);
|
$colorBtnFg: pullForward($colorBodyFg, 10%);
|
||||||
$colorBtnReverseFg: lighten($colorBtnFg, 10%);
|
$colorBtnReverseFg: pullForward($colorBtnFg, 10%);
|
||||||
$colorBtnReverseBg: lighten($colorBtnBg, 10%);
|
$colorBtnReverseBg: pullForward($colorBtnBg, 10%);
|
||||||
$colorBtnFgHov: $colorBtnFg;
|
$colorBtnFgHov: $colorBtnFg;
|
||||||
$colorBtnMajorBg: $colorKey;
|
$colorBtnMajorBg: $colorKey;
|
||||||
$colorBtnMajorBgHov: $colorKeyHov;
|
$colorBtnMajorBgHov: $colorKeyHov;
|
||||||
$colorBtnMajorFg: $colorKeyFg;
|
$colorBtnMajorFg: $colorKeyFg;
|
||||||
$colorBtnMajorFgHov: darken($colorBtnMajorFg, 10%);
|
$colorBtnMajorFgHov: pushBack($colorBtnMajorFg, 10%);
|
||||||
$colorBtnCautionBg: #f16f6f;
|
$colorBtnCautionBg: #f16f6f;
|
||||||
$colorBtnCautionBgHov: #f1504e;
|
$colorBtnCautionBgHov: #f1504e;
|
||||||
$colorBtnCautionFg: $colorBtnFg;
|
$colorBtnCautionFg: $colorBtnFg;
|
||||||
@ -169,20 +179,20 @@ $colorClickIcon: $colorKey;
|
|||||||
$colorClickIconBgHov: rgba($colorKey, 0.6);
|
$colorClickIconBgHov: rgba($colorKey, 0.6);
|
||||||
$colorClickIconFgHov: $colorKeyHov;
|
$colorClickIconFgHov: $colorKeyHov;
|
||||||
$colorDropHint: $colorKey;
|
$colorDropHint: $colorKey;
|
||||||
$colorDropHintBg: darken($colorDropHint, 10%);
|
$colorDropHintBg: pushBack($colorDropHint, 10%);
|
||||||
$colorDropHintBgHov: $colorDropHint;
|
$colorDropHintBgHov: $colorDropHint;
|
||||||
$colorDropHintFg: lighten($colorDropHint, 40%);
|
$colorDropHintFg: pullForward($colorDropHint, 40%);
|
||||||
$colorDisclosureCtrl: rgba($colorBodyFg, 0.5);
|
$colorDisclosureCtrl: rgba($colorBodyFg, 0.5);
|
||||||
$colorDisclosureCtrlHov: rgba($colorBodyFg, 0.7);
|
$colorDisclosureCtrlHov: rgba($colorBodyFg, 0.7);
|
||||||
|
|
||||||
// Menus
|
// Menus
|
||||||
$colorMenuBg: lighten($colorBodyBg, 15%);
|
$colorMenuBg: pullForward($colorBodyBg, 15%);
|
||||||
$colorMenuFg: lighten($colorBodyFg, 30%);
|
$colorMenuFg: pullForward($colorBodyFg, 30%);
|
||||||
$colorMenuIc: lighten($colorKey, 15%);
|
$colorMenuIc: pullForward($colorKey, 15%);
|
||||||
$colorMenuHovBg: $colorMenuIc;
|
$colorMenuHovBg: $colorMenuIc;
|
||||||
$colorMenuHovFg: lighten($colorMenuFg, 10%);
|
$colorMenuHovFg: pullForward($colorMenuFg, 10%);
|
||||||
$colorMenuHovIc: $colorMenuHovFg;
|
$colorMenuHovIc: $colorMenuHovFg;
|
||||||
$colorMenuElementHilite: lighten($colorMenuBg, 10%);
|
$colorMenuElementHilite: pullForward($colorMenuBg, 10%);
|
||||||
$shdwMenu: rgba(black, 0.5) 0 1px 5px;
|
$shdwMenu: rgba(black, 0.5) 0 1px 5px;
|
||||||
$shdwMenuText: none;
|
$shdwMenuText: none;
|
||||||
$menuItemPad: $interiorMargin, floor($interiorMargin * 1.25);
|
$menuItemPad: $interiorMargin, floor($interiorMargin * 1.25);
|
||||||
@ -204,21 +214,21 @@ $colorFormLines: rgba(#000, 0.1);
|
|||||||
$colorFormSectionHeader: rgba(#000, 0.05);
|
$colorFormSectionHeader: rgba(#000, 0.05);
|
||||||
$colorInputBg: rgba(black, 0.2);
|
$colorInputBg: rgba(black, 0.2);
|
||||||
$colorInputFg: $colorBodyFg;
|
$colorInputFg: $colorBodyFg;
|
||||||
$colorInputPlaceholder: darken($colorBodyFg, 20%);
|
$colorInputPlaceholder: pushBack($colorBodyFg, 20%);
|
||||||
$colorFormText: darken($colorBodyFg, 10%);
|
$colorFormText: pushBack($colorBodyFg, 10%);
|
||||||
$colorInputIcon: darken($colorBodyFg, 25%);
|
$colorInputIcon: pushBack($colorBodyFg, 25%);
|
||||||
$colorFieldHint: lighten($colorBodyFg, 40%);
|
$colorFieldHint: pullForward($colorBodyFg, 40%);
|
||||||
$shdwInput: inset rgba(black, 0.4) 0 0 1px;
|
$shdwInput: inset rgba(black, 0.4) 0 0 1px;
|
||||||
$shdwInputHov: inset rgba(black, 0.7) 0 0 2px;
|
$shdwInputHov: inset rgba(black, 0.7) 0 0 2px;
|
||||||
$shdwInputFoc: inset rgba(black, 0.8) 0 0.25px 3px;
|
$shdwInputFoc: inset rgba(black, 0.8) 0 0.25px 3px;
|
||||||
|
|
||||||
// Inspector
|
// Inspector
|
||||||
$colorInspectorBg: lighten($colorBodyBg, 5%);
|
$colorInspectorBg: pullForward($colorBodyBg, 5%);
|
||||||
$colorInspectorFg: $colorBodyFg;
|
$colorInspectorFg: $colorBodyFg;
|
||||||
$colorInspectorPropName: darken($colorBodyFg, 20%);
|
$colorInspectorPropName: pushBack($colorBodyFg, 20%);
|
||||||
$colorInspectorPropVal: lighten($colorInspectorFg, 15%);
|
$colorInspectorPropVal: pullForward($colorInspectorFg, 15%);
|
||||||
$colorInspectorSectionHeaderBg: lighten($colorInspectorBg, 5%);
|
$colorInspectorSectionHeaderBg: pullForward($colorInspectorBg, 5%);
|
||||||
$colorInspectorSectionHeaderFg: lighten($colorInspectorBg, 40%);
|
$colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
|
||||||
|
|
||||||
// Overlay
|
// Overlay
|
||||||
$overlayColorBg: $colorMenuBg;
|
$overlayColorBg: $colorMenuBg;
|
||||||
@ -233,8 +243,8 @@ $colorIndicatorOn: $colorOk;
|
|||||||
$colorIndicatorOff: #777777;
|
$colorIndicatorOff: #777777;
|
||||||
|
|
||||||
// Staleness
|
// Staleness
|
||||||
$colorTelemFresh: lighten($colorBodyFg, 20%);
|
$colorTelemFresh: pullForward($colorBodyFg, 20%);
|
||||||
$colorTelemStale: darken($colorBodyFg, 20%);
|
$colorTelemStale: pushBack($colorBodyFg, 20%);
|
||||||
$styleTelemStale: italic;
|
$styleTelemStale: italic;
|
||||||
|
|
||||||
// Limits
|
// Limits
|
||||||
@ -260,22 +270,22 @@ $colorInfoBubbleFg: #666;
|
|||||||
|
|
||||||
// Items
|
// Items
|
||||||
$colorItemBg: buttonBg($colorBtnBg);
|
$colorItemBg: buttonBg($colorBtnBg);
|
||||||
$colorItemBgHov: buttonBg(lighten($colorBtnBg, 5%));
|
$colorItemBgHov: buttonBg(pullForward($colorBtnBg, 5%));
|
||||||
$colorListItemBg: transparent;
|
$colorListItemBg: transparent;
|
||||||
$colorListItemBgHov: rgba($colorKey, 0.1);
|
$colorListItemBgHov: rgba($colorKey, 0.1);
|
||||||
$colorItemFg: $colorBtnFg;
|
$colorItemFg: $colorBtnFg;
|
||||||
$colorItemFgDetails: darken($colorItemFg, 20%);
|
$colorItemFgDetails: pushBack($colorItemFg, 20%);
|
||||||
$shdwItemText: none;
|
$shdwItemText: none;
|
||||||
|
|
||||||
// Tabular
|
// Tabular
|
||||||
$colorTabBorder: lighten($colorBodyBg, 10%);
|
$colorTabBorder: pullForward($colorBodyBg, 10%);
|
||||||
$colorTabBodyBg: $colorBodyBg;
|
$colorTabBodyBg: $colorBodyBg;
|
||||||
$colorTabBodyFg: lighten($colorBodyFg, 20%);
|
$colorTabBodyFg: pullForward($colorBodyFg, 20%);
|
||||||
$colorTabHeaderBg: lighten($colorBodyBg, 10%);
|
$colorTabHeaderBg: pullForward($colorBodyBg, 10%);
|
||||||
$colorTabHeaderFg: $colorBodyFg;
|
$colorTabHeaderFg: $colorBodyFg;
|
||||||
$colorTabHeaderBorder: $colorBodyBg;
|
$colorTabHeaderBorder: $colorBodyBg;
|
||||||
$colorTabGroupHeaderBg: lighten($colorBodyBg, 5%);
|
$colorTabGroupHeaderBg: pullForward($colorBodyBg, 5%);
|
||||||
$colorTabGroupHeaderFg: darken($colorTabHeaderFg, 10%);
|
$colorTabGroupHeaderFg: pushBack($colorTabHeaderFg, 10%);
|
||||||
|
|
||||||
// Plot
|
// Plot
|
||||||
$colorPlotBg: rgba(black, 0.05);
|
$colorPlotBg: rgba(black, 0.05);
|
||||||
@ -284,22 +294,22 @@ $colorPlotHash: black;
|
|||||||
$opacityPlotHash: 0.2;
|
$opacityPlotHash: 0.2;
|
||||||
$stylePlotHash: dashed;
|
$stylePlotHash: dashed;
|
||||||
$colorPlotAreaBorder: $colorInteriorBorder;
|
$colorPlotAreaBorder: $colorInteriorBorder;
|
||||||
$colorPlotLabelFg: darken($colorPlotFg, 20%);
|
$colorPlotLabelFg: pushBack($colorPlotFg, 20%);
|
||||||
$legendHoverValueBg: rgba($colorBodyFg, 0.2);
|
$legendHoverValueBg: rgba($colorBodyFg, 0.2);
|
||||||
|
|
||||||
// Tree
|
// Tree
|
||||||
$colorTreeBg: transparent;
|
$colorTreeBg: transparent;
|
||||||
$colorItemTreeHoverBg: lighten($colorBodyBg, 10%);
|
$colorItemTreeHoverBg: pullForward($colorBodyBg, 10%);
|
||||||
$colorItemTreeHoverFg: lighten($colorBodyFg, 20%);
|
$colorItemTreeHoverFg: pullForward($colorBodyFg, 20%);
|
||||||
$colorItemTreeIcon: $colorKey; // Used
|
$colorItemTreeIcon: $colorKey; // Used
|
||||||
$colorItemTreeIconHover: $colorItemTreeIcon; // Used
|
$colorItemTreeIconHover: $colorItemTreeIcon; // Used
|
||||||
$colorItemTreeFg: $colorBodyFg;
|
$colorItemTreeFg: $colorBodyFg;
|
||||||
$colorItemTreeSelectedBg: darken($colorKey, 15%);
|
$colorItemTreeSelectedBg: pushBack($colorKey, 15%);
|
||||||
$colorItemTreeSelectedFg: $colorItemTreeHoverFg;
|
$colorItemTreeSelectedFg: $colorItemTreeHoverFg;
|
||||||
$colorItemTreeSelectedIcon: $colorItemTreeSelectedFg;
|
$colorItemTreeSelectedIcon: $colorItemTreeSelectedFg;
|
||||||
$colorItemTreeEditingBg: darken($editColor, 20%);
|
$colorItemTreeEditingBg: pushBack($editUIColor, 20%);
|
||||||
$colorItemTreeEditingFg: $editColorFg;
|
$colorItemTreeEditingFg: $editUIColor;
|
||||||
$colorItemTreeEditingIcon: $editColorFg;
|
$colorItemTreeEditingIcon: $editUIColor;
|
||||||
$colorItemTreeVC: $colorDisclosureCtrl;
|
$colorItemTreeVC: $colorDisclosureCtrl;
|
||||||
$colorItemTreeVCHover: $colorDisclosureCtrlHov;
|
$colorItemTreeVCHover: $colorDisclosureCtrlHov;
|
||||||
$shdwItemTreeIcon: none;
|
$shdwItemTreeIcon: none;
|
||||||
@ -311,18 +321,18 @@ $colorThumbHoverBg: $colorItemTreeHoverBg;
|
|||||||
$scrollbarTrackSize: 7px;
|
$scrollbarTrackSize: 7px;
|
||||||
$scrollbarTrackShdw: rgba(#000, 0.2) 0 1px 2px;
|
$scrollbarTrackShdw: rgba(#000, 0.2) 0 1px 2px;
|
||||||
$scrollbarTrackColorBg: rgba(#000, 0.2);
|
$scrollbarTrackColorBg: rgba(#000, 0.2);
|
||||||
$scrollbarThumbColor: darken($colorBodyBg, 50%);
|
$scrollbarThumbColor: pushBack($colorBodyBg, 50%);
|
||||||
$scrollbarThumbColorHov: $colorKey;
|
$scrollbarThumbColorHov: $colorKey;
|
||||||
$scrollbarThumbColorMenu: lighten($colorMenuBg, 10%);
|
$scrollbarThumbColorMenu: pullForward($colorMenuBg, 10%);
|
||||||
$scrollbarThumbColorMenuHov: lighten($scrollbarThumbColorMenu, 2%);
|
$scrollbarThumbColorMenuHov: pullForward($scrollbarThumbColorMenu, 2%);
|
||||||
|
|
||||||
// Splitter
|
// Splitter
|
||||||
$splitterHandleD: 2px;
|
$splitterHandleD: 2px;
|
||||||
$splitterHandleHitMargin: 4px;
|
$splitterHandleHitMargin: 4px;
|
||||||
$colorSplitterBaseBg: $colorBodyBg;
|
$colorSplitterBaseBg: $colorBodyBg;
|
||||||
$colorSplitterBg: lighten($colorSplitterBaseBg, 10%);
|
$colorSplitterBg: pullForward($colorBodyBg, 10%);
|
||||||
$colorSplitterFg: $colorBodyBg;
|
$colorSplitterFg: $colorBodyBg;
|
||||||
$colorSplitterHover: $colorKey;
|
$colorSplitterHover: $uiColor;
|
||||||
$colorSplitterActive: $colorKey;
|
$colorSplitterActive: $colorKey;
|
||||||
$splitterBtnD: (16px, 35px); // height, width
|
$splitterBtnD: (16px, 35px); // height, width
|
||||||
$splitterBtnColorBg: $colorBtnBg;
|
$splitterBtnColorBg: $colorBtnBg;
|
||||||
@ -334,7 +344,7 @@ $splitterCollapsedBtnColorBgHov: $colorKey;
|
|||||||
$splitterCollapsedBtnColorFgHov: $colorKeyFg;
|
$splitterCollapsedBtnColorFgHov: $colorKeyFg;
|
||||||
|
|
||||||
// Mobile
|
// Mobile
|
||||||
$colorMobilePaneLeft: darken($colorBodyBg, 2%);
|
$colorMobilePaneLeft: pushBack($colorBodyBg, 2%);
|
||||||
$colorMobilePaneLeftTreeItemBg: rgba($colorBodyFg, 0.1);
|
$colorMobilePaneLeftTreeItemBg: rgba($colorBodyFg, 0.1);
|
||||||
$colorMobilePaneLeftTreeItemFg: $colorItemTreeFg;
|
$colorMobilePaneLeftTreeItemFg: $colorItemTreeFg;
|
||||||
$colorMobileSelectListTreeItemBg: rgba(#000, 0.05);
|
$colorMobileSelectListTreeItemBg: rgba(#000, 0.05);
|
||||||
@ -371,10 +381,14 @@ $createBtnTextTransform: uppercase;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@mixin themedButton($c: $colorBtnBg) {
|
@mixin themedButton($c: $colorBtnBg) {
|
||||||
background: linear-gradient(lighten($c, 5%), $c);
|
background: linear-gradient(pullForward($c, 5%), $c);
|
||||||
box-shadow: rgba(black, 0.5) 0 0.5px 2px;
|
box-shadow: rgba(black, 0.5) 0 0.5px 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin themedSelect($bg: $colorBtnBg, $fg: $colorBtnFg) {
|
||||||
|
@include cSelect(linear-gradient(lighten($bg, 5%), $bg), $fg, lighten($bg, 20%), rgba(black, 0.5) 0 0.5px 3px);
|
||||||
|
}
|
||||||
|
|
||||||
/**************************************************** OVERRIDES */
|
/**************************************************** OVERRIDES */
|
||||||
.c-frame {
|
.c-frame {
|
||||||
&:not(.no-frame) {
|
&:not(.no-frame) {
|
||||||
|
@ -47,6 +47,14 @@ $bodyFont: $heroFont;
|
|||||||
@return $c;
|
@return $c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@function pullForward($val, $amt) {
|
||||||
|
@return darken($val, $amt);
|
||||||
|
}
|
||||||
|
|
||||||
|
@function pushBack($val, $amt) {
|
||||||
|
@return lighten($val, $amt);
|
||||||
|
}
|
||||||
|
|
||||||
// Constants
|
// Constants
|
||||||
$fontBaseSize: 12px;
|
$fontBaseSize: 12px;
|
||||||
$smallCr: 2px;
|
$smallCr: 2px;
|
||||||
@ -69,6 +77,7 @@ $colorKeyHov: #00c0f6;
|
|||||||
$colorKeyFilter: invert(37%) sepia(100%) saturate(686%) hue-rotate(157deg) brightness(102%) contrast(102%);
|
$colorKeyFilter: invert(37%) sepia(100%) saturate(686%) hue-rotate(157deg) brightness(102%) contrast(102%);
|
||||||
$colorKeyFilterHov: invert(69%) sepia(87%) saturate(3243%) hue-rotate(151deg) brightness(97%) contrast(102%);
|
$colorKeyFilterHov: invert(69%) sepia(87%) saturate(3243%) hue-rotate(151deg) brightness(97%) contrast(102%);
|
||||||
$colorKeySelectedBg: $colorKey;
|
$colorKeySelectedBg: $colorKey;
|
||||||
|
$uiColor: #289fec; // Resize bars, splitter bars, etc.
|
||||||
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
|
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
|
||||||
$colorA: #999;
|
$colorA: #999;
|
||||||
$colorAHov: $colorKey;
|
$colorAHov: $colorKey;
|
||||||
@ -94,51 +103,52 @@ $colorPausedFg: #fff;
|
|||||||
$colorOk: #33cc33;
|
$colorOk: #33cc33;
|
||||||
|
|
||||||
// Base variations
|
// Base variations
|
||||||
$colorBodyBgSubtle: darken($colorBodyBg, 5%);
|
$colorBodyBgSubtle: pullForward($colorBodyBg, 5%);
|
||||||
$colorBodyBgSubtleHov: lighten($colorKey, 50%);
|
$colorBodyBgSubtleHov: pushBack($colorKey, 50%);
|
||||||
$colorKeySubtle: lighten($colorKey, 50%);
|
$colorKeySubtle: pushBack($colorKey, 10%);
|
||||||
|
|
||||||
// Time Colors
|
// Time Colors
|
||||||
$colorTime: #618cff;
|
$colorTime: #618cff;
|
||||||
$colorTimeBg: $colorTime;
|
$colorTimeBg: $colorTime;
|
||||||
$colorTimeFg: $colorBodyBg;
|
$colorTimeFg: $colorBodyBg;
|
||||||
$colorTimeHov: lighten($colorTime, 5%);
|
$colorTimeHov: pushBack($colorTime, 5%);
|
||||||
$colorTimeSubtle: lighten($colorTime, 20%);
|
$colorTimeSubtle: pushBack($colorTime, 20%);
|
||||||
$colorTOI: $colorBodyFg; // was $timeControllerToiLineColor
|
$colorTOI: $colorBodyFg; // was $timeControllerToiLineColor
|
||||||
$colorTOIHov: $colorTime; // was $timeControllerToiLineColorHov
|
$colorTOIHov: $colorTime; // was $timeControllerToiLineColorHov
|
||||||
|
|
||||||
/************************************************** EDITING */
|
|
||||||
// Base Colors
|
|
||||||
$dlSpread: 20%;
|
|
||||||
$editColor: #00c7c3;
|
|
||||||
$editColorAlt: #9971ff;
|
|
||||||
$editColorBgBase: darken($editColor, $dlSpread);
|
|
||||||
$editColorBg: darken($editColor, $dlSpread);
|
|
||||||
$editColorFg: lighten($editColor, $dlSpread);
|
|
||||||
$editColorHov: lighten($editColor, 20%);
|
|
||||||
// Canvas
|
|
||||||
$editCanvasColorBg: #e6ffff;
|
|
||||||
$editCanvasColorGrid: darken($editCanvasColorBg, 10%);
|
|
||||||
// Selectable
|
|
||||||
$editSelectableColor: #acdad6;
|
|
||||||
$editSelectableColorFg: darken($editSelectableColor, 20%);
|
|
||||||
$editSelectableColorHov: darken($editSelectableColor, 10%);
|
|
||||||
// Selectable selected
|
|
||||||
$editSelectableColorSelected: $editColor;
|
|
||||||
$editSelectableColorSelectedFg: lighten($editSelectableColorSelected, 50%);
|
|
||||||
$editSelectableColorFg: darken($editSelectableColor, 40%);
|
|
||||||
$editSelectableBorder: 1px dotted $editSelectableColor;
|
|
||||||
$editSelectableBorderHov: 1px dotted $editColorAlt;
|
|
||||||
$editSelectableBorderSelected: 1px solid $editColor;
|
|
||||||
$editSelectableShdwSelected: rgba($editColor, 0.75) 0 0 0 1px;
|
|
||||||
$editMoveableSelectedShdw: rgba($editColor, 0.5) 0 0 10px;
|
|
||||||
$editBorderDrilledIn: 1px dashed $editColorAlt;
|
|
||||||
$colorGridLines: rgba($editColor, 0.2);
|
|
||||||
|
|
||||||
/************************************************** BROWSING */
|
/************************************************** BROWSING */
|
||||||
$browseSelectableBorderHov: 1px dotted rgba($colorBodyFg, 0.2);
|
$browseFrameColor: pullForward($colorBodyBg, 10%);
|
||||||
$browseSelectableShdwHov: rgba($colorBodyFg, 0.2) 0 0 3px;
|
$browseFrameBorder: 1px solid $browseFrameColor; // Frames in Disp and Flex Layouts when frame is showing
|
||||||
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.6);
|
$browseSelectableShdwHov: rgba($colorBodyFg, 0.3) 0 0 3px;
|
||||||
|
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.4);
|
||||||
|
|
||||||
|
/************************************************** EDITING */
|
||||||
|
$editUIColor: $uiColor; // Base color
|
||||||
|
$editUIColorHov: pullForward(saturate($uiColor, 10%), 20%); // Hover color when $editUIColor is applied as a base color
|
||||||
|
$editUIBaseColor: #cae1ff; // Base color, toolbar bg
|
||||||
|
$editUIBaseColorHov: pushBack($editUIBaseColor, 20%);
|
||||||
|
$editUIBaseColorFg: #4c4c4c; // Toolbar button icon colors, etc.
|
||||||
|
$editUIAreaBaseColor: pullForward(saturate($editUIBaseColor, 30%), 20%);
|
||||||
|
$editUIAreaShdw: $editUIAreaBaseColor 0 0 0 2px; // Edit area s-selected-parent
|
||||||
|
$editUIAreaShdwSelected: $editUIAreaBaseColor 0 0 0 3px; // Edit area s-selected
|
||||||
|
$editUIGridColorBg: rgba($editUIBaseColor, 0.2); // Background of layout editing area
|
||||||
|
$editUIGridColorFg: rgba($editUIBaseColor, 0.3); // Grid lines in layout editing area
|
||||||
|
$editFrameColor: $browseFrameColor; // Solid or dotted border applied to non-selected frames in a layout; move-bar on frame hover
|
||||||
|
$editFrameBorder: 1px dotted $editFrameColor;
|
||||||
|
$editFrameColorHov: $editUIColor; // Solid border hover on frames; hover should not be applied to selected objects
|
||||||
|
$editFrameBorderHov: 1px solid $editFrameColorHov; // Hover on selectable frames
|
||||||
|
$editFrameColorSelected: #333; // Border of selected frames
|
||||||
|
$editFrameColorHandleBg: $colorBodyBg; // Resize handle 'offset' color to make handle standout
|
||||||
|
$editFrameColorHandleFg: $editFrameColorSelected; // Resize handle main color
|
||||||
|
$editFrameSelectedShdw: rgba(black, 0.5) 0 1px 10px 1px;
|
||||||
|
$editFrameSelectedBorder: 1px dashed $editFrameColorSelected; // Selected frame element
|
||||||
|
$editFrameMovebarColorBg: $editFrameColor; // Movebar bg color
|
||||||
|
$editFrameMovebarColorFg: pullForward($editFrameMovebarColorBg, 20%); // Grippy lines, container size text
|
||||||
|
$editFrameHovMovebarColorBg: pullForward($editFrameMovebarColorBg, 10%); // Hover style
|
||||||
|
$editFrameHovMovebarColorFg: pullForward($editFrameMovebarColorFg, 10%);
|
||||||
|
$editFrameSelectedMovebarColorBg: pullForward($editFrameMovebarColorBg, 15%); // Selected style
|
||||||
|
$editFrameSelectedMovebarColorFg: pullForward($editFrameMovebarColorFg, 15%);
|
||||||
|
$editFrameMovebarH: 10px; // Height of move bar in layout frame
|
||||||
|
|
||||||
// Icons
|
// Icons
|
||||||
$colorIconAlias: #4af6f3;
|
$colorIconAlias: #4af6f3;
|
||||||
@ -149,7 +159,7 @@ $colorTabsHolderBg: rgba($colorBodyFg, 0.2);
|
|||||||
|
|
||||||
// Buttons and Controls
|
// Buttons and Controls
|
||||||
$colorBtnBg: #aaa;
|
$colorBtnBg: #aaa;
|
||||||
$colorBtnBgHov: darken($colorBtnBg, 10%);
|
$colorBtnBgHov: pullForward($colorBtnBg, 10%);
|
||||||
$colorBtnFg: #fff;
|
$colorBtnFg: #fff;
|
||||||
$colorBtnReverseFg: $colorBodyBg;
|
$colorBtnReverseFg: $colorBodyBg;
|
||||||
$colorBtnReverseBg: $colorBodyFg;
|
$colorBtnReverseBg: $colorBodyFg;
|
||||||
@ -157,7 +167,7 @@ $colorBtnFgHov: $colorBtnFg;
|
|||||||
$colorBtnMajorBg: $colorKey;
|
$colorBtnMajorBg: $colorKey;
|
||||||
$colorBtnMajorBgHov: $colorKeyHov;
|
$colorBtnMajorBgHov: $colorKeyHov;
|
||||||
$colorBtnMajorFg: $colorKeyFg;
|
$colorBtnMajorFg: $colorKeyFg;
|
||||||
$colorBtnMajorFgHov: lighten($colorBtnMajorFg, 10%);
|
$colorBtnMajorFgHov: pushBack($colorBtnMajorFg, 10%);
|
||||||
$colorBtnCautionBg: #f16f6f;
|
$colorBtnCautionBg: #f16f6f;
|
||||||
$colorBtnCautionBgHov: #f1504e;
|
$colorBtnCautionBgHov: #f1504e;
|
||||||
$colorBtnCautionFg: $colorBtnFg;
|
$colorBtnCautionFg: $colorBtnFg;
|
||||||
@ -165,15 +175,15 @@ $colorClickIcon: $colorKey;
|
|||||||
$colorClickIconBgHov: rgba($colorKey, 0.2);
|
$colorClickIconBgHov: rgba($colorKey, 0.2);
|
||||||
$colorClickIconFgHov: $colorKeyHov;
|
$colorClickIconFgHov: $colorKeyHov;
|
||||||
$colorDropHint: $colorKey;
|
$colorDropHint: $colorKey;
|
||||||
$colorDropHintBg: lighten($colorDropHint, 30%);
|
$colorDropHintBg: pushBack($colorDropHint, 10%);
|
||||||
$colorDropHintBgHov: lighten($colorDropHint, 40%);
|
$colorDropHintBgHov: pushBack($colorDropHint, 40%);
|
||||||
$colorDropHintFg: lighten($colorDropHint, 0);
|
$colorDropHintFg: pushBack($colorDropHint, 0);
|
||||||
$colorDisclosureCtrl: rgba($colorBodyFg, 0.5);
|
$colorDisclosureCtrl: rgba($colorBodyFg, 0.5);
|
||||||
$colorDisclosureCtrlHov: rgba($colorBodyFg, 0.7);
|
$colorDisclosureCtrlHov: rgba($colorBodyFg, 0.7);
|
||||||
|
|
||||||
// Menus
|
// Menus
|
||||||
$colorMenuBg: lighten($colorBodyBg, 10%);
|
$colorMenuBg: pushBack($colorBodyBg, 10%);
|
||||||
$colorMenuFg: darken($colorMenuBg, 70%);
|
$colorMenuFg: pullForward($colorMenuBg, 70%);
|
||||||
$colorMenuIc: $colorKey;
|
$colorMenuIc: $colorKey;
|
||||||
$colorMenuHovBg: $colorMenuIc;
|
$colorMenuHovBg: $colorMenuIc;
|
||||||
$colorMenuHovFg: $colorMenuBg;
|
$colorMenuHovFg: $colorMenuBg;
|
||||||
@ -200,27 +210,27 @@ $colorFormLines: rgba(#000, 0.1);
|
|||||||
$colorFormSectionHeader: rgba(#000, 0.05);
|
$colorFormSectionHeader: rgba(#000, 0.05);
|
||||||
$colorInputBg: $colorGenBg;
|
$colorInputBg: $colorGenBg;
|
||||||
$colorInputFg: $colorBodyFg;
|
$colorInputFg: $colorBodyFg;
|
||||||
$colorInputPlaceholder: lighten($colorBodyFg, 20%);
|
$colorInputPlaceholder: pushBack($colorBodyFg, 20%);
|
||||||
$colorFormText: lighten($colorBodyFg, 10%);
|
$colorFormText: pushBack($colorBodyFg, 10%);
|
||||||
$colorInputIcon: lighten($colorBodyFg, 25%);
|
$colorInputIcon: pushBack($colorBodyFg, 25%);
|
||||||
$colorFieldHint: darken($colorBodyFg, 40%);
|
$colorFieldHint: pullForward($colorBodyFg, 40%);
|
||||||
$shdwInput: inset rgba(black, 0.7) 0 0 1px;
|
$shdwInput: inset rgba(black, 0.7) 0 0 1px;
|
||||||
$shdwInputHov: inset rgba(black, 0.7) 0 0 2px;
|
$shdwInputHov: inset rgba(black, 0.7) 0 0 2px;
|
||||||
$shdwInputFoc: inset rgba(black, 0.8) 0 0.25px 3px;
|
$shdwInputFoc: inset rgba(black, 0.8) 0 0.25px 3px;
|
||||||
|
|
||||||
// Inspector
|
// Inspector
|
||||||
$colorInspectorBg: darken($colorBodyBg, 5%);
|
$colorInspectorBg: pullForward($colorBodyBg, 5%);
|
||||||
$colorInspectorFg: $colorBodyFg;
|
$colorInspectorFg: $colorBodyFg;
|
||||||
$colorInspectorPropName: lighten($colorBodyFg, 20%);
|
$colorInspectorPropName: pushBack($colorBodyFg, 20%);
|
||||||
$colorInspectorPropVal: darken($colorInspectorFg, 15%);
|
$colorInspectorPropVal: pullForward($colorInspectorFg, 15%);
|
||||||
$colorInspectorSectionHeaderBg: darken($colorInspectorBg, 5%);
|
$colorInspectorSectionHeaderBg: pullForward($colorInspectorBg, 5%);
|
||||||
$colorInspectorSectionHeaderFg: darken($colorInspectorBg, 40%);
|
$colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
|
||||||
|
|
||||||
// Overlay
|
// Overlay
|
||||||
$overlayColorBg: $colorMenuBg;
|
$overlayColorBg: $colorMenuBg;
|
||||||
$overlayColorFg: $colorMenuFg;
|
$overlayColorFg: $colorMenuFg;
|
||||||
$overlayCr: $interiorMarginLg;
|
$overlayCr: $interiorMarginLg;
|
||||||
$overlayBrightnessAdjust: brightness(1);
|
$overlayBrightnessAdjust: brightness(1.3);
|
||||||
|
|
||||||
// Indicator colors
|
// Indicator colors
|
||||||
$colorIndicatorAvailable: $colorKey;
|
$colorIndicatorAvailable: $colorKey;
|
||||||
@ -229,8 +239,8 @@ $colorIndicatorOn: $colorOk;
|
|||||||
$colorIndicatorOff: #666;
|
$colorIndicatorOff: #666;
|
||||||
|
|
||||||
// Staleness
|
// Staleness
|
||||||
$colorTelemFresh: darken($colorBodyFg, 20%);
|
$colorTelemFresh: pullForward($colorBodyFg, 20%);
|
||||||
$colorTelemStale: lighten($colorBodyFg, 20%);
|
$colorTelemStale: pushBack($colorBodyFg, 20%);
|
||||||
$styleTelemStale: italic;
|
$styleTelemStale: italic;
|
||||||
|
|
||||||
// Limits
|
// Limits
|
||||||
@ -255,23 +265,23 @@ $colorInfoBubbleBg: $colorMenuBg;
|
|||||||
$colorInfoBubbleFg: #666;
|
$colorInfoBubbleFg: #666;
|
||||||
|
|
||||||
// Items
|
// Items
|
||||||
$colorItemBg: lighten($colorBtnBg, 20%);
|
$colorItemBg: pushBack($colorBtnBg, 20%);
|
||||||
$colorItemBgHov: lighten($colorItemBg, 5%);
|
$colorItemBgHov: pushBack($colorItemBg, 5%);
|
||||||
$colorListItemBg: transparent;
|
$colorListItemBg: transparent;
|
||||||
$colorListItemBgHov: rgba($colorKey, 0.1);
|
$colorListItemBgHov: rgba($colorKey, 0.1);
|
||||||
$colorItemFg: $colorBodyFg;
|
$colorItemFg: $colorBodyFg;
|
||||||
$colorItemFgDetails: lighten($colorItemFg, 15%);
|
$colorItemFgDetails: pushBack($colorItemFg, 15%);
|
||||||
$shdwItemText: none;
|
$shdwItemText: none;
|
||||||
|
|
||||||
// Tabular
|
// Tabular
|
||||||
$colorTabBorder: darken($colorBodyBg, 10%);
|
$colorTabBorder: pullForward($colorBodyBg, 10%);
|
||||||
$colorTabBodyBg: $colorBodyBg;
|
$colorTabBodyBg: $colorBodyBg;
|
||||||
$colorTabBodyFg: darken($colorBodyFg, 20%);
|
$colorTabBodyFg: pullForward($colorBodyFg, 20%);
|
||||||
$colorTabHeaderBg: darken($colorBodyBg, 10%);
|
$colorTabHeaderBg: pullForward($colorBodyBg, 10%);
|
||||||
$colorTabHeaderFg: darken($colorBodyFg, 20%);
|
$colorTabHeaderFg: pullForward($colorBodyFg, 20%);
|
||||||
$colorTabHeaderBorder: $colorBodyBg;
|
$colorTabHeaderBorder: $colorBodyBg;
|
||||||
$colorTabGroupHeaderBg: darken($colorBodyBg, 5%);
|
$colorTabGroupHeaderBg: pullForward($colorBodyBg, 5%);
|
||||||
$colorTabGroupHeaderFg: darken($colorTabGroupHeaderBg, 40%);
|
$colorTabGroupHeaderFg: pullForward($colorTabGroupHeaderBg, 40%);
|
||||||
|
|
||||||
// Plot
|
// Plot
|
||||||
$colorPlotBg: rgba(black, 0.05);
|
$colorPlotBg: rgba(black, 0.05);
|
||||||
@ -280,22 +290,22 @@ $colorPlotHash: black;
|
|||||||
$opacityPlotHash: 0.2;
|
$opacityPlotHash: 0.2;
|
||||||
$stylePlotHash: dashed;
|
$stylePlotHash: dashed;
|
||||||
$colorPlotAreaBorder: $colorInteriorBorder;
|
$colorPlotAreaBorder: $colorInteriorBorder;
|
||||||
$colorPlotLabelFg: lighten($colorPlotFg, 20%);
|
$colorPlotLabelFg: pushBack($colorPlotFg, 20%);
|
||||||
$legendHoverValueBg: rgba($colorBodyFg, 0.2);
|
$legendHoverValueBg: rgba($colorBodyFg, 0.2);
|
||||||
|
|
||||||
// Tree
|
// Tree
|
||||||
$colorTreeBg: transparent;
|
$colorTreeBg: transparent;
|
||||||
$colorItemTreeHoverBg: darken($colorBodyBg, 10%);
|
$colorItemTreeHoverBg: pullForward($colorBodyBg, 10%);
|
||||||
$colorItemTreeHoverFg: darken($colorBodyFg, 10%);
|
$colorItemTreeHoverFg: pullForward($colorBodyFg, 10%);
|
||||||
$colorItemTreeIcon: $colorKey; // Used
|
$colorItemTreeIcon: $colorKey; // Used
|
||||||
$colorItemTreeIconHover: $colorItemTreeIcon; // Used
|
$colorItemTreeIconHover: $colorItemTreeIcon; // Used
|
||||||
$colorItemTreeFg: $colorBodyFg;
|
$colorItemTreeFg: $colorBodyFg;
|
||||||
$colorItemTreeSelectedBg: lighten($colorKey, 15%);
|
$colorItemTreeSelectedBg: pushBack($colorKey, 15%);
|
||||||
$colorItemTreeSelectedFg: $colorBodyBg;
|
$colorItemTreeSelectedFg: $colorBodyBg;
|
||||||
$colorItemTreeSelectedIcon: $colorItemTreeSelectedFg;
|
$colorItemTreeSelectedIcon: $colorItemTreeSelectedFg;
|
||||||
$colorItemTreeEditingBg: $editColor;
|
$colorItemTreeEditingBg: pushBack($editUIColor, 20%);
|
||||||
$colorItemTreeEditingFg: $editColorFg;
|
$colorItemTreeEditingFg: $editUIColor;
|
||||||
$colorItemTreeEditingIcon: $editColorFg;
|
$colorItemTreeEditingIcon: $editUIColor;
|
||||||
$colorItemTreeVC: $colorDisclosureCtrl;
|
$colorItemTreeVC: $colorDisclosureCtrl;
|
||||||
$colorItemTreeVCHover: $colorDisclosureCtrlHov;
|
$colorItemTreeVCHover: $colorDisclosureCtrlHov;
|
||||||
$shdwItemTreeIcon: none;
|
$shdwItemTreeIcon: none;
|
||||||
@ -307,16 +317,16 @@ $colorThumbHoverBg: $colorItemTreeHoverBg;
|
|||||||
$scrollbarTrackSize: 7px;
|
$scrollbarTrackSize: 7px;
|
||||||
$scrollbarTrackShdw: rgba(#000, 0.2) 0 1px 2px;
|
$scrollbarTrackShdw: rgba(#000, 0.2) 0 1px 2px;
|
||||||
$scrollbarTrackColorBg: rgba(#000, 0.2);
|
$scrollbarTrackColorBg: rgba(#000, 0.2);
|
||||||
$scrollbarThumbColor: darken($colorBodyBg, 50%);
|
$scrollbarThumbColor: pullForward($colorBodyBg, 50%);
|
||||||
$scrollbarThumbColorHov: $colorKey;
|
$scrollbarThumbColorHov: $colorKey;
|
||||||
$scrollbarThumbColorMenu: darken($colorMenuBg, 10%);
|
$scrollbarThumbColorMenu: pullForward($colorMenuBg, 10%);
|
||||||
$scrollbarThumbColorMenuHov: darken($scrollbarThumbColorMenu, 2%);
|
$scrollbarThumbColorMenuHov: darken($scrollbarThumbColorMenu, 2%);
|
||||||
|
|
||||||
// Splitter
|
// Splitter
|
||||||
$splitterHandleD: 2px;
|
$splitterHandleD: 2px;
|
||||||
$splitterHandleHitMargin: 4px;
|
$splitterHandleHitMargin: 4px;
|
||||||
$colorSplitterBaseBg: $colorBodyBg;
|
$colorSplitterBaseBg: $colorBodyBg;
|
||||||
$colorSplitterBg: darken($colorSplitterBaseBg, 20%);
|
$colorSplitterBg: pullForward($colorSplitterBaseBg, 20%);
|
||||||
$colorSplitterFg: $colorBodyBg;
|
$colorSplitterFg: $colorBodyBg;
|
||||||
$colorSplitterHover: $colorKey;
|
$colorSplitterHover: $colorKey;
|
||||||
$colorSplitterActive: $colorKey;
|
$colorSplitterActive: $colorKey;
|
||||||
@ -330,7 +340,7 @@ $splitterCollapsedBtnColorBgHov: $colorKey;
|
|||||||
$splitterCollapsedBtnColorFgHov: $colorKeyFg;
|
$splitterCollapsedBtnColorFgHov: $colorKeyFg;
|
||||||
|
|
||||||
// Mobile
|
// Mobile
|
||||||
$colorMobilePaneLeft: darken($colorBodyBg, 2%);
|
$colorMobilePaneLeft: pullForward($colorBodyBg, 2%);
|
||||||
$colorMobilePaneLeftTreeItemBg: rgba($colorBodyFg, 0.1);
|
$colorMobilePaneLeftTreeItemBg: rgba($colorBodyFg, 0.1);
|
||||||
$colorMobilePaneLeftTreeItemFg: $colorItemTreeFg;
|
$colorMobilePaneLeftTreeItemFg: $colorItemTreeFg;
|
||||||
$colorMobileSelectListTreeItemBg: rgba(#000, 0.05);
|
$colorMobileSelectListTreeItemBg: rgba(#000, 0.05);
|
||||||
@ -370,16 +380,6 @@ $createBtnTextTransform: uppercase;
|
|||||||
background: $c;
|
background: $c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@mixin themedSelect($bg: $colorBtnBg, $fg: $colorBtnFg) {
|
||||||
/**************************************************** NOT USED, LEAVE FOR NOW */
|
@include cSelect($bg, $fg, lighten($bg, 20%), none);
|
||||||
|
}
|
||||||
// Content status
|
|
||||||
/*
|
|
||||||
$colorAlert: #ff3c00;
|
|
||||||
$colorWarningHi: #990000;
|
|
||||||
$colorWarningLo: #ff9900;
|
|
||||||
$colorDiagnostic: #a4b442;
|
|
||||||
$colorCommand: #3693bd;
|
|
||||||
$colorInfo: #2294a2;
|
|
||||||
$colorOk: #33cc33;
|
|
||||||
*/
|
|
||||||
|
@ -228,6 +228,17 @@ input[type=number]::-webkit-outer-spin-button {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SELECTS
|
||||||
|
select {
|
||||||
|
@include appearanceNone();
|
||||||
|
@include themedSelect();
|
||||||
|
background-repeat: no-repeat, no-repeat;
|
||||||
|
background-position: right .4em top 80%, 0 0;
|
||||||
|
border: none;
|
||||||
|
border-radius: $controlCr;
|
||||||
|
padding: 1px 20px 1px $interiorMargin;
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************** HYPERLINKS AND HYPERLINK BUTTONS */
|
/******************************************************** HYPERLINKS AND HYPERLINK BUTTONS */
|
||||||
.c-hyperlink {
|
.c-hyperlink {
|
||||||
&--link {
|
&--link {
|
||||||
@ -411,7 +422,7 @@ input[type=number]::-webkit-outer-spin-button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@mixin cToolbarSeparator() {
|
@mixin cToolbarSeparator() {
|
||||||
$m: $interiorMargin;
|
$m: 1px;
|
||||||
$b: 1px;
|
$b: 1px;
|
||||||
display: block;
|
display: block;
|
||||||
width: $m + $b; // Allow for border
|
width: $m + $b; // Allow for border
|
||||||
@ -421,21 +432,35 @@ input[type=number]::-webkit-outer-spin-button {
|
|||||||
|
|
||||||
.c-toolbar {
|
.c-toolbar {
|
||||||
$p: $interiorMargin;
|
$p: $interiorMargin;
|
||||||
border-top: 1px solid $colorInteriorBorder;
|
background: $editUIBaseColor;
|
||||||
|
border-radius: $basicCr;
|
||||||
height: $p + 24px; // Need to standardize the height
|
height: $p + 24px; // Need to standardize the height
|
||||||
padding-top: $p;
|
padding: $p;
|
||||||
|
|
||||||
|
> * + * {
|
||||||
|
margin-left: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
&__separator {
|
&__separator {
|
||||||
@include cToolbarSeparator();
|
@include cToolbarSeparator();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.c-click-icon,
|
||||||
|
.c-labeled-input {
|
||||||
|
color: $editUIBaseColorFg;
|
||||||
|
}
|
||||||
|
|
||||||
.c-click-icon {
|
.c-click-icon {
|
||||||
@include cControl();
|
@include cControl();
|
||||||
$pLR: $interiorMargin - 1;
|
$pLR: $interiorMargin - 1;
|
||||||
$pTB: 2px;
|
$pTB: 2px;
|
||||||
color: $colorBodyFg;
|
|
||||||
padding: $pTB $pLR;
|
padding: $pTB $pLR;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: $editUIBaseColorHov !important;
|
||||||
|
color: $editUIBaseColorFg !important;
|
||||||
|
}
|
||||||
|
|
||||||
&--swatched {
|
&--swatched {
|
||||||
padding-bottom: floor($pTB / 2);
|
padding-bottom: floor($pTB / 2);
|
||||||
width: 2em; // Standardize the width
|
width: 2em; // Standardize the width
|
||||||
|
@ -191,8 +191,8 @@ body.desktop .has-local-controls {
|
|||||||
.c-grid {
|
.c-grid {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
|
|
||||||
&__x { @include bgTicks($editCanvasColorGrid, 'x'); }
|
&__x { @include bgTicks($editUIGridColorFg, 'x'); }
|
||||||
&__y { @include bgTicks($editCanvasColorGrid, 'y'); }
|
&__y { @include bgTicks($editUIGridColorFg, 'y'); }
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************** SELECTION */
|
/*************************** SELECTION */
|
||||||
@ -200,32 +200,14 @@ body.desktop .has-local-controls {
|
|||||||
&:hover {
|
&:hover {
|
||||||
box-shadow: $browseSelectableShdwHov;
|
box-shadow: $browseSelectableShdwHov;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&[s-selected] {
|
||||||
|
border: $browseSelectedBorder;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************** EDITING */
|
/**************************** EDITING */
|
||||||
.is-editing {
|
.is-editing {
|
||||||
*:not(.is-drilled-in).c-frame {
|
|
||||||
border: $editSelectableBorder;
|
|
||||||
|
|
||||||
&:not([s-selected]) {
|
|
||||||
&:hover {
|
|
||||||
border: $editSelectableBorderHov;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&[s-selected] {
|
|
||||||
box-shadow: $editSelectableShdwSelected;
|
|
||||||
|
|
||||||
> .c-frame-edit {
|
|
||||||
display: block; // Show the editing rect and handles
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*.is-drilled-in {
|
|
||||||
border: $editBorderDrilledIn;
|
|
||||||
}
|
|
||||||
|
|
||||||
.is-moveable {
|
.is-moveable {
|
||||||
cursor: move;
|
cursor: move;
|
||||||
}
|
}
|
||||||
@ -234,116 +216,8 @@ body.desktop .has-local-controls {
|
|||||||
// Applied in markup to objects that provide links. Disable while editing.
|
// Applied in markup to objects that provide links. Disable while editing.
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.c-frame-edit {
|
|
||||||
// In Layouts, this is the editing rect and handles
|
|
||||||
// In Fixed Position, this is a wrapper element
|
|
||||||
$z: 10;
|
|
||||||
|
|
||||||
@include abs();
|
|
||||||
display: none;
|
|
||||||
|
|
||||||
&__move {
|
|
||||||
@include abs();
|
|
||||||
box-shadow: $editMoveableSelectedShdw;
|
|
||||||
cursor: move;
|
|
||||||
z-index: $z;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__handle {
|
|
||||||
$d: 8px;
|
|
||||||
$o: floor($d * -0.5);
|
|
||||||
background: rgba($editColor, 0.3);
|
|
||||||
border: 1px solid $editColor;
|
|
||||||
position: absolute;
|
|
||||||
width: $d; height: $d;
|
|
||||||
top: auto; right: auto; bottom: auto; left: auto;
|
|
||||||
z-index: $z + 1;
|
|
||||||
|
|
||||||
&:before {
|
|
||||||
// Extended hit area
|
|
||||||
$m: -5px;
|
|
||||||
content: '';
|
|
||||||
display: block;
|
|
||||||
position: absolute;
|
|
||||||
top: $m; right: $m; bottom: $m; left: $m;
|
|
||||||
z-index: -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background: $editColor;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--nwse {
|
|
||||||
cursor: nwse-resize;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--nw {
|
|
||||||
cursor: nw-resize;
|
|
||||||
left: $o; top: $o;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--ne {
|
|
||||||
cursor: ne-resize;
|
|
||||||
right: $o; top: $o;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--se {
|
|
||||||
cursor: se-resize;
|
|
||||||
right: $o; bottom: $o;
|
|
||||||
}
|
|
||||||
|
|
||||||
&--sw {
|
|
||||||
cursor: sw-resize;
|
|
||||||
left: $o; bottom: $o;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: move this into DisplayLayout and Fixed Position vue files respectively
|
|
||||||
.l-shell__main-container > .l-layout,
|
|
||||||
.l-shell__main-container > .c-object-view .l-fixed-position {
|
|
||||||
// Target the top-most layout container and color its background
|
|
||||||
background: $editCanvasColorBg;
|
|
||||||
}
|
|
||||||
|
|
||||||
.l-shell__main-container {
|
|
||||||
box-shadow: $colorBodyBg 0 0 0 1px, rgba($editColor, 0.7) 0 0 0 2px;
|
|
||||||
&[s-selected] {
|
|
||||||
// Provide a clearer selection context articulation
|
|
||||||
box-shadow: $colorBodyBg 0 0 0 1px, $editColor 0 0 0px 3px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Layouts
|
|
||||||
[s-selected],
|
|
||||||
[s-selected-parent] {
|
|
||||||
.l-layout {
|
|
||||||
// Show the layout grid for the top-most child of the current selection,
|
|
||||||
// and hide the grid for deeper nested levels.
|
|
||||||
[class*="__grid-holder"] {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.l-layout [class*="__grid-holder"] {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fixed position
|
|
||||||
.l-fixed-position {
|
|
||||||
&__grid-holder {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.c-frame-edit {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************** LEGACY */
|
/************************** LEGACY */
|
||||||
|
|
||||||
mct-container {
|
mct-container {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user