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:
Pegah Sarram
2018-12-04 09:12:45 -08:00
committed by Pete Richards
parent 32a0baa7a3
commit e07cfc9394
24 changed files with 1072 additions and 263 deletions

View File

@ -28,91 +28,116 @@ define([], function () {
key: "layout",
description: "A toolbar for objects inside a display layout.",
forSelection: function (selection) {
// Apply the layout toolbar if the selected object is inside a layout,
// and in edit mode.
return (selection &&
selection[1] &&
selection[1].context.item &&
selection[1].context.item.type === 'layout' &&
openmct.editor.isEditing());
// Apply the layout toolbar if the edit mode is on, and the selected object
// is inside a layout, or the main layout is selected.
return (openmct.editor.isEditing() && selection &&
((selection[1] && selection[1].context.item && selection[1].context.item.type === 'layout') ||
(selection[0].context.item && selection[0].context.item.type === 'layout')));
},
toolbar: function (selection) {
let domainObject = selection[1].context.item;
let layoutItem = selection[0].context.layoutItem;
let selectedParent = selection[1] && selection[1].context.item,
selectedObject = selection[0].context.item,
layoutItem = selection[0].context.layoutItem,
toolbar = [];
if (layoutItem && layoutItem.type === 'telemetry-view') {
let path = "configuration.alphanumerics[" + layoutItem.config.alphanumeric.index + "]";
let metadata = openmct.telemetry.getMetadata(layoutItem.domainObject);
if (selectedObject && selectedObject.type === 'layout') {
toolbar.push({
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];
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 [
{
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"
}
]
},
{
let separator = {
control: "separator"
},
{
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"
},
{
fill = {
control: "color-picker",
domainObject: domainObject,
domainObject: selectedParent,
property: path + ".fill",
icon: "icon-paint-bucket",
title: "Set fill color"
},
{
stroke = {
control: "color-picker",
domainObject: domainObject,
domainObject: selectedParent,
property: path + ".stroke",
icon: "icon-line-horz",
title: "Set border color"
},
{
color = {
control: "color-picker",
domainObject: domainObject,
domainObject: selectedParent,
property: path + ".color",
icon: "icon-font",
mandatory: true,
title: "Set text color",
preventNone: true
},
{
control: "separator"
},
{
size = {
control: "select-menu",
domainObject: domainObject,
domainObject: selectedParent,
property: path + ".size",
title: "Set text size",
options: TEXT_SIZE.map(size => {
@ -121,28 +146,181 @@ define([], function () {
};
})
},
];
} else {
return [
{
control: "toggle-button",
domainObject: domainObject,
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"
}
]
}
];
x = {
control: "input",
type: "number",
domainObject: selectedParent,
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') {
// 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;
}
}
}