mirror of
https://github.com/nasa/openmct.git
synced 2025-03-11 23:14:16 +00:00
Layout drawing (#2232)
* - Show "Add" button in the toolbar when a display layout object is selected. - Add a flag to object view's show() method to indicate immediate selection of the view. If the view implements getSelectionContext() use it, otherwise set to default context. * Create a component for each element. * Saving work * Add element factory for creating new instances of elements. * Mutate element when a new one added and get elements when the component is mounted. * Add create() method for creating a new telemetry and element in their respective view configuration. * Add some of the toolbar controls for box, text, image and line elements. Also, add X, Y, Width and Height controls for alhpanumeric elements. * Pass name to addElement as type. * Add c-frame-inspectable class if item is inspectable. * Clean up * Hide frame for summary widgets by default. * Better styling for editing - s-selected on shell__main-container; - Better edit grid coloring for espresso; * - Update toolbar-button to support dialogs. - Update toolbar to construct a value object based on form keys if a toolbar item has a dialogi, and mutate the form keys. - Add toolbar controls for editing text and url for 'Text' and 'Image' elements respectively. * Editing-related changes - Removed hard-coded .is-selectable and .is-moveable from LayoutItem.vue, updates accordingly to _global.scss; - Theme constants updated; - TODO: apply changes to Flexible Layouts; * Better defaults - Better default grid size and object size; * - Fix toolbar-input to read value as a number if type is 'number'. - Remove rawPosition from view configuration and instead get the position and dimensions from the properties (x, y, width and height) directly. - Set the style property on the view configuration instead of the layout item. - Move the logic for updating the style to the view configuration. * Fix default dimensions for telemetry items and subobjects since the default grid size is changed. * Remove form definition for display layout type. * Reword the comment * Let subobject view configuration handle new panel creation. * Add default grid size back and remove unused code. * Pass in only the needed method. * Define default position in case the object is not added via drag 'n drop.
This commit is contained in:
parent
32a0baa7a3
commit
e07cfc9394
@ -104,9 +104,9 @@ define([
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (openmct.editor.isEditing() &&
|
return (openmct.editor.isEditing() &&
|
||||||
(selection[0] && selection[0].context.elementProxy &&
|
selection[0] && selection[0].context.elementProxy &&
|
||||||
selection[1] && selection[1].context.item.type === 'telemetry.fixed' ||
|
((selection[1] && selection[1].context.item.type === 'telemetry.fixed') ||
|
||||||
selection[0] && selection[0].context.item.type === 'telemetry.fixed'));
|
(selection[0] && selection[0].context.item && selection[0].context.item.type === 'telemetry.fixed')));
|
||||||
},
|
},
|
||||||
toolbar: function (selection) {
|
toolbar: function (selection) {
|
||||||
var imageProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "height", "width", "url"];
|
var imageProperties = ["add", "remove", "order", "stroke", "useGrid", "x", "y", "height", "width", "url"];
|
||||||
|
@ -28,91 +28,116 @@ define([], function () {
|
|||||||
key: "layout",
|
key: "layout",
|
||||||
description: "A toolbar for objects inside a display layout.",
|
description: "A toolbar for objects inside a display layout.",
|
||||||
forSelection: function (selection) {
|
forSelection: function (selection) {
|
||||||
// Apply the layout toolbar if the selected object is inside a layout,
|
// Apply the layout toolbar if the edit mode is on, and the selected object
|
||||||
// and in edit mode.
|
// is inside a layout, or the main layout is selected.
|
||||||
return (selection &&
|
return (openmct.editor.isEditing() && selection &&
|
||||||
selection[1] &&
|
((selection[1] && selection[1].context.item && selection[1].context.item.type === 'layout') ||
|
||||||
selection[1].context.item &&
|
(selection[0].context.item && selection[0].context.item.type === 'layout')));
|
||||||
selection[1].context.item.type === 'layout' &&
|
|
||||||
openmct.editor.isEditing());
|
|
||||||
},
|
},
|
||||||
toolbar: function (selection) {
|
toolbar: function (selection) {
|
||||||
let domainObject = selection[1].context.item;
|
let selectedParent = selection[1] && selection[1].context.item,
|
||||||
let layoutItem = selection[0].context.layoutItem;
|
selectedObject = selection[0].context.item,
|
||||||
|
layoutItem = selection[0].context.layoutItem,
|
||||||
|
toolbar = [];
|
||||||
|
|
||||||
if (layoutItem && layoutItem.type === 'telemetry-view') {
|
if (selectedObject && selectedObject.type === 'layout') {
|
||||||
let path = "configuration.alphanumerics[" + layoutItem.config.alphanumeric.index + "]";
|
toolbar.push({
|
||||||
let metadata = openmct.telemetry.getMetadata(layoutItem.domainObject);
|
control: "menu",
|
||||||
|
domainObject: selectedObject,
|
||||||
|
method: function (option) {
|
||||||
|
selection[0].context.addElement(option.name.toLowerCase());
|
||||||
|
},
|
||||||
|
key: "add",
|
||||||
|
icon: "icon-plus",
|
||||||
|
label: "Add",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
"name": "Box",
|
||||||
|
"class": "icon-box-round-corners"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Line",
|
||||||
|
"class": "icon-line-horz"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Text",
|
||||||
|
"class": "icon-font"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Image",
|
||||||
|
"class": "icon-image"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!layoutItem) {
|
||||||
|
return toolbar;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (layoutItem.type === 'subobject-view') {
|
||||||
|
if (toolbar.length > 0) {
|
||||||
|
toolbar.push({
|
||||||
|
control: "separator"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
toolbar.push({
|
||||||
|
control: "toggle-button",
|
||||||
|
domainObject: selectedParent,
|
||||||
|
property: "configuration.panels[" + layoutItem.id + "].hasFrame",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: false,
|
||||||
|
icon: 'icon-frame-hide',
|
||||||
|
title: "Hide frame"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: true,
|
||||||
|
icon: 'icon-frame-show',
|
||||||
|
title: "Show frame"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
});
|
||||||
|
} else {
|
||||||
const TEXT_SIZE = [9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 30, 36, 48, 72, 96];
|
const TEXT_SIZE = [9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 30, 36, 48, 72, 96];
|
||||||
|
let path;
|
||||||
|
// TODO: get the path from the view configuration
|
||||||
|
// let path = layoutItem.config.path();
|
||||||
|
if (layoutItem.type === 'telemetry-view') {
|
||||||
|
path = "configuration.alphanumerics[" + layoutItem.config.alphanumeric.index + "]";
|
||||||
|
} else {
|
||||||
|
path = "configuration.elements[" + layoutItem.config.element.index + "]";
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
let separator = {
|
||||||
{
|
|
||||||
control: "select-menu",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".displayMode",
|
|
||||||
title: "Set display mode",
|
|
||||||
options: [
|
|
||||||
{
|
|
||||||
name: 'Label + Value',
|
|
||||||
value: 'all'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Label only",
|
|
||||||
value: "label"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "Value only",
|
|
||||||
value: "value"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "separator"
|
control: "separator"
|
||||||
},
|
},
|
||||||
{
|
fill = {
|
||||||
control: "select-menu",
|
|
||||||
domainObject: domainObject,
|
|
||||||
property: path + ".value",
|
|
||||||
title: "Set value",
|
|
||||||
options: metadata.values().map(value => {
|
|
||||||
return {
|
|
||||||
name: value.name,
|
|
||||||
value: value.key
|
|
||||||
}
|
|
||||||
})
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "separator"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "color-picker",
|
control: "color-picker",
|
||||||
domainObject: domainObject,
|
domainObject: selectedParent,
|
||||||
property: path + ".fill",
|
property: path + ".fill",
|
||||||
icon: "icon-paint-bucket",
|
icon: "icon-paint-bucket",
|
||||||
title: "Set fill color"
|
title: "Set fill color"
|
||||||
},
|
},
|
||||||
{
|
stroke = {
|
||||||
control: "color-picker",
|
control: "color-picker",
|
||||||
domainObject: domainObject,
|
domainObject: selectedParent,
|
||||||
property: path + ".stroke",
|
property: path + ".stroke",
|
||||||
icon: "icon-line-horz",
|
icon: "icon-line-horz",
|
||||||
title: "Set border color"
|
title: "Set border color"
|
||||||
},
|
},
|
||||||
{
|
color = {
|
||||||
control: "color-picker",
|
control: "color-picker",
|
||||||
domainObject: domainObject,
|
domainObject: selectedParent,
|
||||||
property: path + ".color",
|
property: path + ".color",
|
||||||
icon: "icon-font",
|
icon: "icon-font",
|
||||||
mandatory: true,
|
mandatory: true,
|
||||||
title: "Set text color",
|
title: "Set text color",
|
||||||
preventNone: true
|
preventNone: true
|
||||||
},
|
},
|
||||||
{
|
size = {
|
||||||
control: "separator"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
control: "select-menu",
|
control: "select-menu",
|
||||||
domainObject: domainObject,
|
domainObject: selectedParent,
|
||||||
property: path + ".size",
|
property: path + ".size",
|
||||||
title: "Set text size",
|
title: "Set text size",
|
||||||
options: TEXT_SIZE.map(size => {
|
options: TEXT_SIZE.map(size => {
|
||||||
@ -121,28 +146,181 @@ define([], function () {
|
|||||||
};
|
};
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
];
|
x = {
|
||||||
} else {
|
control: "input",
|
||||||
return [
|
type: "number",
|
||||||
{
|
domainObject: selectedParent,
|
||||||
control: "toggle-button",
|
property: path + ".x",
|
||||||
domainObject: domainObject,
|
label: "X:",
|
||||||
property: "configuration.panels[" + layoutItem.id + "].hasFrame",
|
title: "X position"
|
||||||
options: [
|
},
|
||||||
{
|
y = {
|
||||||
value: false,
|
control: "input",
|
||||||
icon: 'icon-frame-hide',
|
type: "number",
|
||||||
title: "Hide frame"
|
domainObject: selectedParent,
|
||||||
},
|
property: path + ".y",
|
||||||
{
|
label: "Y:",
|
||||||
value: true,
|
title: "Y position",
|
||||||
icon: 'icon-frame-show',
|
},
|
||||||
title: "Show frame"
|
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') {
|
||||||
|
// TODO: add "remove", "order", "useGrid"
|
||||||
|
let metadata = openmct.telemetry.getMetadata(layoutItem.domainObject),
|
||||||
|
displayMode = {
|
||||||
|
control: "select-menu",
|
||||||
|
domainObject: selectedParent,
|
||||||
|
property: path + ".displayMode",
|
||||||
|
title: "Set display mode",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
name: 'Label + Value',
|
||||||
|
value: 'all'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Label only",
|
||||||
|
value: "label"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Value only",
|
||||||
|
value: "value"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
value = {
|
||||||
|
control: "select-menu",
|
||||||
|
domainObject: selectedParent,
|
||||||
|
property: path + ".value",
|
||||||
|
title: "Set value",
|
||||||
|
options: metadata.values().map(value => {
|
||||||
|
return {
|
||||||
|
name: value.name,
|
||||||
|
value: value.key
|
||||||
|
}
|
||||||
|
})
|
||||||
|
};
|
||||||
|
toolbar = [
|
||||||
|
displayMode,
|
||||||
|
separator,
|
||||||
|
value,
|
||||||
|
separator,
|
||||||
|
fill,
|
||||||
|
stroke,
|
||||||
|
color,
|
||||||
|
separator,
|
||||||
|
size,
|
||||||
|
separator,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
height,
|
||||||
|
width
|
||||||
|
];
|
||||||
|
} else if (layoutItem.type === 'text-view' ) {
|
||||||
|
// TODO: Add "remove", "order", "useGrid"
|
||||||
|
let text = {
|
||||||
|
control: "button",
|
||||||
|
domainObject: selectedParent,
|
||||||
|
property: path,
|
||||||
|
icon: "icon-gear",
|
||||||
|
title: "Edit text properties",
|
||||||
|
dialog: {
|
||||||
|
name: "Text Element Properties",
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
rows: [
|
||||||
|
{
|
||||||
|
key: "text",
|
||||||
|
control: "textfield",
|
||||||
|
name: "Text",
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
toolbar = [
|
||||||
|
fill,
|
||||||
|
stroke,
|
||||||
|
color,
|
||||||
|
separator,
|
||||||
|
size,
|
||||||
|
separator,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
height,
|
||||||
|
width,
|
||||||
|
separator,
|
||||||
|
text
|
||||||
|
];
|
||||||
|
} else if (layoutItem.type === 'box-view') {
|
||||||
|
// TODO: Add "remove", "order", "useGrid"
|
||||||
|
toolbar = [
|
||||||
|
fill,
|
||||||
|
stroke,
|
||||||
|
separator,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
height,
|
||||||
|
width
|
||||||
|
];
|
||||||
|
} else if (layoutItem.type === 'image-view') {
|
||||||
|
// TODO: Add "remove", "order", "useGrid"
|
||||||
|
let url = {
|
||||||
|
control: "button",
|
||||||
|
domainObject: selectedParent,
|
||||||
|
property: path,
|
||||||
|
icon: "icon-image",
|
||||||
|
title: "Edit image properties",
|
||||||
|
dialog: {
|
||||||
|
name: "Image Properties",
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
rows: [
|
||||||
|
{
|
||||||
|
key: "url",
|
||||||
|
control: "textfield",
|
||||||
|
name: "Image URL",
|
||||||
|
"cssClass": "l-input-lg",
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
toolbar = [
|
||||||
|
stroke,
|
||||||
|
separator,
|
||||||
|
x,
|
||||||
|
y,
|
||||||
|
height,
|
||||||
|
width,
|
||||||
|
separator,
|
||||||
|
url
|
||||||
|
];
|
||||||
|
} else if (layoutItem.type === 'line-view') {
|
||||||
|
// TODO: Add "remove", "order", "useGrid", "x1", "y1", x2", "y2"
|
||||||
|
toolbar = [stroke];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return toolbar;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,8 @@ define(function () {
|
|||||||
domainObject.composition = [];
|
domainObject.composition = [];
|
||||||
domainObject.configuration = {
|
domainObject.configuration = {
|
||||||
panels: {},
|
panels: {},
|
||||||
alphanumerics: []
|
alphanumerics: [],
|
||||||
|
elements: []
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
171
src/plugins/displayLayout/ElementViewConfiguration.js
Normal file
171
src/plugins/displayLayout/ElementViewConfiguration.js
Normal file
@ -0,0 +1,171 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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(
|
||||||
|
['./ViewConfiguration'],
|
||||||
|
function (ViewConfiguration) {
|
||||||
|
class ElementViewConfiguration extends ViewConfiguration {
|
||||||
|
|
||||||
|
static create(type, openmct) {
|
||||||
|
const DEFAULT_WIDTH = 10,
|
||||||
|
DEFAULT_HEIGHT = 5,
|
||||||
|
DEFAULT_X = 1,
|
||||||
|
DEFAULT_Y = 1;
|
||||||
|
const INITIAL_STATES = {
|
||||||
|
"image": {
|
||||||
|
stroke: "transparent"
|
||||||
|
},
|
||||||
|
"box": {
|
||||||
|
fill: "#717171",
|
||||||
|
stroke: "transparent"
|
||||||
|
},
|
||||||
|
"line": {
|
||||||
|
x: 5,
|
||||||
|
y: 3,
|
||||||
|
x2: 6,
|
||||||
|
y2: 6,
|
||||||
|
stroke: "#717171"
|
||||||
|
},
|
||||||
|
"text": {
|
||||||
|
fill: "transparent",
|
||||||
|
stroke: "transparent",
|
||||||
|
size: "13px",
|
||||||
|
color: ""
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const DIALOGS = {
|
||||||
|
"image": {
|
||||||
|
name: "Image Properties",
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
rows: [
|
||||||
|
{
|
||||||
|
key: "url",
|
||||||
|
control: "textfield",
|
||||||
|
name: "Image URL",
|
||||||
|
"cssClass": "l-input-lg",
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"text": {
|
||||||
|
name: "Text Element Properties",
|
||||||
|
sections: [
|
||||||
|
{
|
||||||
|
rows: [
|
||||||
|
{
|
||||||
|
key: "text",
|
||||||
|
control: "textfield",
|
||||||
|
name: "Text",
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let element = INITIAL_STATES[type] || {};
|
||||||
|
element = JSON.parse(JSON.stringify(element));
|
||||||
|
element.x = element.x || DEFAULT_X;
|
||||||
|
element.y = element.y || DEFAULT_Y;
|
||||||
|
element.width = DEFAULT_WIDTH;
|
||||||
|
element.height = DEFAULT_HEIGHT;
|
||||||
|
element.type = type;
|
||||||
|
|
||||||
|
return DIALOGS[type] ?
|
||||||
|
openmct.$injector.get('dialogService').getUserInput(DIALOGS[type], element) :
|
||||||
|
element;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Object} configuration the element (line, box, text or image) view configuration
|
||||||
|
* @param {Object} configuration.element
|
||||||
|
* @param {Object} configuration.domainObject the telemetry domain object
|
||||||
|
* @param {Object} configuration.openmct the openmct object
|
||||||
|
*/
|
||||||
|
constructor({element, ...rest}) {
|
||||||
|
super(rest);
|
||||||
|
this.element = element;
|
||||||
|
this.updateStyle(this.position());
|
||||||
|
}
|
||||||
|
|
||||||
|
path() {
|
||||||
|
return "configuration.elements[" + this.element.index + "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
x() {
|
||||||
|
return this.element.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
y() {
|
||||||
|
return this.element.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
width() {
|
||||||
|
return this.element.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
height() {
|
||||||
|
return this.element.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
observeProperties() {
|
||||||
|
[
|
||||||
|
"width",
|
||||||
|
"height",
|
||||||
|
"stroke",
|
||||||
|
"fill",
|
||||||
|
"x",
|
||||||
|
"y",
|
||||||
|
"x1",
|
||||||
|
"y1",
|
||||||
|
"x2",
|
||||||
|
"y2",
|
||||||
|
"color",
|
||||||
|
"size",
|
||||||
|
"text",
|
||||||
|
"url"
|
||||||
|
].forEach(property => {
|
||||||
|
this.attachListener(property, newValue => {
|
||||||
|
this.element[property] = newValue;
|
||||||
|
|
||||||
|
if (property === 'width' || property === 'height' ||
|
||||||
|
property === 'x' || property === 'y') {
|
||||||
|
this.updateStyle();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO: attach listener for useGrid
|
||||||
|
}
|
||||||
|
|
||||||
|
inspectable() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ElementViewConfiguration;
|
||||||
|
}
|
||||||
|
);
|
@ -25,28 +25,94 @@ define(
|
|||||||
function (ViewConfiguration) {
|
function (ViewConfiguration) {
|
||||||
class SubobjectViewConfiguration extends ViewConfiguration {
|
class SubobjectViewConfiguration extends ViewConfiguration {
|
||||||
|
|
||||||
|
static create(domainObject, gridSize, position) {
|
||||||
|
const MINIMUM_FRAME_SIZE = [320, 180],
|
||||||
|
DEFAULT_DIMENSIONS = [10, 10],
|
||||||
|
DEFAULT_POSITION = [0, 0],
|
||||||
|
DEFAULT_HIDDEN_FRAME_TYPES = ['hyperlink', 'summary-widget'];
|
||||||
|
|
||||||
|
function getDefaultDimensions() {
|
||||||
|
return MINIMUM_FRAME_SIZE.map((min, index) => {
|
||||||
|
return Math.max(
|
||||||
|
Math.ceil(min / gridSize[index]),
|
||||||
|
DEFAULT_DIMENSIONS[index]
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasFrameByDefault(type) {
|
||||||
|
return DEFAULT_HIDDEN_FRAME_TYPES.indexOf(type) === -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
position = position || DEFAULT_POSITION;
|
||||||
|
let defaultDimensions = getDefaultDimensions();
|
||||||
|
let panel = {
|
||||||
|
width: defaultDimensions[0],
|
||||||
|
height: defaultDimensions[1],
|
||||||
|
x: position[0],
|
||||||
|
y: position[1],
|
||||||
|
hasFrame: hasFrameByDefault(domainObject.type)
|
||||||
|
};
|
||||||
|
|
||||||
|
return panel;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {Object} configuration the subobject view configuration
|
* @param {Object} configuration the subobject view configuration
|
||||||
* @param {String} configuration.id the domain object keystring identifier
|
* @param {String} configuration.id the domain object keystring identifier
|
||||||
* @param {Boolean} configuration.hasFrame flag to show/hide the frame
|
* @param {Boolean} configuration.panel
|
||||||
* @param {Object} configuration.domainObject the domain object
|
* @param {Object} configuration.domainObject the domain object to observe the changes on
|
||||||
* @param {Object} configuration.rawPosition an object that holds raw position and dimensions
|
|
||||||
* @param {Object} configuration.openmct the openmct object
|
* @param {Object} configuration.openmct the openmct object
|
||||||
*/
|
*/
|
||||||
constructor({id, hasFrame, ...rest}) {
|
constructor({panel, id, ...rest}) {
|
||||||
super(rest);
|
super(rest);
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.hasFrame = hasFrame;
|
this.panel = panel;
|
||||||
|
this.hasFrame = this.hasFrame.bind(this);
|
||||||
|
this.updateStyle(this.position());
|
||||||
}
|
}
|
||||||
|
|
||||||
path() {
|
path() {
|
||||||
return "configuration.panels[" + this.id + "]";
|
return "configuration.panels[" + this.id + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x() {
|
||||||
|
return this.panel.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
y() {
|
||||||
|
return this.panel.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
width() {
|
||||||
|
return this.panel.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
height() {
|
||||||
|
return this.panel.height;
|
||||||
|
}
|
||||||
|
|
||||||
|
hasFrame() {
|
||||||
|
return this.panel.hasFrame;
|
||||||
|
}
|
||||||
|
|
||||||
observeProperties() {
|
observeProperties() {
|
||||||
this.attachListener("hasFrame", newValue => {
|
[
|
||||||
this.hasFrame = newValue;
|
'hasFrame',
|
||||||
|
'x',
|
||||||
|
'y',
|
||||||
|
'width',
|
||||||
|
'height'
|
||||||
|
].forEach(property => {
|
||||||
|
this.attachListener(property, newValue => {
|
||||||
|
this.panel[property] = newValue;
|
||||||
|
|
||||||
|
if (property === 'width' || property === 'height' ||
|
||||||
|
property === 'x' || property === 'y') {
|
||||||
|
this.updateStyle();
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,24 +23,77 @@
|
|||||||
define(
|
define(
|
||||||
['./ViewConfiguration'],
|
['./ViewConfiguration'],
|
||||||
function (ViewConfiguration) {
|
function (ViewConfiguration) {
|
||||||
|
|
||||||
class TelemetryViewConfiguration extends ViewConfiguration {
|
class TelemetryViewConfiguration extends ViewConfiguration {
|
||||||
|
static create(domainObject, position, openmct) {
|
||||||
|
const DEFAULT_TELEMETRY_DIMENSIONS = [10, 5];
|
||||||
|
|
||||||
|
function getDefaultTelemetryValue(domainObject, openmct) {
|
||||||
|
let metadata = openmct.telemetry.getMetadata(domainObject);
|
||||||
|
let valueMetadata = metadata.valuesForHints(['range'])[0];
|
||||||
|
|
||||||
|
if (valueMetadata === undefined) {
|
||||||
|
valueMetadata = metadata.values().filter(values => {
|
||||||
|
return !(values.hints.domain);
|
||||||
|
})[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valueMetadata === undefined) {
|
||||||
|
valueMetadata = metadata.values()[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return valueMetadata.key;
|
||||||
|
}
|
||||||
|
|
||||||
|
let alphanumeric = {
|
||||||
|
identifier: domainObject.identifier,
|
||||||
|
x: position[0],
|
||||||
|
y: position[1],
|
||||||
|
width: DEFAULT_TELEMETRY_DIMENSIONS[0],
|
||||||
|
height: DEFAULT_TELEMETRY_DIMENSIONS[1],
|
||||||
|
displayMode: 'all',
|
||||||
|
value: getDefaultTelemetryValue(domainObject, openmct),
|
||||||
|
stroke: "transparent",
|
||||||
|
fill: "",
|
||||||
|
color: "",
|
||||||
|
size: "13px",
|
||||||
|
};
|
||||||
|
|
||||||
|
return alphanumeric;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Object} configuration the telemetry object view configuration
|
* @param {Object} configuration the telemetry object view configuration
|
||||||
* @param {Object} configuration.alphanumeric
|
* @param {Object} configuration.alphanumeric
|
||||||
* @param {Object} configuration.domainObject the telemetry domain object
|
* @param {Object} configuration.domainObject the domain object to observe the changes on
|
||||||
* @param {Object} configuration.rawPosition an object that holds raw position and dimensions
|
|
||||||
* @param {Object} configuration.openmct the openmct object
|
* @param {Object} configuration.openmct the openmct object
|
||||||
*/
|
*/
|
||||||
constructor({alphanumeric, ...rest}) {
|
constructor({alphanumeric, ...rest}) {
|
||||||
super(rest);
|
super(rest);
|
||||||
this.alphanumeric = alphanumeric;
|
this.alphanumeric = alphanumeric;
|
||||||
|
this.updateStyle(this.position());
|
||||||
}
|
}
|
||||||
|
|
||||||
path() {
|
path() {
|
||||||
return "configuration.alphanumerics[" + this.alphanumeric.index + "]";
|
return "configuration.alphanumerics[" + this.alphanumeric.index + "]";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x() {
|
||||||
|
return this.alphanumeric.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
y() {
|
||||||
|
return this.alphanumeric.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
width() {
|
||||||
|
return this.alphanumeric.width;
|
||||||
|
}
|
||||||
|
|
||||||
|
height() {
|
||||||
|
return this.alphanumeric.height;
|
||||||
|
}
|
||||||
|
|
||||||
observeProperties() {
|
observeProperties() {
|
||||||
[
|
[
|
||||||
'displayMode',
|
'displayMode',
|
||||||
@ -48,10 +101,19 @@ define(
|
|||||||
'fill',
|
'fill',
|
||||||
'stroke',
|
'stroke',
|
||||||
'color',
|
'color',
|
||||||
'size'
|
'size',
|
||||||
|
'x',
|
||||||
|
'y',
|
||||||
|
'width',
|
||||||
|
'height'
|
||||||
].forEach(property => {
|
].forEach(property => {
|
||||||
this.attachListener(property, newValue => {
|
this.attachListener(property, newValue => {
|
||||||
this.alphanumeric[property] = newValue;
|
this.alphanumeric[property] = newValue;
|
||||||
|
|
||||||
|
if (property === 'width' || property === 'height' ||
|
||||||
|
property === 'x' || property === 'y') {
|
||||||
|
this.updateStyle();
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -24,20 +24,23 @@
|
|||||||
function () {
|
function () {
|
||||||
class ViewConfiguration {
|
class ViewConfiguration {
|
||||||
|
|
||||||
constructor({domainObject, openmct, rawPosition}) {
|
constructor({domainObject, openmct, gridSize}) {
|
||||||
this.domainObject = domainObject;
|
this.domainObject = domainObject;
|
||||||
this.rawPosition = rawPosition;
|
this.gridSize = gridSize;
|
||||||
this.mutatePosition = this.mutatePosition.bind(this);
|
this.mutatePosition = this.mutatePosition.bind(this);
|
||||||
this.listeners = [];
|
this.listeners = [];
|
||||||
this.observe = openmct.objects.observe.bind(openmct.objects);
|
this.observe = openmct.objects.observe.bind(openmct.objects);
|
||||||
this.mutate = function (path, value) {
|
this.mutate = function (path, value) {
|
||||||
openmct.objects.mutate(this.domainObject, path, value);
|
openmct.objects.mutate(this.domainObject, path, value);
|
||||||
}.bind(this);
|
}.bind(this);
|
||||||
|
this.newPosition = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
mutatePosition() {
|
mutatePosition() {
|
||||||
this.mutate(this.path() + ".dimensions", this.rawPosition.dimensions);
|
this.mutate(this.path() + ".x", this.newPosition.position[0]);
|
||||||
this.mutate(this.path() + ".position", this.rawPosition.position);
|
this.mutate(this.path() + ".y", this.newPosition.position[1]);
|
||||||
|
this.mutate(this.path() + ".width", this.newPosition.dimensions[0]);
|
||||||
|
this.mutate(this.path() + ".height", this.newPosition.dimensions[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
attachListener(property, callback) {
|
attachListener(property, callback) {
|
||||||
@ -58,13 +61,59 @@
|
|||||||
this.listeners = [];
|
this.listeners = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
path() {
|
position() {
|
||||||
|
return {
|
||||||
|
position: [this.x(), this.y()],
|
||||||
|
dimensions: [this.width(), this.height()]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
path() {
|
||||||
throw "NOT IMPLEMENTED;"
|
throw "NOT IMPLEMENTED;"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inspectable() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateStyle(raw) {
|
||||||
|
if (!raw) {
|
||||||
|
raw = this.position();
|
||||||
|
}
|
||||||
|
|
||||||
|
this.style = {
|
||||||
|
left: (this.gridSize[0] * raw.position[0]) + 'px',
|
||||||
|
top: (this.gridSize[1] * raw.position[1]) + 'px',
|
||||||
|
width: (this.gridSize[0] * raw.dimensions[0]) + 'px',
|
||||||
|
height: (this.gridSize[1] * raw.dimensions[1]) + 'px',
|
||||||
|
minWidth: (this.gridSize[0] * raw.dimensions[0]) + 'px',
|
||||||
|
minHeight: (this.gridSize[1] * raw.dimensions[1]) + 'px'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
observeProperties() {
|
observeProperties() {
|
||||||
// Not implemented
|
// Not implemented
|
||||||
}
|
}
|
||||||
|
|
||||||
|
x() {
|
||||||
|
// Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
y() {
|
||||||
|
// Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
width() {
|
||||||
|
// Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
height() {
|
||||||
|
// Not implemented
|
||||||
|
}
|
||||||
|
|
||||||
|
hasFrame() {
|
||||||
|
// Not implemented
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ViewConfiguration;
|
return ViewConfiguration;
|
||||||
|
63
src/plugins/displayLayout/components/BoxView.vue
Normal file
63
src/plugins/displayLayout/components/BoxView.vue
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="c-box-view"
|
||||||
|
:style="styleObject">
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import '~styles/sass-base';
|
||||||
|
|
||||||
|
.c-box-view {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
|
||||||
|
.c-frame & {
|
||||||
|
@include abs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
item: Object
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
styleObject() {
|
||||||
|
let element = this.item.config.element;
|
||||||
|
return {
|
||||||
|
backgroundColor: element.fill,
|
||||||
|
border: '1px solid ' + element.stroke
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.item.config.attachListeners();
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
this.item.config.removeListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -88,15 +88,9 @@
|
|||||||
import LayoutItem from './LayoutItem.vue';
|
import LayoutItem from './LayoutItem.vue';
|
||||||
import TelemetryViewConfiguration from './../TelemetryViewConfiguration.js'
|
import TelemetryViewConfiguration from './../TelemetryViewConfiguration.js'
|
||||||
import SubobjectViewConfiguration from './../SubobjectViewConfiguration.js'
|
import SubobjectViewConfiguration from './../SubobjectViewConfiguration.js'
|
||||||
|
import ElementViewConfiguration from './../ElementViewConfiguration.js'
|
||||||
|
|
||||||
const DEFAULT_GRID_SIZE = [32, 32],
|
const DEFAULT_GRID_SIZE = [10, 10];
|
||||||
DEFAULT_DIMENSIONS = [12, 8],
|
|
||||||
DEFAULT_TELEMETRY_DIMENSIONS = [2, 1],
|
|
||||||
DEFAULT_POSITION = [0, 0],
|
|
||||||
MINIMUM_FRAME_SIZE = [320, 180],
|
|
||||||
DEFAULT_HIDDEN_FRAME_TYPES = [
|
|
||||||
'hyperlink'
|
|
||||||
];
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
@ -119,25 +113,25 @@
|
|||||||
this.makeTelemetryItem(alphanumeric, false);
|
this.makeTelemetryItem(alphanumeric, false);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
makeFrameItem(panel, initSelect) {
|
getElements() {
|
||||||
let rawPosition = {
|
let elements = this.newDomainObject.configuration.elements || [];
|
||||||
position: panel.position,
|
elements.forEach((element, index) => {
|
||||||
dimensions: panel.dimensions
|
element.index = index;
|
||||||
};
|
this.makeElementItem(element, false);
|
||||||
let style = this.convertPosition(rawPosition);
|
});
|
||||||
|
},
|
||||||
|
makeSubobjectItem(panel, initSelect) {
|
||||||
let id = this.openmct.objects.makeKeyString(panel.domainObject.identifier);
|
let id = this.openmct.objects.makeKeyString(panel.domainObject.identifier);
|
||||||
let config = new SubobjectViewConfiguration({
|
let config = new SubobjectViewConfiguration({
|
||||||
domainObject: this.newDomainObject,
|
domainObject: this.newDomainObject,
|
||||||
|
panel: panel,
|
||||||
id: id,
|
id: id,
|
||||||
hasFrame: panel.hasFrame,
|
openmct: openmct,
|
||||||
rawPosition: rawPosition,
|
gridSize: this.gridSize
|
||||||
openmct: openmct
|
|
||||||
});
|
});
|
||||||
|
|
||||||
this.layoutItems.push({
|
this.layoutItems.push({
|
||||||
id: id,
|
id: id,
|
||||||
domainObject: panel.domainObject,
|
domainObject: panel.domainObject,
|
||||||
style: style,
|
|
||||||
drilledIn: this.isItemDrilledIn(id),
|
drilledIn: this.isItemDrilledIn(id),
|
||||||
initSelect: initSelect,
|
initSelect: initSelect,
|
||||||
type: 'subobject-view',
|
type: 'subobject-view',
|
||||||
@ -145,60 +139,35 @@
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
makeTelemetryItem(alphanumeric, initSelect) {
|
makeTelemetryItem(alphanumeric, initSelect) {
|
||||||
let rawPosition = {
|
|
||||||
position: alphanumeric.position,
|
|
||||||
dimensions: alphanumeric.dimensions
|
|
||||||
};
|
|
||||||
let style = this.convertPosition(rawPosition);
|
|
||||||
let id = this.openmct.objects.makeKeyString(alphanumeric.identifier);
|
let id = this.openmct.objects.makeKeyString(alphanumeric.identifier);
|
||||||
|
|
||||||
this.openmct.objects.get(id).then(domainObject => {
|
this.openmct.objects.get(id).then(domainObject => {
|
||||||
let config = new TelemetryViewConfiguration({
|
let config = new TelemetryViewConfiguration({
|
||||||
domainObject: this.newDomainObject,
|
domainObject: this.newDomainObject,
|
||||||
alphanumeric: alphanumeric,
|
alphanumeric: alphanumeric,
|
||||||
rawPosition: rawPosition,
|
openmct: openmct,
|
||||||
openmct: openmct
|
gridSize: this.gridSize
|
||||||
});
|
});
|
||||||
|
|
||||||
this.layoutItems.push({
|
this.layoutItems.push({
|
||||||
id: id,
|
id: id,
|
||||||
domainObject: domainObject,
|
domainObject: domainObject,
|
||||||
style: style,
|
|
||||||
initSelect: initSelect,
|
initSelect: initSelect,
|
||||||
alphanumeric: alphanumeric,
|
|
||||||
type: 'telemetry-view',
|
type: 'telemetry-view',
|
||||||
config: config
|
config: config
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
getSubobjectDefaultDimensions() {
|
makeElementItem(element, initSelect) {
|
||||||
let gridSize = this.gridSize;
|
let config = new ElementViewConfiguration({
|
||||||
return MINIMUM_FRAME_SIZE.map(function (min, i) {
|
domainObject: this.newDomainObject,
|
||||||
return Math.max(
|
element: element,
|
||||||
Math.ceil(min / gridSize[i]),
|
openmct: openmct,
|
||||||
DEFAULT_DIMENSIONS[i]
|
gridSize: this.gridSize
|
||||||
);
|
});
|
||||||
|
this.layoutItems.push({
|
||||||
|
initSelect: initSelect,
|
||||||
|
type: element.type + '-view',
|
||||||
|
config: config
|
||||||
});
|
});
|
||||||
},
|
|
||||||
convertPosition(raw) {
|
|
||||||
return {
|
|
||||||
left: (this.gridSize[0] * raw.position[0]) + 'px',
|
|
||||||
top: (this.gridSize[1] * raw.position[1]) + 'px',
|
|
||||||
width: (this.gridSize[0] * raw.dimensions[0]) + 'px',
|
|
||||||
height: (this.gridSize[1] * raw.dimensions[1]) + 'px',
|
|
||||||
minWidth: (this.gridSize[0] * raw.dimensions[0]) + 'px',
|
|
||||||
minHeight: (this.gridSize[1] * raw.dimensions[1]) + 'px'
|
|
||||||
};
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Checks if the frame should be hidden or not.
|
|
||||||
*
|
|
||||||
* @param type the domain object type
|
|
||||||
* @return {boolean} true if the object should have
|
|
||||||
* frame by default, false, otherwise
|
|
||||||
*/
|
|
||||||
hasFrameByDefault(type) {
|
|
||||||
return DEFAULT_HIDDEN_FRAME_TYPES.indexOf(type) === -1;
|
|
||||||
},
|
},
|
||||||
setSelection(selection) {
|
setSelection(selection) {
|
||||||
if (selection.length === 0) {
|
if (selection.length === 0) {
|
||||||
@ -219,9 +188,8 @@
|
|||||||
return this.drilledIn === id;
|
return this.drilledIn === id;
|
||||||
},
|
},
|
||||||
updatePosition(item, newPosition) {
|
updatePosition(item, newPosition) {
|
||||||
let newStyle = this.convertPosition(newPosition);
|
item.config.newPosition = newPosition;
|
||||||
item.config.rawPosition = newPosition;
|
item.config.updateStyle(newPosition);
|
||||||
item.style = newStyle;
|
|
||||||
},
|
},
|
||||||
bypassSelection($event) {
|
bypassSelection($event) {
|
||||||
if (this.dragInProgress) {
|
if (this.dragInProgress) {
|
||||||
@ -236,7 +204,7 @@
|
|||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
this.dragInProgress = false;
|
this.dragInProgress = false;
|
||||||
}.bind(this), 0);
|
}.bind(this), 0);
|
||||||
|
// TODO: emit "finishResizing" for view components to mutate position?
|
||||||
item.config.mutatePosition();
|
item.config.mutatePosition();
|
||||||
},
|
},
|
||||||
mutate(path, value) {
|
mutate(path, value) {
|
||||||
@ -278,39 +246,12 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
addAlphanumeric(domainObject, position) {
|
addAlphanumeric(domainObject, position) {
|
||||||
let alphanumeric = {
|
|
||||||
identifier: domainObject.identifier,
|
|
||||||
position: position,
|
|
||||||
dimensions: DEFAULT_TELEMETRY_DIMENSIONS,
|
|
||||||
displayMode: 'all',
|
|
||||||
value: this.getDefaultTelemetryValue(domainObject),
|
|
||||||
stroke: "transparent",
|
|
||||||
fill: "",
|
|
||||||
color: "",
|
|
||||||
size: "13px",
|
|
||||||
};
|
|
||||||
let alphanumerics = this.newDomainObject.configuration.alphanumerics || [];
|
let alphanumerics = this.newDomainObject.configuration.alphanumerics || [];
|
||||||
|
let alphanumeric = TelemetryViewConfiguration.create(domainObject, position, this.openmct);
|
||||||
alphanumeric.index = alphanumerics.push(alphanumeric) - 1;
|
alphanumeric.index = alphanumerics.push(alphanumeric) - 1;
|
||||||
|
|
||||||
this.mutate("configuration.alphanumerics", alphanumerics);
|
this.mutate("configuration.alphanumerics", alphanumerics);
|
||||||
this.makeTelemetryItem(alphanumeric, true);
|
this.makeTelemetryItem(alphanumeric, true);
|
||||||
},
|
},
|
||||||
getDefaultTelemetryValue(domainObject) {
|
|
||||||
let metadata = this.openmct.telemetry.getMetadata(domainObject);
|
|
||||||
let valueMetadata = metadata.valuesForHints(['range'])[0];
|
|
||||||
|
|
||||||
if (valueMetadata === undefined) {
|
|
||||||
valueMetadata = metadata.values().filter(values => {
|
|
||||||
return !(values.hints.domain);
|
|
||||||
})[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (valueMetadata === undefined) {
|
|
||||||
valueMetadata = metadata.values()[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
return valueMetadata.key;
|
|
||||||
},
|
|
||||||
handleDragOver($event){
|
handleDragOver($event){
|
||||||
$event.preventDefault();
|
$event.preventDefault();
|
||||||
},
|
},
|
||||||
@ -322,7 +263,7 @@
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
addObject(domainObject) {
|
addSubobject(domainObject) {
|
||||||
if (!this.isTelemetry(domainObject)) {
|
if (!this.isTelemetry(domainObject)) {
|
||||||
let panels = this.newDomainObject.configuration.panels,
|
let panels = this.newDomainObject.configuration.panels,
|
||||||
id = this.openmct.objects.makeKeyString(domainObject.identifier),
|
id = this.openmct.objects.makeKeyString(domainObject.identifier),
|
||||||
@ -330,35 +271,29 @@
|
|||||||
mutateObject = false,
|
mutateObject = false,
|
||||||
initSelect = false;
|
initSelect = false;
|
||||||
|
|
||||||
// If this is a new panel, select it and save the configuration.
|
// If the panel doesn't exist, create one and mutate the configuration
|
||||||
if (!panel) {
|
if (!panel) {
|
||||||
panel = {};
|
panel = SubobjectViewConfiguration.create(domainObject, this.gridSize, this.droppedObjectPosition);
|
||||||
mutateObject = true;
|
|
||||||
initSelect = true;
|
initSelect = true;
|
||||||
}
|
|
||||||
|
|
||||||
panel.dimensions = panel.dimensions || this.getSubobjectDefaultDimensions();
|
|
||||||
panel.hasFrame = panel.hasOwnProperty('hasFrame') ?
|
|
||||||
panel.hasFrame :
|
|
||||||
this.hasFrameByDefault(domainObject.type);
|
|
||||||
|
|
||||||
if (this.droppedObjectPosition) {
|
|
||||||
panel.position = this.droppedObjectPosition;
|
|
||||||
this.droppedObjectPosition = undefined;
|
|
||||||
} else {
|
|
||||||
panel.position = panel.position || DEFAULT_POSITION;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mutateObject) {
|
|
||||||
this.mutate("configuration.panels[" + id + "]", panel);
|
this.mutate("configuration.panels[" + id + "]", panel);
|
||||||
|
delete this.droppedObjectPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
panel.domainObject = domainObject;
|
panel.domainObject = domainObject;
|
||||||
this.makeFrameItem(panel, initSelect);
|
this.makeSubobjectItem(panel, initSelect);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
removeObject() {
|
removeSubobject() {
|
||||||
|
// Not yet implemented
|
||||||
|
},
|
||||||
|
addElement(type) {
|
||||||
|
let elements = this.newDomainObject.configuration.elements || [];
|
||||||
|
Promise.resolve(ElementViewConfiguration.create(type, this.openmct))
|
||||||
|
.then(element => {
|
||||||
|
element.index = elements.push(element) - 1;
|
||||||
|
this.mutate("configuration.elements", elements);
|
||||||
|
this.makeElementItem(element, true);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -373,15 +308,16 @@
|
|||||||
this.openmct.selection.on('change', this.setSelection);
|
this.openmct.selection.on('change', this.setSelection);
|
||||||
|
|
||||||
this.composition = this.openmct.composition.get(this.newDomainObject);
|
this.composition = this.openmct.composition.get(this.newDomainObject);
|
||||||
this.composition.on('add', this.addObject);
|
this.composition.on('add', this.addSubobject);
|
||||||
this.composition.on('remove', this.removeObject);
|
this.composition.on('remove', this.removeSubobject);
|
||||||
this.composition.load();
|
this.composition.load();
|
||||||
this.getAlphanumerics();
|
this.getAlphanumerics();
|
||||||
|
this.getElements();
|
||||||
},
|
},
|
||||||
destroyed: function () {
|
destroyed: function () {
|
||||||
this.openmct.off('change', this.setSelection);
|
this.openmct.off('change', this.setSelection);
|
||||||
this.composition.off('add', this.addObject);
|
this.composition.off('add', this.addSubobject);
|
||||||
this.composition.off('remove', this.removeObject);
|
this.composition.off('remove', this.removeSubobject);
|
||||||
this.unlisten();
|
this.unlisten();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
65
src/plugins/displayLayout/components/ImageView.vue
Normal file
65
src/plugins/displayLayout/components/ImageView.vue
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="c-image-view"
|
||||||
|
:style="styleObject">
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import '~styles/sass-base';
|
||||||
|
|
||||||
|
.c-image-view {
|
||||||
|
background-size: cover;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center;
|
||||||
|
|
||||||
|
.c-frame & {
|
||||||
|
@include abs();
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
item: Object
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
styleObject() {
|
||||||
|
let element = this.item.config.element;
|
||||||
|
return {
|
||||||
|
backgroundImage: 'url(' + element.url + ')',
|
||||||
|
border: '1px solid ' + element.stroke
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.item.config.attachListeners();
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
this.item.config.removeListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -21,12 +21,14 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="c-frame has-local-controls is-selectable is-moveable"
|
<div class="c-frame has-local-controls"
|
||||||
:style="item.style"
|
:style="item.config.style"
|
||||||
:class="classObject"
|
:class="[classObject, {
|
||||||
|
'u-inspectable': item.config.inspectable()
|
||||||
|
}]"
|
||||||
@dblclick="drill(item.id, $event)">
|
@dblclick="drill(item.id, $event)">
|
||||||
|
|
||||||
<component :is="item.type" :item="item"></component>
|
<component :is="item.type" :item="item" :gridSize="gridSize"></component>
|
||||||
|
|
||||||
<!-- Drag handles -->
|
<!-- Drag handles -->
|
||||||
<div class="c-frame-edit">
|
<div class="c-frame-edit">
|
||||||
@ -72,6 +74,10 @@
|
|||||||
<script>
|
<script>
|
||||||
import SubobjectView from './SubobjectView.vue'
|
import SubobjectView from './SubobjectView.vue'
|
||||||
import TelemetryView from './TelemetryView.vue'
|
import TelemetryView from './TelemetryView.vue'
|
||||||
|
import BoxView from './BoxView.vue'
|
||||||
|
import TextView from './TextView.vue'
|
||||||
|
import LineView from './LineView.vue'
|
||||||
|
import ImageView from './ImageView.vue'
|
||||||
import LayoutDrag from './../LayoutDrag'
|
import LayoutDrag from './../LayoutDrag'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
@ -82,13 +88,17 @@
|
|||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
SubobjectView,
|
SubobjectView,
|
||||||
TelemetryView
|
TelemetryView,
|
||||||
|
BoxView,
|
||||||
|
TextView,
|
||||||
|
LineView,
|
||||||
|
ImageView
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
classObject: function () {
|
classObject: function () {
|
||||||
return {
|
return {
|
||||||
'is-drilled-in': this.item.drilledIn,
|
'is-drilled-in': this.item.drilledIn,
|
||||||
'no-frame': !this.item.config.hasFrame
|
'no-frame': !this.item.config.hasFrame()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -102,6 +112,10 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.item.domainObject) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.openmct.composition.get(this.item.domainObject) === undefined) {
|
if (this.openmct.composition.get(this.item.domainObject) === undefined) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -126,7 +140,7 @@
|
|||||||
|
|
||||||
this.updatePosition(event);
|
this.updatePosition(event);
|
||||||
this.activeDrag = new LayoutDrag(
|
this.activeDrag = new LayoutDrag(
|
||||||
this.item.config.rawPosition,
|
this.item.config.position(),
|
||||||
posFactor,
|
posFactor,
|
||||||
dimFactor,
|
dimFactor,
|
||||||
this.gridSize
|
this.gridSize
|
||||||
@ -157,7 +171,8 @@
|
|||||||
mounted() {
|
mounted() {
|
||||||
let context = {
|
let context = {
|
||||||
item: this.item.domainObject,
|
item: this.item.domainObject,
|
||||||
layoutItem: this.item
|
layoutItem: this.item,
|
||||||
|
addElement: this.$parent.addElement
|
||||||
};
|
};
|
||||||
|
|
||||||
this.removeSelectable = this.openmct.selection.selectable(
|
this.removeSelectable = this.openmct.selection.selectable(
|
||||||
|
56
src/plugins/displayLayout/components/LineView.vue
Normal file
56
src/plugins/displayLayout/components/LineView.vue
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<svg :width="gridSize[0] * element.width"
|
||||||
|
:height=" gridSize[1] * element.height">
|
||||||
|
<line :x1=" gridSize[0] * element.x1 + 1"
|
||||||
|
:y1="gridSize[1] * element.y1 + 1 "
|
||||||
|
:x2="gridSize[0] * element.x2 + 1"
|
||||||
|
:y2=" gridSize[1] * element.y2 + 1 "
|
||||||
|
:stroke="element.stroke"
|
||||||
|
stroke-width="2">
|
||||||
|
</line>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
item: Object,
|
||||||
|
gridSize: Array
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
element() {
|
||||||
|
return this.item.config.element;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.item.config.attachListeners();
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
this.item.config.removeListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
67
src/plugins/displayLayout/components/TextView.vue
Normal file
67
src/plugins/displayLayout/components/TextView.vue
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
/*****************************************************************************
|
||||||
|
* 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.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="c-text-view"
|
||||||
|
:style="styleObject">
|
||||||
|
{{ item.config.element.text }}
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import '~styles/sass-base';
|
||||||
|
|
||||||
|
.c-text-view {
|
||||||
|
display: flex;
|
||||||
|
align-items: stretch;
|
||||||
|
|
||||||
|
.c-frame & {
|
||||||
|
@include abs();
|
||||||
|
border: 1px solid transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
item: Object
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
styleObject() {
|
||||||
|
let element = this.item.config.element;
|
||||||
|
return {
|
||||||
|
backgroundColor: element.fill,
|
||||||
|
borderColor: element.stroke,
|
||||||
|
color: element.color,
|
||||||
|
fontSize: element.size
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.item.config.attachListeners();
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
this.item.config.removeListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -41,7 +41,7 @@ export default function () {
|
|||||||
components: {
|
components: {
|
||||||
Layout
|
Layout
|
||||||
},
|
},
|
||||||
template: '<layout :domain-object="domainObject"></layout>',
|
template: '<layout ref="displayLayout" :domain-object="domainObject"></layout>',
|
||||||
provide: {
|
provide: {
|
||||||
openmct,
|
openmct,
|
||||||
objectUtils
|
objectUtils
|
||||||
@ -54,6 +54,12 @@ export default function () {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
getSelectionContext() {
|
||||||
|
return {
|
||||||
|
item: domainObject,
|
||||||
|
addElement: component && component.$refs.displayLayout.addElement
|
||||||
|
}
|
||||||
|
},
|
||||||
destroy() {
|
destroy() {
|
||||||
component.$destroy();
|
component.$destroy();
|
||||||
}
|
}
|
||||||
|
@ -92,12 +92,13 @@ $colorTOIHov: $colorTime; // was $timeControllerToiLineColorHov
|
|||||||
// Base Colors
|
// Base Colors
|
||||||
$dlSpread: 20%;
|
$dlSpread: 20%;
|
||||||
$editColor: #00c7c3;
|
$editColor: #00c7c3;
|
||||||
$editColorBg: darken($editColor, $dlSpread);
|
$editColorBgBase: darken($editColor, $dlSpread);
|
||||||
|
$editColorBg: rgba($editColorBgBase, 0.2);
|
||||||
$editColorFg: lighten($editColor, $dlSpread);
|
$editColorFg: lighten($editColor, $dlSpread);
|
||||||
$editColorHov: lighten($editColor, 20%);
|
$editColorHov: lighten($editColor, 20%);
|
||||||
// Canvas
|
// Canvas
|
||||||
$editCanvasColorBg: #002524;
|
$editCanvasColorBg: $editColorBg; //#002524;
|
||||||
$editCanvasColorGrid: darken($editCanvasColorBg, 2%);
|
$editCanvasColorGrid: rgba($editColorBgBase, 0.4); //lighten($editCanvasColorBg, 3%);
|
||||||
// Selectable
|
// Selectable
|
||||||
$editSelectableColor: #006563;
|
$editSelectableColor: #006563;
|
||||||
$editSelectableColorFg: lighten($editSelectableColor, 20%);
|
$editSelectableColorFg: lighten($editSelectableColor, 20%);
|
||||||
|
@ -92,6 +92,7 @@ $colorTOIHov: $colorTime; // was $timeControllerToiLineColorHov
|
|||||||
// Base Colors
|
// Base Colors
|
||||||
$dlSpread: 20%;
|
$dlSpread: 20%;
|
||||||
$editColor: #00c7c3;
|
$editColor: #00c7c3;
|
||||||
|
$editColorBgBase: darken($editColor, $dlSpread);
|
||||||
$editColorBg: darken($editColor, $dlSpread);
|
$editColorBg: darken($editColor, $dlSpread);
|
||||||
$editColorFg: lighten($editColor, $dlSpread);
|
$editColorFg: lighten($editColor, $dlSpread);
|
||||||
$editColorHov: lighten($editColor, 20%);
|
$editColorHov: lighten($editColor, 20%);
|
||||||
@ -99,9 +100,9 @@ $editColorHov: lighten($editColor, 20%);
|
|||||||
$editCanvasColorBg: #e6ffff;
|
$editCanvasColorBg: #e6ffff;
|
||||||
$editCanvasColorGrid: darken($editCanvasColorBg, 10%);
|
$editCanvasColorGrid: darken($editCanvasColorBg, 10%);
|
||||||
// Selectable
|
// Selectable
|
||||||
$editSelectableColor: darken($colorBodyBg, 10%);
|
$editSelectableColor: #acdad6;
|
||||||
$editSelectableColorFg: darken($editSelectableColor, 20%);
|
$editSelectableColorFg: darken($editSelectableColor, 20%);
|
||||||
$editSelectableColorHov: darken($editSelectableColor, 10%); //darken($colorBodyBg, 20%);
|
$editSelectableColorHov: darken($editSelectableColor, 10%);
|
||||||
// Selectable selected
|
// Selectable selected
|
||||||
$editSelectableColorSelected: $editColor; //$editSelectableColorHov;
|
$editSelectableColorSelected: $editColor; //$editSelectableColorHov;
|
||||||
$editSelectableColorSelectedFg: lighten($editSelectableColorSelected, 50%);
|
$editSelectableColorSelectedFg: lighten($editSelectableColorSelected, 50%);
|
||||||
@ -111,6 +112,7 @@ $editSelectableBorderHov: 1px dotted $editColor;
|
|||||||
$editSelectableBorderSelected: 1px solid $editColor;
|
$editSelectableBorderSelected: 1px solid $editColor;
|
||||||
$editMoveableSelectedShdw: rgba($editColor, 0.5) 0 0 10px;
|
$editMoveableSelectedShdw: rgba($editColor, 0.5) 0 0 10px;
|
||||||
$editBorderDrilledIn: 1px dashed #9971ff;
|
$editBorderDrilledIn: 1px dashed #9971ff;
|
||||||
|
$colorGridLines: rgba($editColor, 0.2);
|
||||||
|
|
||||||
/************************************************** BROWSING */
|
/************************************************** BROWSING */
|
||||||
$browseBorderSelectableHov: 1px dotted rgba($colorBodyFg, 0.2);
|
$browseBorderSelectableHov: 1px dotted rgba($colorBodyFg, 0.2);
|
||||||
|
@ -240,7 +240,7 @@ body.desktop .has-local-controls {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*************************** SELECTION */
|
/*************************** SELECTION */
|
||||||
.is-selectable {
|
.u-inspectable {
|
||||||
&:hover {
|
&:hover {
|
||||||
box-shadow: $browseShdwSelectableHov;
|
box-shadow: $browseShdwSelectableHov;
|
||||||
}
|
}
|
||||||
@ -248,7 +248,7 @@ body.desktop .has-local-controls {
|
|||||||
|
|
||||||
/**************************** EDITING */
|
/**************************** EDITING */
|
||||||
.is-editing {
|
.is-editing {
|
||||||
*:not(.is-drilled-in).is-selectable {
|
*:not(.is-drilled-in).c-frame {
|
||||||
border: $editSelectableBorder;
|
border: $editSelectableBorder;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
@ -269,7 +269,7 @@ body.desktop .has-local-controls {
|
|||||||
border: $editBorderDrilledIn;
|
border: $editBorderDrilledIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
*[s-selected] .is-moveable {
|
*[s-selected] {
|
||||||
cursor: move;
|
cursor: move;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -350,6 +350,14 @@ body.desktop .has-local-controls {
|
|||||||
background: $editCanvasColorBg;
|
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
|
// Layouts
|
||||||
[s-selected],
|
[s-selected],
|
||||||
[s-selected-parent] {
|
[s-selected-parent] {
|
||||||
|
@ -70,11 +70,14 @@ export default {
|
|||||||
if (this.mutationUnobserver) {
|
if (this.mutationUnobserver) {
|
||||||
this.mutationUnobserver();
|
this.mutationUnobserver();
|
||||||
}
|
}
|
||||||
this.mutationUnobserver = this.openmct.objects.observe(this.parentObject, '*', (updatedModel) => {
|
|
||||||
this.parentObject = updatedModel;
|
if (this.parentObject) {
|
||||||
|
this.mutationUnobserver = this.openmct.objects.observe(this.parentObject, '*', (updatedModel) => {
|
||||||
|
this.parentObject = updatedModel;
|
||||||
|
this.refreshComposition();
|
||||||
|
});
|
||||||
this.refreshComposition();
|
this.refreshComposition();
|
||||||
});
|
}
|
||||||
this.refreshComposition();
|
|
||||||
},
|
},
|
||||||
refreshComposition() {
|
refreshComposition() {
|
||||||
let composition = this.openmct.composition.get(this.parentObject);
|
let composition = this.openmct.composition.get(this.parentObject);
|
||||||
|
@ -41,7 +41,7 @@ export default {
|
|||||||
delete this.viewContainer;
|
delete this.viewContainer;
|
||||||
delete this.currentView;
|
delete this.currentView;
|
||||||
},
|
},
|
||||||
updateView() {
|
updateView(immediatelySelect) {
|
||||||
this.clear();
|
this.clear();
|
||||||
if (!this.currentObject) {
|
if (!this.currentObject) {
|
||||||
return;
|
return;
|
||||||
@ -58,18 +58,34 @@ export default {
|
|||||||
}
|
}
|
||||||
this.currentView = provider.view(this.currentObject);
|
this.currentView = provider.view(this.currentObject);
|
||||||
this.currentView.show(this.viewContainer);
|
this.currentView.show(this.viewContainer);
|
||||||
|
|
||||||
|
if (immediatelySelect) {
|
||||||
|
this.removeSelectable = openmct.selection.selectable(
|
||||||
|
this.$el,
|
||||||
|
this.currentView.getSelectionContext ?
|
||||||
|
this.currentView.getSelectionContext() :
|
||||||
|
{ item: this.currentObject },
|
||||||
|
true
|
||||||
|
);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
show(object, viewKey) {
|
show(object, viewKey, immediatelySelect) {
|
||||||
if (this.unlisten) {
|
if (this.unlisten) {
|
||||||
this.unlisten();
|
this.unlisten();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.removeSelectable) {
|
||||||
|
this.removeSelectable();
|
||||||
|
delete this.removeSelectable;
|
||||||
|
}
|
||||||
|
|
||||||
this.currentObject = object;
|
this.currentObject = object;
|
||||||
this.unlisten = this.openmct.objects.observe(this.currentObject, '*', (mutatedObject) => {
|
this.unlisten = this.openmct.objects.observe(this.currentObject, '*', (mutatedObject) => {
|
||||||
this.currentObject = mutatedObject;
|
this.currentObject = mutatedObject;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.viewKey = viewKey;
|
this.viewKey = viewKey;
|
||||||
this.updateView();
|
this.updateView(immediatelySelect);
|
||||||
},
|
},
|
||||||
onDragOver(event) {
|
onDragOver(event) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
@ -46,18 +46,33 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
let structure = this.openmct.toolbars.get(selection) || [];
|
let structure = this.openmct.toolbars.get(selection) || [];
|
||||||
this.structure = structure.map(function (item) {
|
this.structure = structure.map(item => {
|
||||||
let toolbarItem = {...item};
|
let toolbarItem = {...item};
|
||||||
let domainObject = toolbarItem.domainObject;
|
let domainObject = toolbarItem.domainObject;
|
||||||
|
let formKeys = [];
|
||||||
toolbarItem.control = "toolbar-" + toolbarItem.control;
|
toolbarItem.control = "toolbar-" + toolbarItem.control;
|
||||||
|
|
||||||
|
if (toolbarItem.dialog) {
|
||||||
|
toolbarItem.dialog.sections.forEach(section => {
|
||||||
|
section.rows.forEach(row => {
|
||||||
|
formKeys.push(row.key);
|
||||||
|
})
|
||||||
|
});
|
||||||
|
toolbarItem.formKeys = formKeys;
|
||||||
|
}
|
||||||
|
|
||||||
if (domainObject) {
|
if (domainObject) {
|
||||||
toolbarItem.value = _.get(domainObject, item.property);
|
if (formKeys.length > 0) {
|
||||||
|
toolbarItem.value = this.getFormValue(domainObject, toolbarItem);
|
||||||
|
} else {
|
||||||
|
toolbarItem.value = _.get(domainObject, item.property);
|
||||||
|
}
|
||||||
|
|
||||||
this.registerListener(domainObject);
|
this.registerListener(domainObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
return toolbarItem;
|
return toolbarItem;
|
||||||
}.bind(this));
|
});
|
||||||
},
|
},
|
||||||
registerListener(domainObject) {
|
registerListener(domainObject) {
|
||||||
let id = this.openmct.objects.makeKeyString(domainObject.identifier);
|
let id = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||||
@ -85,7 +100,7 @@
|
|||||||
setTimeout(this.updateToolbarAfterMutation.bind(this));
|
setTimeout(this.updateToolbarAfterMutation.bind(this));
|
||||||
},
|
},
|
||||||
updateToolbarAfterMutation() {
|
updateToolbarAfterMutation() {
|
||||||
this.structure = this.structure.map((item) => {
|
this.structure = this.structure.map(item => {
|
||||||
let toolbarItem = {...item};
|
let toolbarItem = {...item};
|
||||||
let domainObject = toolbarItem.domainObject;
|
let domainObject = toolbarItem.domainObject;
|
||||||
|
|
||||||
@ -95,10 +110,11 @@
|
|||||||
|
|
||||||
if (newObject) {
|
if (newObject) {
|
||||||
toolbarItem.domainObject = newObject;
|
toolbarItem.domainObject = newObject;
|
||||||
let newValue = _.get(newObject, item.property);
|
|
||||||
|
|
||||||
if (toolbarItem.value !== newValue) {
|
if (toolbarItem.formKeys) {
|
||||||
toolbarItem.value = newValue;
|
toolbarItem.value = this.getFormValue(newObject, toolbarItem);
|
||||||
|
} else {
|
||||||
|
toolbarItem.value = _.get(newObject, item.property);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -114,6 +130,13 @@
|
|||||||
});
|
});
|
||||||
this.toolbarUpdateScheduled = false;
|
this.toolbarUpdateScheduled = false;
|
||||||
},
|
},
|
||||||
|
getFormValue(domainObject, toolbarItem) {
|
||||||
|
let value = {};
|
||||||
|
toolbarItem.formKeys.map(key => {
|
||||||
|
value[key] = _.get(domainObject, toolbarItem.property + "." + key);
|
||||||
|
});
|
||||||
|
return value;
|
||||||
|
},
|
||||||
removeListeners() {
|
removeListeners() {
|
||||||
if (this.unObserveObjects) {
|
if (this.unObserveObjects) {
|
||||||
this.unObserveObjects.forEach((unObserveObject) => {
|
this.unObserveObjects.forEach((unObserveObject) => {
|
||||||
@ -138,7 +161,20 @@
|
|||||||
|
|
||||||
return toolbarItem;
|
return toolbarItem;
|
||||||
});
|
});
|
||||||
this.openmct.objects.mutate(item.domainObject, item.property, value);
|
|
||||||
|
// If value is an object, iterate the toolbar structure and mutate all keys in form.
|
||||||
|
// Otherwise, mutate the property.
|
||||||
|
if (value === Object(value)) {
|
||||||
|
this.structure.map(s => {
|
||||||
|
if (s.formKeys) {
|
||||||
|
s.formKeys.forEach(key => {
|
||||||
|
this.openmct.objects.mutate(item.domainObject, item.property + "." + key, value[key]);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
this.openmct.objects.mutate(item.domainObject, item.property, value);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
triggerMethod(item, event) {
|
triggerMethod(item, event) {
|
||||||
if (item.method) {
|
if (item.method) {
|
||||||
|
@ -18,13 +18,18 @@
|
|||||||
|
|
||||||
<script>
|
<script>
|
||||||
export default {
|
export default {
|
||||||
|
inject: ['openmct'],
|
||||||
props: {
|
props: {
|
||||||
options: Object
|
options: Object
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onClick(event) {
|
onClick(event) {
|
||||||
if (this.options.dialog) {
|
if (this.options.dialog) {
|
||||||
// TODO: display a dialog
|
this.openmct.$injector.get('dialogService')
|
||||||
|
.getUserInput(this.options.dialog, this.options.value)
|
||||||
|
.then(value => {
|
||||||
|
this.$emit('change', {...value}, this.options);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
this.$emit('click', this.options);
|
this.$emit('click', this.options);
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,13 @@ export default {
|
|||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onChange(event) {
|
onChange(event) {
|
||||||
this.$emit('change', event.target.value, this.options);
|
let value = event.target.value;
|
||||||
|
|
||||||
|
if (this.options.type === 'number') {
|
||||||
|
value = event.target.valueAsNumber;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.$emit('change', value, this.options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,6 +131,16 @@ define([], function () {
|
|||||||
* @memberof module:openmct.View#
|
* @memberof module:openmct.View#
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the selection context.
|
||||||
|
*
|
||||||
|
* View implementations should use this method to customize
|
||||||
|
* the selection context.
|
||||||
|
*
|
||||||
|
* @method getSelectionContext
|
||||||
|
* @memberof module:openmct.View#
|
||||||
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Exposes types of views in Open MCT.
|
* Exposes types of views in Open MCT.
|
||||||
*
|
*
|
||||||
|
@ -7,24 +7,11 @@ define([
|
|||||||
return function install(openmct) {
|
return function install(openmct) {
|
||||||
let navigateCall = 0;
|
let navigateCall = 0;
|
||||||
let browseObject;
|
let browseObject;
|
||||||
let removeSelectable = undefined;
|
|
||||||
|
|
||||||
|
|
||||||
function viewObject(object, viewProvider) {
|
function viewObject(object, viewProvider) {
|
||||||
if (removeSelectable) {
|
openmct.layout.$refs.browseObject.show(object, viewProvider.key, true);
|
||||||
removeSelectable();
|
|
||||||
removeSelectable = undefined;
|
|
||||||
}
|
|
||||||
openmct.layout.$refs.browseObject.show(object, viewProvider.key);
|
|
||||||
openmct.layout.$refs.browseBar.domainObject = object;
|
openmct.layout.$refs.browseBar.domainObject = object;
|
||||||
openmct.layout.$refs.browseBar.viewKey = viewProvider.key;
|
openmct.layout.$refs.browseBar.viewKey = viewProvider.key;
|
||||||
removeSelectable = openmct.selection.selectable(
|
|
||||||
openmct.layout.$refs.browseObject.$el,
|
|
||||||
{
|
|
||||||
item: object
|
|
||||||
},
|
|
||||||
true
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
function navigateToPath(path, currentViewKey) {
|
function navigateToPath(path, currentViewKey) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user