Compare commits

..

20 Commits

Author SHA1 Message Date
5f6ff074cd Theme constants syncing
- Bring Espresso _constants into parity with Snow;
- Fix buttons in overlay.vue and Notebook EntryController;
- TODO: styles for buttons in Overlay, particularly for Espresso;
2018-10-11 14:50:46 -07:00
2cbcf7d004 make reviewer requested changes 2018-10-11 13:35:14 -07:00
543bc0a4b3 added progress bar, with setter and getter functions 2018-10-11 13:34:22 -07:00
c9f5fcb730 Fix code to remove warnings in conductor (#2192) 2018-10-11 13:20:27 -07:00
a47dfe2584 Vue toolbar (#2191)
* Add a toolbar provider for display layout.

* Move toolbar provider to the plugin

* basic toolbar generation

* componentize different toolbar control types

Break toolbar control types down into different parts and provide
a test toolbar generator in index.html that utilizes all the
controls.

* Get the 'Show frame' checkbox working in the toolbar

* - Remove extra listener.
- Display toolbar only when editing.

* Modify the Selection API to set s-selected and s-selected-parent attributes instead of adding to the css class names.

* Move the logic for allowing the toolbar in the edit mode to the provider.

* Use toggle-button component to toggle frame

* Delete old files

* Remove MCTToolbar

* Modify the toggle button component to return the computed value

* Remove reload=true

* Revert to the original setting

* use value from props

* Always update toolbars on edit status change

* restore fixed position bundle

* bring back reload when hmr unavailable
2018-10-11 13:20:27 -07:00
6cb05bc74a added jsdocs for overlayService 2018-10-11 13:20:27 -07:00
d5e48b2b1f Vue status bar (#2188)
* Implemented indicators

* WIP

* Fixed templates from notifications example

* Message bar implemented

* Implemented notifications

* Fixed bug with destruction of notifications

* Renamed MessageBanner to NotificationBanner

* Add save success message

* Removed NotificationServiceSpec

* Removed legacy constants from bundle
2018-10-11 13:20:27 -07:00
f7914ab36d Conductor fixes (#2189)
* Conductor fixes

- Restore RT update time field;
- Colors tweaked;
- Much better mobile layout;

* Significant fixes in Conductor markup and styling

- Markup/CSS simplified and clearer;
- Better coloring in both Themes;
- Better clarity for axis UI element;
- Fixed hover and focus styles on inputs;
2018-10-11 13:20:27 -07:00
279815a6c3 Topic themes (#2187)
* Bringing over in-progress changes from topic-core-css

- Adds _espresso-constants.scss;
- Cleanup colors and naming;
- Remove conflict res leftover 'domainObject' in mct-tree.vue;
- Still WIP!

* Various

- Remove pushBack / pullForward functions;
- Fix c-input-inline, remove bg until hover;
- TODO: input bg colors
- Increased margin in main-pane;

* Themeing WIP

- Conductor markup: convert to buttons for accessibility;
- Conductor styles consolidated and changed for better theme support;

* Themeing WIP; significant rewrite of pane headers

- Pane headers restructured for better semantics and clarity;
- Espresso design refined and tightened;
- Grid Vue changes for better themeing support;
- TODO: fix mobile version, collapse icon is whack;

* Restored Number-type input styling for correct positioning of spinner
button;

* Themeing mods for click-icon styles

* Bring Snow theme into style parity with Espresso

- TODO: refine Snow colors;

* Mobile styling fixed

- Mobile menu icon significant fixes;
- Hover only applied to desktop;
- Reorg of mixins;

* Bring Snow theme constants into parity with Espresso

- Refined Snow styles;
- Fixed missing scroll and padding in tree;
- Pane collapse button now uses proper color;
- Item Grid view refinement;
- Cleaned up code;

* Color fixes

- Super-menu description;
- Conductor time buttons hover;
- Datepicker "in-month" items color;
- Espresso colorKeyFilter brightened;
2018-10-11 13:20:27 -07:00
ce32e6190b Fixes for Inspector Plot properties, and more
- Fixed overflow problem when Inspector collapsed;
- Temp legacy styling for Plot inspection, series options, etc.
- Factored out non-useful gridTwoColumn mixin;
- Brought back legacy tree.scss file in legacy-styles.scss;
2018-10-11 13:14:26 -07:00
a4993a6e8e Fix s-selected, edit grid displays 2018-10-11 13:14:26 -07:00
023068d03e apply is-editing only when editing 2018-10-11 13:14:26 -07:00
34b296f553 Remove selectable from display layut 2018-10-11 13:14:26 -07:00
36d2fc659d Merge duplicate data method, correct is-editing class 2018-10-11 13:14:26 -07:00
9062901c06 Revisions to bg-icons
- Added status colors and filter versions in _constants;
  - TODO: bring Espresso _constants into parity with Snow;
- Changed default bg-icon SVG color to black, adjusted filters;
- Added bg-icon classes to blockingMessage.vue;
2018-10-11 13:07:32 -07:00
be5da7fa72 Dialog markup/styling conversion to Vue
- WIP!
2018-10-10 18:03:12 -07:00
5e3acc4363 return dismiss function on show 2018-10-09 18:19:57 -07:00
196f49fca6 move blocking message to overlay service 2018-10-09 16:00:11 -07:00
f9cb753fce working blocking message 2018-10-09 13:46:41 -07:00
9bc1630cb4 modify overlay service to accept bottomBarButtons option, working annotate on snapshot view 2018-10-05 14:38:45 -07:00
94 changed files with 1483 additions and 1904 deletions

2
app.js
View File

@ -46,7 +46,7 @@ webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
webpackConfig.plugins.push(function() { this.plugin('watch-run', function(watching, callback) { console.log('Begin compile at ' + new Date()); callback(); }) });
webpackConfig.entry.openmct = [
'webpack-hot-middleware/client',
'webpack-hot-middleware/client?reload=true',
webpackConfig.entry.openmct
];

View File

@ -79,5 +79,203 @@
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
openmct.time.timeSystem('utc');
openmct.start();
// openmct.toolbars.addProvider({
// name: "Testing Toolbar",
// key: "testing",
// description: "a mock toolbar that exercises all controls",
// forSelection: function (selection) {
// return true; // always applies.
// },
// toolbar: function (selection) {
// return [
// {
// control: 'menu',
// icon: 'icon-plus',
// label: 'Add',
// options: [
// { name: 'Box', class: 'icon-box', title: 'Add Box' },
// { name: 'Line', class: 'icon-line-horz', title: 'Add Line' },
// { name: 'Text', class: 'icon-font', title: 'Add Text' },
// { name: 'Image', class: 'icon-image', title: 'Add Image' }
// ]
// },
// {
// control: 'separator'
// },
// {
// control: 'color-picker',
// icon: 'icon-paint-bucket',
// value: '#33ff00',
// },
// {
// control: 'color-picker',
// icon: 'icon-pencil',
// value: '#ffffff',
// },
// {
// control: 'color-picker',
// icon: 'icon-font',
// value: '#333333',
// },
//
// {
// control: 'separator'
// },
// {
// control: 'select-menu',
// value: 11,
// options: [
// { value: 9, name: '9 px' },
// { value: 10, name: '10 px' },
// { value: 11, name: '11 px' },
// { value: 12, name: '12 px' },
// { value: 13, name: '13 px' },
// { value: 14, name: '14 px' },
// { value: 16, name: '16 px' },
// { value: 18, name: '18 px' },
// { value: 20, name: '20 px' },
// { value: 24, name: '24 px' },
// { value: 28, name: '28 px' },
// { value: 32, name: '32 px' },
// { value: 40, name: '40 px' },
// { value: 48, name: '48 px' },
// { value: 56, name: '56 px' },
// { value: 64, name: '64 px' },
// { value: 72, name: '72 px' },
// { value: 80, name: '80 px' },
// { value: 88, name: '88 px' },
// { value: 96, name: '96 px' },
// { value: 128, name: '128 px' },
// { value: 160, name: '160 px' }
// ]
// },
//
// {
// control: 'separator'
// },
// {
// control: 'menu',
// icon: 'icon-layers',
// options: [
// { name: 'Move to top', class: 'icon-arrow-double-up', title: 'Move to top' },
// { name: 'Move up', class: 'icon-arrow-up', title: 'Move up' },
// { name: 'Move down', class: 'icon-arrow-down', title: 'Move down' },
// { name: 'Move to bottom', class: 'icon-arrow-double-down', title: 'Move to bottom' }
// ]
// },
//
// {
// control: 'separator'
// },
// {
// control: 'button',
// icon: 'icon-gear'
// },
//
// {
// control: 'separator'
// },
// {
// control: 'input',
// type: 'number',
// label: 'X',
// value: 1,
// title: 'X position'
// },
// {
// control: 'input',
// type: 'number',
// label: 'Y',
// value: 2,
// title: 'Y position'
// },
// {
// control: 'input',
// type: 'number',
// label: 'W',
// value: 3,
// title: 'Width'
// },
// {
// control: 'input',
// type: 'number',
// label: 'H',
// value: 4,
// title: 'Height'
// },
//
// {
// control: 'separator'
// },
// {
// control: 'button',
// icon: 'icon-trash',
// label: 'delete',
// modifier: 'caution'
// },
//
// {
// control: 'separator'
// },
// {
// control: 'checkbox',
// name: 'this is a checkbox',
// },
// {
// control: 'separator'
// },
// {
// control: 'toggle-button',
// title: 'Toggle Frame',
// property: 'hideFrame',
// value: false,
// options: [
// {
// value: true,
// icon: 'icon-frame-hide'
// },
// {
// value: false,
// icon: 'icon-frame-show'
// }
// ]
// },
// {
// control: 'toggle-button',
// title: 'Snap to grid',
// property: 'snapToGrid',
// value: true,
// options: [
// {
// value: true,
// icon: 'icon-grid-snap-to'
// },
// {
// value: false,
// icon: 'icon-grid-snap-no'
// }
// ]
// },
// {
// control: 'toggle-button',
// title: 'Toggle label',
// property: 'showLabel',
// value: true,
// options: [
// {
// value: true,
// icon: 'icon-two-parts-both'
// },
// {
// value: false,
// icon: 'icon-two-parts-one-only'
// }
// ]
// }
// ];
// }
// });
</script>
</html>

View File

@ -1,254 +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/api/objects/object-utils',
'lodash'
],
function (
objectUtils,
_
) {
/**
* Provides initial structure and state (as suitable for provision
* to the `mct-toolbar` directive) for a view's toolbar, based on
* that view's declaration of what belongs in its toolbar and on
* the current selection.
*
* @param $scope the Angular scope
* @param {Object} openmct the openmct object
* @param structure the toolbar structure
* @memberof platform/commonUI/edit
* @constructor
*/
function EditToolbar($scope, openmct, structure) {
this.toolbarStructure = [];
this.properties = [];
this.toolbarState = [];
this.openmct = openmct;
this.domainObjectsById = {};
this.unobserveObjects = [];
this.stateTracker = [];
$scope.$watchCollection(this.getState.bind(this), this.handleStateChanges.bind(this));
$scope.$on("$destroy", this.destroy.bind(this));
this.updateToolbar(structure);
this.registerListeners(structure);
}
/**
* Updates the toolbar with a new structure.
*
* @param {Array} structure the toolbar structure
*/
EditToolbar.prototype.updateToolbar = function (structure) {
var self = this;
function addKey(item) {
self.stateTracker.push({
id: objectUtils.makeKeyString(item.domainObject.identifier),
domainObject: item.domainObject,
property: item.property
});
self.properties.push(item.property);
return self.properties.length - 1; // Return index of property
}
function convertItem(item) {
var converted = Object.create(item || {});
if (item.property) {
converted.key = addKey(item);
}
if (item.method) {
converted.click = function (value) {
item.method(value);
};
}
return converted;
}
// Get initial value for a given property
function initializeState(property) {
var result;
structure.forEach(function (item) {
if (item.property === property) {
result = _.get(item.domainObject, item.property);
}
});
return result;
}
// Tracks the domain object and property for every element in the state array
this.stateTracker = [];
this.toolbarStructure = structure.map(convertItem);
this.toolbarState = this.properties.map(initializeState);
};
/**
* Gets the structure of the toolbar, as appropriate to
* pass to `mct-toolbar`.
*
* @returns {Array} the toolbar structure
*/
EditToolbar.prototype.getStructure = function () {
return this.toolbarStructure;
};
/**
* Gets the current state of the toolbar, as appropriate
* to two-way bind to the state handled by `mct-toolbar`.
*
* @returns {Array} state of the toolbar
*/
EditToolbar.prototype.getState = function () {
return this.toolbarState;
};
/**
* Mutates the domain object's property with a new value.
*
* @param {Object} dominObject the domain object
* @param {string} property the domain object's property to update
* @param value the property's new value
*/
EditToolbar.prototype.updateDomainObject = function (domainObject, property, value) {
this.openmct.objects.mutate(domainObject, property, value);
};
/**
* Updates state with the new value.
*
* @param {number} index the index of the corresponding
* element in the state array
* @param value the new value to update the state array with
*/
EditToolbar.prototype.updateState = function (index, value) {
this.toolbarState[index] = value;
};
/**
* Register listeners for domain objects to watch for updates.
*
* @param {Array} the toolbar structure
*/
EditToolbar.prototype.registerListeners = function (structure) {
var self = this;
function observeObject(domainObject, id) {
var unobserveObject = self.openmct.objects.observe(domainObject, '*', function (newObject) {
self.domainObjectsById[id].newObject = JSON.parse(JSON.stringify(newObject));
self.scheduleStateUpdate();
});
self.unobserveObjects.push(unobserveObject);
}
structure.forEach(function (item) {
var domainObject = item.domainObject;
var id = objectUtils.makeKeyString(domainObject.identifier);
if (!self.domainObjectsById[id]) {
self.domainObjectsById[id] = {
domainObject: domainObject,
properties: []
};
observeObject(domainObject, id);
}
self.domainObjectsById[id].properties.push(item.property);
});
};
/**
* Delays updating the state.
*/
EditToolbar.prototype.scheduleStateUpdate = function () {
if (this.stateUpdateScheduled) {
return;
}
this.stateUpdateScheduled = true;
setTimeout(this.updateStateAfterMutation.bind(this));
};
EditToolbar.prototype.updateStateAfterMutation = function () {
this.stateTracker.forEach(function (state, index) {
if (!this.domainObjectsById[state.id].newObject) {
return;
}
var domainObject = this.domainObjectsById[state.id].domainObject;
var newObject = this.domainObjectsById[state.id].newObject;
var currentValue = _.get(domainObject, state.property);
var newValue = _.get(newObject, state.property);
state.domainObject = newObject;
if (currentValue !== newValue) {
this.updateState(index, newValue);
}
}, this);
Object.values(this.domainObjectsById).forEach(function (tracker) {
if (tracker.newObject) {
tracker.domainObject = tracker.newObject;
}
delete tracker.newObject;
});
this.stateUpdateScheduled = false;
};
/**
* Removes the listeners.
*/
EditToolbar.prototype.deregisterListeners = function () {
this.unobserveObjects.forEach(function (unobserveObject) {
unobserveObject();
});
this.unobserveObjects = [];
};
EditToolbar.prototype.handleStateChanges = function (state) {
(state || []).map(function (newValue, index) {
var domainObject = this.stateTracker[index].domainObject;
var property = this.stateTracker[index].property;
var currentValue = _.get(domainObject, property);
if (currentValue !== newValue) {
this.updateDomainObject(domainObject, property, newValue);
}
}, this);
};
EditToolbar.prototype.destroy = function () {
this.deregisterListeners();
};
return EditToolbar;
}
);

View File

@ -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(
['../../src/representers/EditToolbar'],
function (EditToolbar) {
describe("An Edit mode toolbar", function () {
var mockOpenMCT,
mockScope,
mockObjects,
mockDomainObject,
testStructure,
toolbar;
beforeEach(function () {
mockOpenMCT = jasmine.createSpy('openmct', ['objects']);
mockObjects = jasmine.createSpyObj('objects', ['observe']);
mockObjects.observe.and.returnValue();
mockOpenMCT.objects = mockObjects;
mockScope = jasmine.createSpyObj("$scope", [
"$watchCollection",
"$on"
]);
mockScope.$watchCollection.and.returnValue();
mockDomainObject = jasmine.createSpyObj("domainObject", [
'identifier'
]);
testStructure = [
{ name: "A", property: "a", domainObject: mockDomainObject },
{ name: "B", property: "b", domainObject: mockDomainObject },
{ name: "C", property: "c", domainObject: mockDomainObject },
{ name: "X", property: "x", domainObject: mockDomainObject },
{ name: "Y", property: "y", domainObject: mockDomainObject },
{ name: "Z", property: "z", domainObject: mockDomainObject },
{ name: "M", method: "m", domainObject: mockDomainObject }
];
toolbar = new EditToolbar(mockScope, mockOpenMCT, testStructure);
});
it("adds click functions when a method is specified", function () {
var structure = toolbar.getStructure();
expect(structure[6].click).toBeDefined();
});
it("adds key for controls that define a property", function () {
var structure = toolbar.getStructure();
expect(structure[0].key).toEqual(0);
});
});
}
);

View File

@ -21,10 +21,24 @@
*****************************************************************************/
define([
"../layout/res/templates/fixed.html",
'legacyRegistry'
"./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
) {
@ -39,10 +53,46 @@ define([
"cssClass": "icon-box-with-dashed-lines",
"type": "telemetry.fixed",
"template": fixedTemplate,
"uses": [],
"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",

View File

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@ -1,356 +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/LayoutController",
"./src/FixedController",
"./src/LayoutCompositionPolicy",
'./src/MCTTriggerModal',
"./res/templates/layout.html",
"./res/templates/fixed.html",
"./res/templates/frame.html",
"./res/templates/elements/telemetry.html",
"./res/templates/elements/box.html",
"./res/templates/elements/line.html",
"./res/templates/elements/text.html",
"./res/templates/elements/image.html",
'legacyRegistry'
], function (
LayoutController,
FixedController,
LayoutCompositionPolicy,
MCTTriggerModal,
layoutTemplate,
fixedTemplate,
frameTemplate,
telemetryTemplate,
boxTemplate,
lineTemplate,
textTemplate,
imageTemplate,
legacyRegistry
) {
legacyRegistry.register("platform/features/layout", {
"name": "Layout components.",
"description": "Plug in adding Layout capabilities.",
"extensions": {
"views": [
{
"key": "layout",
"name": "Display Layout",
"cssClass": "icon-layout",
"type": "layout",
"template": layoutTemplate,
"editable": true,
"uses": []
},
{
"key": "fixed",
"name": "Fixed Position",
"cssClass": "icon-box-with-dashed-lines",
"type": "telemetry.panel",
"template": fixedTemplate,
"uses": [
"composition"
],
"toolbar": {
"sections": [
{
"items": [
{
"method": "add",
"cssClass": "icon-plus",
"control": "menu-button",
"text": "Add",
"title": "Add",
"description": "Add new items",
"options": [
{
"name": "Box",
"cssClass": "icon-box",
"key": "fixed.box"
},
{
"name": "Line",
"cssClass": "icon-line-horz",
"key": "fixed.line"
},
{
"name": "Text",
"cssClass": "icon-T",
"key": "fixed.text"
},
{
"name": "Image",
"cssClass": "icon-image",
"key": "fixed.image"
}
]
}
]
},
{
"items": [
{
"method": "order",
"cssClass": "icon-layers",
"control": "menu-button",
"title": "Layering",
"description": "Move the selected object above or below other objects",
"options": [
{
"name": "Move to Top",
"cssClass": "icon-arrow-double-up",
"key": "top"
},
{
"name": "Move Up",
"cssClass": "icon-arrow-up",
"key": "up"
},
{
"name": "Move Down",
"cssClass": "icon-arrow-down",
"key": "down"
},
{
"name": "Move to Bottom",
"cssClass": "icon-arrow-double-down",
"key": "bottom"
}
]
},
{
"property": "fill",
"cssClass": "icon-paint-bucket",
"title": "Fill color",
"description": "Set fill color",
"control": "color"
},
{
"property": "stroke",
"cssClass": "icon-line-horz",
"title": "Border color",
"description": "Set border color",
"control": "color"
},
{
"property": "color",
"cssClass": "icon-T",
"title": "Text color",
"description": "Set text color",
"mandatory": true,
"control": "color"
},
{
"property": "url",
"cssClass": "icon-image",
"control": "dialog-button",
"title": "Image Properties",
"description": "Edit image properties",
"dialog": {
"control": "textfield",
"name": "Image URL",
"cssClass": "l-input-lg",
"required": true
}
},
{
"property": "text",
"cssClass": "icon-gear",
"control": "dialog-button",
"title": "Text Properties",
"description": "Edit text properties",
"dialog": {
"control": "textfield",
"name": "Text",
"required": true
}
},
{
"method": "showTitle",
"cssClass": "icon-two-parts-both",
"control": "button",
"title": "Show title",
"description": "Show telemetry element title"
},
{
"method": "hideTitle",
"cssClass": "icon-two-parts-one-only",
"control": "button",
"title": "Hide title",
"description": "Hide telemetry element title"
}
]
},
{
"items": [
{
"method": "remove",
"control": "button",
"cssClass": "icon-trash",
"title": "Delete",
"description": "Delete the selected item"
}
]
}
]
}
}
],
"representations": [
{
"key": "frame",
"template": frameTemplate
}
],
"directives": [
{
"key": "mctTriggerModal",
"implementation": MCTTriggerModal,
"depends": [
"$document"
]
}
],
"controllers": [
{
"key": "LayoutController",
"implementation": LayoutController,
"depends": [
"$scope",
"$element",
"openmct"
]
},
{
"key": "FixedController",
"implementation": FixedController,
"depends": [
"$scope",
"$q",
"dialogService",
"openmct",
"$element"
]
}
],
"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
}
],
"policies": [
{
"category": "composition",
"implementation": LayoutCompositionPolicy
}
],
"toolbars": [
{
name: "Display Layout Toolbar",
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.
return (selection && selection[1] && selection[1].context.item.type === 'layout');
},
toolbar: function (selection) {
return [
{
control: "checkbox",
name: "Show frame",
domainObject: selection[1].context.item,
property: "configuration.layout.panels[" + selection[0].context.oldItem.id + "].hasFrame"
}
];
}
}
],
"types": [
{
"key": "layout",
"name": "Display Layout",
"cssClass": "icon-layout",
"description": "Assemble other objects and components together into a reusable screen layout. Working in a simple canvas workspace, simply drag in the objects you want, position and size them. Save your design and view or edit it at any time.",
"priority": 900,
"features": "creation",
"model": {
"composition": [],
configuration: {
layout: {
panels: {
}
}
}
},
"properties": [
{
"name": "Layout Grid",
"control": "composite",
"pattern": "^(\\d*[1-9]\\d*)?$",
"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"
}
],
"key": "layoutGrid",
"conversion": "number[]"
},
{
"name": "Advanced",
"control": "textfield",
"key": "layoutAdvancedCss",
"cssClass": "l-input-lg"
}
]
}
]
}
});
});

View File

@ -22,7 +22,6 @@
define([
"./src/MCTForm",
"./src/MCTToolbar",
"./src/MCTControl",
"./src/MCTFileInput",
"./src/FileInputService",
@ -48,7 +47,6 @@ define([
'legacyRegistry'
], function (
MCTForm,
MCTToolbar,
MCTControl,
MCTFileInput,
FileInputService,
@ -83,10 +81,6 @@ define([
"key": "mctForm",
"implementation": MCTForm
},
{
"key": "mctToolbar",
"implementation": MCTToolbar
},
{
"key": "mctControl",
"implementation": MCTControl,

View File

@ -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.
-->
<form novalidate>
<div class="tool-bar btn-bar contents abs">
<span ng-repeat="item in structure">
<span ng-if="item.control === 'divider'" class="l-control-group">
</span>
<ng-form ng-class="{ 'input-labeled': item.name }"
ng-hide="item.hidden"
ng-if="item.control !== 'divider'"
class="inline"
title="{{item.description}}"
name="mctFormInner">
<label ng-if="item.name">
{{item.name}}:
</label>
<mct-control key="item.control"
ng-class="{ disabled: item.disabled }"
ng-model="ngModel"
ng-required="item.required"
ng-pattern="getRegExp(item.pattern)"
options="item.options"
structure="item"
field="item.key">
</mct-control>
</ng-form>
</span>
</div>
</form>

View File

@ -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.
*****************************************************************************/
/**
* Module defining MCTForm. Created by vwoeltje on 11/10/14.
*/
define(
[
"./MCTForm",
"../res/templates/toolbar.html",
"./controllers/ToolbarController"
],
function (
MCTForm,
toolbarTemplate,
ToolbarController
) {
/**
* The mct-toolbar directive allows generation of displayable
* forms based on a declarative description of the form's
* structure.
*
* This directive accepts three attributes:
*
* * `ng-model`: The model for the form; where user input
* will be stored.
* * `structure`: The declarative structure of the toolbar.
* Describes what controls should be shown and where
* their values should be read/written in the model.
* * `name`: The name under which to expose the form's
* dirty/valid state. This is similar to ng-form's use
* of name, except this will be made available in the
* parent scope.
*
* @memberof platform/forms
* @constructor
*/
function MCTToolbar() {
// Use Directive Definition Object from mct-form,
// but use the toolbar's template and controller instead.
var ddo = new MCTForm();
ddo.template = toolbarTemplate;
ddo.controller = ['$scope', 'openmct', ToolbarController];
return ddo;
}
return MCTToolbar;
}
);

View File

@ -1,84 +0,0 @@
define(
[
'../../../commonUI/edit/src/representers/EditToolbar'
],
function (EditToolbar) {
// Default ng-pattern; any non whitespace
var NON_WHITESPACE = /\S/;
/**
* Controller for mct-toolbar directive.
*
* @memberof platform/forms
* @constructor
*/
function ToolbarController($scope, openmct) {
var regexps = [];
// ng-pattern seems to want a RegExp, and not a
// string (despite what documentation says) but
// we want toolbar structure to be JSON-expressible,
// so we make RegExp's from strings as-needed
function getRegExp(pattern) {
// If undefined, don't apply a pattern
if (!pattern) {
return NON_WHITESPACE;
}
// Just echo if it's already a regexp
if (pattern instanceof RegExp) {
return pattern;
}
// Otherwise, assume a string
// Cache for easy lookup later (so we don't
// creat a new RegExp every digest cycle)
if (!regexps[pattern]) {
regexps[pattern] = new RegExp(pattern);
}
return regexps[pattern];
}
this.openmct = openmct;
this.$scope = $scope;
$scope.editToolbar = {};
$scope.getRegExp = getRegExp;
$scope.$on("$destroy", this.destroy.bind(this));
openmct.selection.on('change', this.handleSelection.bind(this));
}
ToolbarController.prototype.handleSelection = function (selection) {
var domainObject = selection[0].context.oldItem;
var element = selection[0].context.elementProxy;
if ((domainObject && domainObject === this.selectedObject) || (element && element === this.selectedObject)) {
return;
}
this.selectedObject = domainObject || element;
if (this.editToolbar) {
this.editToolbar.destroy();
}
var structure = this.openmct.toolbars.get(selection) || [];
this.editToolbar = new EditToolbar(this.$scope, this.openmct, structure);
this.$scope.$parent.editToolbar = this.editToolbar;
this.$scope.$parent.editToolbar.structure = this.editToolbar.getStructure();
this.$scope.$parent.editToolbar.state = this.editToolbar.getState();
setTimeout(function () {
this.$scope.$apply();
}.bind(this));
};
ToolbarController.prototype.destroy = function () {
this.openmct.selection.off("change", this.handleSelection);
};
return ToolbarController;
}
);

View File

@ -1,112 +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/MCTToolbar"],
function (MCTToolbar) {
describe("The mct-toolbar directive", function () {
var mockScope,
mockOpenMCT,
mockSelection,
mctToolbar;
function installController() {
var Controller = mctToolbar.controller[2];
return new Controller(mockScope, mockOpenMCT);
}
beforeEach(function () {
mockScope = jasmine.createSpyObj("$scope", [
"$watch",
"$on"
]);
mockScope.$parent = {};
mockSelection = jasmine.createSpyObj("selection", [
'on',
'off'
]);
mockOpenMCT = {
selection: mockSelection
};
mctToolbar = new MCTToolbar();
});
it("is restricted to elements", function () {
expect(mctToolbar.restrict).toEqual("E");
});
it("listens for selection change event", function () {
installController();
expect(mockOpenMCT.selection.on).toHaveBeenCalledWith(
"change",
jasmine.any(Function)
);
});
it("allows strings to be converted to RegExps", function () {
// This is needed to support ng-pattern in the template
installController();
// Should have added getRegExp to the scope,
// to convert strings to regular expressions
expect(mockScope.getRegExp("^\\d+$")).toEqual(/^\d+$/);
});
it("returns the same regexp instance for the same string", function () {
// Don't want new instances each digest cycle, for performance
var strRegExp = "^[a-z]\\d+$",
regExp;
// Add getRegExp to scope
installController();
regExp = mockScope.getRegExp(strRegExp);
// Same object instance each time...
expect(mockScope.getRegExp(strRegExp)).toBe(regExp);
expect(mockScope.getRegExp(strRegExp)).toBe(regExp);
});
it("passes RegExp objects through untouched", function () {
// Permit using forms to simply provide their own RegExp object
var regExp = /^\d+[a-d]$/;
// Add getRegExp to scope
installController();
// Should have added getRegExp to the scope,
// to convert strings to regular expressions
expect(mockScope.getRegExp(regExp)).toBe(regExp);
});
it("passes a non-whitespace regexp when no pattern is defined", function () {
// If no pattern is supplied, ng-pattern should match anything
installController();
expect(mockScope.getRegExp()).toEqual(/\S/);
expect(mockScope.getRegExp(undefined)).toEqual(/\S/);
});
});
}
);

View File

@ -91,8 +91,8 @@
background: rgba($editColor, 0.1);
}
.s-selected,
.s-selected-parent {
[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.
@ -128,7 +128,6 @@
frames: [],
frameStyles: [],
rawPositions: {},
initSelect: true,
drilledIn: undefined
}
},
@ -141,6 +140,7 @@
this.newDomainObject = this.domainObject;
this.gridSize = this.newDomainObject.layoutGrid || DEFAULT_GRID_SIZE;
this.composition = this.openmct.composition.get(this.newDomainObject);
this.Listeners = [];
let panels = (((this.newDomainObject.configuration || {}).layout || {}).panels || {});
if (this.composition !== undefined) {
@ -237,8 +237,32 @@
return;
}
let domainObject = selection[0].context.item;
if (domainObject && domainObject === this.selectedObject) {
return;
}
this.selectedObject = domainObject;
this.removeListeners();
if (selection[1]) {
this.attachSelectionListeners();
}
this.updateDrilledInState();
},
attachSelectionListeners() {
let id = this.openmct.objects.makeKeyString(this.selectedObject.identifier);
let path = "configuration.layout.panels[" + id + "]";
this.listeners.push(this.openmct.objects.observe(this.newDomainObject, path + ".hasFrame", function (newValue) {
this.frameItems.forEach(function (item) {
if (item.id === id) {
item.hasFrame = newValue;
}
});
this.frames[id] = newValue;
}.bind(this)));
},
updateDrilledInState(id) {
this.drilledIn = id;
this.frameItems.forEach(function (item) {
@ -282,6 +306,7 @@
},
handleDrop($event) {
$event.preventDefault();
$event.stopPropagation();
let child = JSON.parse($event.dataTransfer.getData('domainObject'));
let duplicates = [];
@ -311,6 +336,14 @@
},
handleDragOver($event){
$event.preventDefault();
},
removeListeners() {
if (this.listeners) {
this.listeners.forEach(function (l) {
l();
})
}
this.listeners = [];
}
},
mounted() {
@ -321,6 +354,7 @@
this.composition.off('remove', this.onRemoveComposition);
this.openmct.off('change', this.selection);
this.unlisten();
this.removeListeners();
}
}

View File

@ -139,7 +139,7 @@
}
}
&.s-selected, // LEGACY
&[s-selected], // LEGACY
&.is-selected {
border: $browseBorderSelected;
}
@ -155,7 +155,7 @@
border: $editBorderSelectableHov;
}
&.s-selected,
&[s-selected],
&.is-selected {
border: $editBorderSelected;

View File

@ -63,5 +63,40 @@ export default function () {
}
});
openmct.types.addType('layout', DisplayLayoutType());
openmct.toolbars.addProvider({
name: "Display Layout Toolbar",
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.type === 'layout' &&
openmct.editor.isEditing());
},
toolbar: function (selection) {
let id = openmct.objects.makeKeyString(selection[0].context.item.identifier);
return [
{
control: "toggle-button",
domainObject: selection[1].context.item,
property: "configuration.layout.panels[" + id + "].hasFrame",
options: [
{
value: false,
icon: 'icon-frame-hide',
title: "Hide frame"
},
{
value: true,
icon: 'icon-frame-show',
title: "Show frame"
}
]
}
];
}
});
}
}
}

View File

@ -1,7 +1,7 @@
<div class="c-ne__embed">
<div class="c-ne__embed__snap-thumb"
v-if="embed.snapshot"
v-on:click="openSnapshot">
v-on:click="openSnapshot(domainObject, entry, embed)">
<img v-bind:src="embed.snapshot.src">
</div>
<div class="c-ne__embed__info">

View File

@ -15,7 +15,7 @@
<div class="flex-elem holder flex-can-shrink s-snapshot-datetime">
SNAPSHOT {{formatTime(embed.createdOn, 'YYYY-MM-DD HH:mm:ss')}}
</div>
<a class="s-button icon-pencil" title="Annotate">
<a class="s-button icon-pencil" title="Annotate" @click="annotateSnapshot">
<span class="title-label">Annotate</span>
</a>
</div>
@ -23,7 +23,7 @@
<div class="abs object-holder t-image-holder s-image-holder">
<div
class="image-main s-image-main"
v-bind:style="{ backgroundImage: 'url(' + embed.snapshot.src + ')' }">
:style="{ backgroundImage: 'url(' + embed.snapshot.src + ')' }">
</div>
</div>
</div>

View File

@ -23,16 +23,16 @@
define([
'moment',
'zepto',
'../utils/SnapshotOverlay',
'../../res/templates/snapshotTemplate.html',
'vue'
'vue',
'painterro'
],
function (
Moment,
$,
SnapshotOverlay,
SnapshotTemplate,
Vue
Vue,
Painterro
) {
function EmbedController (openmct, domainObject) {
this.openmct = openmct;
@ -52,11 +52,102 @@ function (
EmbedController.prototype.navigate = function (embedType) {
this.objectService.getObjects([embedType]).then(function (objects) {
this.navigationService.setNavigation(objects[embedType]);
this.navigationService.setNavigation(objects[embedType]);
}.bind(this));
};
EmbedController.prototype.openSnapshot = function () {
EmbedController.prototype.openSnapshot = function (domainObject, entry, embed) {
function annotateSnapshot(openmct) {
return function () {
var save = false,
painterroInstance = {},
annotateOverlay = new Vue({
template: '<div id="snap-annotation"></div>'
}),
self = this;
var options = {
cssClass: 'l-large-view',
onDestroy: function () {
annotateOverlay.$destroy(true);
},
buttons: [
{
label: 'Cancel',
callback: function () {
save = false;
painterroInstance.save();
}
},
{
label: 'Save',
callback: function () {
save = true;
painterroInstance.save();
}
}
]
};
openmct.OverlayService.show(annotateOverlay.$mount().$el, options);
painterroInstance = Painterro({
id: 'snap-annotation',
activeColor: '#ff0000',
activeColorAlpha: 1.0,
activeFillColor: '#fff',
activeFillColorAlpha: 0.0,
backgroundFillColor: '#000',
backgroundFillColorAlpha: 0.0,
defaultFontSize: 16,
defaultLineWidth: 2,
defaultTool: 'ellipse',
hiddenTools: ['save', 'open', 'close', 'eraser', 'pixelize', 'rotate', 'settings', 'resize'],
translation: {
name: 'en',
strings: {
lineColor: 'Line',
fillColor: 'Fill',
lineWidth: 'Size',
textColor: 'Color',
fontSize: 'Size',
fontStyle: 'Style'
}
},
saveHandler: function (image, done) {
if (save) {
var entryPos = self.findInArray(domainObject.entries, entry.id),
embedPos = self.findInArray(entry.embeds, embed.id);
if (entryPos !== -1 && embedPos !== -1) {
var url = image.asBlob(),
reader = new window.FileReader();
reader.readAsDataURL(url);
reader.onloadend = function () {
var snapshot = reader.result,
snapshotObject = {
src: snapshot,
type: url.type,
size: url.size,
modified: Date.now()
},
dirString = 'entries[' + entryPos + '].embeds[' + embedPos + '].snapshot';
openmct.objects.mutate(domainObject, dirString, snapshotObject);
};
}
} else {
console.log('You cancelled the annotation!!!');
}
done(true);
}
}).show(embed.snapshot.src);
};
}
var self = this,
snapshot = new Vue({
template: SnapshotTemplate,
@ -66,15 +157,22 @@ function (
};
},
methods: {
formatTime: self.formatTime
formatTime: self.formatTime,
annotateSnapshot: annotateSnapshot(self.openmct),
findInArray: self.findInArray
}
});
function onDestroyCallback() {
snapshot.$destroy(true);
}
var options = {
onDestroy: onDestroyCallback,
cssClass: 'l-large-view'
};
this.openmct.OverlayService.show(snapshot.$mount().$el, {onDestroy: onDestroyCallback, cssClass: 'l-large-view'});
this.openmct.OverlayService.show(snapshot.$mount().$el, options);
};
EmbedController.prototype.formatTime = function (unixTime, timeFormat) {
@ -125,23 +223,20 @@ function (
var entryPosition = self.findInArray(self.domainObject.entries, entry.id),
embedPosition = self.findInArray(entry.embeds, embed.id);
var warningDialog = self.dialogService.showBlockingMessage({
self.openmct.OverlayService.showBlockingMessage({
severity: "error",
title: "This action will permanently delete this embed. Do you wish to continue?",
options: [{
label: "OK",
actionText: 'This Action will permanently delete this embed. Do you wish to continue?',
buttons: [{
label: "No",
callback: function () {}
},
{
label: "Yes",
callback: function () {
entry.embeds.splice(embedPosition, 1);
var dirString = 'entries[' + entryPosition + '].embeds';
self.openmct.objects.mutate(self.domainObject, dirString, entry.embeds);
warningDialog.dismiss();
}
},{
label: "Cancel",
callback: function () {
warningDialog.dismiss();
}
}]
});
@ -207,7 +302,8 @@ function (
openSnapshot: self.openSnapshot,
formatTime: self.formatTime,
toggleActionMenu: self.toggleActionMenu,
actionToMenuDecorator: self.actionToMenuDecorator
actionToMenuDecorator: self.actionToMenuDecorator,
findInArray: self.findInArray
};
};

View File

@ -81,23 +81,23 @@ function (
if (entryPos !== -1) {
var errorDialog = this.dialogService.showBlockingMessage({
severity: "error",
title: "This action will permanently delete this Notebook entry. Do you wish to continue?",
options: [{
label: "OK",
callback: function () {
domainObject.entries.splice(entryPos, 1);
openmct.objects.mutate(domainObject, 'entries', domainObject.entries);
errorDialog.dismiss();
this.openmct.OverlayService.showBlockingMessage({
severity: "alert",
actionText: "This action will permanently delete this Notebook entry. Do you wish to continue?",
buttons: [
{
label: "Ok",
emphasis: true,
callback: function () {
domainObject.entries.splice(entryPos, 1);
openmct.objects.mutate(domainObject, 'entries', domainObject.entries);
}
},
{
label: "Cancel",
callback: function () {}
}
},{
label: "Cancel",
callback: function () {
errorDialog.dismiss();
}
}]
]
});
}
};

View File

@ -60,7 +60,7 @@ function (
this.container = container;
var notebookEmbed = {
inject:['openmct'],
inject:['openmct', 'domainObject'],
props:['embed', 'entry'],
template: EmbedTemplate,
data: embedController.exposedData,
@ -81,7 +81,7 @@ function (
var notebookVue = Vue.extend({
template: NotebookTemplate,
provide: {openmct: self.openmct},
provide: {openmct: self.openmct, domainObject: self.domainObject},
components: {
'notebook-entry': entryComponent,
'search': search.default

View File

@ -21,7 +21,7 @@
*****************************************************************************/
<template>
<div class="c-conductor"
:class="[isFixed ? 'is-fixed-mode' : 'is-realtime-mode', panning ? 'status-panning' : '']">
:class="[isFixed ? 'is-fixed-mode' : 'is-realtime-mode']">
<form class="u-contents" ref="conductorForm"
@submit="isFixed ? setBoundsFromView($event) : setOffsetsFromView($event)">

View File

@ -203,11 +203,10 @@ export default {
let bounds = this.openmct.time.bounds();
let deltaTime = bounds.end - bounds.start;
let newStart = bounds.start - percX * deltaTime;
this.bounds = {
this.$emit('panAxis',{
start: newStart,
end: newStart + deltaTime
};
this.$emit('panAxis', this.bounds);
});
this.dragging = false;
})
} else {

View File

@ -55,19 +55,19 @@ define(['EventEmitter'], function (EventEmitter) {
}
if (this.selected[0] && this.selected[0].element) {
this.selected[0].element.classList.remove('s-selected');
this.selected[0].element.removeAttribute('s-selected');
}
if (this.selected[1] && this.selected[1].element) {
this.selected[1].element.classList.remove('s-selected-parent');
this.selected[1].element.removeAttribute('s-selected-parent');
}
if (selectable[0] && selectable[0].element) {
selectable[0].element.classList.add('s-selected');
selectable[0].element.setAttribute('s-selected', "");
}
if (selectable[1] && selectable[1].element) {
selectable[1].element.classList.add('s-selected-parent');
selectable[1].element.setAttribute('s-selected-parent', "");
}
this.selected = selectable;

View File

@ -47,23 +47,27 @@ $colorStatusBarFgHov: #aaa;
$colorKey: #0099cc;
$colorKeyFg: #fff;
$colorKeyHov: #00c0f6;
$colorKeyFilter: brightness(1) sepia(1) hue-rotate(145deg) saturate(6);
$colorKeyFilterHov: brightness(1) sepia(1) hue-rotate(145deg) saturate(7);
$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%);
$colorKeySelectedBg: $colorKey;
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
$colorA: #ccc;
$colorAHov: #fff;
// Layout
$shellMainPad: 4px 0;
$shellPanePad: $interiorMargin, 7px; // TODO: Sync this with Snow theme
$shellPanePad: $interiorMargin, 7px;
// Status colors, mainly used for messaging and item ancillary symbols
$colorStatusFg: #999;
$colorStatusDefault: #ccc;
$colorStatusInfo: #60ba7b;
$colorStatusInfoFilter: invert(58%) sepia(44%) saturate(405%) hue-rotate(85deg) brightness(102%) contrast(92%);
$colorStatusAlert: #ffb66c;
$colorStatusAlertFilter: invert(78%) sepia(26%) saturate(1160%) hue-rotate(324deg) brightness(107%) contrast(101%);
$colorStatusError: #da0004;
$colorStatusBtnBg: #666;
$colorStatusErrorFilter: invert(10%) sepia(96%) saturate(4360%) hue-rotate(351deg) brightness(111%) contrast(115%);
$colorStatusBtnBg: #666; // Where is this used?
// States
$colorPausedBg: #ff9900;
@ -96,9 +100,11 @@ $editBorderSelected: 1px solid $editColor;
$editBorderDrilledIn: 1px dashed #ff4d9a;
$colorGridLines: rgba($editColor, 0.2);
// UI elements
// Icons
$colorIconAlias: #4af6f3;
$colorIconAliasForKeyFilter: #aaa;
// Alerts, dialogs and notifications
$colorProgressBarOuter: rgba(#000, 0.1);
$colorProgressBarAmt: #0a0;
@ -300,7 +306,7 @@ $createBtnTextTransform: uppercase;
@mixin themedButton($c: $colorBtnBg) {
background: linear-gradient(lighten($c, 5%), $c);
box-shadow: rgba(black, 0.5) 0 0 2px;
box-shadow: rgba(black, 0.5) 0 0.5px 2px;
}
/**************************************************** NOT USED, LEAVE FOR NOW */

View File

@ -47,23 +47,27 @@ $colorStatusBarFgHov: #aaa;
$colorKey: #0099cc;
$colorKeyFg: #fff;
$colorKeyHov: #00c0f6;
$colorKeyFilter: brightness(0.9) sepia(1) hue-rotate(145deg) saturate(6);
$colorKeyFilterHov: brightness(1) sepia(1) hue-rotate(145deg) saturate(7);
$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%);
$colorKeySelectedBg: $colorKey;
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
$colorA: #999;
$colorAHov: $colorKey;
// Layout
$shellMainPad: 4px 0;
$shellPanePad: 0 7px;
$shellPanePad: $interiorMargin, 7px;
// Status colors, mainly used for messaging and item ancillary symbols
$colorStatusFg: #999;
$colorStatusDefault: #ccc;
$colorStatusInfo: #60ba7b;
$colorStatusInfoFilter: invert(64%) sepia(42%) saturate(416%) hue-rotate(85deg) brightness(93%) contrast(93%);
$colorStatusAlert: #ffb66c;
$colorStatusAlertFilter: invert(89%) sepia(26%) saturate(5035%) hue-rotate(316deg) brightness(114%) contrast(107%);
$colorStatusError: #da0004;
$colorStatusBtnBg: #666;
$colorStatusErrorFilter: invert(8%) sepia(96%) saturate(4511%) hue-rotate(352deg) brightness(136%) contrast(114%);
$colorStatusBtnBg: #666; // Where is this used?
// States
$colorPausedBg: #ff9900;
@ -96,9 +100,11 @@ $editBorderSelected: 1px solid $editColor;
$editBorderDrilledIn: 1px dashed #ff4d9a;
$colorGridLines: rgba($editColor, 0.2);
// UI elements
// Icons
$colorIconAlias: #4af6f3;
$colorIconAliasForKeyFilter: #aaa;
// Alerts, dialogs and notifications
$colorProgressBarOuter: rgba(#000, 0.1);
$colorProgressBarAmt: #0a0;

View File

@ -40,7 +40,8 @@ $inputTextP: $inputTextPTopBtm $inputTextPLeftRight;
$menuLineH: 1.5rem;
$treeItemIndent: 16px;
$treeTypeIconW: 18px;
$overlayOuterMargin: 5%;
$overlayOuterMarginLg: 5%;
$overlayOuterMarginDialog: 20%;
$overlayInnerMargin: 25px;
/*************** Items */
@ -177,34 +178,38 @@ $glyph-icon-notebook: '\e1131';
/************************** GLYPHS AS DATA URI */
// Only objects have been converted, for use in Create menu and folder views
$bg-icon-activity: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M288 32H160l160 160H174.872C152.74 153.742 111.377 128 64 128H0v256h64c47.377 0 88.74-25.742 110.872-64H320L160 480h128l224-224L288 32z'/%3e%3c/svg%3e");
$bg-icon-activity-mode: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M256 0C148.6 0 56.6 66.2 18.6 160H64c28.4 0 54 12.4 71.5 32H256l-96-96h128l160 160-160 160H160l96-96H135.5C118 339.6 92.4 352 64 352H18.6c38 93.8 129.9 160 237.4 160 141.4 0 256-114.6 256-256S397.4 0 256 0z'/%3e%3c/svg%3e");
$bg-icon-autoflow-tabular: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M96 0C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h32V0H96zM192 0h128v512H192zM416 0h-32v352h128V96c0-52.8-43.2-96-96-96z'/%3e%3c/svg%3e");
$bg-icon-clock: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256 256-114.6 256-256S397.4 0 256 0zm135 345c-6.4 11.1-18.3 18-31.2 18-6.3 0-12.5-1.7-18-4.8l-110.9-64-.1-.1c-.4-.2-.8-.5-1.2-.7l-.4-.3-.9-.6-.6-.5-.6-.5-.9-.7-.3-.3c-.4-.3-.7-.6-1.1-.9-2.5-2.3-4.7-5-6.5-7.9-.1-.2-.3-.5-.4-.7s-.3-.5-.4-.7c-1.6-3-2.9-6.2-3.6-9.6v-.1c-.1-.5-.2-.9-.3-1.4 0-.1 0-.3-.1-.4-.1-.3-.1-.7-.1-1.1s-.1-.5-.1-.8 0-.5-.1-.8-.1-.8-.1-1.1v-.5-1.4V81c0-19.9 16.1-36 36-36s36 16.1 36 36v161.2l92.9 53.6c17.1 10 22.9 32 13 49.2z'/%3e%3c/svg%3e");
$bg-icon-database: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M256 256C114.615 256 0 213.019 0 160v256c0 53.019 114.615 96 256 96s256-42.981 256-96V160c0 53.019-114.615 96-256 96z'/%3e%3cellipse fill='%23666666' cx='256' cy='96' rx='256' ry='96'/%3e%3c/svg%3e");
$bg-icon-database-query: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M341.76 409.643C316.369 423.871 287.118 432 256 432c-97.047 0-176-78.953-176-176S158.953 80 256 80s176 78.953 176 176c0 31.118-8.129 60.369-22.357 85.76l95.846 95.846C509.747 430.661 512 423.429 512 416V96c0-53.019-114.615-96-256-96S0 42.981 0 96v320c0 53.019 114.615 96 256 96 63.055 0 120.774-8.554 165.388-22.73l-79.628-79.627z'/%3e%3cpath fill='%23666666' d='M176 256c0 44.112 35.888 80 80 80s80-35.888 80-80-35.888-80-80-80-80 35.888-80 80z'/%3e%3c/svg%3e");
$bg-icon-dataset: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M448 96H288l-54.6-54.6-18.7-18.7C202.2 10.2 177.6 0 160 0H32C14.4 0 0 14.4 0 32v192c0-35.2 28.8-64 64-64h384c35.2 0 64 28.8 64 64v-64c0-35.2-28.8-64-64-64zM448 224H64c-35.2 0-64 28.8-64 64v160c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V288c0-35.2-28.8-64-64-64zM160 448H96V288h64v160zm128 0h-64V288h64v160zm128 0h-64V288h64v160z'/%3e%3c/svg%3e");
$bg-icon-datatable: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M256 256C114.6 256 0 213 0 160v256c0 53 114.6 96 256 96s256-43 256-96V160c0 53-114.6 96-256 96zm192 31.5v128c-18.3 7.8-39.9 14.4-64 19.7v-128c24.1-5.3 45.7-11.9 64-19.7zm-320 19.7v128c-24.1-5.2-45.7-11.9-64-19.7v-128c18.3 7.8 39.9 14.4 64 19.7zM192 445V317c20.5 2 41.9 3 64 3s43.5-1.1 64-3v128c-20.5 2-41.9 3-64 3s-43.5-1.1-64-3z'/%3e%3cellipse fill='%23666666' cx='256' cy='96' rx='256' ry='96'/%3e%3c/svg%3e");
$bg-icon-dictionary: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M416 320c52.8 0 96-43.2 96-96V96c0-52.8-43.2-96-96-96v160l-64-32-64 32V0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h320c52.8 0 96-43.2 96-96v-96c0 52.8-43.2 96-96 96H96v-96h320z'/%3e%3c/svg%3e");
$bg-icon-folder: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M448 96H288l-54.6-54.6-18.7-18.7C202.2 10.2 177.6 0 160 0H32C14.4 0 0 14.4 0 32v192c0-35.2 28.8-64 64-64h384c35.2 0 64 28.8 64 64v-64c0-35.2-28.8-64-64-64zM448 224H64c-35.2 0-64 28.8-64 64v160c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V288c0-35.2-28.8-64-64-64z'/%3e%3c/svg%3e");
$bg-icon-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M448 0H64C28.8 0 0 28.8 0 64v384c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V64c0-35.2-28.8-64-64-64zm0 448H64V64h384v384z'/%3e%3cpath fill='%23666666' d='M160 128l-64 64v224h320V256l-64-64-64 64z'/%3e%3c/svg%3e");
$bg-icon-layout: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M224 0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h128V0zM416 0H288v288.832h224V96c0-52.8-43.2-96-96-96zM288 512h128c52.8 0 96-43.2 96-96v-64.832H288V512z'/%3e%3c/svg%3e");
$bg-icon-object: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='none' d='M256 96L76.8 208 256 320l179.2-112z'/%3e%3cpath fill='%23666666' d='M256 512l256-160V160L255.99 0 0 160v192l256 160zm0-416l179.2 112L256 320 76.8 208 256 96z'/%3e%3c/svg%3e");
$bg-icon-object-unknown: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M255-1L-1 159v192l256 160 256-160V159L255-1zm37.7 430.6c-10.6 10.4-23 15.4-38 15.4-15.6 0-28.1-4.9-38.1-14.8-10-10-14.8-22.4-14.8-38.1 0-15.2 5.1-27.6 15.5-38.1s22.6-15.6 37.4-15.6c14.8 0 27.1 5.2 37.8 16 10.7 10.8 15.9 23.2 15.9 38-.1 14.5-5.4 27-15.7 37.2zm26.4-156.3c-11.8 5.9-18.7 11-21.7 16.2-1.8 3.1-3 7.4-3.7 13.4v20.5H213v-22.1c0-20.1 2.2-34.9 6.5-44 4-8.6 11.3-15.1 22.4-20l17.4-7.7c16-7.1 24.1-17.6 24.1-31.4 0-8-3-15.2-8.6-20.9-5.6-5.6-12.8-8.6-20.8-8.6-12 0-27.2 5-31.4 28.7l-1.1 6.1H148l.7-8.1c2-22.3 8.5-41.2 19.4-56.1 9.8-13.5 22.8-24.3 38.5-32.3 15.7-8 32.3-12 49.1-12 30.3 0 55.1 9.7 75.7 29.8 20.6 20 30.6 44 30.6 73.6 0 35.4-14.4 60.7-42.9 74.9z'/%3e%3c/svg%3e");
$bg-icon-packet: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='none' d='M256 96L76.8 208 256 320l179.2-112z'/%3e%3cpath fill='%23666666' d='M256 0L0 160v256c0 52.8 43.2 96 96 96h320c52.8 0 96-43.2 96-96V160L256 0zm0 96l179.2 112L256 320 76.8 208 256 96z'/%3e%3c/svg%3e");
$bg-icon-page: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M352 256c-52.8 0-96-43.2-96-96V0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h320c52.8 0 96-43.2 96-96V256H352z'/%3e%3cpath fill='%23666666' d='M384 192h128L320 0v128c0 35.2 28.8 64 64 64z'/%3e%3c/svg%3e");
$bg-icon-plot-overlay: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M415 0H97C43.65 0 0 43.65 0 97v203.41c7.09 9.32 12.83 14.17 16 15.42 7.14-2.81 27.22-23.77 46.48-73C83.71 188.64 120.64 124 176 124c26.2 0 50.71 14.58 72.85 43.34 18.67 24.25 32.42 54.46 40.67 75.54 19.26 49.19 39.34 70.15 46.48 73 7.14-2.81 27.22-23.77 46.48-73C403.71 188.64 440.64 124 496 124a69.55 69.55 0 0 1 16 1.87V97c0-53.35-43.65-97-97-97z'/%3e%3cpath fill='%23666666' d='M496 196.17c-7.14 2.81-27.22 23.76-46.48 73C428.29 323.36 391.36 388 336 388c-26.2 0-50.71-14.58-72.85-43.34-18.67-24.25-32.42-54.46-40.67-75.54-19.26-49.19-39.34-70.15-46.48-73-7.14 2.81-27.22 23.76-46.48 73C108.29 323.36 71.36 388 16 388a69.56 69.56 0 0 1-16-1.87V415c0 53.35 43.65 97 97 97h318c53.35 0 97-43.65 97-97V211.59c-7.09-9.32-12.83-14.17-16-15.42z'/%3e%3c/svg%3e");
$bg-icon-plot-stacked: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M44.8 156c12.49 0 24.48-13.26 42.76-35.09 22.71-27.14 51-60.91 98-60.91 22.32 0 43.31 7.73 62.4 23 14.34 11.45 25.58 25.21 36.46 38.53C303.63 145 314 156 326.4 156H512V97c0-53.35-43.65-97-97-97H97C43.65 0 0 43.65 0 97v59h44.8z'/%3e%3cpath fill='%23666666' d='M264.75 205.2c-14.12-11.32-25.26-25-36-38.14C211 145.32 199.37 132 185.6 132c-12.53 0-24.54 13.27-42.83 35.12-22.7 27.12-51 60.88-98 60.88H0v56h185.6c22 0 42.77 7.67 61.65 22.8 14.12 11.32 25.26 25 36 38.14C301 366.68 312.63 380 326.4 380c12.53 0 24.54-13.27 42.83-35.12 22.7-27.12 51-60.88 98-60.88H512v-56H326.4c-22.03 0-42.77-7.67-61.65-22.8z'/%3e%3cpath fill='%23666666' d='M467.2 356c-12.49 0-24.48 13.26-42.76 35.09-22.71 27.14-51 60.91-98 60.91-22.32 0-43.31-7.73-62.4-23-14.34-11.45-25.58-25.21-36.46-38.53C208.37 367 198 356 185.6 356H0v59c0 53.35 43.65 97 97 97h318c53.35 0 97-43.65 97-97v-59h-44.8z'/%3e%3c/svg%3e");
$bg-icon-session: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M317.8 262.2c3.3 2.1 6.6 4.3 9.6 6.8l60.2 48.2c14.8 11.9 41.9 11.9 56.7 0l67.6-54c.1-2.4.1-4.7.1-7.1 0-26.1-3.9-51.2-11.1-74.9L423.5 243c-29.1 23.3-70.1 29.6-105.7 19.2zM124.3 317.1l60.2-48.2c29-23.2 70-29.6 105.6-19.2-3.3-2.1-6.6-4.3-9.6-6.8l-60.2-48.2c-14.8-11.9-41.9-11.9-56.7 0L103.5 243c-20 16-45.7 24-71.5 24-10.8 0-21.5-1.4-31.9-4.2v.8c2.5 1.7 5 3.4 7.3 5.3l60.2 48.2c14.9 11.9 41.9 11.9 56.7 0z'/%3e%3cpath fill='%23666666' d='M60.3 189.1l60.2-48.2c40.1-32.1 102.8-32.1 142.9 0l60.2 48.2c14.8 11.9 41.9 11.9 56.7 0l90.5-72.4C425.2 46.5 346 0 256 0 136.7 0 36.4 81.6 8 192.1c15.4 8.8 38.9 7.8 52.3-3zM344.5 371l-60.2-48.2c-14.8-11.9-41.9-11.9-56.7 0L167.5 371c-20 16-45.7 24-71.5 24-23.9 0-47.7-6.9-67.1-20.7C71.7 456.1 157.3 512 256 512s184.3-55.9 227.1-137.7c-40.2 28.7-99.9 27.6-138.6-3.3z'/%3e%3c/svg%3e");
$bg-icon-tabular: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M448 0H64C28.8 0 0 28.8 0 64v384c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V64c0-35.2-28.8-64-64-64zM320 224H192v-96h128v96zm-128 32h128v96H192v-96zm-32 96H32v-96h128v96zm0-224v96H32v-96h128zM64 480c-8.5 0-16.5-3.3-22.6-9.4S32 456.5 32 448v-64h128v96H64zm128 0v-96h128v96H192zm288-32c0 8.5-3.3 16.5-9.4 22.6S456.5 480 448 480h-96v-96h128v64zm0-96H352v-96h128v96zm0-128H352v-96h128v96z'/%3e%3c/svg%3e");
$bg-icon-tabular-lad: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M448 0H64C28.7.1.1 28.7 0 64v384c.1 35.3 28.7 63.9 64 64h384c35.3-.1 63.9-28.7 64-64V64c-.1-35.3-28.7-63.9-64-64zM32 128h128v96H32v-96zm0 128h128v96H32v-96zm32 224c-17.6-.1-31.9-14.4-32-32v-64h128v96H64zm128 0v-96h128v96H192zm288-32c-.1 17.6-14.4 31.9-32 32h-96v-96h128v64zm0-192v96H192v-96h32v-32h-32v-96h288v96h-32v32h32z'/%3e%3cpath fill='%23666666' d='M391.2 273.7L336 246.1V160c0-8.8-7.2-16-16-16s-16 7.2-16 16v105.9l72.8 36.4c7.9 4 17.5.8 21.5-7.2 4-7.8.8-17.5-7.1-21.4z'/%3e%3c/svg%3e");
$bg-icon-tabular-lad-set: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M64 384V96c-35.3.1-63.9 28.7-64 64v288c.1 35.3 28.7 63.9 64 64h288c35.3-.1 63.9-28.7 64-64H128c-35.3-.1-63.9-28.7-64-64z'/%3e%3cpath fill='%23666666' d='M448 0H160c-35.3.1-63.9 28.7-64 64v288c.1 35.3 28.7 63.9 64 64h288c35.3-.1 63.9-28.7 64-64V64c-.1-35.3-28.7-63.9-64-64zM128 96h96v64h-96V96zm0 96h96v96h-96v-96zm32 192c-17.6-.1-31.9-14.4-32-32v-32h96v64h-64zm96 0v-64h96v64h-96zm224-32c-.1 17.6-14.4 31.9-32 32h-64v-64h96v32zm0-64H256V96h224v192z'/%3e%3cpath fill='%23666666' d='M416 240c8.8 0 16-7.2 16-16 0-6.9-4.4-13-10.9-15.2L384 196.5V144c0-8.8-7.2-16-16-16s-16 7.2-16 16v75.5l58.9 19.6c1.7.6 3.4.9 5.1.9z'/%3e%3c/svg%3e");
$bg-icon-tabular-realtime: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M0 64v384c0 35.2 28.8 64 64 64h288c35.2 0 64-28.8 64-64V340c-19.8 7.8-41.4 12-64 12-35.4 0-68.4-10.5-96-28.6V352h-96v-96h35.3c-5.2-10.1-9.4-20.8-12.6-32H160v-96h22.7C203.6 54.2 271.6 0 352 0H64C28.8 0 0 28.8 0 64zm288 320h96v64c0 8.5-3.3 16.5-9.4 22.6S360.5 480 352 480h-64v-96zm-160 96H64c-8.5 0-16.5-3.3-22.6-9.4S32 456.5 32 448v-64h96v96zm0-128H32v-96h96v96zm32 32h96v96h-96v-96zm-32-160H32v-96h96v96z'/%3e%3cpath fill='%23666666' d='M192 160c0 88.4 71.6 160 160 160s160-71.6 160-160S440.4 0 352 0 192 71.6 192 160zm49.7 39.8L227 187.5c-1.4-6.4-2.3-12.9-2.7-19.6 15.1-.1 30.1-5 41.9-14.8l39.6-33c7.5-6.2 21.1-6.2 28.6 0l39.6 33c2.8 2.3 5.7 4.3 8.8 6.1-23-11.7-52.7-9.2-72.8 7.5l-39.6 33c-7.6 6.3-21.2 6.3-28.7.1zM352 288c-36.7 0-69.7-15.4-93-40.1 14.2-.6 28.1-5.5 39.2-14.7l39.6-33c7.5-6.2 21.1-6.2 28.6 0l39.6 33c11 9.2 25 14.1 39.2 14.7-23.5 24.7-56.5 40.1-93.2 40.1zm125.9-151.3c1.4 7.5 2.1 15.3 2.1 23.3 0 9.4-1 18.6-3 27.5l-14.7 12.3c-7.5 6.2-21.1 6.2-28.6 0l-39.6-33c-2.8-2.3-5.7-4.3-8.8-6.1 23 11.7 52.7 9.2 72.8-7.5l19.8-16.5zM352 32c46.4 0 87.1 24.7 109.5 61.7l-31.2 26c-7.5 6.2-21.1 6.2-28.6 0l-39.6-33c-23.6-19.7-60.6-19.7-84.3 0l-39.6 33c-2.5 2.1-5.7 3.5-9.1 4.2C244.7 70.8 293.8 32 352 32z'/%3e%3c/svg%3e");
$bg-icon-tabular-scrolling: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M32 0C14.4 0 0 14.4 0 32v96h224V0H32zM512 128V32c0-17.6-14.4-32-32-32H288v128h224zM0 192v96c0 17.6 14.4 32 32 32h192V192H0zM480 320c17.6 0 32-14.4 32-32v-96H288v128h192zM256 512L128 384h256z'/%3e%3c/svg%3e");
$bg-icon-telemetry: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M16 315.83c7.14-2.81 27.22-23.77 46.48-73C83.71 188.64 120.64 124 176 124c26.2 0 50.71 14.58 72.85 43.34 18.67 24.25 32.42 54.46 40.67 75.54 19.26 49.19 39.34 70.15 46.48 73 7.14-2.81 27.22-23.77 46.48-73 18.7-47.75 49.57-103.57 94.47-116.23A255.87 255.87 0 0 0 256 0C114.62 0 0 114.62 0 256a257.18 257.18 0 0 0 5 50.52c4.77 5.39 8.61 8.37 11 9.31z'/%3e%3cpath fill='%23666666' d='M496 196.17c-7.14 2.81-27.22 23.76-46.48 73C428.29 323.36 391.36 388 336 388c-26.2 0-50.71-14.58-72.85-43.34-18.67-24.25-32.42-54.46-40.67-75.54-19.26-49.19-39.34-70.15-46.48-73-7.14 2.81-27.22 23.76-46.48 73-18.7 47.75-49.57 103.57-94.47 116.23A255.87 255.87 0 0 0 256 512c141.38 0 256-114.62 256-256a257.18 257.18 0 0 0-5-50.52c-4.77-5.39-8.61-8.37-11-9.31z'/%3e%3c/svg%3e");
$bg-icon-timeline: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M128 128h192v64H128zM192 224h192v64H192zM160 320h192v64H160z'/%3e%3cpath fill='%23666666' d='M416 0h-64v96h63.8c.1 0 .1.1.2.2v319.7c0 .1-.1.1-.2.2H352v96h64c52.8 0 96-43.2 96-96V96c0-52.8-43.2-96-96-96zM96 415.8V96.2c0-.1.1-.1.2-.2H160V0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h64v-96H96.2c-.1 0-.2-.1-.2-.2z'/%3e%3c/svg%3e");
$bg-icon-timer: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M288 73.3V32.01a32 32 0 0 0-32-32h-64a32 32 0 0 0-32 32V73.3C67.48 100.84 0 186.54 0 288.01c0 123.71 100.29 224 224 224s224-100.29 224-224c0-101.48-67.5-187.2-160-214.71zm-54 224.71l-131.88 105.5A167.4 167.4 0 0 1 56 288.01c0-92.64 75.36-168 168-168 3.36 0 6.69.11 10 .31v177.69z'/%3e%3c/svg%3e");
$bg-icon-topic: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M227.18 238.32l43.15-43.15a25.18 25.18 0 0 1 35.36 0l43.15 43.15a94.42 94.42 0 0 0 35.18 22.25V174.5l-28.82-28.82a95.11 95.11 0 0 0-134.35 0l-43.15 43.15a25.18 25.18 0 0 1-35.36 0L128 174.5v86.07a95.11 95.11 0 0 0 99.18-22.25z'/%3e%3cpath fill='%23666666' d='M252.82 273.68l-43.15 43.15a25.18 25.18 0 0 1-35.36 0l-43.15-43.15c-1-1-2.1-2-3.18-3v98.68a95.11 95.11 0 0 0 131.18-3l43.15-43.15a25.18 25.18 0 0 1 35.36 0l43.15 43.15c1 1 2.1 2 3.18 3v-98.68a95.11 95.11 0 0 0-131.18 3z'/%3e%3cpath fill='%23666666' d='M416 0h-64v96h63.83l.17.17v319.66l-.17.17H352v96h64c52.8 0 96-43.2 96-96V96c0-52.8-43.2-96-96-96zM160 416H96.17l-.17-.17V96.17l.17-.17H160V0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h64v-96z'/%3e%3c/svg%3e");
$bg-icon-box-with-dashed-lines: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M0 192h64v128H0zM64 64.11l.11-.11H160V0H64A64.19 64.19 0 0 0 0 64v96h64V64.11zM64 447.89V352H0v96a64.19 64.19 0 0 0 64 64h96v-64H64.11zM192 0h128v64H192zM448 447.89l-.11.11H352v64h96a64.19 64.19 0 0 0 64-64v-96h-64v95.89zM448 0h-96v64h95.89l.11.11V160h64V64a64.19 64.19 0 0 0-64-64zM448 192h64v128h-64zM192 448h128v64H192zM128 128h256v256H128z'/%3e%3c/svg%3e");
$bg-icon-summary-widget: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M448 0H64C28.8 0 0 28.8 0 64v384c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V64c0-35.2-28.8-64-64-64zm-24.1 305.2l-41.3 71.6-94.8-65.8 9.6 115h-82.7l9.6-115-94.8 65.8-41.3-71.6L192.5 256 88.1 206.8l41.3-71.6 94.8 65.8-9.6-115h82.7l-9.6 115 94.8-65.8 41.3 71.6L319.5 256l104.4 49.2z'/%3e%3c/svg%3e");
$bg-icon-notebook: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M448 55.4c0-39.9-27.7-63.7-61.5-52.7L0 128h448V55.4zM448 160H0v288c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V224c0-35.2-28.8-64-64-64zm-32 256H224V256h192v160z'/%3e%3c/svg%3e");
$bg-icon-alert-rect: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath d='M448 0H64C28.7.1.1 28.7 0 64v384c.1 35.3 28.7 63.9 64 64h384c35.3-.1 63.9-28.7 64-64V64c-.1-35.3-28.7-63.9-64-64zM288 448h-64v-64h64v64zm10.9-192L280 352h-48l-18.9-96V64H299v192z' fill='%23000000'/%3e%3c/svg%3e");
$bg-icon-alert-triangle: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath d='M499.1 424.4L287.8 54.6c-17.5-30.6-46-30.6-63.5 0L12.9 424.4C-4.6 455 9.9 480 45.1 480h421.7c35.3 0 49.8-25 32.3-55.6zM288 448h-64v-64h64v64zm10.9-192L280 352h-48l-18.9-96V128H299v128z' fill='%23000000'/%3e%3c/svg%3e");
$bg-icon-bell: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cg fill='%23000000'%3e%3cpath d='M256 512c53 0 96-43 96-96H160c0 53 43 96 96 96zM448 224v-32C448 86 362 0 256 0S64 86 64 192v32c0 35.3-28.7 64-64 64v64h512v-64c-35.3 0-64-28.7-64-64z'/%3e%3c/g%3e%3c/svg%3e");
$bg-icon-info: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath d='M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256 256-114.6 256-256S397.4 0 256 0zm0 64c35.3 0 64 28.7 64 64s-28.7 64-64 64-64-28.7-64-64 28.7-64 64-64zm96 352H160v-64h32V224h128v128h32v64z' fill='%23000000'/%3e%3c/svg%3e");
$bg-icon-activity: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M288 32H160l160 160H174.872C152.74 153.742 111.377 128 64 128H0v256h64c47.377 0 88.74-25.742 110.872-64H320L160 480h128l224-224L288 32z'/%3e%3c/svg%3e");
$bg-icon-activity-mode: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M256 0C148.6 0 56.6 66.2 18.6 160H64c28.4 0 54 12.4 71.5 32H256l-96-96h128l160 160-160 160H160l96-96H135.5C118 339.6 92.4 352 64 352H18.6c38 93.8 129.9 160 237.4 160 141.4 0 256-114.6 256-256S397.4 0 256 0z'/%3e%3c/svg%3e");
$bg-icon-autoflow-tabular: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M96 0C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h32V0H96zM192 0h128v512H192zM416 0h-32v352h128V96c0-52.8-43.2-96-96-96z'/%3e%3c/svg%3e");
$bg-icon-clock: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256 256-114.6 256-256S397.4 0 256 0zm135 345c-6.4 11.1-18.3 18-31.2 18-6.3 0-12.5-1.7-18-4.8l-110.9-64-.1-.1c-.4-.2-.8-.5-1.2-.7l-.4-.3-.9-.6-.6-.5-.6-.5-.9-.7-.3-.3c-.4-.3-.7-.6-1.1-.9-2.5-2.3-4.7-5-6.5-7.9-.1-.2-.3-.5-.4-.7s-.3-.5-.4-.7c-1.6-3-2.9-6.2-3.6-9.6v-.1c-.1-.5-.2-.9-.3-1.4 0-.1 0-.3-.1-.4-.1-.3-.1-.7-.1-1.1s-.1-.5-.1-.8 0-.5-.1-.8-.1-.8-.1-1.1v-.5-1.4V81c0-19.9 16.1-36 36-36s36 16.1 36 36v161.2l92.9 53.6c17.1 10 22.9 32 13 49.2z'/%3e%3c/svg%3e");
$bg-icon-database: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M256 256C114.615 256 0 213.019 0 160v256c0 53.019 114.615 96 256 96s256-42.981 256-96V160c0 53.019-114.615 96-256 96z'/%3e%3cellipse fill='%23000000' cx='256' cy='96' rx='256' ry='96'/%3e%3c/svg%3e");
$bg-icon-database-query: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M341.76 409.643C316.369 423.871 287.118 432 256 432c-97.047 0-176-78.953-176-176S158.953 80 256 80s176 78.953 176 176c0 31.118-8.129 60.369-22.357 85.76l95.846 95.846C509.747 430.661 512 423.429 512 416V96c0-53.019-114.615-96-256-96S0 42.981 0 96v320c0 53.019 114.615 96 256 96 63.055 0 120.774-8.554 165.388-22.73l-79.628-79.627z'/%3e%3cpath fill='%23000000' d='M176 256c0 44.112 35.888 80 80 80s80-35.888 80-80-35.888-80-80-80-80 35.888-80 80z'/%3e%3c/svg%3e");
$bg-icon-dataset: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 96H288l-54.6-54.6-18.7-18.7C202.2 10.2 177.6 0 160 0H32C14.4 0 0 14.4 0 32v192c0-35.2 28.8-64 64-64h384c35.2 0 64 28.8 64 64v-64c0-35.2-28.8-64-64-64zM448 224H64c-35.2 0-64 28.8-64 64v160c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V288c0-35.2-28.8-64-64-64zM160 448H96V288h64v160zm128 0h-64V288h64v160zm128 0h-64V288h64v160z'/%3e%3c/svg%3e");
$bg-icon-datatable: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M256 256C114.6 256 0 213 0 160v256c0 53 114.6 96 256 96s256-43 256-96V160c0 53-114.6 96-256 96zm192 31.5v128c-18.3 7.8-39.9 14.4-64 19.7v-128c24.1-5.3 45.7-11.9 64-19.7zm-320 19.7v128c-24.1-5.2-45.7-11.9-64-19.7v-128c18.3 7.8 39.9 14.4 64 19.7zM192 445V317c20.5 2 41.9 3 64 3s43.5-1.1 64-3v128c-20.5 2-41.9 3-64 3s-43.5-1.1-64-3z'/%3e%3cellipse fill='%23000000' cx='256' cy='96' rx='256' ry='96'/%3e%3c/svg%3e");
$bg-icon-dictionary: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M416 320c52.8 0 96-43.2 96-96V96c0-52.8-43.2-96-96-96v160l-64-32-64 32V0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h320c52.8 0 96-43.2 96-96v-96c0 52.8-43.2 96-96 96H96v-96h320z'/%3e%3c/svg%3e");
$bg-icon-folder: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 96H288l-54.6-54.6-18.7-18.7C202.2 10.2 177.6 0 160 0H32C14.4 0 0 14.4 0 32v192c0-35.2 28.8-64 64-64h384c35.2 0 64 28.8 64 64v-64c0-35.2-28.8-64-64-64zM448 224H64c-35.2 0-64 28.8-64 64v160c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V288c0-35.2-28.8-64-64-64z'/%3e%3c/svg%3e");
$bg-icon-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 0H64C28.8 0 0 28.8 0 64v384c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V64c0-35.2-28.8-64-64-64zm0 448H64V64h384v384z'/%3e%3cpath fill='%23000000' d='M160 128l-64 64v224h320V256l-64-64-64 64z'/%3e%3c/svg%3e");
$bg-icon-layout: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M224 0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h128V0zM416 0H288v288.832h224V96c0-52.8-43.2-96-96-96zM288 512h128c52.8 0 96-43.2 96-96v-64.832H288V512z'/%3e%3c/svg%3e");
$bg-icon-object: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='none' d='M256 96L76.8 208 256 320l179.2-112z'/%3e%3cpath fill='%23000000' d='M256 512l256-160V160L255.99 0 0 160v192l256 160zm0-416l179.2 112L256 320 76.8 208 256 96z'/%3e%3c/svg%3e");
$bg-icon-object-unknown: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M255-1L-1 159v192l256 160 256-160V159L255-1zm37.7 430.6c-10.6 10.4-23 15.4-38 15.4-15.6 0-28.1-4.9-38.1-14.8-10-10-14.8-22.4-14.8-38.1 0-15.2 5.1-27.6 15.5-38.1s22.6-15.6 37.4-15.6c14.8 0 27.1 5.2 37.8 16 10.7 10.8 15.9 23.2 15.9 38-.1 14.5-5.4 27-15.7 37.2zm26.4-156.3c-11.8 5.9-18.7 11-21.7 16.2-1.8 3.1-3 7.4-3.7 13.4v20.5H213v-22.1c0-20.1 2.2-34.9 6.5-44 4-8.6 11.3-15.1 22.4-20l17.4-7.7c16-7.1 24.1-17.6 24.1-31.4 0-8-3-15.2-8.6-20.9-5.6-5.6-12.8-8.6-20.8-8.6-12 0-27.2 5-31.4 28.7l-1.1 6.1H148l.7-8.1c2-22.3 8.5-41.2 19.4-56.1 9.8-13.5 22.8-24.3 38.5-32.3 15.7-8 32.3-12 49.1-12 30.3 0 55.1 9.7 75.7 29.8 20.6 20 30.6 44 30.6 73.6 0 35.4-14.4 60.7-42.9 74.9z'/%3e%3c/svg%3e");
$bg-icon-packet: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='none' d='M256 96L76.8 208 256 320l179.2-112z'/%3e%3cpath fill='%23000000' d='M256 0L0 160v256c0 52.8 43.2 96 96 96h320c52.8 0 96-43.2 96-96V160L256 0zm0 96l179.2 112L256 320 76.8 208 256 96z'/%3e%3c/svg%3e");
$bg-icon-page: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M352 256c-52.8 0-96-43.2-96-96V0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h320c52.8 0 96-43.2 96-96V256H352z'/%3e%3cpath fill='%23000000' d='M384 192h128L320 0v128c0 35.2 28.8 64 64 64z'/%3e%3c/svg%3e");
$bg-icon-plot-overlay: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M415 0H97C43.65 0 0 43.65 0 97v203.41c7.09 9.32 12.83 14.17 16 15.42 7.14-2.81 27.22-23.77 46.48-73C83.71 188.64 120.64 124 176 124c26.2 0 50.71 14.58 72.85 43.34 18.67 24.25 32.42 54.46 40.67 75.54 19.26 49.19 39.34 70.15 46.48 73 7.14-2.81 27.22-23.77 46.48-73C403.71 188.64 440.64 124 496 124a69.55 69.55 0 0 1 16 1.87V97c0-53.35-43.65-97-97-97z'/%3e%3cpath fill='%23000000' d='M496 196.17c-7.14 2.81-27.22 23.76-46.48 73C428.29 323.36 391.36 388 336 388c-26.2 0-50.71-14.58-72.85-43.34-18.67-24.25-32.42-54.46-40.67-75.54-19.26-49.19-39.34-70.15-46.48-73-7.14 2.81-27.22 23.76-46.48 73C108.29 323.36 71.36 388 16 388a69.56 69.56 0 0 1-16-1.87V415c0 53.35 43.65 97 97 97h318c53.35 0 97-43.65 97-97V211.59c-7.09-9.32-12.83-14.17-16-15.42z'/%3e%3c/svg%3e");
$bg-icon-plot-stacked: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M44.8 156c12.49 0 24.48-13.26 42.76-35.09 22.71-27.14 51-60.91 98-60.91 22.32 0 43.31 7.73 62.4 23 14.34 11.45 25.58 25.21 36.46 38.53C303.63 145 314 156 326.4 156H512V97c0-53.35-43.65-97-97-97H97C43.65 0 0 43.65 0 97v59h44.8z'/%3e%3cpath fill='%23000000' d='M264.75 205.2c-14.12-11.32-25.26-25-36-38.14C211 145.32 199.37 132 185.6 132c-12.53 0-24.54 13.27-42.83 35.12-22.7 27.12-51 60.88-98 60.88H0v56h185.6c22 0 42.77 7.67 61.65 22.8 14.12 11.32 25.26 25 36 38.14C301 366.68 312.63 380 326.4 380c12.53 0 24.54-13.27 42.83-35.12 22.7-27.12 51-60.88 98-60.88H512v-56H326.4c-22.03 0-42.77-7.67-61.65-22.8z'/%3e%3cpath fill='%23000000' d='M467.2 356c-12.49 0-24.48 13.26-42.76 35.09-22.71 27.14-51 60.91-98 60.91-22.32 0-43.31-7.73-62.4-23-14.34-11.45-25.58-25.21-36.46-38.53C208.37 367 198 356 185.6 356H0v59c0 53.35 43.65 97 97 97h318c53.35 0 97-43.65 97-97v-59h-44.8z'/%3e%3c/svg%3e");
$bg-icon-session: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M317.8 262.2c3.3 2.1 6.6 4.3 9.6 6.8l60.2 48.2c14.8 11.9 41.9 11.9 56.7 0l67.6-54c.1-2.4.1-4.7.1-7.1 0-26.1-3.9-51.2-11.1-74.9L423.5 243c-29.1 23.3-70.1 29.6-105.7 19.2zM124.3 317.1l60.2-48.2c29-23.2 70-29.6 105.6-19.2-3.3-2.1-6.6-4.3-9.6-6.8l-60.2-48.2c-14.8-11.9-41.9-11.9-56.7 0L103.5 243c-20 16-45.7 24-71.5 24-10.8 0-21.5-1.4-31.9-4.2v.8c2.5 1.7 5 3.4 7.3 5.3l60.2 48.2c14.9 11.9 41.9 11.9 56.7 0z'/%3e%3cpath fill='%23000000' d='M60.3 189.1l60.2-48.2c40.1-32.1 102.8-32.1 142.9 0l60.2 48.2c14.8 11.9 41.9 11.9 56.7 0l90.5-72.4C425.2 46.5 346 0 256 0 136.7 0 36.4 81.6 8 192.1c15.4 8.8 38.9 7.8 52.3-3zM344.5 371l-60.2-48.2c-14.8-11.9-41.9-11.9-56.7 0L167.5 371c-20 16-45.7 24-71.5 24-23.9 0-47.7-6.9-67.1-20.7C71.7 456.1 157.3 512 256 512s184.3-55.9 227.1-137.7c-40.2 28.7-99.9 27.6-138.6-3.3z'/%3e%3c/svg%3e");
$bg-icon-tabular: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 0H64C28.8 0 0 28.8 0 64v384c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V64c0-35.2-28.8-64-64-64zM320 224H192v-96h128v96zm-128 32h128v96H192v-96zm-32 96H32v-96h128v96zm0-224v96H32v-96h128zM64 480c-8.5 0-16.5-3.3-22.6-9.4S32 456.5 32 448v-64h128v96H64zm128 0v-96h128v96H192zm288-32c0 8.5-3.3 16.5-9.4 22.6S456.5 480 448 480h-96v-96h128v64zm0-96H352v-96h128v96zm0-128H352v-96h128v96z'/%3e%3c/svg%3e");
$bg-icon-tabular-lad: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 0H64C28.7.1.1 28.7 0 64v384c.1 35.3 28.7 63.9 64 64h384c35.3-.1 63.9-28.7 64-64V64c-.1-35.3-28.7-63.9-64-64zM32 128h128v96H32v-96zm0 128h128v96H32v-96zm32 224c-17.6-.1-31.9-14.4-32-32v-64h128v96H64zm128 0v-96h128v96H192zm288-32c-.1 17.6-14.4 31.9-32 32h-96v-96h128v64zm0-192v96H192v-96h32v-32h-32v-96h288v96h-32v32h32z'/%3e%3cpath fill='%23000000' d='M391.2 273.7L336 246.1V160c0-8.8-7.2-16-16-16s-16 7.2-16 16v105.9l72.8 36.4c7.9 4 17.5.8 21.5-7.2 4-7.8.8-17.5-7.1-21.4z'/%3e%3c/svg%3e");
$bg-icon-tabular-lad-set: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M64 384V96c-35.3.1-63.9 28.7-64 64v288c.1 35.3 28.7 63.9 64 64h288c35.3-.1 63.9-28.7 64-64H128c-35.3-.1-63.9-28.7-64-64z'/%3e%3cpath fill='%23000000' d='M448 0H160c-35.3.1-63.9 28.7-64 64v288c.1 35.3 28.7 63.9 64 64h288c35.3-.1 63.9-28.7 64-64V64c-.1-35.3-28.7-63.9-64-64zM128 96h96v64h-96V96zm0 96h96v96h-96v-96zm32 192c-17.6-.1-31.9-14.4-32-32v-32h96v64h-64zm96 0v-64h96v64h-96zm224-32c-.1 17.6-14.4 31.9-32 32h-64v-64h96v32zm0-64H256V96h224v192z'/%3e%3cpath fill='%23000000' d='M416 240c8.8 0 16-7.2 16-16 0-6.9-4.4-13-10.9-15.2L384 196.5V144c0-8.8-7.2-16-16-16s-16 7.2-16 16v75.5l58.9 19.6c1.7.6 3.4.9 5.1.9z'/%3e%3c/svg%3e");
$bg-icon-tabular-realtime: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M0 64v384c0 35.2 28.8 64 64 64h288c35.2 0 64-28.8 64-64V340c-19.8 7.8-41.4 12-64 12-35.4 0-68.4-10.5-96-28.6V352h-96v-96h35.3c-5.2-10.1-9.4-20.8-12.6-32H160v-96h22.7C203.6 54.2 271.6 0 352 0H64C28.8 0 0 28.8 0 64zm288 320h96v64c0 8.5-3.3 16.5-9.4 22.6S360.5 480 352 480h-64v-96zm-160 96H64c-8.5 0-16.5-3.3-22.6-9.4S32 456.5 32 448v-64h96v96zm0-128H32v-96h96v96zm32 32h96v96h-96v-96zm-32-160H32v-96h96v96z'/%3e%3cpath fill='%23000000' d='M192 160c0 88.4 71.6 160 160 160s160-71.6 160-160S440.4 0 352 0 192 71.6 192 160zm49.7 39.8L227 187.5c-1.4-6.4-2.3-12.9-2.7-19.6 15.1-.1 30.1-5 41.9-14.8l39.6-33c7.5-6.2 21.1-6.2 28.6 0l39.6 33c2.8 2.3 5.7 4.3 8.8 6.1-23-11.7-52.7-9.2-72.8 7.5l-39.6 33c-7.6 6.3-21.2 6.3-28.7.1zM352 288c-36.7 0-69.7-15.4-93-40.1 14.2-.6 28.1-5.5 39.2-14.7l39.6-33c7.5-6.2 21.1-6.2 28.6 0l39.6 33c11 9.2 25 14.1 39.2 14.7-23.5 24.7-56.5 40.1-93.2 40.1zm125.9-151.3c1.4 7.5 2.1 15.3 2.1 23.3 0 9.4-1 18.6-3 27.5l-14.7 12.3c-7.5 6.2-21.1 6.2-28.6 0l-39.6-33c-2.8-2.3-5.7-4.3-8.8-6.1 23 11.7 52.7 9.2 72.8-7.5l19.8-16.5zM352 32c46.4 0 87.1 24.7 109.5 61.7l-31.2 26c-7.5 6.2-21.1 6.2-28.6 0l-39.6-33c-23.6-19.7-60.6-19.7-84.3 0l-39.6 33c-2.5 2.1-5.7 3.5-9.1 4.2C244.7 70.8 293.8 32 352 32z'/%3e%3c/svg%3e");
$bg-icon-tabular-scrolling: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M32 0C14.4 0 0 14.4 0 32v96h224V0H32zM512 128V32c0-17.6-14.4-32-32-32H288v128h224zM0 192v96c0 17.6 14.4 32 32 32h192V192H0zM480 320c17.6 0 32-14.4 32-32v-96H288v128h192zM256 512L128 384h256z'/%3e%3c/svg%3e");
$bg-icon-telemetry: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M16 315.83c7.14-2.81 27.22-23.77 46.48-73C83.71 188.64 120.64 124 176 124c26.2 0 50.71 14.58 72.85 43.34 18.67 24.25 32.42 54.46 40.67 75.54 19.26 49.19 39.34 70.15 46.48 73 7.14-2.81 27.22-23.77 46.48-73 18.7-47.75 49.57-103.57 94.47-116.23A255.87 255.87 0 0 0 256 0C114.62 0 0 114.62 0 256a257.18 257.18 0 0 0 5 50.52c4.77 5.39 8.61 8.37 11 9.31z'/%3e%3cpath fill='%23000000' d='M496 196.17c-7.14 2.81-27.22 23.76-46.48 73C428.29 323.36 391.36 388 336 388c-26.2 0-50.71-14.58-72.85-43.34-18.67-24.25-32.42-54.46-40.67-75.54-19.26-49.19-39.34-70.15-46.48-73-7.14 2.81-27.22 23.76-46.48 73-18.7 47.75-49.57 103.57-94.47 116.23A255.87 255.87 0 0 0 256 512c141.38 0 256-114.62 256-256a257.18 257.18 0 0 0-5-50.52c-4.77-5.39-8.61-8.37-11-9.31z'/%3e%3c/svg%3e");
$bg-icon-timeline: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M128 128h192v64H128zM192 224h192v64H192zM160 320h192v64H160z'/%3e%3cpath fill='%23000000' d='M416 0h-64v96h63.8c.1 0 .1.1.2.2v319.7c0 .1-.1.1-.2.2H352v96h64c52.8 0 96-43.2 96-96V96c0-52.8-43.2-96-96-96zM96 415.8V96.2c0-.1.1-.1.2-.2H160V0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h64v-96H96.2c-.1 0-.2-.1-.2-.2z'/%3e%3c/svg%3e");
$bg-icon-timer: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M288 73.3V32.01a32 32 0 0 0-32-32h-64a32 32 0 0 0-32 32V73.3C67.48 100.84 0 186.54 0 288.01c0 123.71 100.29 224 224 224s224-100.29 224-224c0-101.48-67.5-187.2-160-214.71zm-54 224.71l-131.88 105.5A167.4 167.4 0 0 1 56 288.01c0-92.64 75.36-168 168-168 3.36 0 6.69.11 10 .31v177.69z'/%3e%3c/svg%3e");
$bg-icon-topic: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M227.18 238.32l43.15-43.15a25.18 25.18 0 0 1 35.36 0l43.15 43.15a94.42 94.42 0 0 0 35.18 22.25V174.5l-28.82-28.82a95.11 95.11 0 0 0-134.35 0l-43.15 43.15a25.18 25.18 0 0 1-35.36 0L128 174.5v86.07a95.11 95.11 0 0 0 99.18-22.25z'/%3e%3cpath fill='%23000000' d='M252.82 273.68l-43.15 43.15a25.18 25.18 0 0 1-35.36 0l-43.15-43.15c-1-1-2.1-2-3.18-3v98.68a95.11 95.11 0 0 0 131.18-3l43.15-43.15a25.18 25.18 0 0 1 35.36 0l43.15 43.15c1 1 2.1 2 3.18 3v-98.68a95.11 95.11 0 0 0-131.18 3z'/%3e%3cpath fill='%23000000' d='M416 0h-64v96h63.83l.17.17v319.66l-.17.17H352v96h64c52.8 0 96-43.2 96-96V96c0-52.8-43.2-96-96-96zM160 416H96.17l-.17-.17V96.17l.17-.17H160V0H96C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h64v-96z'/%3e%3c/svg%3e");
$bg-icon-box-with-dashed-lines: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M0 192h64v128H0zM64 64.11l.11-.11H160V0H64A64.19 64.19 0 0 0 0 64v96h64V64.11zM64 447.89V352H0v96a64.19 64.19 0 0 0 64 64h96v-64H64.11zM192 0h128v64H192zM448 447.89l-.11.11H352v64h96a64.19 64.19 0 0 0 64-64v-96h-64v95.89zM448 0h-96v64h95.89l.11.11V160h64V64a64.19 64.19 0 0 0-64-64zM448 192h64v128h-64zM192 448h128v64H192zM128 128h256v256H128z'/%3e%3c/svg%3e");
$bg-icon-summary-widget: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 0H64C28.8 0 0 28.8 0 64v384c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V64c0-35.2-28.8-64-64-64zm-24.1 305.2l-41.3 71.6-94.8-65.8 9.6 115h-82.7l9.6-115-94.8 65.8-41.3-71.6L192.5 256 88.1 206.8l41.3-71.6 94.8 65.8-9.6-115h82.7l-9.6 115 94.8-65.8 41.3 71.6L319.5 256l104.4 49.2z'/%3e%3c/svg%3e");
$bg-icon-notebook: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23000000' d='M448 55.4c0-39.9-27.7-63.7-61.5-52.7L0 128h448V55.4zM448 160H0v288c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V224c0-35.2-28.8-64-64-64zm-32 256H224V256h192v160z'/%3e%3c/svg%3e");

View File

@ -50,7 +50,12 @@ button {
.c-click-icon {
@include cClickIcon();
.c-click-icon__label {
margin-left: $interiorMargin;
}
&--menu {
&:after {
content: $glyph-icon-arrow-down;
font-family: symbolsfont;

View File

@ -20,34 +20,6 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
@mixin glyphBefore($unicode, $family: 'symbolsfont') {
&:before {
content: $unicode;
font-family: $family;
}
}
@mixin glyphAfter($unicode, $family: 'symbolsfont') {
&:after {
content: $unicode;
font-family: $family;
}
}
@mixin glyphBg($glyphUrl) {
background-image: $glyphUrl;
background-position: center;
background-size: contain;
background-repeat: no-repeat;
}
[class*="icon-"] {
&:before, &:after
{
-webkit-font-smoothing: antialiased;
}
}
/************************** 16 PX CLASSES */
.icon-alert-rect { @include glyphBefore($glyph-icon-alert-rect); }
.icon-alert-triangle { @include glyphBefore($glyph-icon-alert-triangle); }
@ -171,6 +143,10 @@
.icon-grippy-12px { @include glyphBefore($glyph-icon-grippy,'symbolsfont-12px'); }
/************************** GLYPH BG CLASSES */
.bg-icon-alert-rect { @include glyphBg($bg-icon-alert-rect); }
.bg-icon-alert-triangle { @include glyphBg($bg-icon-alert-triangle); }
.bg-icon-bell { @include glyphBg($bg-icon-bell); }
.bg-icon-info { @include glyphBg($bg-icon-info); }
.bg-icon-activity { @include glyphBg($bg-icon-activity); }
.bg-icon-activity-mode { @include glyphBg($bg-icon-activity-mode); }
.bg-icon-autoflow-tabular { @include glyphBg($bg-icon-autoflow-tabular); }

View File

@ -20,6 +20,35 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
/************************** GLYPHS */
@mixin glyphBefore($unicode, $family: 'symbolsfont') {
&:before {
content: $unicode;
font-family: $family;
}
}
@mixin glyphAfter($unicode, $family: 'symbolsfont') {
&:after {
content: $unicode;
font-family: $family;
}
}
@mixin glyphBg($glyphUrl) {
background-image: $glyphUrl;
background-position: center;
background-size: contain;
background-repeat: no-repeat;
}
[class*="icon-"] {
&:before, &:after
{
-webkit-font-smoothing: antialiased;
}
}
/************************** VISUALS */
@mixin ancillaryIcon($d, $c) {
// Used for small icons used in combination with larger icons,
@ -318,15 +347,6 @@
}
}
@mixin wrappedInput() {
// An input that is wrapped. Optionally includes a __label or icon element.
// Based on .c-search.

View File

@ -85,15 +85,15 @@
}
// Display grid when selected or selection parent.
.s-selected .l-grid-holder,
.s-selected-parent .l-grid-holder {
[s-selected] .l-grid-holder,
[s-selected-parent] .l-grid-holder {
display: block;
}
// Display in nested frames...
.t-frame-outer {
// ...when drilled in or selection parent...
&.s-drilled-in, &.s-selected-parent {
&.s-drilled-in, &[s-selected-parent] {
.l-grid-holder {
display: block;
}

View File

@ -49,7 +49,7 @@ body.desktop {
border-style: dashed !important;
}
}
.s-selected {
[s-selected] {
> .s-hover-border,
&.s-hover-border {
// Styles for a selected object. Also used by legacy Fixed Position/Panel objects.
@ -71,8 +71,8 @@ body.desktop {
}
}
.s-selected > .s-hover-border,
.s-selected.s-hover-border {
[s-selected] > .s-hover-border,
[s-selected].s-hover-border {
border-color: $colorSelectableSelectedPrimary !important;
//z-index: 1; // Bring selected item from beneath others. BUT, this breaks editing in Fixed Position.
}

View File

@ -11,8 +11,6 @@
</template>
<script>
import ContextMenuDirective from './ContextMenuDirective.js';
export default {
data: function () {
return {

View File

@ -1,168 +0,0 @@
<template>
<div class="c-custom-checkbox">
<input type="checkbox"
:id="id"
:name="name"
:value="value"
:required="required"
:disabled="disabled"
@change="onChange"
:checked="state">
<label :for="id">
<div class="c-custom-checkbox__box"></div>
<div class="c-custom-checkbox__label-text">
<slot></slot>
</div>
</label>
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-custom-checkbox {
$d: 14px;
display: flex;
align-items: center;
label {
@include userSelectNone();
display: flex;
align-items: center;
}
&__box {
@include nice-input();
display: flex;
align-items: center;
justify-content: center;
line-height: $d;
width: $d;
height: $d;
margin-right: $interiorMarginSm;
}
input {
opacity: 0;
position: absolute;
&:checked + label > .c-custom-checkbox__box {
background: $colorKey;
&:before {
color: $colorKeyFg;
content: $glyph-icon-check;
font-family: symbolsfont;
font-size: 0.6em;
}
}
&:not(:disabled) + label {
cursor: pointer;
}
&:disabled + label {
opacity: 0.5;
}
}
}
</style>
<script>
/*
Custom checkbox control. Use just like a checkbox in HTML, except label string is passed within tag.
Supports value, true-value, false-value, checked and disabled attributes.
Example usage:
<checkbox checked>Enable markers</checkbox>
*/
export default {
model: {
prop: 'modelValue',
event: 'input'
},
props: {
id: {
type: String,
default: function () {
return 'checkbox-id-' + this._uid;
},
},
name: {
type: String,
default: null,
},
value: {
default: null,
},
modelValue: {
default: undefined,
},
checked: {
type: Boolean,
default: false,
},
required: {
type: Boolean,
default: false,
},
disabled: {
type: Boolean,
default: false,
},
model: {}
},
computed: {
state() {
if (this.modelValue === undefined) {
return this.checked;
}
if (Array.isArray(this.modelValue)) {
return this.modelValue.indexOf(this.value) > -1;
}
return !!this.modelValue;
}
},
methods: {
onChange() {
this.toggle();
},
toggle() {
let value;
if (Array.isArray(this.modelValue)) {
value = this.modelValue.slice(0);
if (this.state) {
value.splice(value.indexOf(this.value), 1);
} else {
value.push(this.value);
}
} else {
value = !this.state;
}
this.$emit('input', value);
}
},
watch: {
checked(newValue) {
if (newValue !== this.state) {
this.toggle();
}
}
},
mounted() {
if (this.checked && !this.state) {
this.toggle();
}
},
};
</script>

View File

@ -1,51 +0,0 @@
<template>
<div class="c-labeled-input"
:title="title">
<div class="c-labeled-input__label">{{ label }}</div>
<input type="number"
v-bind="$attrs"
v-bind:value="value"
v-on="inputListeners"/>
</div>
</template>
<script>
/* Emits input and clear events */
export default {
inheritAttrs: false,
props: {
value: String,
label: String,
title: String
},
computed: {
inputListeners: function () {
let vm = this;
return Object.assign({},
this.$listeners,
{
input: function (event) {
vm.$emit('input', event.target.value);
},
change: function (event) {
vm.$emit('change', event.target.value);
}
}
)
}
},
data: function() {
return {
// active: false
}
},
methods: {
clearInput() {
// Clear the user's input and set 'active' to false
this.value = '';
this.$emit('clear','');
this.active = false;
}
}
}
</script>

View File

@ -1,176 +0,0 @@
<template>
<div class="c-togglebutton">
<input type="checkbox"
:id="id"
:name="name"
:value="value"
:required="required"
:disabled="disabled"
@change="onChange"
:checked="state">
<label :for="id">
<div class="c-togglebutton__on"
:class="innerClassOn"></div>
<div class="c-togglebutton__off"
:class="innerClassOff"></div>
</label>
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-togglebutton {
$d: 14px;
display: flex;
align-items: center;
label {
display: flex;
align-items: center;
justify-content: center;
.c-togglebutton__on {
display: none;
}
}
input {
opacity: 0;
position: absolute;
&:checked + label {
.c-togglebutton__on {
display: block;
}
.c-togglebutton__off {
display: none;
}
}
&:not(:disabled) + label {
cursor: pointer;
}
&:disabled + label {
opacity: 0.5;
}
}
}
</style>
<script>
/*
Toggle button control, based on checkboxCustom. Use just like a checkbox in HTML.
Requires inner-class-on and -off attributes to be passed.
Supports checked and disabled attributes.
Example usage:
<toggle-button checked
class="c-click-icon"
inner-class-on="icon-grid-snap-to"
inner-class-off="icon-grid-snap-no"></toggle-button>
*/
export default {
model: {
prop: 'modelValue',
event: 'input'
},
props: {
innerClassOn: {
type: String,
default: null,
required: true
},
innerClassOff: {
type: String,
default: null,
required: true
},
id: {
type: String,
default: function () {
return 'checkbox-id-' + this._uid;
},
},
name: {
type: String,
default: null,
},
value: {
default: null,
},
modelValue: {
default: undefined,
},
checked: {
type: Boolean,
default: false,
},
required: {
type: Boolean,
default: false,
},
disabled: {
type: Boolean,
default: false,
},
model: {}
},
computed: {
state() {
if (this.modelValue === undefined) {
return this.checked;
}
if (Array.isArray(this.modelValue)) {
return this.modelValue.indexOf(this.value) > -1;
}
return !!this.modelValue;
},
stateClass() {
return this.onClass;
}
},
methods: {
onChange() {
this.toggle();
},
toggle() {
let value;
if (Array.isArray(this.modelValue)) {
value = this.modelValue.slice(0);
if (this.state) {
value.splice(value.indexOf(this.value), 1);
} else {
value.push(this.value);
}
} else {
value = !this.state;
}
this.$emit('input', value);
}
},
watch: {
checked(newValue) {
if (newValue !== this.state) {
this.toggle();
}
}
},
mounted() {
if (this.checked && !this.state) {
this.toggle();
}
},
};
</script>

View File

@ -246,7 +246,7 @@
import pane from '../controls/pane.vue';
import BrowseBar from './BrowseBar.vue';
import StatusBar from './status-bar/StatusBar.vue';
import Toolbar from './Toolbar.vue';
import Toolbar from '../toolbar/Toolbar.vue';
var enterFullScreen = () => {
var docElm = document.documentElement;

View File

@ -1,291 +0,0 @@
<template>
<div class="c-toolbar">
<!-- VERSION MANUALLY RESTORED FROM VUE-LAYOUT -->
<div class="c-button-set">
<div class="c-ctrl-wrapper">
<div class="c-button--menu js-add-button icon-plus"
@click="toggleMenus">
<div class="c-button__label">Add</div>
</div>
<div class="c-menu" v-if="showMenus">
<ul>
<li v-for="item in addMenuItems"
:class="item.class"
:title="item.title">
{{ item.name }}
</li>
</ul>
</div>
</div>
</div>
<div class="c-button-set"
v-if="toolsItemSelected">
<div class="c-ctrl-wrapper"
v-if="toolsItemSelected">
<div class="c-click-icon c-click-icon--menu js-layers icon-layers"
@click="toggleMenus"></div>
<div class="c-menu" v-if="showMenus">
<ul>
<li v-for="item in layersMenuItems"
:class="item.class"
:title="item.title">
{{ item.name }}
</li>
</ul>
</div>
</div>
<div class="c-ctrl-wrapper"
v-if="toolsColorFill">
<div class="c-click-icon c-click-icon--swatched js-color-fill icon-paint-bucket"
@click="toggleMenus">
<div class="c-swatch" style="background: #33ff00;"></div>
</div>
<div class="c-menu c-palette c-palette--color"
v-if="showMenus">
<div class="c-palette__item-none"
vif="this.palette.itemNone === true">
<div class="c-palette__item"
@click="this.setColor('no-color')"></div>
No fill
</div>
<div class="c-palette__items">
<div class="c-palette__item"
v-for="color in colorPalette"
:style="{ background: color.value }"
@click="this.setColor(color.value)"></div>
</div>
</div>
</div>
<div class="c-ctrl-wrapper"
v-if="toolsColorStroke">
<div class="c-click-icon c-click-icon--swatched js-color-stroke icon-pencil">
<div class="c-toolbar-button__swatch" style="background: #ffffff;"></div>
</div>
</div>
<div class="c-ctrl-wrapper"
v-if="toolsColorText">
<div class="c-click-icon c-click-icon--swatched js-color-text icon-font">
<div class="c-toolbar-button__swatch" style="background: #333333;"></div>
</div>
</div>
</div>
<div class="c-button-set"
v-if="toolsItemSelected && toolsFontSize">
<div class="c-ctrl-wrapper">
<div class="c-click-icon c-click-icon--menu js-font-size"
@click="toggleMenus">
<div class="c-button__label">11 px</div>
</div>
<div class="c-menu" v-if="showMenus">
<ul>
<li v-for="item in fontSizeMenuItems">
{{ item.name }}
</li>
</ul>
</div>
</div>
</div>
<div class="c-button-set"
v-if="toolsItemSelected && toolsEditProperties">
<div class="c-ctrl-wrapper">
<div class="c-click-icon js-image icon-gear"></div>
</div>
</div>
<div class="c-button-set"
v-if="toolsItemSelected">
<labeledNumberInput label="X" value=1 title="X position"></labeledNumberInput>
<labeledNumberInput label="Y" value=2 title="Y position"></labeledNumberInput>
<labeledNumberInput label="W" value=3 title="Width"></labeledNumberInput>
<labeledNumberInput label="H" value=4 title="Height"></labeledNumberInput>
</div>
<div class="c-button-set"
v-if="toolsItemSelected">
<div class="c-click-icon c-click-icon--caution icon-trash"></div>
</div>
<div class="c-button-set"
v-if="toolsItemSelected">
<checkbox checked title="This is a checkbox">Checkbox</checkbox>
</div>
<div class="c-button-set"
v-if="toolsItemSelected">
<toggle-button title="Toggle frame" checked
class="c-click-icon"
inner-class-on="icon-frame-show"
inner-class-off="icon-frame-hide"></toggle-button>
<toggle-button title="Snap to grid" checked
class="c-click-icon"
inner-class-on="icon-grid-snap-to"
inner-class-off="icon-grid-snap-no"></toggle-button>
<toggle-button title="Show label and value" checked
class="c-click-icon"
inner-class-on="icon-two-parts-both"
inner-class-off="icon-two-parts-one-only"></toggle-button>
</div>
</div>
</template>
<script>
import labeledNumberInput from '../controls/labeledNumberInput.vue';
import checkbox from '../controls/checkboxCustom.vue';
import toggleButton from '../controls/toggleButton.vue';
export default {
components: {
labeledNumberInput,
checkbox,
toggleButton
},
methods: {
toggleMenus: function () {
this.showMenus = !this.showMenus;
}
},
props: {
toolsItemSelected: { type: Boolean, default: true },
toolsColorFill: { type: Boolean, default: true },
toolsColorStroke: { type: Boolean, default: true },
toolsColorText: { type: Boolean, default: true },
toolsFontSize: { type: Boolean, default: true },
toolsEditProperties: { type: Boolean, default: true },
toolSetBox: ['toolsColorFill', 'toolsColorStroke'],
toolSetLine: ['toolsColorStroke'],
toolSetText: ['toolsColorFill', 'toolsColorStroke', 'toolsColorText', 'toolsFontSize', 'toolsEditProperties'],
toolSetImage: ['toolsColorStroke', 'toolsEditProperties'],
toolSetTelemetry: ['toolsColorFill', 'toolsColorStroke', 'toolsColorText', 'toolsFontSize', 'toolsLabelValue']
},
data: function () {
return {
showMenus: false,
addMenuItems: [
{ name: 'Box', class: 'icon-box', title: 'Add Box' },
{ name: 'Line', class: 'icon-line-horz', title: 'Add Line' },
{ name: 'Text', class: 'icon-font', title: 'Add Text' },
{ name: 'Image', class: 'icon-image', title: 'Add Image' }
],
layersMenuItems: [
{ name: 'Move to top', class: 'icon-arrow-double-up', title: 'Move to top' },
{ name: 'Move up', class: 'icon-arrow-up', title: 'Move up' },
{ name: 'Move down', class: 'icon-arrow-down', title: 'Move down' },
{ name: 'Move to bottom', class: 'icon-arrow-double-down', title: 'Move to bottom' }
],
fontSizeMenuItems: [
{ value: '9', name: '9 px' },
{ value: '10', name: '10 px' },
{ value: '11', name: '11 px' },
{ value: '12', name: '12 px' },
{ value: '13', name: '13 px' },
{ value: '14', name: '14 px' },
{ value: '16', name: '16 px' },
{ value: '18', name: '18 px' },
{ value: '20', name: '20 px' },
{ value: '24', name: '24 px' },
{ value: '28', name: '28 px' },
{ value: '32', name: '32 px' },
{ value: '40', name: '40 px' },
{ value: '48', name: '48 px' },
{ value: '56', name: '56 px' },
{ value: '64', name: '64 px' },
{ value: '72', name: '72 px' },
{ value: '80', name: '80 px' },
{ value: '88', name: '88 px' },
{ value: '96', name: '96 px' },
{ value: '128', name: '128 px' },
{ value: '160', name: '160 px' }
],
colorPalette: [
{ value: '#000000' },
{ value: '#434343' },
{ value: '#666666' },
{ value: '#999999' },
{ value: '#b7b7b7' },
{ value: '#cccccc' },
{ value: '#d9d9d9' },
{ value: '#efefef' },
{ value: '#f3f3f3' },
{ value: '#ffffff' },
{ value: '#980000' },
{ value: '#ff0000' },
{ value: '#ff9900' },
{ value: '#ffff00' },
{ value: '#00ff00' },
{ value: '#00ffff' },
{ value: '#4a86e8' },
{ value: '#0000ff' },
{ value: '#9900ff' },
{ value: '#ff00ff' },
{ value: '#e6b8af' },
{ value: '#f4cccc' },
{ value: '#fce5cd' },
{ value: '#fff2cc' },
{ value: '#d9ead3' },
{ value: '#d0e0e3' },
{ value: '#c9daf8' },
{ value: '#cfe2f3' },
{ value: '#d9d2e9' },
{ value: '#ead1dc' },
{ value: '#dd7e6b' },
{ value: '#dd7e6b' },
{ value: '#f9cb9c' },
{ value: '#ffe599' },
{ value: '#b6d7a8' },
{ value: '#a2c4c9' },
{ value: '#a4c2f4' },
{ value: '#9fc5e8' },
{ value: '#b4a7d6' },
{ value: '#d5a6bd' },
{ value: '#cc4125' },
{ value: '#e06666' },
{ value: '#f6b26b' },
{ value: '#ffd966' },
{ value: '#93c47d' },
{ value: '#76a5af' },
{ value: '#6d9eeb' },
{ value: '#6fa8dc' },
{ value: '#8e7cc3' },
{ value: '#c27ba0' },
{ value: '#a61c00' },
{ value: '#cc0000' },
{ value: '#e69138' },
{ value: '#f1c232' },
{ value: '#6aa84f' },
{ value: '#45818e' },
{ value: '#3c78d8' },
{ value: '#3d85c6' },
{ value: '#674ea7' },
{ value: '#a64d79' },
{ value: '#85200c' },
{ value: '#990000' },
{ value: '#b45f06' },
{ value: '#bf9000' },
{ value: '#38761d' },
{ value: '#134f5c' },
{ value: '#1155cc' },
{ value: '#0b5394' },
{ value: '#351c75' },
{ value: '#741b47' },
{ value: '#5b0f00' },
{ value: '#660000' },
{ value: '#783f04' },
{ value: '#7f6000' },
{ value: '#274e13' },
{ value: '#0c343d' },
{ value: '#1c4587' },
{ value: '#073763' },
{ value: '#20124d' },
{ value: '#4c1130' }
]
}
}
}
</script>

View File

@ -0,0 +1,109 @@
<template>
<div class="c-toolbar">
<component v-for="item in structure"
:is="item.control"
:options="item"
@change="updateObjectValue"></component>
</div>
</template>
<script>
import toolbarButton from './components/toolbar-button.vue';
import toolbarColorPicker from './components/toolbar-color-picker.vue';
import toolbarCheckbox from './components/toolbar-checkbox.vue';
import toolbarInput from './components/toolbar-input.vue';
import toolbarMenu from './components/toolbar-menu.vue';
import toolbarSelectMenu from './components/toolbar-select-menu.vue';
import toolbarSeparator from './components/toolbar-separator.vue';
import toolbarToggleButton from './components/toolbar-toggle-button.vue';
export default {
inject: ['openmct', 'lodash'],
components: {
toolbarButton,
toolbarColorPicker,
toolbarCheckbox,
toolbarInput,
toolbarMenu,
toolbarSelectMenu,
toolbarSeparator,
toolbarToggleButton
},
data: function () {
return {
structure: []
};
},
methods: {
handleSelection(selection) {
if (!selection[0]) {
this.structure = [];
this.selectedObject = undefined;
this.removeListeners();
return;
}
let domainObject = selection[0].context.item;
this.selectedObject = domainObject;
this.removeListeners();
let structure = this.openmct.toolbars.get(selection) || [];
this.structure = structure.map(function (item) {
let toolbarItem = {...item};
toolbarItem.control = "toolbar-" + toolbarItem.control;
toolbarItem.value = _.get(toolbarItem.domainObject, item.property);
this.registerListener(toolbarItem.domainObject);
return toolbarItem;
}.bind(this));
},
registerListener(domainObject) {
let unobserveObject = this.openmct.objects.observe(domainObject, '*', function(newObject) {
let newObjectId = this.openmct.objects.makeKeyString(newObject.identifier);
this.structure = this.structure.map((item) => {
let toolbarItem = {...item};
let domainObjectId = this.openmct.objects.makeKeyString(toolbarItem.domainObject.identifier);
if (domainObjectId === newObjectId) {
toolbarItem.domainObject = JSON.parse(JSON.stringify(newObject));
}
return toolbarItem;
});
}.bind(this));
this.unObserveObjects.push(unobserveObject);
},
removeListeners() {
if (this.unObserveObjects) {
this.unObserveObjects.forEach((unObserveObject) => {
unObserveObject();
});
}
this.unObserveObjects = [];
},
updateObjectValue(value, item) {
let changedId = this.openmct.objects.makeKeyString(item.domainObject.identifier);
this.structure = this.structure.map((s) => {
let toolbarItem = {...s};
if (changedId === this.openmct.objects.makeKeyString(toolbarItem.domainObject.identifier)) {
toolbarItem.value = value;
}
return toolbarItem;
});
this.openmct.objects.mutate(item.domainObject, item.property, value);
}
},
mounted() {
this.openmct.selection.on('change', this.handleSelection);
this.handleSelection(this.openmct.selection.get());
// Toolbars may change when edit mode is enabled/disabled, so listen
// for edit mode changes and update toolbars if necessary.
this.openmct.editor.on('isEditing', (isEditing) => {
this.handleSelection(this.openmct.selection.get());
});
},
detroyed() {
this.openmct.selection.off('change', this.handleSelection);
this.removeListeners();
}
}
</script>

View File

@ -0,0 +1,22 @@
export default {
data() {
return {
open: false
}
},
methods: {
toggle(event) {
if (this.open) {
document.removeEventListener('click', this.toggle);
this.open = false;
} else {
document.addEventListener('click', this.toggle);
event.stopPropagation();
this.open = true;
}
}
},
destroyed() {
document.removeEventListener('click', this.toggle);
},
}

View File

@ -0,0 +1,29 @@
<template>
<div class="c-ctrl-wrapper">
<div class="c-click-icon"
:class="{
[options.icon]: true,
'c-click-icon--caution': options.modifier === 'caution'
}"
@click="onClick">
<div class="c-click-icon__label"
v-if="options.label">
{{ options.label }}
</div>
</div>
</div>
</template>
<script>
export default {
props: {
options: Object
},
methods: {
onClick(event) {
this.$emit('click', this.options);
}
}
}
</script>

View File

@ -0,0 +1,89 @@
<template>
<div class="c-custom-checkbox">
<input type="checkbox"
:id="uid"
:name="options.name"
:checked="options.value"
:disabled="options.disabled"
@change="onChange">
<label :for="uid">
<div class="c-custom-checkbox__box"></div>
<div class="c-custom-checkbox__label-text">
{{options.name}}
</div>
</label>
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-custom-checkbox {
$d: 14px;
display: flex;
align-items: center;
label {
@include userSelectNone();
display: flex;
align-items: center;
}
&__box {
@include nice-input();
display: flex;
align-items: center;
justify-content: center;
line-height: $d;
width: $d;
height: $d;
margin-right: $interiorMarginSm;
}
input {
opacity: 0;
position: absolute;
&:checked + label > .c-custom-checkbox__box {
background: $colorKey;
&:before {
color: $colorKeyFg;
content: $glyph-icon-check;
font-family: symbolsfont;
font-size: 0.6em;
}
}
&:not(:disabled) + label {
cursor: pointer;
}
&:disabled + label {
opacity: 0.5;
}
}
}
</style>
<script>
let uniqueId = 100;
export default {
props: {
options: Object
},
data() {
uniqueId++;
return {
uid: `mct-checkbox-id-${uniqueId}`
};
},
methods: {
onChange(event) {
this.$emit('change', event.target.checked, {...this.options});
}
}
}
</script>

View File

@ -0,0 +1,132 @@
<template>
<div class="c-ctrl-wrapper">
<div class="c-click-icon c-click-icon--swatched"
:class="options.icon"
@click="toggle">
<div class="c-swatch" :style="{
background: options.value
}"></div>
</div>
<div class="c-menu c-palette c-palette--color"
v-if="open">
<div class="c-palette__item-none"
v-if="!this.options.preventNone"
@click="select({value: 'transparent'})">
<div class="c-palette__item"></div>
No fill
</div>
<div class="c-palette__items">
<div class="c-palette__item"
v-for="color in colorPalette"
:style="{ background: color.value }"
@click="select(color)"
></div>
</div>
</div>
</div>
</template>
<script>
import toggleMixin from './toggle-mixin';
export default {
mixins: [toggleMixin],
props: {
options: Object
},
methods: {
select(color) {
if (color.value !== this.options.value) {
this.$emit('change', color, this.options);
}
}
},
data() {
return {
colorPalette: [
{ value: '#000000' },
{ value: '#434343' },
{ value: '#666666' },
{ value: '#999999' },
{ value: '#b7b7b7' },
{ value: '#cccccc' },
{ value: '#d9d9d9' },
{ value: '#efefef' },
{ value: '#f3f3f3' },
{ value: '#ffffff' },
{ value: '#980000' },
{ value: '#ff0000' },
{ value: '#ff9900' },
{ value: '#ffff00' },
{ value: '#00ff00' },
{ value: '#00ffff' },
{ value: '#4a86e8' },
{ value: '#0000ff' },
{ value: '#9900ff' },
{ value: '#ff00ff' },
{ value: '#e6b8af' },
{ value: '#f4cccc' },
{ value: '#fce5cd' },
{ value: '#fff2cc' },
{ value: '#d9ead3' },
{ value: '#d0e0e3' },
{ value: '#c9daf8' },
{ value: '#cfe2f3' },
{ value: '#d9d2e9' },
{ value: '#ead1dc' },
{ value: '#dd7e6b' },
{ value: '#dd7e6b' },
{ value: '#f9cb9c' },
{ value: '#ffe599' },
{ value: '#b6d7a8' },
{ value: '#a2c4c9' },
{ value: '#a4c2f4' },
{ value: '#9fc5e8' },
{ value: '#b4a7d6' },
{ value: '#d5a6bd' },
{ value: '#cc4125' },
{ value: '#e06666' },
{ value: '#f6b26b' },
{ value: '#ffd966' },
{ value: '#93c47d' },
{ value: '#76a5af' },
{ value: '#6d9eeb' },
{ value: '#6fa8dc' },
{ value: '#8e7cc3' },
{ value: '#c27ba0' },
{ value: '#a61c00' },
{ value: '#cc0000' },
{ value: '#e69138' },
{ value: '#f1c232' },
{ value: '#6aa84f' },
{ value: '#45818e' },
{ value: '#3c78d8' },
{ value: '#3d85c6' },
{ value: '#674ea7' },
{ value: '#a64d79' },
{ value: '#85200c' },
{ value: '#990000' },
{ value: '#b45f06' },
{ value: '#bf9000' },
{ value: '#38761d' },
{ value: '#134f5c' },
{ value: '#1155cc' },
{ value: '#0b5394' },
{ value: '#351c75' },
{ value: '#741b47' },
{ value: '#5b0f00' },
{ value: '#660000' },
{ value: '#783f04' },
{ value: '#7f6000' },
{ value: '#274e13' },
{ value: '#0c343d' },
{ value: '#1c4587' },
{ value: '#073763' },
{ value: '#20124d' },
{ value: '#4c1130' }
]
};
}
}
</script>

View File

@ -0,0 +1,40 @@
<template>
<div class="c-labeled-input"
:title="options.title">
<label :for="uid">
<div class="c-labeled-input__label">{{ options.label }}</div>
</label>
<input :id="uid"
:type="options.type"
:value="options.value"
v-bind="options.attrs"
@change="onChange"/>
</div>
</template>
<script>
let inputUniqueId = 100;
export default {
props: {
options: {
type: Object,
validator(value) {
return ['number', 'text'].indexOf(value.type) !== -1;
}
}
},
data() {
inputUniqueId++;
return {
uid: `mct-input-id-${inputUniqueId}`
};
},
methods: {
onChange(event) {
this.$emit('change', event.target.value, this.options);
}
}
}
</script>

View File

@ -0,0 +1,38 @@
<template>
<div class="c-ctrl-wrapper">
<div class="c-click-icon c-click-icon--menu"
:class="options.icon"
@click="toggle">
<div class="c-click-icon__label"
v-if="options.label">
{{ options.label }}
</div>
</div>
<div class="c-menu" v-if="open">
<ul>
<li v-for="option in options.options"
:class="option.class"
:title="option.title">
{{ option.name }}
</li>
</ul>
</div>
</div>
</template>
<script>
import toggle from './toggle-mixin';
export default {
mixins: [toggle],
props: {
options: {
type: Object,
validator(value) {
// must pass valid options array.
return Array.isArray(value.options) &&
value.options.every((o) => o.name);
}
}
}
}
</script>

View File

@ -0,0 +1,55 @@
<template>
<div class="c-ctrl-wrapper">
<div class="c-click-icon c-click-icon--menu"
:class="options.icon"
@click="toggle">
<div class="c-button__label">{{ selectedName }}</div>
</div>
<div class="c-menu" v-if="open">
<ul>
<li v-for="option in options.options"
:key="option.value"
@click="select(option)">
{{ option.name }}
</li>
</ul>
</div>
</div>
</template>
<script>
import toggleMixin from './toggle-mixin';
export default {
mixins: [toggleMixin],
props: {
options: {
type: Object,
validator(value) {
// must pass valid options array.
return Array.isArray(value.options) &&
value.options.every((o) => o.value && o.name);
}
}
},
methods: {
select(option) {
if (this.options.value === option.value) {
return;
}
this.$emit('change', option.value, this.options);
}
},
data() {
},
computed: {
selectedName() {
let selectedOption = this.options.options.filter((o) => o.value === this.options.value)[0];
if (selectedOption) {
return selectedOption.name
}
return '';
}
}
}
</script>

View File

@ -0,0 +1,13 @@
<template>
<div>
<div class="c-button-set"></div>
</div>
</template>
<script>
export default {
props: {
options: Object
}
}
</script>

View File

@ -0,0 +1,34 @@
<template>
<div class="c-ctrl-wrapper">
<div class="c-click-icon"
:title="nextValue.title"
:class="nextValue.icon"
@click="cycle">
</div>
</div>
</template>
<script>
export default {
props: {
options: {
type: Object
}
},
computed: {
nextValue() {
let currentValue = this.options.options.filter((v) => this.options.value === v.value)[0];
let nextIndex = this.options.options.indexOf(currentValue) + 1;
if (nextIndex >= this.options.options.length) {
nextIndex = 0;
}
return this.options.options[nextIndex];
}
},
methods: {
cycle() {
this.$emit('change', this.nextValue.value, this.options);
}
}
};
</script>

View File

@ -1,10 +0,0 @@
import ContextMenuGesture from './ContextMenuGesture.js';
export default {
bind(element, binding) {
binding.vnode.context.destroy = new ContextMenuGesture(element, binding.value);
},
unbind(){
}
}

View File

@ -1,31 +0,0 @@
import ContextMenu from '../components/ContextMenu.vue';
import Vue from 'vue';
export default function ContextMenuGesture (element, object) {
let vm;
element.addEventListener('context', showContextMenu);
function showContextMenu(event){
vm = new Vue({
...ContextMenu
});
document.body.appendChild(vm.$el);
document.addEventListener('click', hideContextMenu, {
capture: true,
once: true
});
event.preventDefault();
event.stopPropagation();
}
function hideContextMenu() {
vm.destroy();
document.body.removeChild(vm.$el);
}
return function destroy() {
element.removeEventListener('context', this.showContextMenu);
document.removeEventListener('click', hideContextMenu);
}
}
}

View File

@ -0,0 +1,112 @@
<template>
<div class="c-message"
v-bind:class="">
<!-- This element is displayed within the overlay service as well as in the list of messages
Uses flex-row -->
<div class="c-message__icon"
:class="['message-severity-' + model.severity]"></div>
<div class="c-message__text">
<!-- Uses flex-column -->
<div class="c-message__title"
v-if="model.title">
{{model.title}}
</div>
<div class="c-message__hint"
v-if="model.hint">
{{model.hint}}
<span v-if="model.timestamp">[{{model.timestamp}}]</span>
</div>
<div class="c-message__action-text"
v-if="model.actionText">
{{model.actionText}}
</div>
<div class="banner-elem" v-if="model.progress !== undefined">
<span class="l-progress-bar s-progress-bar"
:class="{'indeterminate': model.unknownProgress }">
<span class="progress-amt-holder">
<span class="progress-amt" :style="progressWidth"></span>
</span>
</span>
<div class="progress-info hint" v-if="progressText !== undefined">
<span class="progress-amt-text" v-if="progressValue > 0">{{progressValue}}% complete. </span>
{{progressText}}
</div>
</div>
</div>
</div>
</template>
<style lang="scss">
@import "~styles/sass-base";
.c-message {
display: flex;
align-items: center;
padding: $interiorMarginLg;
> * + * {
margin-left: $interiorMarginLg;
}
&__icon {
// Holds a background SVG graphic
$s: 50px;
flex: 0 0 auto;
min-width: $s;
min-height: $s;
&.message-severity {
// TEMP: TODO: Move this into a common SCSS file so that messages and notifications can use it as well.
// Info, alert, error
&-info {
@include glyphBg($bg-icon-info);
filter: $colorStatusInfoFilter;
}
&-alert {
@include glyphBg($bg-icon-alert-rect);
filter: $colorStatusAlertFilter;
}
&-error {
@include glyphBg($bg-icon-alert-triangle);
filter: $colorStatusErrorFilter;
}
}
}
&__text {
display: flex;
flex-direction: column;
flex: 1 1 auto;
> * + * {
@include test();
margin-top: $interiorMargin;
}
}
// __text elements
&__title,
&__action-text {
font-size: 1.2em; // TEMP
}
}
</style>
<script>
export default {
inject:['model'],
props: ['progressValue', 'progressText'],
computed: {
progressWidth() {
return {width: this.progressValue + '%'};
}
}
}
</script>

View File

@ -8,9 +8,20 @@
v-on:click="destroy">
</button>
<div class="c-overlay__contents" ref="element"></div>
<div class="c-overlay__button-bar">
<div class="c-overlay__button-bar" v-if="!buttons">
<button class="c-button c-button--major"
v-on:click="destroy">Done</button>
v-on:click="destroy">
Done
</button>
</div>
<div class="c-overlay__button-bar" v-if="buttons">
<button class="c-button"
v-for="(button, index) in buttons"
:key="index"
:class="button.emphasis ? 'c-button--major' : ''"
@click="buttonClickHandler(button.callback)">
{{button.label}}
</button>
</div>
</div>
</div>
@ -19,6 +30,13 @@
<style lang="scss">
@import "~styles/sass-base";
@mixin overlaySizing($marginTB: 5%, $marginLR: $marginTB, $width: auto, $height: auto) {
position: absolute;
top: $marginTB; right: $marginLR; bottom: $marginTB; left: $marginLR;
width: $width;
height: $height;
}
.l-overlay-wrapper {
// Created by overlayService.js, contains this template.
// Acts as an anchor for one or more overlays.
@ -60,9 +78,31 @@
display: flex;
justify-content: flex-end;
margin-top: $interiorMargin;
> * + * {
margin-left: $interiorMargin;
}
}
body.desktop & {
// Overlay types, styling independent of platform.
.l-large-view & {
// Default
}
.l-dialog & {
//
}
.l-message & {
&__outer {
// background: orange;
}
}
}
body.desktop {
.c-overlay {
&__blocker {
@include abs();
background: rgba(black, 0.7);
@ -71,21 +111,49 @@
}
&__outer {
$m: $overlayOuterMargin;
top: $m; right: $m; bottom: $m; left: $m;
border-radius: $overlayCr;
box-shadow: rgba(black, 0.5) 0 2px 25px;
// Defaults to l-large-view
@include overlaySizing($overlayOuterMarginLg);
}
}
// Overlay types, styling for desktop.
.l-large-view {
// Default
}
.l-dialog {
.c-overlay__outer {
@include overlaySizing($overlayOuterMarginDialog);
}
}
.l-message {
.c-overlay__outer {
@include overlaySizing(auto);
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
}
}
}
</style>
<script>
export default {
inject: ['destroy', 'element'],
inject: ['destroy', 'element', 'buttons'],
mounted() {
this.$refs.element.appendChild(this.element);
},
methods: {
buttonClickHandler: function (method) {
method();
this.destroy();
}
}
}
</script>

View File

@ -22,17 +22,49 @@
define([
'./overlay.vue',
'./blockingMessage.vue',
'vue'
], function (
OverlayComponent,
BlockingMessage,
Vue
) {
/**
* The OverlayService is responsible for pre-pending templates to
* the body of the document, which is useful for displaying templates
* which need to block the full screen.
*
* @memberof platform/ui/overlayService
* @constructor
*/
function OverlayService() {
this.activeOverlays = [];
this.overlayId = 0;
this.showBlockingMessage = this.showBlockingMessage.bind(this);
}
/**
* A description of option properties that can be passed into the overlay
* @typedef options
* @property {string} cssClass class to be applied to overlay.
* supported classes are - l-large-view, l-dialog, l-message
* @property {array} buttons optional button objects with label and callback properties
* @property {function} onDestroy callback to be called when overlay is destroyed
* (useful for clearing out listeners and destroying components)
*/
/**
* Add a new overlay to the document. This will be
* prepended to the document body
*
* @param {object} element a DOM element, that needs to be inserted into the Overlay
* @param {object} options
* @returns {object} with a dismiss function that can be called to dimiss/destroy the overlay from
* the calling code.
*/
OverlayService.prototype.show = function (element, options) {
if(this.activeOverlays.length) {
this.activeOverlays[this.activeOverlays.length - 1].overlay.classList.add('invisible');
@ -43,45 +75,155 @@ define([
component = new Vue({
provide: {
destroy: this.destroy.bind(this),
element: element
element: element,
buttons: options.buttons
},
components: {
OverlayComponent: OverlayComponent.default
},
template: '<overlay-component></overlay-component>'
});
}),
dialog = {};
overlay.classList.add('l-overlay-wrapper', overlayTypeCssClass);
document.body.appendChild(overlay);
overlay.appendChild(component.$mount().$el);
this.activeOverlays.push({
var overlayObject = {
overlay: overlay,
component: component,
onDestroy: options.onDestroy,
id: this.overlayId
});
id: this.overlayId,
dialog: dialog
};
dialog.dismiss = function () {
let pos = findInArray(overlayObject.id, this.activeOverlays);
if (pos !== -1) {
if (overlayObject.onDestroy && typeof overlayObject.onDestroy === 'function') {
overlayObject.onDestroy();
}
overlayObject.component.$destroy();
document.body.removeChild(overlayObject.overlay);
this.activeOverlays.splice(pos, 1);
if (this.activeOverlays.length) {
this.activeOverlays[this.activeOverlays.length - 1].overlay.classList.remove('invisible');
}
}
}.bind(this);
this.activeOverlays.push(overlayObject);
this.overlayId++;
return dialog;
};
OverlayService.prototype.destroy = function () {
var lastActiveOverlayObject = this.activeOverlays.pop(),
lastActiveOverlay = lastActiveOverlayObject.overlay,
lastActiveComponent = lastActiveOverlayObject.component;
var lastActiveOverlayObject = this.activeOverlays[this.activeOverlays.length - 1];
if (lastActiveOverlayObject.onDestroy && typeof lastActiveOverlayObject.onDestroy === 'function') {
lastActiveOverlayObject.onDestroy();
}
lastActiveComponent.$destroy(true);
document.body.removeChild(lastActiveOverlay);
if (this.activeOverlays.length) {
this.activeOverlays[this.activeOverlays.length - 1].overlay.classList.remove('invisible');
}
lastActiveOverlayObject.dialog.dismiss();
};
/**
* A description of the model options that may be passed to the
* showBlockingMessage method. Note that the DialogModel described
* here is shared with the Notifications framework.
* @see NotificationService
*
* @typedef model
* @property {string} title the title to use for the dialog
* @property {string} severity the severity level of this message.
* These are defined in a bundle constant with key 'dialogSeverity'
* @property {string} hint the 'hint' message to show below the title
* @property {string} actionText text that indicates a current action,
* shown above a progress bar to indicate what's happening.
* @property {number} progress a percentage value (1-100)
* indicating the completion of the blocking task
* @property {string} progressText the message to show below a
* progress bar to indicate progress. For example, this might be
* used to indicate time remaining, or items still to process.
* @property {boolean} unknownProgress some tasks may be
* impossible to provide an estimate for. Providing a true value for
* this attribute will indicate to the user that the progress and
* duration cannot be estimated.
* @property {buttons[]} buttons a list of buttons with title and callback properties that will
* be added to the dialog.
*/
/**
* Displays a blocking (modal) dialog. This dialog can be used for
* displaying messages that require the user's
* immediate attention. The message may include an indication of
* progress, as well as a series of actions that
* the user can take if necessary
* @param {model} dialogModel defines options for the dialog
* @returns {object} with an object with a dismiss function that can be called from the calling code
* to dismiss/destroy the dialog, progressValue function that is a setter/getter for updating the progress percentage,
* and a progressText function that is a setter/getter for updating the progress text.
*/
OverlayService.prototype.showBlockingMessage = function (model) {
let component = new Vue({
provide: {
model: model
},
components: {
BlockingMessage: BlockingMessage.default
},
data: function () {
return {
progressValue: 0,
progressText: model.progressText
};
},
template: '<blocking-message :progressValue="progressValue" :progressText="progressText"></blocking-message>'
});
function destroy() {
component.$destroy();
}
let options = {
cssClass: 'l-message',
onDestroy: destroy,
buttons: model.buttons
};
return {
dialog: this.show(component.$mount().$el, options),
progressValue: (value) => {
if (value) {
component.progressValue = value;
}
return component.progressValue;
},
progressText: (value) => {
if (value) {
component.progressText = value;
}
return component.progressText;
}
};
};
function findInArray(id, array) {
var found = -1;
array.forEach(function (o,i) {
if (o.id === id) {
found = i;
return;
}
});
return found;
}
return OverlayService;
});