Compare commits

..

20 Commits

Author SHA1 Message Date
Andrew Henry
099eaed83c Temporarily setting absolute config file path 2019-01-23 15:31:41 -08:00
Pegah Sarram
9e811e722f [Display Layout] support ordering items (#2266)
* Add a toolbar menu for changing the display order of items.

* - Wire up orderItem
- Modify the toolbar API to support function as alternative for property path.
2019-01-23 10:51:29 -08:00
Charles Hacskaylo
8ef53d85c4 R&I Layout editing mods (#2256)
* Layout mods for sub object editing without is-drilled-in
* Remove drilled-in logic
2019-01-22 11:52:56 -08:00
Andrew Henry
abcc5cb023 Implemented go to parent (#2264) 2019-01-17 16:32:12 -08:00
Pegah Sarram
931871ff95 [Display Layout] Snap to grid toolbar toggle button (#2262)
* Add a  button in the toolbar to toggle snapp to grid.

* Convert item's coordinates and size from grid unit to pixels depending on useGrid value.

* Rename selectionListener to removeSelectionListener
2019-01-17 09:24:59 -08:00
Andrew Henry
6b1e8862ef Tables composition error (#2260)
* Removed debubgging statement

* Change order of mutation events so that composition handlers are working with latest object version.

* Remove suppression of mutation event

* Minor code reformatting
2019-01-15 09:55:22 -08:00
Pete Richards
00ce246fc5 Merge pull request #2261 from nasa/object-path-on-drop
Change domain-object event transfer data to domain-object-path
2019-01-15 09:48:32 -08:00
Andrew Henry
c0c7d96429 Change domain-object event transfer data to domain-object-path 2019-01-14 12:07:31 -08:00
Andrew Henry
92b2582d0d Preview instead of navigate in edit mode + highlight navigated object (#2252)
* Preview instead of navigate when in edit mode.

* Prevent preview of navigated object

* Removed trailing comma

* Observe navigation from tree items instead of mct-tree

* Cleanup of redundant code

* .is-selected -> .is-navigated-object
2019-01-11 11:21:52 -08:00
Andrew Henry
4084a1ac86 Drag and drop fixes (#2249)
* Drag-drop edit mode from capture handler. Drag-drop composition from bubble handler. Check composability on drag start

* Show drop hints without being in edit mode.

* Don't serialize objects twice on drag
2019-01-11 11:20:57 -08:00
Charles Hacskaylo
cb1a1c2616 R&I Clock timer fixes (#2254)
* Clocks and timers styling WIP

- Markup, new styles;
- Renamed _legacy-plots.scss > _legacy;
- New $colorBodyFgEm constants - theme files all updated;

* Clocks and timers styling complete

* Styles clean up

- Moved legacy styles out of _global into _legacy.scss;
2018-12-24 14:02:37 -08:00
Deep Tailor
ce6c1f173e Lad table vue (#2231)
* working telemetry subs

* Styling for LAD table

- Fixed markup;
- Corrected icon, added description;
- Expand c-table styles slightly, moved some definitions into
c-telemetry-table;

* add LADTableSummary

* change function names

* make reviewer requested changes

* add lad table headers in sets

* make column widths fixed

* handle composition remove in sets and tables

* finish updateTimeSystem

* add correct support for limits

* LAD Table and Table Set styling

- Removed fixed table layout;
- Col widths set to 33% for now;
- New c-lad-table class and styling;
- New __group-header class added;
- All themes updated with __group-header style colors;

* make reviewer requested changes

* use lodash findIndex
2018-12-20 13:18:22 -08:00
Charles Hacskaylo
30a4888363 R&I Misc UI 3 (#2253)
* Limits-related changes; WIP

- Renamed CSS classes: `s-limit-*` > `is-limit--*`;
- Removed load of legacy _status.scss and added new _status.scss file;
- Minor re-org of limit/status constants in theme files;
- Limit colors in theme constants all updated;

* Fixes for s-selected always displaying the move cursor

- Mod s-selected;
- Reinstitute `.is-moveable` class;

* Layout-related cleanup and refinements

- LineView cleaned up;
- Selection, hover, etc. classes for c-frame cleaned up;
- Constant names normalized, theme files updated;

* Fixes for editing plot options

- Color palette now more flexible;
- Styles for color palette button refined;
- c-input--flex added for more flexible inputs;

* Various swatch-related changes

- Swatch refinements, new .c-click-swatch class;
- Added .c-click-icon--major modifier style, applied in markup;

* Local controls class application and behavior cleanup

- Remmoved .has-local-controls from selected markup;
- Refined CSS selector for better hover behavior;

* Misc UI tweaks

- click-icon--major in Notebook;
- .test mixin improved;

* Update _constants-espresso.scss

* Update _constants-maelstrom.scss
2018-12-20 13:17:44 -08:00
Deep Tailor
b0917a9866 Pending fixes for Grid and List Folder views (#2247)
* fix view names, and persist sort order across list views by persisting in local storage

* use keystring as key

* add openmct namespace to localstorage persisted listview-sort-order to avoid name collision, rename key in composition-loader to objectKeyString
2018-12-20 13:16:23 -08:00
Pegah Sarram
464e5de947 [Display Layout] Add delete button (#2251)
* Add delete button in the toolbar for removing items

* Mutate composition if there are no telemetry objects. Select the parent layout after deleting an item.

* Saving work

* Watch for index in the components and update it in the context.

* Select the parent after a composition is removed.

* Address reviewer's feedback.
- Rename mutatComposition() to removeFromComposition().
- Inline logic for filtering composition
- Use separate branches for each item type in trackItem().

* Address reviewer's requested changes
2018-12-20 13:15:23 -08:00
Pete Richards
47a07da17d Merge pull request #2246 from nasa/conditional-edit-button
Conditional edit button
2018-12-20 09:37:43 -08:00
Charles Hacskaylo
ec4c443299 Misc ui 2 (#2248)
* Create button disabled when editing
* New disabled mixin;
* Tree styling
* Fixed icons for fullscreen toggle button
* Local controls fixed for Imagery and Plots
* Range control styling updated;
* Plot styling, significant mods
* Disclosure controls improved;
* New _legacy-plots.scss file added, no longer loads legacy plot SCSS
files;
* Removed 12px crosshair cursor in legend hover;
* Inspector tree styling in plot options
* Fix z-indexing related to Overlays
2018-12-18 11:07:09 -08:00
Andrew Henry
3122168b0e Removed unused legacy code 2018-12-13 17:11:39 -08:00
Andrew Henry
da3af4b3db Merged from TCR 2018-12-13 15:36:13 -08:00
Andrew Henry
d026bc2134 Show edit only if view is editable. Rename editable to canEdit 2018-12-12 17:17:49 -08:00
81 changed files with 2861 additions and 1301 deletions

View File

@@ -37,25 +37,25 @@ define([
},
LIMITS = {
rh: {
cssClass: "s-limit-upr s-limit-red",
cssClass: "is-limit--upr is-limit--red",
low: RED,
high: Number.POSITIVE_INFINITY,
name: "Red High"
},
rl: {
cssClass: "s-limit-lwr s-limit-red",
cssClass: "is-limit--lwr is-limit--red",
high: -RED,
low: Number.NEGATIVE_INFINITY,
name: "Red Low"
},
yh: {
cssClass: "s-limit-upr s-limit-yellow",
cssClass: "is-limit--upr is-limit--yellow",
low: YELLOW,
high: RED,
name: "Yellow High"
},
yl: {
cssClass: "s-limit-lwr s-limit-yellow",
cssClass: "is-limit--lwr is-limit--yellow",
low: -RED,
high: -YELLOW,
name: "Yellow Low"

View File

@@ -79,6 +79,7 @@
openmct.install(openmct.plugins.FolderView());
openmct.install(openmct.plugins.Tabs());
openmct.install(openmct.plugins.FlexibleLayout());
openmct.install(openmct.plugins.LADTable());
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
openmct.time.timeSystem('utc');
openmct.start();

View File

@@ -74,7 +74,7 @@
"start": "node app.js",
"lint": "eslint platform src openmct.js",
"lint:fix": "eslint platform src openmct.js --fix",
"build:prod": "NODE_ENV=production webpack",
"build:prod": "NODE_ENV=production webpack ./webpack.config.js",
"build:dev": "webpack",
"build:watch": "webpack --watch",
"test": "karma start --single-run",

View File

@@ -32,7 +32,6 @@ define([
"./src/actions/SaveAndStopEditingAction",
"./src/actions/SaveAsAction",
"./src/actions/CancelAction",
"./src/policies/EditActionPolicy",
"./src/policies/EditPersistableObjectsPolicy",
"./src/representers/EditRepresenter",
"./src/capabilities/EditorCapability",
@@ -64,7 +63,6 @@ define([
SaveAndStopEditingAction,
SaveAsAction,
CancelAction,
EditActionPolicy,
EditPersistableObjectsPolicy,
EditRepresenter,
EditorCapability,
@@ -225,10 +223,6 @@ define([
}
],
"policies": [
{
"category": "action",
"implementation": EditActionPolicy
},
{
"category": "action",
"implementation": EditPersistableObjectsPolicy,

View File

@@ -1,111 +0,0 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define(
[],
function () {
/**
* Policy controlling when the `edit` and/or `properties` actions
* can appear as applicable actions of the `view-control` category
* (shown as buttons in the top-right of browse mode.)
* @memberof platform/commonUI/edit
* @constructor
* @implements {Policy.<Action, ActionContext>}
*/
function EditActionPolicy(policyService) {
this.policyService = policyService;
}
/**
* Get a count of views which are not flagged as non-editable.
* @private
*/
EditActionPolicy.prototype.countEditableViews = function (context) {
var domainObject = context.domainObject,
count = 0,
type, views;
if (!domainObject) {
return count;
}
type = domainObject.getCapability('type');
views = domainObject.useCapability('view');
// A view is editable unless explicitly flagged as not
(views || []).forEach(function (view) {
if (isEditable(view) ||
(view.key === 'plot' && type.getKey() === 'telemetry.panel') ||
(view.key === 'table' && type.getKey() === 'table') ||
(view.key === 'rt-table' && type.getKey() === 'rttable')
) {
count++;
}
});
function isEditable(view) {
if (typeof view.editable === Function) {
return view.editable(domainObject.useCapability('adapter'));
} else {
return view.editable === true;
}
}
return count;
};
/**
* Checks whether the domain object is currently being edited. If
* so, the edit action is not applicable.
* @param context
* @returns {*|boolean}
*/
function isEditing(context) {
var domainObject = (context || {}).domainObject;
return domainObject &&
domainObject.hasCapability('editor') &&
domainObject.getCapability('editor').isEditContextRoot();
}
EditActionPolicy.prototype.allow = function (action, context) {
var key = action.getMetadata().key,
category = (context || {}).category;
// Restrict 'edit' to cases where there are editable
// views (similarly, restrict 'properties' to when
// the converse is true), and where the domain object is not
// already being edited.
if (key === 'edit') {
return this.countEditableViews(context) > 0 && !isEditing(context);
} else if (key === 'properties' && category === 'view-control') {
return this.countEditableViews(context) < 1 && !isEditing(context);
}
// Like all policies, allow by default.
return true;
};
return EditActionPolicy;
}
);

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.
*****************************************************************************/
define(
[],
function () {
/**
* Policy controlling which views should be visible in Edit mode.
* @memberof platform/commonUI/edit
* @constructor
* @implements {Policy.<View, DomainObject>}
*/
function EditableViewPolicy() {
}
EditableViewPolicy.prototype.allow = function (view, domainObject) {
// If a view is flagged as non-editable, only allow it
// while we're not in Edit mode.
if ((view || {}).editable === false) {
return !(domainObject.hasCapability('editor') && domainObject.getCapability('editor').inEditContext());
}
// Like all policies, allow by default.
return true;
};
return EditableViewPolicy;
}
);

View File

@@ -1,138 +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/policies/EditActionPolicy"],
function (EditActionPolicy) {
describe("The Edit action policy", function () {
var editableView,
nonEditableView,
testViews,
testContext,
mockDomainObject,
mockEditAction,
mockPropertiesAction,
mockTypeCapability,
mockEditorCapability,
capabilities,
plotView,
policy;
beforeEach(function () {
mockDomainObject = jasmine.createSpyObj(
'domainObject',
[
'useCapability',
'hasCapability',
'getCapability'
]
);
mockEditorCapability = jasmine.createSpyObj('editorCapability', ['isEditContextRoot']);
mockTypeCapability = jasmine.createSpyObj('type', ['getKey']);
capabilities = {
'editor': mockEditorCapability,
'type': mockTypeCapability
};
mockEditAction = jasmine.createSpyObj('edit', ['getMetadata']);
mockPropertiesAction = jasmine.createSpyObj('edit', ['getMetadata']);
mockDomainObject.getCapability.and.callFake(function (capability) {
return capabilities[capability];
});
mockDomainObject.hasCapability.and.callFake(function (capability) {
return !!capabilities[capability];
});
editableView = { editable: true };
nonEditableView = { editable: false };
plotView = { key: "plot", editable: false };
testViews = [];
mockDomainObject.useCapability.and.callFake(function (c) {
// Provide test views, only for the view capability
return c === 'view' && testViews;
});
mockEditAction.getMetadata.and.returnValue({ key: 'edit' });
mockPropertiesAction.getMetadata.and.returnValue({ key: 'properties' });
testContext = {
domainObject: mockDomainObject,
category: 'view-control'
};
policy = new EditActionPolicy();
});
it("allows the edit action when there are editable views", function () {
testViews = [editableView];
expect(policy.allow(mockEditAction, testContext)).toBe(true);
});
it("allows the edit properties action when there are no editable views", function () {
testViews = [nonEditableView, nonEditableView];
expect(policy.allow(mockPropertiesAction, testContext)).toBe(true);
});
it("disallows the edit action when there are no editable views", function () {
testViews = [nonEditableView, nonEditableView];
expect(policy.allow(mockEditAction, testContext)).toBe(false);
});
it("disallows the edit properties action when there are" +
" editable views", function () {
testViews = [editableView];
expect(policy.allow(mockPropertiesAction, testContext)).toBe(false);
});
it("disallows the edit action when object is already being" +
" edited", function () {
testViews = [editableView];
mockEditorCapability.isEditContextRoot.and.returnValue(true);
expect(policy.allow(mockEditAction, testContext)).toBe(false);
});
it("allows editing of panels in plot view", function () {
testViews = [plotView];
mockTypeCapability.getKey.and.returnValue('telemetry.panel');
expect(policy.allow(mockEditAction, testContext)).toBe(true);
});
it("disallows editing of plot view when object not a panel type", function () {
testViews = [plotView];
mockTypeCapability.getKey.and.returnValue('something.else');
expect(policy.allow(mockEditAction, testContext)).toBe(false);
});
it("allows the edit properties outside of the 'view-control' category", function () {
testViews = [nonEditableView];
testContext.category = "something-else";
expect(policy.allow(mockPropertiesAction, testContext)).toBe(true);
});
});
}
);

View File

@@ -1,79 +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/policies/EditableViewPolicy"],
function (EditableViewPolicy) {
describe("The editable view policy", function () {
var mockDomainObject,
testMode,
policy;
beforeEach(function () {
testMode = true; // Act as if we're in Edit mode by default
mockDomainObject = jasmine.createSpyObj(
'domainObject',
['hasCapability', 'getCapability']
);
mockDomainObject.getCapability.and.returnValue({
inEditContext: function () {
return true;
}
});
mockDomainObject.hasCapability.and.callFake(function (c) {
return (c === 'editor') && testMode;
});
policy = new EditableViewPolicy();
});
it("disallows views in edit mode that are flagged as non-editable", function () {
expect(policy.allow({ editable: false }, mockDomainObject))
.toBeFalsy();
});
it("allows views in edit mode that are flagged as editable", function () {
expect(policy.allow({ editable: true }, mockDomainObject))
.toBeTruthy();
});
it("allows any view outside of edit mode", function () {
var testViews = [
{ editable: false },
{ editable: true },
{ someKey: "some value" }
];
testMode = false; // Act as if we're not in Edit mode
testViews.forEach(function (testView) {
expect(policy.allow(testView, mockDomainObject)).toBeTruthy();
});
});
it("treats views with no defined 'editable' property as editable", function () {
expect(policy.allow({ someKey: "some value" }, mockDomainObject))
.toBeTruthy();
});
});
}
);

View File

@@ -19,16 +19,14 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<div class="l-time-display l-digital l-clock s-clock" ng-controller="ClockController as clock">
<div class="l-elem-wrapper">
<span class="l-elem timezone">
{{clock.zone()}}
</span>
<span class="l-elem value active">
{{clock.text()}}
</span>
<span class="l-elem ampm">
{{clock.ampm()}}
</span>
<div class="c-clock l-time-display" ng-controller="ClockController as clock">
<div class="c-clock__timezone">
{{clock.zone()}}
</div>
<div class="c-clock__value">
{{clock.text()}}
</div>
<div class="c-clock__ampm">
{{clock.ampm()}}
</div>
</div>

View File

@@ -19,21 +19,19 @@
this source code distribution or the Licensing information page available
at runtime from the About dialog for additional information.
-->
<div class="l-time-display l-digital l-timer s-timer s-state-{{timer.timerState}}" ng-controller="TimerController as timer">
<div class="l-elem-wrapper l-flex-row">
<div class="l-elem-wrapper l-flex-row controls">
<a ng-click="timer.clickStopButton()"
title="Stop"
class="flex-elem s-icon-button t-btn-stop icon-box"></a>
<a ng-click="timer.clickButton()"
title="{{timer.buttonText()}}"
class="flex-elem s-icon-button t-btn-pauseplay {{timer.buttonCssClass()}}"></a>
</div>
<span class="flex-elem l-value {{timer.signClass()}}">
<span class="value"
ng-class="{ active:timer.text() }">{{timer.text() || "--:--:--"}}
</span>
</span>
<span ng-controller="RefreshingController"></span>
<div class="c-timer is-{{timer.timerState}}" ng-controller="TimerController as timer">
<div class="c-timer__controls">
<button ng-click="timer.clickStopButton()"
ng-hide="timer.timerState == 'stopped'"
title="Reset"
class="c-timer__ctrl-reset c-click-icon c-click-icon--major icon-reset"></button>
<button ng-click="timer.clickButton()"
title="{{timer.buttonText()}}"
class="c-timer__ctrl-pause-play c-click-icon c-click-icon--major {{timer.buttonCssClass()}}"></button>
</div>
<div class="c-timer__direction {{timer.signClass()}}"
ng-hide="!timer.signClass()"></div>
<div class="c-timer__value">{{timer.text() || "--:--:--"}}
</div>
<span class="c-timer__ng-controller u-contents" ng-controller="RefreshingController"></span>
</div>

View File

@@ -43,6 +43,7 @@ define([
'./ui/layout/Layout.vue',
'../platform/core/src/objects/DomainObjectImpl',
'../platform/core/src/capabilities/ContextualDomainObject',
'./ui/preview/plugin',
'vue'
], function (
EventEmitter,
@@ -67,6 +68,7 @@ define([
Layout,
DomainObjectImpl,
ContextualDomainObject,
PreviewPlugin,
Vue
) {
/**
@@ -230,7 +232,7 @@ define([
this.install(this.plugins.Plot());
this.install(this.plugins.TelemetryTable());
this.install(this.plugins.DisplayLayout());
this.install(this.plugins.Preview());
this.install(PreviewPlugin.default());
if (typeof BUILD_CONSTANTS !== 'undefined') {
this.install(buildInfoPlugin(BUILD_CONSTANTS));

View File

@@ -58,11 +58,8 @@ define([
handleLegacyMutation = function (legacyObject) {
var newStyleObject = utils.toNewFormat(legacyObject.getModel(), legacyObject.getId());
//Don't trigger self
this.eventEmitter.off('mutation', handleMutation);
this.eventEmitter.emit(newStyleObject.identifier.key + ":*", newStyleObject);
this.eventEmitter.on('mutation', handleMutation);
this.eventEmitter.emit('mutation', newStyleObject);
}.bind(this);
this.eventEmitter.on('mutation', handleMutation);

View File

@@ -21,7 +21,9 @@ define([
name: legacyView.name,
cssClass: legacyView.cssClass,
description: legacyView.description,
editable: legacyView.editable,
canEdit: function () {
return legacyView.editable === true;
},
canView: function (domainObject) {
if (!domainObject || !domainObject.identifier) {
return false;

View File

@@ -46,6 +46,7 @@ define([
function DefaultCompositionProvider(publicAPI, compositionAPI) {
this.publicAPI = publicAPI;
this.listeningTo = {};
this.onMutation = this.onMutation.bind(this);
this.cannotContainDuplicates = this.cannotContainDuplicates.bind(this);
this.cannotContainItself = this.cannotContainItself.bind(this);
@@ -208,9 +209,10 @@ define([
if (this.topicListener) {
return;
}
var topic = this.publicAPI.$injector.get('topic');
var mutation = topic('mutation');
this.topicListener = mutation.listen(this.onMutation.bind(this));
this.publicAPI.objects.eventEmitter.on('mutation', this.onMutation);
this.topicListener = () => {
this.publicAPI.objects.eventEmitter.off('mutation', this.onMutation)
};
};
/**
@@ -220,7 +222,7 @@ define([
* @private
*/
DefaultCompositionProvider.prototype.onMutation = function (oldDomainObject) {
var id = oldDomainObject.getId();
var id = objectUtils.makeKeyString(oldDomainObject.identifier);
var listeners = this.listeningTo[id];
if (!listeners) {
@@ -228,7 +230,7 @@ define([
}
var oldComposition = listeners.composition.map(objectUtils.makeKeyString);
var newComposition = oldDomainObject.getModel().composition.map(objectUtils.makeKeyString);
var newComposition = oldDomainObject.composition.map(objectUtils.makeKeyString);
var added = _.difference(newComposition, oldComposition).map(objectUtils.parseKeyString);
var removed = _.difference(oldComposition, newComposition).map(objectUtils.parseKeyString);

View File

@@ -83,18 +83,15 @@ define([
this.object = newObject;
}.bind(this);
this.eventEmitter.on(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
//Emit event specific to property
this.eventEmitter.emit(qualifiedEventName(this.object, path), value);
this.eventEmitter.off(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
//Emit wildcare event
//Emit wildcard event
this.eventEmitter.emit(qualifiedEventName(this.object, '*'), this.object);
//Emit a general "any object" event
this.eventEmitter.emit(ANY_OBJECT_EVENT, this.object);
this.eventEmitter.on(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
//Emit event specific to property
this.eventEmitter.emit(qualifiedEventName(this.object, path), value);
this.eventEmitter.off(qualifiedEventName(this.object, '*'), handleRecursiveMutation);
};
return MutableObject;

View File

@@ -0,0 +1,67 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define([
'./components/LadTableSet.vue',
'vue'
], function (
LadTableSet,
Vue
) {
function LADTableSetViewProvider(openmct) {
return {
key: 'LadTableSet',
name: 'LAD Table Set',
cssClass: 'icon-tabular-lad-set',
canView: function (domainObject) {
return domainObject.type === 'LadTableSet';
},
view: function (domainObject) {
let component;
return {
show: function (element) {
component = new Vue({
components: {
LadTableSet: LadTableSet.default
},
provide: {
openmct,
domainObject
},
el: element,
template: '<lad-table-set></lad-table-set>'
});
},
destroy: function (element) {
component.$destroy();
component = undefined;
}
};
},
priority: function () {
return 1;
}
};
}
return LADTableSetViewProvider;
});

View File

@@ -0,0 +1,67 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define([
'./components/LadTable.vue',
'vue'
], function (
LadTableComponent,
Vue
) {
function LADTableViewProvider(openmct) {
return {
key: 'LadTable',
name: 'LAD Table',
cssClass: 'icon-tabular-lad',
canView: function (domainObject) {
return domainObject.type === 'LadTable';
},
view: function (domainObject) {
let component;
return {
show: function (element) {
component = new Vue({
components: {
LadTableComponent: LadTableComponent.default
},
provide: {
openmct,
domainObject
},
el: element,
template: '<lad-table-component></lad-table-component>'
});
},
destroy: function (element) {
component.$destroy();
component = undefined;
}
};
},
priority: function () {
return 1;
}
};
}
return LADTableViewProvider;
});

View File

@@ -0,0 +1,120 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
<template>
<tr>
<td>{{name}}</td>
<td>{{timestamp}}</td>
<td :class="valueClass">
{{value}}
</td>
</tr>
</template>
<style lang="scss">
</style>
<script>
export default {
inject: ['openmct'],
props: ['domainObject'],
data() {
return {
name: this.domainObject.name,
timestamp: '---',
value: '---',
valueClass: ''
}
},
methods: {
updateValues(datum) {
this.timestamp = this.formats[this.timestampKey].format(datum);
this.value = this.formats[this.valueKey].format(datum);
var limit = this.limitEvaluator.evaluate(datum, this.valueMetadata);
if (limit) {
this.valueClass = limit.cssClass;
} else {
this.valueClass = '';
}
},
updateName(name){
this.name = name;
},
updateTimeSystem(timeSystem) {
this.value = '---';
this.timestamp = '---';
this.valueClass = '';
this.timestampKey = timeSystem.key;
this.openmct
.telemetry
.request(this.domainObject, {strategy: 'latest'})
.then((array) => this.updateValues(array[array.length - 1]));
}
},
mounted() {
this.metadata = this.openmct.telemetry.getMetadata(this.domainObject);
this.formats = this.openmct.telemetry.getFormatMap(this.metadata);
this.limitEvaluator = openmct
.telemetry
.limitEvaluator(this.domainObject);
this.stopWatchingMutation = openmct
.objects
.observe(
this.domainObject,
'*',
this.updateName
);
this.openmct.time.on('timeSystem', this.updateTimeSystem);
this.timestampKey = this.openmct.time.timeSystem().key;
this.valueMetadata = this
.metadata
.valuesForHints(['range'])[0];
this.valueKey = this.valueMetadata.key
this.unsubscribe = this.openmct
.telemetry
.subscribe(this.domainObject, this.updateValues);
this.openmct
.telemetry
.request(this.domainObject, {strategy: 'latest'})
.then((array) => this.updateValues(array[array.length - 1]));
},
destroyed() {
this.stopWatchingMutation();
this.unsubscribe();
this.openmct.off('timeSystem', this.updateTimeSystem);
}
}
</script>

View File

@@ -0,0 +1,82 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
<template>
<table class="c-table c-lad-table">
<thead>
<tr>
<th>Name</th>
<th>Timestamp</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<lad-row
v-for="item in items"
:key="item.key"
:domainObject="item.domainObject">
</lad-row>
</tbody>
</table>
</template>
<script>
import lodash from 'lodash';
import LadRow from './LadRow.vue';
export default {
inject: ['openmct', 'domainObject'],
components: {
LadRow
},
data() {
return {
items: []
}
},
methods: {
addItem(domainObject) {
let item = {};
item.domainObject = domainObject;
item.key = this.openmct.objects.makeKeyString(domainObject.identifier);
this.items.push(item);
},
removeItem(identifier) {
let index = _.findIndex(this.items, (item) => this.openmct.objects.makeKeyString(identifier) === item.key);
this.items.splice(index, 1);
}
},
mounted() {
this.composition = this.openmct.composition.get(this.domainObject);
this.composition.on('add', this.addItem);
this.composition.on('remove', this.removeItem);
this.composition.load();
},
destroyed() {
this.composition.off('add', this.addItem);
this.composition.off('remove', this.removeItem);
}
}
</script>

View File

@@ -0,0 +1,135 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
<template>
<table class="c-table c-lad-table">
<thead>
<tr>
<th>Name</th>
<th>Timestamp</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<template
v-for="primary in primaryTelemetryObjects">
<tr class="c-table__group-header"
:key="primary.key">
<td colspan="10">{{primary.domainObject.name}}</td>
</tr>
<lad-row
v-for="secondary in secondaryTelemetryObjects[primary.key]"
:key="secondary.key"
:domainObject="secondary.domainObject">
</lad-row>
</template>
</tbody>
</table>
</template>
<style lang="scss">
</style>
<script>
import lodash from 'lodash';
import LadRow from './LadRow.vue';
export default {
inject: ['openmct', 'domainObject'],
components: {
LadRow
},
data() {
return {
primaryTelemetryObjects: [],
secondaryTelemetryObjects: {},
compositions: []
}
},
methods: {
addPrimary(domainObject) {
let primary = {};
primary.domainObject = domainObject;
primary.key = this.openmct.objects.makeKeyString(domainObject.identifier);
this.$set(this.secondaryTelemetryObjects, primary.key, []);
this.primaryTelemetryObjects.push(primary);
let composition = openmct.composition.get(primary.domainObject),
addCallback = this.addSecondary(primary),
removeCallback = this.removeSecondary(primary);
composition.on('add', addCallback);
composition.on('remove', removeCallback);
composition.load();
this.compositions.push({composition, addCallback, removeCallback});
},
removePrimary(identifier) {
let index = _.findIndex(this.primaryTelemetryObjects, (primary) => this.openmct.objects.makeKeyString(identifier) === primary.key),
primary = this.primaryTelemetryObjects[index];
this.$set(this.secondaryTelemetryObjects, primary.key, undefined);
this.primaryTelemetryObjects.splice(index,1);
primary = undefined;
},
addSecondary(primary) {
return (domainObject) => {
let secondary = {};
secondary.key = this.openmct.objects.makeKeyString(domainObject.identifier);
secondary.domainObject = domainObject;
let array = this.secondaryTelemetryObjects[primary.key];
array.push(secondary);
this.$set(this.secondaryTelemetryObjects, primary.key, array);
}
},
removeSecondary(primary) {
return (identifier) => {
let array = this.secondaryTelemetryObjects[primary.key],
index = _.findIndex(array, (secondary) => this.openmct.objects.makeKeyString(identifier) === secondary.key);
array.splice(index, 1);
this.$set(this.secondaryTelemetryObjects, primary.key, array);
}
}
},
mounted() {
this.composition = this.openmct.composition.get(this.domainObject);
this.composition.on('add', this.addPrimary);
this.composition.on('remove', this.removePrimary);
this.composition.load();
},
destroyed() {
this.composition.off('add', this.addPrimary);
this.composition.off('remove', this.removePrimary);
this.compositions.forEach(c => {
c.composition.off('add', c.addCallback);
c.composition.off('remove', c.removeCallback);
});
}
}
</script>

View File

@@ -0,0 +1,56 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2018, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define([
'./LADTableViewProvider',
'./LADTableSetViewProvider'
], function (
LADTableViewProvider,
LADTableSetViewProvider
) {
return function plugin() {
return function install(openmct) {
openmct.objectViews.addProvider(new LADTableViewProvider(openmct));
openmct.objectViews.addProvider(new LADTableSetViewProvider(openmct));
openmct.types.addType('LadTable', {
name: "LAD Table",
creatable: true,
description: "A Latest Available Data tabular view in which each row displays the values for one or more contained telemetry objects.",
cssClass: 'icon-tabular-lad',
initialize(domainObject) {
domainObject.composition = [];
}
});
openmct.types.addType('LadTableSet', {
name: "LAD Table Set",
creatable: true,
description: "A Latest Available Data tabular view in which each row displays the values for one or more contained telemetry objects.",
cssClass: 'icon-tabular-lad-set',
initialize(domainObject) {
domainObject.composition = [];
}
});
};
};
});

View File

@@ -73,10 +73,13 @@ define([], function () {
return openmct.$injector.get('dialogService').getUserInput(form, {});
}
function getPath() {
return `configuration.items[${selection[0].context.index}]`;
}
let selectedParent = selection[1] && selection[1].context.item,
selectedObject = selection[0].context.item,
layoutItem = selection[0].context.layoutItem,
layoutItemIndex = selection[0].context.index,
toolbar = [];
if (selectedObject && selectedObject.type === 'layout') {
@@ -121,19 +124,102 @@ define([], function () {
return toolbar;
}
let path = `configuration.items[${layoutItemIndex}]`;
let separator = {
control: "separator"
};
let remove = {
control: "button",
domainObject: selectedParent,
icon: "icon-trash",
title: "Delete the selected object",
method: function () {
let removeItem = selection[1].context.removeItem;
let prompt = openmct.overlays.dialog({
iconClass: 'alert',
message: `Warning! This action will remove this item from the Display Layout. Do you want to continue?`,
buttons: [
{
label: 'Ok',
emphasis: 'true',
callback: function () {
removeItem(layoutItem, selection[0].context.index);
prompt.dismiss();
}
},
{
label: 'Cancel',
callback: function () {
prompt.dismiss();
}
}
]
});
}
};
let stackOrder = {
control: "menu",
domainObject: selectedParent,
icon: "icon-layers",
title: "Move the selected object above or below other objects",
options: [
{
name: "Move to Top",
value: "top",
class: "icon-arrow-double-up"
},
{
name: "Move Up",
value: "up",
class: "icon-arrow-up"
},
{
name: "Move Down",
value: "down",
class: "icon-arrow-down"
},
{
name: "Move to Bottom",
value: "bottom",
class: "icon-arrow-double-down"
}
],
method: function (option) {
selection[1].context.orderItem(option.value, selection[0].context.index);
}
};
let useGrid = {
control: "toggle-button",
domainObject: selectedParent,
property: function () {
return getPath() + ".useGrid";
},
options: [
{
value: false,
icon: "icon-grid-snap-no",
title: "Do not snap to grid"
},
{
value: true,
icon: "icon-grid-snap-to",
title: "Snap to grid"
}
]
};
if (layoutItem.type === 'subobject-view') {
if (toolbar.length > 0) {
toolbar.push(separator);
}
toolbar.push(stackOrder);
toolbar.push(separator);
toolbar.push({
control: "toggle-button",
domainObject: selectedParent,
property: path + ".hasFrame",
property: function () {
return getPath() + ".hasFrame";
},
options: [
{
value: false,
@@ -147,26 +233,36 @@ define([], function () {
}
]
});
toolbar.push(separator);
toolbar.push(useGrid);
toolbar.push(separator);
toolbar.push(remove);
} else {
const TEXT_SIZE = [9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 30, 36, 48, 72, 96];
let fill = {
control: "color-picker",
domainObject: selectedParent,
property: path + ".fill",
property: function () {
return getPath() + ".fill";
},
icon: "icon-paint-bucket",
title: "Set fill color"
},
stroke = {
control: "color-picker",
domainObject: selectedParent,
property: path + ".stroke",
property: function () {
return getPath() + ".stroke";
},
icon: "icon-line-horz",
title: "Set border color"
},
color = {
control: "color-picker",
domainObject: selectedParent,
property: path + ".color",
property: function () {
return getPath() + ".color";
},
icon: "icon-font",
mandatory: true,
title: "Set text color",
@@ -175,7 +271,9 @@ define([], function () {
size = {
control: "select-menu",
domainObject: selectedParent,
property: path + ".size",
property: function () {
return getPath() + ".size";
},
title: "Set text size",
options: TEXT_SIZE.map(size => {
return {
@@ -187,7 +285,9 @@ define([], function () {
control: "input",
type: "number",
domainObject: selectedParent,
property: path + ".x",
property: function () {
return getPath() + ".x";
},
label: "X:",
title: "X position"
},
@@ -195,7 +295,9 @@ define([], function () {
control: "input",
type: "number",
domainObject: selectedParent,
property: path + ".y",
property: function () {
return getPath() + ".y";
},
label: "Y:",
title: "Y position",
},
@@ -203,7 +305,9 @@ define([], function () {
control: 'input',
type: 'number',
domainObject: selectedParent,
property: path + ".width",
property: function () {
return getPath() + ".width";
},
label: 'W:',
title: 'Resize object width'
},
@@ -211,7 +315,9 @@ define([], function () {
control: 'input',
type: 'number',
domainObject: selectedParent,
property: path + ".height",
property: function () {
return getPath() + ".height";
},
label: 'H:',
title: 'Resize object height'
};
@@ -220,7 +326,9 @@ define([], function () {
let displayMode = {
control: "select-menu",
domainObject: selectedParent,
property: path + ".displayMode",
property: function () {
return getPath() + ".displayMode";
},
title: "Set display mode",
options: [
{
@@ -240,7 +348,9 @@ define([], function () {
value = {
control: "select-menu",
domainObject: selectedParent,
property: path + ".value",
property: function () {
return getPath() + ".value";
},
title: "Set value",
options: openmct.telemetry.getMetadata(selectedObject).values().map(value => {
return {
@@ -254,6 +364,7 @@ define([], function () {
separator,
value,
separator,
stackOrder,
fill,
stroke,
color,
@@ -263,66 +374,87 @@ define([], function () {
x,
y,
height,
width
width,
useGrid,
separator,
remove
];
} else if (layoutItem.type === 'text-view' ) {
let text = {
control: "button",
domainObject: selectedParent,
property: path,
property: function () {
return getPath();
},
icon: "icon-gear",
title: "Edit text properties",
dialog: DIALOG_FORM['text']
};
toolbar = [
stackOrder,
fill,
stroke,
color,
separator,
color,
size,
separator,
x,
y,
height,
width,
useGrid,
separator,
text
text,
separator,
remove
];
} else if (layoutItem.type === 'box-view') {
toolbar = [
stackOrder,
fill,
stroke,
separator,
x,
y,
height,
width
width,
useGrid,
separator,
remove
];
} else if (layoutItem.type === 'image-view') {
let url = {
control: "button",
domainObject: selectedParent,
property: path,
property: function () {
return getPath();
},
icon: "icon-image",
title: "Edit image properties",
dialog: DIALOG_FORM['image']
};
toolbar = [
stackOrder,
stroke,
separator,
x,
y,
height,
width,
useGrid,
separator,
url
url,
separator,
remove
];
} else if (layoutItem.type === 'line-view') {
let x2 = {
control: "input",
type: "number",
domainObject: selectedParent,
property: path + ".x2",
property: function () {
return getPath() + ".x2";
},
label: "X2:",
title: "X2 position"
},
@@ -330,17 +462,23 @@ define([], function () {
control: "input",
type: "number",
domainObject: selectedParent,
property: path + ".y2",
property: function () {
return getPath() + ".y2";
},
label: "Y2:",
title: "Y2 position",
};
toolbar = [
stackOrder,
stroke,
separator,
x,
y,
x2,
y2
y2,
useGrid,
separator,
remove
];
}
}

View File

@@ -25,6 +25,7 @@ define(function () {
return {
name: "Display Layout",
creatable: true,
description: 'Assemble other objects and components together into a reusable screen layout. Simply drag in the objects you want, position and size them. Save your design and view or edit it at any time.',
cssClass: 'icon-layout',
initialize(domainObject) {
domainObject.composition = [];

View File

@@ -54,7 +54,8 @@
x: 1,
y: 1,
width: 10,
height: 5
height: 5,
useGrid: true
};
},
inject: ['openmct'],
@@ -75,16 +76,22 @@
};
}
},
watch: {
index(newIndex) {
if (!this.context) {
return;
}
this.context.index = newIndex;
}
},
mounted() {
let context = {
this.context = {
layoutItem: this.item,
index: this.index
};
this.removeSelectable = this.openmct.selection.selectable(
this.$el,
context,
this.initSelect
);
this.$el, this.context, this.initSelect);
},
destroyed() {
if (this.removeSelectable) {

View File

@@ -25,29 +25,26 @@
@dragover="handleDragOver"
@click="bypassSelection"
@drop="handleDrop">
<div class="l-layout__object">
<!-- Background grid -->
<div class="l-layout__grid-holder c-grid"
v-if="!drilledIn">
<div class="c-grid__x l-grid l-grid-x"
v-if="gridSize[0] >= 3"
:style="[{ backgroundSize: gridSize[0] + 'px 100%' }]">
</div>
<div class="c-grid__y l-grid l-grid-y"
v-if="gridSize[1] >= 3"
:style="[{ backgroundSize: '100%' + gridSize[1] + 'px' }]"></div>
<!-- Background grid -->
<div class="l-layout__grid-holder c-grid">
<div class="c-grid__x l-grid l-grid-x"
v-if="gridSize[0] >= 3"
:style="[{ backgroundSize: gridSize[0] + 'px 100%' }]">
</div>
<component v-for="(item, index) in layoutItems"
:is="item.type"
:item="item"
:gridSize="gridSize"
:initSelect="initSelectIndex === index"
:index="index"
@drilledIn="updateDrilledIn"
@endDrag="endDrag"
>
</component>
<div class="c-grid__y l-grid l-grid-y"
v-if="gridSize[1] >= 3"
:style="[{ backgroundSize: '100%' + gridSize[1] + 'px' }]"></div>
</div>
<component v-for="(item, index) in layoutItems"
:is="item.type"
:item="item"
:key="item.id"
:gridSize="item.useGrid ? gridSize : [1, 1]"
:initSelect="initSelectIndex === index"
:index="index"
@endDrag="endDrag"
>
</component>
</div>
</template>
@@ -58,30 +55,47 @@
@include abs();
display: flex;
flex-direction: column;
overflow: auto;
&__grid-holder {
display: none;
}
&__object {
flex: 1 1 auto;
overflow: auto;
}
&__frame {
position: absolute;
}
}
.l-shell__main-container {
> .l-layout {
[s-selected] {
border: $browseBorderSelected;
.is-editing {
.l-shell__main-container {
&[s-selected],
&[s-selected-parent] {
// Display grid in main layout holder when editing
> .l-layout {
background: $editUIGridColorBg;
> [class*="__grid-holder"] {
display: block;
}
}
}
}
.l-layout__frame {
&[s-selected],
&[s-selected-parent] {
// Display grid in nested layouts when editing
> * > * > .l-layout {
background: $editUIGridColorBg;
box-shadow: inset $editUIGridColorFg 0 0 2px 1px;
> [class*='grid-holder'] {
display: block;
}
}
}
}
}
// Styles moved to _global.scss;
</style>
@@ -103,6 +117,12 @@
'text-view': TextView,
'image-view': ImageView
};
const ORDERS = {
top: Number.POSITIVE_INFINITY,
up: 1,
down: -1,
bottom: Number.NEGATIVE_INFINITY
};
function getItemDefinition(itemType, ...options) {
let itemView = ITEM_TYPE_VIEW_MAP[itemType];
@@ -118,7 +138,6 @@
data() {
let domainObject = JSON.parse(JSON.stringify(this.domainObject));
return {
drilledIn: undefined,
internalDomainObject: domainObject,
initSelectIndex: undefined
};
@@ -143,8 +162,52 @@
return;
}
if (this.removeSelectionListener) {
this.removeSelectionListener();
}
let itemIndex = selection[0].context.index;
if (itemIndex !== undefined) {
this.attachSelectionListener(itemIndex);
}
this.updateDrilledIn();
},
attachSelectionListener(index) {
let path = `configuration.items[${index}].useGrid`;
this.removeSelectionListener = this.openmct.objects.observe(this.internalDomainObject, path, function (value) {
let item = this.layoutItems[index];
if (value) {
item.x = Math.round(item.x / this.gridSize[0]);
item.y = Math.round(item.y / this.gridSize[1]);
item.width = Math.round(item.width / this.gridSize[0]);
item.height = Math.round(item.height / this.gridSize[1]);
if (item.x2) {
item.x2 = Math.round(item.x2 / this.gridSize[0]);
}
if (item.y2) {
item.y2 = Math.round(item.y2 / this.gridSize[1]);
}
} else {
item.x = this.gridSize[0] * item.x;
item.y = this.gridSize[1] * item.y;
item.width = this.gridSize[0] * item.width;
item.height = this.gridSize[1] * item.height;
if (item.x2) {
item.x2 = this.gridSize[0] * item.x2;
}
if (item.y2) {
item.y2 = this.gridSize[1] * item.y2;
}
}
item.useGrid = value;
this.mutate(`configuration.items[${index}]`, item);
}.bind(this));
},
updateDrilledIn(drilledInItem) {
let identifier = drilledInItem && this.openmct.objects.makeKeyString(drilledInItem.identifier);
this.drilledIn = identifier;
@@ -176,13 +239,13 @@
this.openmct.objects.mutate(this.internalDomainObject, path, value);
},
handleDrop($event) {
if (!$event.dataTransfer.types.includes('openmct/domain-object')) {
if (!$event.dataTransfer.types.includes('openmct/domain-object-path')) {
return;
}
$event.preventDefault();
let domainObject = JSON.parse($event.dataTransfer.getData('openmct/domain-object'));
let domainObject = JSON.parse($event.dataTransfer.getData('openmct/domain-object-path'))[0];
let elementRect = this.$el.getBoundingClientRect();
let droppedObjectPosition = [
Math.floor(($event.pageX - elementRect.left) / this.gridSize[0]),
@@ -226,17 +289,58 @@
addItem(itemType, ...options) {
let item = getItemDefinition(itemType, this.openmct, this.gridSize, ...options);
item.type = itemType;
item.id = uuid();
this.trackItem(item);
this.layoutItems.push(item);
this.openmct.objects.mutate(this.internalDomainObject, "configuration.items", this.layoutItems);
this.initSelectIndex = this.layoutItems.length - 1;
},
trackItem(item) {
if (item.type === "telemetry-view") {
this.telemetryViewMap[this.openmct.objects.makeKeyString(item.identifier)] = true;
} else if (item.type === "subobject-view") {
this.objectViewMap[this.openmct.objects.makeKeyString(item.identifier)] = true;
if (!item.identifier) {
return;
}
let keyString = this.openmct.objects.makeKeyString(item.identifier);
if (item.type === "telemetry-view") {
let count = this.telemetryViewMap[keyString] || 0;
this.telemetryViewMap[keyString] = ++count;
} else if (item.type === "subobject-view") {
this.objectViewMap[keyString] = true;
}
},
removeItem(item, index) {
this.initSelectIndex = -1;
this.layoutItems.splice(index, 1);
this.mutate("configuration.items", this.layoutItems);
this.untrackItem(item);
this.$el.click();
},
untrackItem(item) {
if (!item.identifier) {
return;
}
let keyString = this.openmct.objects.makeKeyString(item.identifier);
if (item.type === 'telemetry-view') {
let count = --this.telemetryViewMap[keyString];
if (count === 0) {
delete this.telemetryViewMap[keyString];
this.removeFromComposition(keyString);
}
} else if (item.type === 'subobject-view') {
delete this.objectViewMap[keyString];
this.removeFromComposition(keyString);
}
},
removeFromComposition(keyString) {
let composition = _.get(this.internalDomainObject, 'composition');
composition = composition.filter(identifier => {
return this.openmct.objects.makeKeyString(identifier) !== keyString;
});
this.mutate("composition", composition);
},
initializeItems() {
this.telemetryViewMap = {};
@@ -254,14 +358,48 @@
}
},
removeChild(identifier) {
// TODO: implement
let keyString = this.openmct.objects.makeKeyString(identifier);
if (this.objectViewMap[keyString]) {
delete this.objectViewMap[keyString];
this.removeFromConfiguration(keyString);
} else if (this.telemetryViewMap[keyString]) {
delete this.telemetryViewMap[keyString];
this.removeFromConfiguration(keyString);
}
},
removeFromConfiguration(keyString) {
let layoutItems = this.layoutItems.filter(item => {
if (!item.identifier) {
return true;
} else {
return this.openmct.objects.makeKeyString(item.identifier) !== keyString;
}
});
this.mutate("configuration.items", layoutItems);
this.$el.click();
},
orderItem(position, index) {
let delta = ORDERS[position];
let newIndex = Math.max(Math.min(index + delta, this.layoutItems.length - 1), 0);
let item = this.layoutItems[index];
if (newIndex !== index) {
this.layoutItems.splice(index, 1);
this.layoutItems.splice(newIndex, 0, item);
this.mutate('configuration.items', this.layoutItems);
if (this.removeSelectionListener) {
this.removeSelectionListener();
this.attachSelectionListener(newIndex);
}
}
}
},
mounted() {
this.unlisten = this.openmct.objects.observe(this.internalDomainObject, '*', function (obj) {
this.internalDomainObject = JSON.parse(JSON.stringify(obj));
}.bind(this));
this.openmct.selection.on('change', this.setSelection);
this.initializeItems();
this.composition = this.openmct.composition.get(this.internalDomainObject);
@@ -274,7 +412,10 @@
this.composition.off('add', this.addChild);
this.composition.off('remove', this.removeChild);
this.unlisten();
if (this.removeSelectionListener) {
this.removeSelectionListener();
}
}
}
</script>

View File

@@ -56,7 +56,8 @@
y: 1,
width: 10,
height: 5,
url: element.url
url: element.url,
useGrid: true
};
},
inject: ['openmct'],
@@ -77,13 +78,22 @@
}
}
},
watch: {
index(newIndex) {
if (!this.context) {
return;
}
this.context.index = newIndex;
}
},
mounted() {
let context = {
this.context = {
layoutItem: this.item,
index: this.index
};
this.removeSelectable = this.openmct.selection.selectable(
this.$el, context, this.initSelect);
this.$el, this.context, this.initSelect);
},
destroyed() {
if (this.removeSelectable) {

View File

@@ -21,29 +21,28 @@
*****************************************************************************/
<template>
<div class="l-layout__frame c-frame has-local-controls"
<div class="l-layout__frame c-frame"
:class="{
'no-frame': !item.hasFrame,
'u-inspectable': inspectable,
'is-drilled-in': item.drilledIn
'is-resizing': isResizing
}"
:style="style"
@dblclick="drill($event)">
:style="style">
<slot></slot>
<!-- Drag handles -->
<div class="c-frame-edit">
<div class="c-frame-edit__move"
@mousedown="startDrag([1,1], [0,0], $event)"></div>
@mousedown="startDrag([1,1], [0,0], $event, 'move')"></div>
<div class="c-frame-edit__handle c-frame-edit__handle--nw"
@mousedown="startDrag([1,1], [-1,-1], $event)"></div>
@mousedown="startDrag([1,1], [-1,-1], $event, 'resize')"></div>
<div class="c-frame-edit__handle c-frame-edit__handle--ne"
@mousedown="startDrag([0,1], [1,-1], $event)"></div>
@mousedown="startDrag([0,1], [1,-1], $event, 'resize')"></div>
<div class="c-frame-edit__handle c-frame-edit__handle--sw"
@mousedown="startDrag([1,0], [-1,1], $event)"></div>
@mousedown="startDrag([1,0], [-1,1], $event, 'resize')"></div>
<div class="c-frame-edit__handle c-frame-edit__handle--se"
@mousedown="startDrag([0,0], [1,1], $event)"></div>
@mousedown="startDrag([0,0], [1,1], $event, 'resize')"></div>
</div>
</div>
</template>
@@ -55,20 +54,167 @@
.c-frame {
display: flex;
flex-direction: column;
border: 1px solid transparent;
/*************************** NO-FRAME */
&.no-frame {
> [class*="contents"] > [class*="__header"] {
display: none;
}
// Whatever is placed into the slot, make it fill the entirety of the space, obeying padding
> *:first-child {
flex: 1 1 auto;
}
&:not(.no-frame) {
background: $colorBodyBg;
border: 1px solid $colorInteriorBorder;
border: $browseFrameBorder;
padding: $interiorMargin;
}
}
.c-frame-edit {
// In Layouts, this is the editing rect and handles
// In Fixed Position, this is a wrapper element
@include abs();
display: none;
&__move {
@include abs();
cursor: move;
}
&__handle {
$d: 6px;
$o: floor($d * -0.5);
background: $editFrameColorHandleFg;
box-shadow: $editFrameColorHandleBg 0 0 0 2px;
display: none; // Set to block via s-selected selector
position: absolute;
width: $d; height: $d;
top: auto; right: auto; bottom: auto; left: auto;
&:before {
// Extended hit area
@include abs(-10px);
content: '';
display: block;
z-index: 0;
}
&:hover {
background: $editUIColor;
}
&--nwse {
cursor: nwse-resize;
}
&--nw {
cursor: nw-resize;
left: $o; top: $o;
}
&--ne {
cursor: ne-resize;
right: $o; top: $o;
}
&--se {
cursor: se-resize;
right: $o; bottom: $o;
}
&--sw {
cursor: sw-resize;
left: $o; bottom: $o;
}
}
}
.c-so-view.has-complex-content + .c-frame-edit {
// Target frames that hold domain objects that include header elements, as opposed to drawing and alpha objects
// Make the __move element a more affordable drag UI element
.c-frame-edit__move {
@include userSelectNone();
background: $editFrameMovebarColorBg;
box-shadow: rgba(black, 0.2) 0 1px;
bottom: auto;
height: 0; // Height is set on hover on s-selected.c-frame
opacity: 0.8;
max-height: 100%;
overflow: hidden;
text-align: center;
&:before {
// Grippy
$h: 4px;
$tbOffset: ($editFrameMovebarH - $h) / 2;
$lrOffset: 25%;
@include grippy($editFrameMovebarColorFg);
content: '';
display: block;
position: absolute;
top: $tbOffset; right: $lrOffset; bottom: $tbOffset; left: $lrOffset;
}
&:hover {
background: $editFrameHovMovebarColorBg;
&:before { @include grippy($editFrameHovMovebarColorFg); }
}
}
}
.is-editing {
.c-frame {
$moveBarOutDelay: 500ms;
&.no-frame {
border: $editFrameBorder; // Base border style for a frame element while editing.
}
&-edit {
display: contents;
}
&-edit__move,
.c-so-view {
transition: $transOut;
transition-delay: $moveBarOutDelay;
}
&:not([s-selected]) {
&:hover {
border: $editFrameBorderHov;
}
}
&[s-selected] {
// All frames selected while editing
border: $editFrameSelectedBorder;
box-shadow: $editFrameSelectedShdw;
> .c-frame-edit {
[class*='__handle'] {
display: block;
}
}
}
}
.l-layout__frame:not(.is-resizing) {
// Show and animate the __move bar for sub-object views with complex content
&:hover > .c-so-view.has-complex-content {
// Move content down so the __move bar doesn't cover it.
padding-top: $editFrameMovebarH;
transition: $transIn;
&.c-so-view--no-frame {
// Move content down with a bit more space
padding-top: $editFrameMovebarH + $interiorMarginSm;
}
// Show the move bar
+ .c-frame-edit .c-frame-edit__move {
height: $editFrameMovebarH;
transition: $transIn;
}
}
}
}
</style>
@@ -84,7 +230,8 @@
},
data() {
return {
dragPosition: undefined
dragPosition: undefined,
isResizing: undefined
}
},
computed: {
@@ -110,24 +257,6 @@
}
},
methods: {
drill($event) {
if ($event) {
$event.stopPropagation();
}
if (!this.openmct.editor.isEditing() || !this.item.identifier) {
return;
}
this.openmct.objects.get(this.item.identifier)
.then(domainObject => {
if (this.openmct.composition.get(domainObject) === undefined) {
return;
}
this.$emit('drilledIn', this.item);
});
},
updatePosition(event) {
let currentPosition = [event.pageX, event.pageY];
this.initialPosition = this.initialPosition || currentPosition;
@@ -135,7 +264,7 @@
return value - this.initialPosition[index];
}.bind(this));
},
startDrag(posFactor, dimFactor, event) {
startDrag(posFactor, dimFactor, event, type) {
document.body.addEventListener('mousemove', this.continueDrag);
document.body.addEventListener('mouseup', this.endDrag);
@@ -145,6 +274,7 @@
};
this.updatePosition(event);
this.activeDrag = new LayoutDrag(this.dragPosition, posFactor, dimFactor, this.gridSize);
this.isResizing = type === 'resize';
event.preventDefault();
},
continueDrag(event) {
@@ -162,6 +292,7 @@
this.dragPosition = undefined;
this.initialPosition = undefined;
this.delta = undefined;
this.isResizing = undefined;
event.preventDefault();
}
}

View File

@@ -21,10 +21,9 @@
*****************************************************************************/
<template>
<div class="l-layout__frame c-frame has-local-controls no-frame"
<div class="l-layout__frame c-frame no-frame"
:style="style">
<svg width="100%"
height="100%">
<svg width="100%" height="100%">
<line v-bind="linePosition"
:stroke="item.stroke"
stroke-width="2">
@@ -67,7 +66,8 @@
y: 10,
x2: 10,
y2: 5,
stroke: '#717171'
stroke: '#717171',
useGrid: true
};
},
inject: ['openmct'],
@@ -101,9 +101,6 @@
top: `${top}px`,
width: `${width}px`,
height: `${height}px`,
minWidth: `${width}px`,
minHeight: `${height}px`,
position: 'absolute'
};
},
startHandleClass() {
@@ -210,17 +207,22 @@
return dragPosition;
}
},
watch: {
index(newIndex) {
if (!this.context) {
return;
}
this.context.index = newIndex;
}
},
mounted() {
let context = {
this.context = {
layoutItem: this.item,
index: this.index
};
this.removeSelectable = this.openmct.selection.selectable(
this.$el,
context,
this.initSelect
);
this.$el, this.context, this.initSelect);
},
destroyed() {
if (this.removeSelectable) {

View File

@@ -22,8 +22,7 @@
<template>
<layout-frame :item="item"
:grid-size="gridSize"
@endDrag="(item, updates) => $emit('endDrag', item, updates)"
@drilledIn="item => $emit('drilledIn', item)">
@endDrag="(item, updates) => $emit('endDrag', item, updates)">
<object-frame v-if="domainObject"
:domain-object="domainObject"
:object-path="objectPath"
@@ -65,7 +64,8 @@
x: position[0],
y: position[1],
identifier: domainObject.identifier,
hasFrame: hasFrameByDefault(domainObject.type)
hasFrame: hasFrameByDefault(domainObject.type),
useGrid: true
};
},
inject: ['openmct'],
@@ -85,21 +85,29 @@
ObjectFrame,
LayoutFrame
},
watch: {
index(newIndex) {
if (!this.context) {
return;
}
this.context.index = newIndex;
}
},
methods: {
setObject(domainObject) {
this.domainObject = domainObject;
this.objectPath = [this.domainObject].concat(this.openmct.router.path);
let context = {
this.context = {
item: domainObject,
layoutItem: this.item,
index: this.index
};
this.removeSelectable = this.openmct.selection.selectable(
this.$el, context, this.initSelect);
this.$el, this.context, this.initSelect);
}
},
mounted() {
console.log(this.item);
this.openmct.objects.get(this.item.identifier)
.then(this.setObject);
},

View File

@@ -99,6 +99,7 @@
fill: "",
color: "",
size: "13px",
useGrid: true
};
},
inject: ['openmct'],
@@ -160,6 +161,15 @@
domainObject: undefined
}
},
watch: {
index(newIndex) {
if (!this.context) {
return;
}
this.context.index = newIndex;
}
},
methods: {
requestHistoricalData() {
let bounds = this.openmct.time.bounds();
@@ -205,13 +215,13 @@
this.requestHistoricalData();
this.subscribeToObject();
let context = {
this.context = {
item: domainObject,
layoutItem: this.item,
index: this.index
};
this.removeSelectable = this.openmct.selection.selectable(
this.$el, context, this.initSelect);
this.$el, this.context, this.initSelect);
}
},
mounted() {

View File

@@ -59,7 +59,8 @@
y: 1,
width: 10,
height: 5,
text: element.text
text: element.text,
useGrid: true
};
},
inject: ['openmct'],
@@ -82,13 +83,22 @@
};
}
},
watch: {
index(newIndex) {
if (!this.context) {
return;
}
this.context.index = newIndex;
}
},
mounted() {
let context = {
this.context = {
layoutItem: this.item,
index: this.index
};
this.removeSelectable = this.openmct.selection.selectable(
this.$el, context, this.initSelect);
this.$el, this.context, this.initSelect);
},
destroyed() {
if (this.removeSelectable) {

View File

@@ -33,6 +33,9 @@ export default function () {
canView: function (domainObject) {
return domainObject.type === 'layout';
},
canEdit: function (domainObject) {
return domainObject.type === 'layout';
},
view: function (domainObject) {
let component;
return {
@@ -57,7 +60,9 @@ export default function () {
getSelectionContext() {
return {
item: domainObject,
addElement: component && component.$refs.displayLayout.addElement
addElement: component && component.$refs.displayLayout.addElement,
removeItem: component && component.$refs.displayLayout.removeItem,
orderItem: component && component.$refs.displayLayout.orderItem
}
},
destroy() {

View File

@@ -24,7 +24,7 @@
<div class="c-fl-container"
:style="[{'flex-basis': sizeString}]"
:class="{'is-empty': !frames.length}">
<div class="c-fl-container__header icon-grippy-ew"
<div class="c-fl-container__header"
v-show="isEditing"
draggable="true"
@dragstart="startContainerDrag">
@@ -100,7 +100,7 @@ export default {
},
methods: {
allowDrop(event, index) {
if (event.dataTransfer.getData('openmct/domain-object')) {
if (event.dataTransfer.types.includes('openmct/domain-object-path')) {
return true;
}
let frameId = event.dataTransfer.getData('frameid'),
@@ -124,9 +124,9 @@ export default {
}
},
moveOrCreateFrame(insertIndex, event) {
if (event.dataTransfer.types.includes('openmct/domain-object')) {
if (event.dataTransfer.types.includes('openmct/domain-object-path')) {
// create frame using domain object
let domainObject = JSON.parse(event.dataTransfer.getData('openmct/domain-object'));
let domainObject = JSON.parse(event.dataTransfer.getData('openmct/domain-object-path'))[0];
this.$emit(
'create-frame',
this.index,

View File

@@ -79,6 +79,22 @@
<style lang="scss">
@import '~styles/sass-base';
@mixin containerGrippy($headerSize, $dir) {
position: absolute;
$h: 6px;
$minorOffset: ($headerSize - $h) / 2;
$majorOffset: 35%;
content: '';
display: block;
position: absolute;
@include grippy($c: $editFrameSelectedMovebarColorFg, $dir: $dir);
@if $dir == 'x' {
top: $minorOffset; right: $majorOffset; bottom: $minorOffset; left: $majorOffset;
} @else {
top: $majorOffset; right: $minorOffset; bottom: $majorOffset; left: $minorOffset;
}
}
.c-fl {
@include abs();
@@ -100,7 +116,6 @@
> * + * { margin-left: 1px; }
&[class*='--rows'] {
//@include test(blue, 0.1);
flex-direction: column;
> * + * {
margin-left: 0;
@@ -128,7 +143,6 @@
/***************************************************** CONTAINERS */
$headerSize: 16px;
border: 1px solid transparent;
display: flex;
flex-direction: column;
overflow: auto;
@@ -138,9 +152,9 @@
flex-shrink: 1;
&__header {
// Only displayed when editing
background: $editSelectableColor;
color: $editSelectableColorFg;
// Only displayed when editing, controlled via JS
background: $editFrameMovebarColorBg;
color: $editFrameMovebarColorFg;
cursor: move;
display: flex;
align-items: center;
@@ -148,12 +162,8 @@
&:before {
// Drag grippy
font-size: 0.8em;
@include containerGrippy($headerSize, 'x');
opacity: 0.5;
position: absolute;
left: 50%; top: 50%;
transform-origin: center;
transform: translate(-50%, -50%);
}
}
@@ -173,19 +183,27 @@
}
.is-editing & {
//background: $editCanvasColorBg;
border-color: $editSelectableColor;
&:hover {
border-color: $editSelectableColorHov;
.c-fl-container__header {
background: $editFrameHovMovebarColorBg;
color: $editFrameHovMovebarColorFg;
&:before {
opacity: .75;
}
}
}
&[s-selected] {
border-color: $editSelectableColorSelected;
border: $editFrameSelectedBorder;
.c-fl-container__header {
background: $editSelectableColorSelected;
color: $editSelectableColorSelectedFg;
background:$editFrameSelectedMovebarColorBg;
color: $editFrameSelectedMovebarColorFg;
&:before {
// Grippy
opacity: 1;
}
}
}
}
@@ -194,11 +212,6 @@
// Frames get styled here because this is particular to their presence in this layout type
.c-fl-frame {
@include browserPrefix(margin-collapse, collapse);
margin: 1px;
//&__drag-wrapper {
// border: 1px solid $colorInteriorBorder; // Now handled by is-selectable
//}
}
/****** ROWS LAYOUT */
@@ -211,8 +224,8 @@
overflow: hidden;
&:before {
// Drag grippy
transform: rotate(90deg) translate(-50%, 50%);
// Grippy
@include containerGrippy($headerSize, 'y');
}
}
@@ -235,8 +248,6 @@
$dropHintSize: 15px;
display: flex;
// justify-content: stretch;
// align-items: stretch;
flex: 1 1;
flex-direction: column;
overflow: hidden; // Needed to allow frames to collapse when sized down
@@ -275,7 +286,6 @@
pointer-events: none;
text-align: center;
width: $size;
z-index: 2;
// Changed when layout is different, see below
border-top-right-radius: $controlCr;
@@ -304,37 +314,16 @@
&:before {
// The visible resize line
background: $editColor;
background: $editUIColor;
content: '';
display: block;
flex: 1 1 auto;
min-height: $size; min-width: $size;
}
&__grippy {
// Grippy element
$d: 4px;
$c: black;
$a: 0.9;
$d: 5px;
background: $editColor;
color: $editColorBg;
border-radius: $smallCr;
font-size: 0.8em;
height: $d;
width: $d * 10;
position: absolute;
left: 50%; top: 50%;
text-align: center;
transform-origin: center center;
transform: translate(-50%, -50%);
z-index: 10;
}
&.vertical {
padding: $margin $size;
&:hover{
// padding: $marginHov 0;
cursor: row-resize;
}
}
@@ -342,20 +331,15 @@
&.horizontal {
padding: $size $margin;
&:hover{
// padding: 0 $marginHov;
cursor: col-resize;
}
[class*='grippy'] {
transform: translate(-50%) rotate(90deg);
}
}
&:hover {
transition: $transOut;
&:before {
// The visible resize line
background: $editColorHov;
background: $editUIColorHov;
}
}
}

View File

@@ -26,7 +26,7 @@
'flex-basis': `${frame.size}%`
}">
<div class="c-frame c-fl-frame__drag-wrapper is-selectable is-moveable"
<div class="c-frame c-fl-frame__drag-wrapper is-selectable u-inspectable is-moveable"
draggable="true"
@dragstart="initDrag"
ref="frame">

View File

@@ -35,6 +35,9 @@ define([
canView: function (domainObject) {
return domainObject.type === 'flexible-layout';
},
canEdit: function (domainObject) {
return domainObject.type === 'flexible-layout';
},
view: function (domainObject) {
let component;

View File

@@ -30,7 +30,7 @@ define([
function FolderGridView(openmct) {
return {
key: 'grid',
name: 'Grid Vue',
name: 'Grid View',
cssClass: 'icon-thumbs-strip',
canView: function (domainObject) {
return domainObject.type === 'folder';

View File

@@ -32,7 +32,7 @@ define([
function FolderListView(openmct) {
return {
key: 'list-view',
name: 'List Vue',
name: 'List View',
cssClass: 'icon-list-view',
canView: function (domainObject) {
return domainObject.type === 'folder';

View File

@@ -42,7 +42,8 @@
</tr>
</thead>
<tbody>
<list-item v-for="(item,index) in sortedItems"
<list-item v-for="item in sortedItems"
:key="item.objectKeyString"
:item="item"
:object-path="item.objectPath">
</list-item>
@@ -99,9 +100,20 @@ export default {
mixins: [compositionLoader],
inject: ['domainObject', 'openmct'],
data() {
let sortBy = 'model.name',
ascending = true,
persistedSortOrder = window.localStorage.getItem('openmct-listview-sort-order');
if (persistedSortOrder) {
let parsed = JSON.parse(persistedSortOrder);
sortBy = parsed.sortBy;
ascending = parsed.ascending;
}
return {
sortBy: 'model.name',
ascending: true
sortBy,
ascending
};
},
computed: {
@@ -121,6 +133,17 @@ export default {
this.sortBy = field;
this.ascending = defaultDirection;
}
window.localStorage
.setItem(
'openmct-listview-sort-order',
JSON.stringify(
{
sortBy: this.sortBy,
ascending: this.ascending
}
)
);
}
}
}

View File

@@ -35,7 +35,8 @@ export default {
model: child,
type: type.definition,
isAlias: this.domainObject.identifier.key !== child.location,
objectPath: [child].concat(openmct.router.path)
objectPath: [child].concat(this.openmct.router.path),
objectKeyString: this.openmct.objects.makeKeyString(child.identifier)
});
},
remove(identifier) {

View File

@@ -28,7 +28,7 @@
</div>
<div class="c-ne__local-controls--hidden">
<button class="c-click-icon icon-trash"
<button class="c-click-icon c-click-icon--major icon-trash"
title="Delete this entry"
v-on:click="deleteEntry"></button>
</div>

View File

@@ -107,10 +107,10 @@ function (
EntryController.prototype.dropOnEntry = function (entryid, event) {
var data = event.dataTransfer.getData('openmct/domain-object');
var data = event.dataTransfer.getData('openmct/domain-object-path');
if (data) {
var selectedObject = JSON.parse(data),
var selectedObject = JSON.parse(data)[0],
selectedObjectId = selectedObject.identifier.key,
cssClass = this.openmct.types.get(selectedObject.type),
entryPos = this.entryPosById(entryid),

View File

@@ -120,8 +120,8 @@ function (
var date = Date.now(),
embed;
if (event.dataTransfer && event.dataTransfer.getData('openmct/domain-object')) {
var selectedObject = JSON.parse(event.dataTransfer.getData('openmct/domain-object')),
if (event.dataTransfer && event.dataTransfer.getData('openmct/domain-object-path')) {
var selectedObject = JSON.parse(event.dataTransfer.getData('openmct/domain-object-path'))[0],
selectedObjectId = selectedObject.identifier.key,
cssClass = this.openmct.types.get(selectedObject.type);

View File

@@ -20,13 +20,13 @@
at runtime from the About dialog for additional information.
-->
<div class="gl-plot plot-legend-{{legend.get('position')}} {{legend.get('expanded')? 'plot-legend-expanded' : 'plot-legend-collapsed'}}">
<div class="gl-plot-legend flex-elem l-flex-row"
<div class="gl-plot-legend"
ng-class="{ 'hover-on-plot': !!highlights.length }"
ng-show="legend.get('position') !== 'hidden'">
<span class="view-control flex-elem"
ng-class="{ expanded: legend.get('expanded') }"
<div class="gl-plot-legend__view-control c-disclosure-triangle is-enabled"
ng-class="{ 'c-disclosure-triangle--expanded': legend.get('expanded') }"
ng-click="legend.set('expanded', !legend.get('expanded'));">
</span>
</div>
<!-- COLLAPSED PLOT LEGEND -->
<div class="plot-wrapper-collapsed-legend">
@@ -52,7 +52,7 @@
</div>
<!-- EXPANDED PLOT LEGEND -->
<div class="plot-wrapper-expanded-legend flex-elem grows">
<div class="plot-wrapper-expanded-legend">
<table>
<thead>
<tr>
@@ -133,7 +133,9 @@
ng-style="{
left: (tickWidth + 30) + 'px'
}">
<span class="t-object-alert t-alert-unsynced" title="This plot is not currently displaying the latest data. Reset Pan/zoom to return to view latest data."></span>
<span class="t-object-alert t-alert-unsynced"
title="This plot is not currently displaying the latest data.
Reset Pan/zoom to return to view latest data."></span>
<div class="gl-plot-display-area">
<mct-ticks axis="xAxis">
<div class="gl-plot-hash hash-v"

View File

@@ -20,20 +20,20 @@
at runtime from the About dialog for additional information.
-->
<div ng-controller="PlotOptionsController">
<ul class="tree">
<ul class="tree c-tree">
<h2 title="Plot series display properties in this object">Plot Series</h2>
<li ng-repeat="series in config.series.models">
<span class="tree-item menus-to-left">
<span class='ui-symbol view-control flex-elem'
ng-class="{ expanded: series.expanded }"
<div class="c-tree__item menus-to-left">
<span class='c-disclosure-triangle is-enabled flex-elem'
ng-class="{ 'c-disclosure-triangle--expanded': series.expanded }"
ng-click="series.expanded = !series.expanded">
</span>
<mct-representation
class="rep-object-label"
class="rep-object-label c-tree__item__label"
key="'label'"
mct-object="series.oldObject">
</mct-representation>
</span>
</div>
<ul class="grid-properties" ng-show="series.expanded">
<li class="grid-row">
<div class="grid-cell label"
@@ -70,17 +70,9 @@
<div class="grid-cell label"
title="The plot line and marker color for this series.">Color</div>
<div class="grid-cell value">
<!-- TODO: get this into a class -->
<span class="color-swatch"
<span class="c-color-swatch"
ng-style="{
'background': series.get('color').asHexString(),
'display': 'inline-block',
'border': '1px solid rgba(255, 255, 255, 0.2)',
'height': '10px',
'width': '10px',
'vertical-align': 'middle',
'margin-left': '3px',
'margin-top': -'2px'
'background': series.get('color').asHexString()
}">
</span>
</div>

View File

@@ -20,21 +20,21 @@
at runtime from the About dialog for additional information.
-->
<div ng-controller="PlotOptionsController">
<ul class="tree l-inspector-part">
<h2 title="Display properties for this object">Plot Series Options</h2>
<ul class="tree c-tree">
<h2 title="Display properties for this object">Plot Series</h2>
<li ng-repeat="series in plotSeries"
ng-controller="PlotSeriesFormController"
form-model="series">
<span class="tree-item menus-to-left">
<span class='ui-symbol view-control flex-elem'
ng-class="{ expanded: expanded }"
<div class="c-tree__item menus-to-left">
<span class='c-disclosure-triangle is-enabled flex-elem'
ng-class="{ 'c-disclosure-triangle--expanded': expanded }"
ng-click="expanded = !expanded">
</span>
<mct-representation class="rep-object-label"
<mct-representation class="rep-object-label c-tree__item__label"
key="'label'"
mct-object="series.oldObject">
</mct-representation>
</span>
</div>
<ul class="grid-properties" ng-show="expanded">
<li class="grid-row">
<!-- Value to be displayed -->
@@ -78,7 +78,7 @@
<li class="grid-row" ng-show="form.markers || form.alarmMarkers">
<div class="grid-cell label"
title="The size of regular and alarm markers for this series.">Marker Size:</div>
<div class="grid-cell value"><input class="sm" type="text" ng-model="form.markerSize"/></div>
<div class="grid-cell value"><input class="c-input--flex" type="text" ng-model="form.markerSize"/></div>
</li>
<li class="grid-row"
ng-controller="ClickAwayController as toggle"
@@ -86,14 +86,14 @@
<div class="grid-cell label"
title="Manually set the plot line and marker color for this series.">Color</div>
<div class="grid-cell value">
<div class="s-menu-button" ng-click="toggle.toggle()">
<span class="color-swatch" ng-style="{ background: series.get('color').asHexString() }">
<div class="c-click-swatch c-click-swatch--menu" ng-click="toggle.toggle()">
<span class="c-color-swatch"
ng-style="{ background: series.get('color').asHexString() }">
</span>
</div>
<div class="l-inline-palette" ng-show="toggle.isActive()">
<!-- TODO: redo this as a grid -->
<div class="l-palette-row" ng-repeat="group in config.series.palette.groups()">
<div class="l-palette-item s-palette-item"
<div class="c-palette--inline c-palette__items" ng-show="toggle.isActive()">
<div class="u-contents" ng-repeat="group in config.series.palette.groups()">
<div class="c-palette__item"
ng-repeat="color in group"
ng-class="{ 'selected': series.get('color').equalTo(color) }"
ng-style="{ background: color.asHexString() }"
@@ -115,7 +115,7 @@
<li class="grid-row">
<div class="grid-cell label"
title="Manually override how the Y axis is labeled.">Label</div>
<div class="grid-cell value"><input class="control" type="text" ng-model="form.label"/></div>
<div class="grid-cell value"><input class="c-input--flex" type="text" ng-model="form.label"/></div>
</li>
</ul>
<ul class="l-inspector-part">
@@ -130,7 +130,7 @@
title="Percentage of padding above and below plotted min and max values. 0.1, 1.0, etc.">
Padding</div>
<div class="grid-cell value">
<input class="sm" type="text" ng-model="form.autoscalePadding"/>
<input class="c-input--flex" type="text" ng-model="form.autoscalePadding"/>
</div>
</li>
</ul>
@@ -143,13 +143,13 @@
<div class="grid-cell label"
title="Minimum Y axis value.">Minimum Value</div>
<div class="grid-cell value">
<input class="sm" type="number" ng-model="form.range.min"/>
<input class="c-input--flex" type="number" ng-model="form.range.min"/>
</div>
</li>
<li class="grid-row">
<div class="grid-cell label"
title="Maximum Y axis value.">Maximum Value</div>
<div class="grid-cell value"><input class="sm" type="number" ng-model="form.range.max"/></div>
<div class="grid-cell value"><input class="c-input--flex" type="number" ng-model="form.range.max"/></div>
</li>
</ul>
</div>

View File

@@ -40,7 +40,7 @@ define([
'./flexibleLayout/plugin',
'./tabs/plugin',
'../../platform/features/fixed/plugin',
'./preview/plugin'
'./LADTable/plugin'
], function (
_,
UTCTimeSystem,
@@ -61,7 +61,7 @@ define([
FlexibleLayout,
Tabs,
FixedView,
PreviewPlugin
LADTable
) {
var bundleMap = {
LocalStorage: 'platform/persistence/local',
@@ -176,7 +176,7 @@ define([
plugins.Tabs = Tabs;
plugins.FixedView = FixedView;
plugins.FlexibleLayout = FlexibleLayout;
plugins.Preview = PreviewPlugin.default;
plugins.LADTable = LADTable;
return plugins;
});

View File

@@ -20,6 +20,9 @@ define([
canView: function (domainObject) {
return domainObject.type === 'summary-widget';
},
canEdit: function (domainObject) {
return domainObject.type === 'summary-widget';
},
view: function (domainObject) {
var statusService = openmct.$injector.get('statusService');
var objectId = objectUtils.makeKeyString(domainObject.identifier);
@@ -32,7 +35,6 @@ define([
return new SummaryWidgetView(domainObject, openmct);
}
},
editable: true,
priority: function (domainObject) {
if (domainObject.type === 'summary-widget') {
return Number.MAX_VALUE;

View File

@@ -147,7 +147,7 @@ export default {
this.setCurrentTab = true;
},
dragstart (e) {
if (e.dataTransfer.getData('openmct/domain-object')) {
if (e.dataTransfer.types.includes('openmct/domain-object-path')) {
this.isDragging = true;
}
},

View File

@@ -35,6 +35,9 @@ define([
canView: function (domainObject) {
return domainObject.type === 'tabs';
},
canEdit: function (domainObject) {
return domainObject.type === 'tabs';
},
view: function (domainObject) {
let component;

View File

@@ -79,8 +79,8 @@ define([
loadComposition() {
this.tableComposition = this.openmct.composition.get(this.domainObject);
if (this.tableComposition !== undefined){
this.tableComposition.load().then((composition)=>{
if (this.tableComposition !== undefined) {
this.tableComposition.load().then((composition) => {
composition = composition.filter(this.isTelemetryObject);
this.configuration.addColumnsForAllObjects(composition);
@@ -122,7 +122,6 @@ define([
let telemetryRows = telemetryData.map(datum => new TelemetryTableRow(datum, columnMap, keyString, limitEvaluator));
this.boundedRows.add(telemetryRows);
console.log('Loaded %i rows', telemetryRows.length);
this.decrementOutstandingRequests();
});
}
@@ -131,7 +130,7 @@ define([
* @private
*/
incrementOutstandingRequests() {
if (this.outstandingRequests === 0){
if (this.outstandingRequests === 0) {
this.emit('outstanding-requests', true);
}
this.outstandingRequests++;
@@ -143,7 +142,7 @@ define([
decrementOutstandingRequests() {
this.outstandingRequests--;
if (this.outstandingRequests === 0){
if (this.outstandingRequests === 0) {
this.emit('outstanding-requests', false);
}
}

View File

@@ -64,6 +64,7 @@ define([
objectMutated(object) {
//Synchronize domain object reference. Duplicate object otherwise change detection becomes impossible.
this.domainObject = object;
//Was it the configuration that changed?
if (!_.eq(object.configuration, this.oldConfiguration)) {
//Make copy of configuration, otherwise change detection is impossible if shared instance is being modified.
this.oldConfiguration = JSON.parse(JSON.stringify(this.getConfiguration()));
@@ -91,16 +92,19 @@ define([
let columnsToRemove = this.columns[objectKeyString];
delete this.columns[objectKeyString];
let configuration = this.domainObject.configuration;
let configurationChanged = false;
columnsToRemove.forEach((column) => {
//There may be more than one column with the same key (eg. time system columns)
if (!this.hasColumnWithKey(column.getKey())) {
let configuration = this.domainObject.configuration;
delete configuration.hiddenColumns[column.getKey()];
// If there are no more columns with this key, delete any configuration, and trigger
// a column refresh.
this.openmct.objects.mutate(this.domainObject, 'configuration', configuration);
configurationChanged = true;
}
});
if (configurationChanged) {
this.updateConfiguration(configuration);
}
}
hasColumnWithKey(columnKey) {

View File

@@ -36,13 +36,13 @@ define([
key: 'table',
name: 'Telemetry Table',
cssClass: 'icon-tabular-realtime',
editable: function(domainObject) {
return domainObject.type === 'table';
},
canView: function (domainObject) {
canView(domainObject) {
return domainObject.type === 'table' || domainObject.hasOwnProperty('telemetry');
},
view: function (domainObject) {
canEdit(domainObject) {
return domainObject.type === 'table';
},
view(domainObject) {
let csvExporter = new CSVExporter.default();
let table = new TelemetryTable(domainObject, openmct);
let component;
@@ -67,7 +67,7 @@ define([
}
}
},
priority: function () {
priority() {
return 1;
}
}

View File

@@ -106,19 +106,21 @@
<style lang="scss">
@import "~styles/sass-base";
@import "~styles/table";
.c-telemetry-table__drop-target {
position: absolute;
width: 2px;
background-color: $editColor;
box-shadow: rgba($editColor, 0.5) 0 0 10px;
background-color: $editUIColor;
box-shadow: rgba($editUIColor, 0.5) 0 0 10px;
z-index: 1;
pointer-events: none;
}
.c-telemetry-table {
// Table that displays telemetry in a scrolling body area
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
overflow: hidden;
th, td {
@@ -128,6 +130,10 @@
vertical-align: middle; // This is crucial to hiding f**king 4px height injected by browser by default
}
td {
color: $colorTelemFresh;
}
/******************************* WRAPPERS */
&__headers-w {
// Wraps __headers table

View File

@@ -47,6 +47,14 @@ $bodyFont: $heroFont;
@return linear-gradient(lighten($c, 5%), $c);
}
@function pullForward($val, $amt) {
@return lighten($val, $amt);
}
@function pushBack($val, $amt) {
@return darken($val, $amt);
}
// Constants
$fontBaseSize: 12px;
$smallCr: 2px;
@@ -55,7 +63,8 @@ $basicCr: 4px;
// Base colors
$colorBodyBg: #393939;
$colorBodyFg: #aaa;
$colorBodyFg: #aaaaaa;
$colorBodyFgEm: #fff;
$colorGenBg: #222;
$colorHeadBg: #262626;
$colorHeadFg: $colorBodyFg;
@@ -64,10 +73,11 @@ $colorStatusBarFg: $colorBodyFg;
$colorStatusBarFgHov: #aaa;
$colorKey: #0099cc;
$colorKeyFg: #fff;
$colorKeyHov: #00c0f6;
$colorKeyHov: #26d8ff;
$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;
$uiColor: #00b2ff; // Resize bars, splitter bars, etc.
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
$colorA: #ccc;
$colorAHov: #fff;
@@ -93,49 +103,52 @@ $colorPausedFg: #fff;
$colorOk: #33cc33;
// Base variations
$colorBodyBgSubtle: lighten($colorBodyBg, 5%);
$colorBodyBgSubtleHov: darken($colorKey, 50%);
$colorKeySubtle: darken($colorKey, 10%);
$colorBodyBgSubtle: pullForward($colorBodyBg, 5%);
$colorBodyBgSubtleHov: pushBack($colorKey, 50%);
$colorKeySubtle: pushBack($colorKey, 10%);
// Time Colors
$colorTime: #618cff;
$colorTimeBg: $colorTime;
$colorTimeFg: lighten($colorTimeBg, 30%);
$colorTimeHov: lighten($colorTime, 10%);
$colorTimeSubtle: darken($colorTime, 20%);
$colorTimeFg: pullForward($colorTimeBg, 30%);
$colorTimeHov: pullForward($colorTime, 10%);
$colorTimeSubtle: pushBack($colorTime, 20%);
$colorTOI: $colorBodyFg; // was $timeControllerToiLineColor
$colorTOIHov: $colorTime; // was $timeControllerToiLineColorHov
/************************************************** EDITING */
// Base Colors
$dlSpread: 20%;
$editColor: #00c7c3;
$editColorBgBase: darken($editColor, $dlSpread);
$editColorBg: rgba($editColorBgBase, 0.2);
$editColorFg: lighten($editColor, $dlSpread);
$editColorHov: lighten($editColor, 20%);
// Canvas
$editCanvasColorBg: $editColorBg; //#002524;
$editCanvasColorGrid: rgba($editColorBgBase, 0.4); //lighten($editCanvasColorBg, 3%);
// Selectable
$editSelectableColor: #006563;
$editSelectableColorFg: lighten($editSelectableColor, 20%);
$editSelectableColorHov: lighten($editSelectableColor, 10%);
// Selectable selected
$editSelectableColorSelected: $editSelectableColorHov;
$editSelectableColorSelectedFg: lighten($editSelectableColorSelected, 30%);
$editSelectableColorFg: darken($editSelectableColor, 40%);
$editSelectableBorder: 1px dotted $editSelectableColor;
$editSelectableBorderHov: 1px dotted $editColor;
$editSelectableBorderSelected: 1px solid $editColor;
$editMoveableSelectedShdw: rgba($editColor, 0.5) 0 0 10px;
$editBorderDrilledIn: 1px dashed #9971ff;
$colorGridLines: rgba($editColor, 0.2);
/************************************************** BROWSING */
$browseBorderSelectableHov: 1px dotted rgba($colorBodyFg, 0.2);
$browseShdwSelectableHov: rgba($colorBodyFg, 0.2) 0 0 3px;
$browseBorderSelected: 1px solid rgba($colorBodyFg, 0.6);
$browseFrameColor: pullForward($colorBodyBg, 10%);
$browseFrameBorder: 1px solid $browseFrameColor; // Frames in Disp and Flex Layouts when frame is showing
$browseSelectableShdwHov: rgba($colorBodyFg, 0.3) 0 0 3px;
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.4);
/************************************************** EDITING */
$editUIColor: $uiColor; // Base color
$editUIColorHov: pullForward(saturate($uiColor, 10%), 20%); // Hover color when $editUIColor is applied as a base color
$editUIBaseColor: #344b8d; // Base color, toolbar bg
$editUIBaseColorHov: pullForward($editUIBaseColor, 20%);
$editUIBaseColorFg: #ffffff; // Toolbar button icon colors, etc.
$editUIAreaBaseColor: pullForward(saturate($editUIBaseColor, 30%), 20%);
$editUIAreaShdw: $editUIAreaBaseColor 0 0 0 2px; // Edit area s-selected-parent
$editUIAreaShdwSelected: $editUIAreaBaseColor 0 0 0 3px; // Edit area s-selected
$editUIGridColorBg: rgba($editUIBaseColor, 0.2); // Background of layout editing area
$editUIGridColorFg: rgba(#000, 0.1); // Grid lines in layout editing area
$editFrameColor: $browseFrameColor; // Solid or dotted border applied to non-selected frames in a layout; move-bar on frame hover
$editFrameBorder: 1px dotted $editFrameColor;
$editFrameColorHov: $editUIColor; // Solid border hover on frames; hover should not be applied to selected objects
$editFrameBorderHov: 1px solid $editFrameColorHov; // Hover on selectable frames
$editFrameColorSelected: #ccc; // Border of selected frames
$editFrameColorHandleBg: $colorBodyBg; // Resize handle 'offset' color to make handle standout
$editFrameColorHandleFg: $editFrameColorSelected; // Resize handle main color
$editFrameSelectedShdw: rgba(black, 0.5) 0 1px 10px 1px;
$editFrameSelectedBorder: 1px dashed $editFrameColorSelected; // Selected frame element
$editFrameMovebarColorBg: $editFrameColor; // Movebar bg color
$editFrameMovebarColorFg: pullForward($editFrameMovebarColorBg, 20%); // Grippy lines, container size text
$editFrameHovMovebarColorBg: pullForward($editFrameMovebarColorBg, 10%); // Hover style
$editFrameHovMovebarColorFg: pullForward($editFrameMovebarColorFg, 10%);
$editFrameSelectedMovebarColorBg: pullForward($editFrameMovebarColorBg, 15%); // Selected style
$editFrameSelectedMovebarColorFg: pullForward($editFrameMovebarColorFg, 15%);
$editFrameMovebarH: 10px; // Height of move bar in layout frame
// Icons
$colorIconAlias: #4af6f3;
@@ -145,16 +158,16 @@ $colorIconAliasForKeyFilter: #aaa;
$colorTabsHolderBg: rgba(black, 0.2);
// Buttons and Controls
$colorBtnBg: lighten($colorBodyBg, 10%);
$colorBtnBgHov: lighten($colorBtnBg, 10%);
$colorBtnFg: lighten($colorBodyFg, 10%);
$colorBtnReverseFg: lighten($colorBtnFg, 10%);
$colorBtnReverseBg: lighten($colorBtnBg, 10%);
$colorBtnBg: pullForward($colorBodyBg, 10%);
$colorBtnBgHov: pullForward($colorBtnBg, 10%);
$colorBtnFg: pullForward($colorBodyFg, 10%);
$colorBtnReverseFg: pullForward($colorBtnFg, 10%);
$colorBtnReverseBg: pullForward($colorBtnBg, 10%);
$colorBtnFgHov: $colorBtnFg;
$colorBtnMajorBg: $colorKey;
$colorBtnMajorBgHov: $colorKeyHov;
$colorBtnMajorFg: $colorKeyFg;
$colorBtnMajorFgHov: darken($colorBtnMajorFg, 10%);
$colorBtnMajorFgHov: pushBack($colorBtnMajorFg, 10%);
$colorBtnCautionBg: #f16f6f;
$colorBtnCautionBgHov: #f1504e;
$colorBtnCautionFg: $colorBtnFg;
@@ -162,18 +175,20 @@ $colorClickIcon: $colorKey;
$colorClickIconBgHov: rgba($colorKey, 0.6);
$colorClickIconFgHov: $colorKeyHov;
$colorDropHint: $colorKey;
$colorDropHintBg: darken($colorDropHint, 10%);
$colorDropHintBg: pushBack($colorDropHint, 10%);
$colorDropHintBgHov: $colorDropHint;
$colorDropHintFg: lighten($colorDropHint, 40%);
$colorDropHintFg: pullForward($colorDropHint, 40%);
$colorDisclosureCtrl: rgba($colorBodyFg, 0.5);
$colorDisclosureCtrlHov: rgba($colorBodyFg, 0.7);
// Menus
$colorMenuBg: lighten($colorBodyBg, 15%);
$colorMenuFg: lighten($colorBodyFg, 30%);
$colorMenuIc: lighten($colorKey, 15%);
$colorMenuBg: pullForward($colorBodyBg, 15%);
$colorMenuFg: pullForward($colorBodyFg, 30%);
$colorMenuIc: pullForward($colorKey, 15%);
$colorMenuHovBg: $colorMenuIc;
$colorMenuHovFg: lighten($colorMenuFg, 10%);
$colorMenuHovFg: pullForward($colorMenuFg, 10%);
$colorMenuHovIc: $colorMenuHovFg;
$colorMenuElementHilite: lighten($colorMenuBg, 10%);
$colorMenuElementHilite: pullForward($colorMenuBg, 10%);
$shdwMenu: rgba(black, 0.5) 0 1px 5px;
$shdwMenuText: none;
$menuItemPad: $interiorMargin, floor($interiorMargin * 1.25);
@@ -195,21 +210,21 @@ $colorFormLines: rgba(#000, 0.1);
$colorFormSectionHeader: rgba(#000, 0.05);
$colorInputBg: rgba(black, 0.2);
$colorInputFg: $colorBodyFg;
$colorInputPlaceholder: darken($colorBodyFg, 20%);
$colorFormText: darken($colorBodyFg, 10%);
$colorInputIcon: darken($colorBodyFg, 25%);
$colorFieldHint: lighten($colorBodyFg, 40%);
$colorInputPlaceholder: pushBack($colorBodyFg, 20%);
$colorFormText: pushBack($colorBodyFg, 10%);
$colorInputIcon: pushBack($colorBodyFg, 25%);
$colorFieldHint: pullForward($colorBodyFg, 40%);
$shdwInput: inset rgba(black, 0.4) 0 0 1px;
$shdwInputHov: inset rgba(black, 0.7) 0 0 2px;
$shdwInputFoc: inset rgba(black, 0.8) 0 0.25px 3px;
// Inspector
$colorInspectorBg: lighten($colorBodyBg, 5%);
$colorInspectorBg: pullForward($colorBodyBg, 5%);
$colorInspectorFg: $colorBodyFg;
$colorInspectorPropName: darken($colorBodyFg, 20%);
$colorInspectorPropVal: lighten($colorInspectorFg, 15%);
$colorInspectorSectionHeaderBg: lighten($colorInspectorBg, 5%);
$colorInspectorSectionHeaderFg: lighten($colorInspectorBg, 40%);
$colorInspectorPropName: pushBack($colorBodyFg, 20%);
$colorInspectorPropVal: pullForward($colorInspectorFg, 15%);
$colorInspectorSectionHeaderBg: pullForward($colorInspectorBg, 5%);
$colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
// Overlay
$overlayColorBg: $colorMenuBg;
@@ -219,18 +234,31 @@ $overlayBrightnessAdjust: brightness(1.3);
// Indicator colors
$colorIndicatorAvailable: $colorKey;
$colorIndicatorDisabled: #444;
$colorIndicatorDisabled: #555555;
$colorIndicatorOn: $colorOk;
$colorIndicatorOff: #666;
$colorIndicatorOff: #777777;
// Limits and staleness colors//
$colorTelemFresh: lighten($colorBodyFg, 20%);
$colorTelemStale: darken($colorBodyFg, 20%);
// Staleness
$colorTelemFresh: pullForward($colorBodyFg, 20%);
$colorTelemStale: pushBack($colorBodyFg, 20%);
$styleTelemStale: italic;
$colorLimitYellowBg: rgba(#ffaa00, 0.3);
$colorLimitYellowIc: #ffaa00;
$colorLimitRedBg: rgba(red, 0.3);
$colorLimitRedIc: red;
// Limits
$colorLimitYellowBg: #ac7300;
$colorLimitYellowFg: #ffe64d;
$colorLimitYellowIc: #ffb607;
$colorLimitRedBg: #940000;
$colorLimitRedFg: #ffa489;
$colorLimitRedIc: #ff4222;
// Status
$colorAlert: #ff3c00;
$colorWarningHi: #990000;
$colorWarningLo: #ff9900;
$colorDiagnostic: #a4b442;
$colorCommand: #3693bd;
$colorInfo: #2294a2;
$colorOk: #33cc33;
// Bubble colors
$colorInfoBubbleBg: $colorMenuBg;
@@ -238,20 +266,22 @@ $colorInfoBubbleFg: #666;
// Items
$colorItemBg: buttonBg($colorBtnBg);
$colorItemBgHov: buttonBg(lighten($colorBtnBg, 5%));
$colorItemBgHov: buttonBg(pullForward($colorBtnBg, 5%));
$colorListItemBg: transparent;
$colorListItemBgHov: rgba($colorKey, 0.1);
$colorItemFg: $colorBtnFg;
$colorItemFgDetails: darken($colorItemFg, 20%);
$colorItemFgDetails: pushBack($colorItemFg, 20%);
$shdwItemText: none;
// Tabular
$colorTabBorder: lighten($colorBodyBg, 10%);
$colorTabBorder: pullForward($colorBodyBg, 10%);
$colorTabBodyBg: $colorBodyBg;
$colorTabBodyFg: lighten($colorBodyFg, 20%);
$colorTabHeaderBg: lighten($colorBodyBg, 10%);
$colorTabHeaderFg: lighten($colorBodyFg, 20%);
$colorTabBodyFg: pullForward($colorBodyFg, 20%);
$colorTabHeaderBg: pullForward($colorBodyBg, 10%);
$colorTabHeaderFg: $colorBodyFg;
$colorTabHeaderBorder: $colorBodyBg;
$colorTabGroupHeaderBg: pullForward($colorBodyBg, 5%);
$colorTabGroupHeaderFg: pushBack($colorTabHeaderFg, 10%);
// Plot
$colorPlotBg: rgba(black, 0.05);
@@ -260,25 +290,24 @@ $colorPlotHash: black;
$opacityPlotHash: 0.2;
$stylePlotHash: dashed;
$colorPlotAreaBorder: $colorInteriorBorder;
$colorPlotLabelFg: darken($colorPlotFg, 20%);
$legendCollapsedNameMaxW: 50%;
$colorPlotLabelFg: pushBack($colorPlotFg, 20%);
$legendHoverValueBg: rgba($colorBodyFg, 0.2);
// Tree
$colorTreeBg: transparent;
$colorItemTreeHoverBg: lighten($colorBodyBg, 10%);
$colorItemTreeHoverFg: lighten($colorBodyFg, 20%);
$colorItemTreeHoverBg: pullForward($colorBodyBg, 10%);
$colorItemTreeHoverFg: pullForward($colorBodyFg, 20%);
$colorItemTreeIcon: $colorKey; // Used
$colorItemTreeIconHover: $colorItemTreeIcon; // Used
$colorItemTreeFg: $colorBodyFg;
$colorItemTreeSelectedBg: darken($colorKey, 15%);
$colorItemTreeSelectedBg: pushBack($colorKey, 15%);
$colorItemTreeSelectedFg: $colorItemTreeHoverFg;
$colorItemTreeSelectedIcon: $colorItemTreeSelectedFg;
$colorItemTreeEditingBg: darken($editColor, 20%);
$colorItemTreeEditingFg: $editColorFg;
$colorItemTreeEditingIcon: $editColorFg;
$colorItemTreeVC: rgba($colorBodyFg, 0.5);
$colorItemTreeVCHover: $colorKey;
$colorItemTreeEditingBg: pushBack($editUIColor, 20%);
$colorItemTreeEditingFg: $editUIColor;
$colorItemTreeEditingIcon: $editUIColor;
$colorItemTreeVC: $colorDisclosureCtrl;
$colorItemTreeVCHover: $colorDisclosureCtrlHov;
$shdwItemTreeIcon: none;
// Images
@@ -288,18 +317,18 @@ $colorThumbHoverBg: $colorItemTreeHoverBg;
$scrollbarTrackSize: 7px;
$scrollbarTrackShdw: rgba(#000, 0.2) 0 1px 2px;
$scrollbarTrackColorBg: rgba(#000, 0.2);
$scrollbarThumbColor: darken($colorBodyBg, 50%);
$scrollbarThumbColor: pushBack($colorBodyBg, 50%);
$scrollbarThumbColorHov: $colorKey;
$scrollbarThumbColorMenu: lighten($colorMenuBg, 10%);
$scrollbarThumbColorMenuHov: lighten($scrollbarThumbColorMenu, 2%);
$scrollbarThumbColorMenu: pullForward($colorMenuBg, 10%);
$scrollbarThumbColorMenuHov: pullForward($scrollbarThumbColorMenu, 2%);
// Splitter
$splitterHandleD: 2px;
$splitterHandleHitMargin: 4px;
$colorSplitterBaseBg: $colorBodyBg;
$colorSplitterBg: lighten($colorSplitterBaseBg, 10%);
$colorSplitterBg: pullForward($colorBodyBg, 10%);
$colorSplitterFg: $colorBodyBg;
$colorSplitterHover: $colorKey;
$colorSplitterHover: $uiColor;
$colorSplitterActive: $colorKey;
$splitterBtnD: (16px, 35px); // height, width
$splitterBtnColorBg: $colorBtnBg;
@@ -311,7 +340,7 @@ $splitterCollapsedBtnColorBgHov: $colorKey;
$splitterCollapsedBtnColorFgHov: $colorKeyFg;
// Mobile
$colorMobilePaneLeft: darken($colorBodyBg, 2%);
$colorMobilePaneLeft: pushBack($colorBodyBg, 2%);
$colorMobilePaneLeftTreeItemBg: rgba($colorBodyFg, 0.1);
$colorMobilePaneLeftTreeItemFg: $colorItemTreeFg;
$colorMobileSelectListTreeItemBg: rgba(#000, 0.05);
@@ -348,7 +377,7 @@ $createBtnTextTransform: uppercase;
}
@mixin themedButton($c: $colorBtnBg) {
background: linear-gradient(lighten($c, 5%), $c);
background: linear-gradient(pullForward($c, 5%), $c);
box-shadow: rgba(black, 0.5) 0 0.5px 2px;
}
@@ -359,21 +388,10 @@ $sliderColorBase: $colorKey;
$sliderColorRangeHolder: rgba(black, 0.07);
$sliderColorRange: rgba($sliderColorBase, 0.2);
$sliderColorRangeHov: rgba($sliderColorBase, 0.4);
$sliderColorKnob: darken($sliderColorBase, 20%);
$sliderColorKnob: pushBack($sliderColorBase, 20%);
$sliderColorKnobHov: rgba($sliderColorBase, 0.7);
$sliderColorRangeValHovBg: $sliderColorRange;
$sliderColorRangeValHovFg: $colorBodyFg;
$sliderKnobW: 15px;
$sliderKnobR: 2px;
*/
// Content status
/*
$colorAlert: #ff3c00;
$colorWarningHi: #990000;
$colorWarningLo: #ff9900;
$colorDiagnostic: #a4b442;
$colorCommand: #3693bd;
$colorInfo: #2294a2;
$colorOk: #33cc33;
*/

View File

@@ -20,7 +20,7 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
/************************************************** MAELSTROM2 THEME CONSTANTS */
/************************************************** MAELSTROM THEME CONSTANTS */
// Fonts
@import url('https://fonts.googleapis.com/css?family=Chakra+Petch:400,600,700|Michroma|Teko:400,700');
@@ -51,6 +51,14 @@ $bodyFont: 'Chakra Petch', sans-serif;
@return linear-gradient(lighten($c, 5%), $c);
}
@function pullForward($val, $amt) {
@return lighten($val, $amt);
}
@function pushBack($val, $amt) {
@return darken($val, $amt);
}
// Constants
$fontBaseSize: 12px;
$smallCr: 2px;
@@ -60,6 +68,7 @@ $basicCr: 4px;
// Base colors
$colorBodyBg: #393939;
$colorBodyFg: #ccc;
$colorBodyFgEm: #fff;
$colorGenBg: #222;
$colorHeadBg: #262626;
$colorHeadFg: $colorBodyFg;
@@ -68,10 +77,11 @@ $colorStatusBarFg: $colorBodyFg;
$colorStatusBarFgHov: #aaa;
$colorKey: #0099cc;
$colorKeyFg: #fff;
$colorKeyHov: #00c0f6;
$colorKeyHov: #26d8ff;
$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;
$uiColor: #00b2ff; // Resize bars, splitter bars, etc.
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
$colorA: #ccc;
$colorAHov: #fff;
@@ -97,48 +107,52 @@ $colorPausedFg: #fff;
$colorOk: #33cc33;
// Base variations
$colorBodyBgSubtle: lighten($colorBodyBg, 5%);
$colorBodyBgSubtleHov: darken($colorKey, 50%);
$colorKeySubtle: darken($colorKey, 10%);
$colorBodyBgSubtle: pullForward($colorBodyBg, 5%);
$colorBodyBgSubtleHov: pushBack($colorKey, 50%);
$colorKeySubtle: pushBack($colorKey, 10%);
// Time Colors
$colorTime: #618cff;
$colorTimeBg: $colorTime;
$colorTimeFg: lighten($colorTimeBg, 30%);
$colorTimeHov: lighten($colorTime, 10%);
$colorTimeSubtle: darken($colorTime, 20%);
$colorTimeFg: pullForward($colorTimeBg, 30%);
$colorTimeHov: pullForward($colorTime, 10%);
$colorTimeSubtle: pushBack($colorTime, 20%);
$colorTOI: $colorBodyFg; // was $timeControllerToiLineColor
$colorTOIHov: $colorTime; // was $timeControllerToiLineColorHov
/************************************************** EDITING */
// Base Colors
$dlSpread: 20%;
$editColor: #00c7c3;
$editColorBg: darken($editColor, $dlSpread);
$editColorFg: lighten($editColor, $dlSpread);
$editColorHov: lighten($editColor, 20%);
// Canvas
$editCanvasColorBg: #002524;
$editCanvasColorGrid: darken($editCanvasColorBg, 2%);
// Selectable
$editSelectableColor: #006563;
$editSelectableColorFg: lighten($editSelectableColor, 20%);
$editSelectableColorHov: lighten($editSelectableColor, 10%);
// Selectable selected
$editSelectableColorSelected: $editSelectableColorHov;
$editSelectableColorSelectedFg: lighten($editSelectableColorSelected, 30%);
$editSelectableColorFg: darken($editSelectableColor, 40%);
$editSelectableBorder: 1px dotted $editSelectableColor;
$editSelectableBorderHov: 1px dotted $editColor;
$editSelectableBorderSelected: 1px solid $editColor;
$editMoveableSelectedShdw: rgba($editColor, 0.5) 0 0 10px;
$editBorderDrilledIn: 1px dashed #9971ff;
$colorGridLines: rgba($editColor, 0.2);
/************************************************** BROWSING */
$browseBorderSelectableHov: 1px dotted rgba($colorBodyFg, 0.2);
$browseShdwSelectableHov: rgba($colorBodyFg, 0.2) 0 0 3px;
$browseBorderSelected: 1px solid rgba($colorBodyFg, 0.6);
$browseFrameColor: pullForward($colorBodyBg, 10%);
$browseFrameBorder: 1px solid $browseFrameColor; // Frames in Disp and Flex Layouts when frame is showing
$browseSelectableShdwHov: rgba($colorBodyFg, 0.3) 0 0 3px;
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.4);
/************************************************** EDITING */
$editUIColor: $uiColor; // Base color
$editUIColorHov: pullForward(saturate($uiColor, 10%), 20%); // Hover color when $editUIColor is applied as a base color
$editUIBaseColor: #344b8d; // Base color, toolbar bg
$editUIBaseColorHov: pullForward($editUIBaseColor, 20%);
$editUIBaseColorFg: #ffffff; // Toolbar button icon colors, etc.
$editUIAreaBaseColor: pullForward(saturate($editUIBaseColor, 30%), 20%);
$editUIAreaShdw: $editUIAreaBaseColor 0 0 0 2px; // Edit area s-selected-parent
$editUIAreaShdwSelected: $editUIAreaBaseColor 0 0 0 3px; // Edit area s-selected
$editUIGridColorBg: rgba($editUIBaseColor, 0.2); // Background of layout editing area
$editUIGridColorFg: rgba(#000, 0.1); // Grid lines in layout editing area
$editFrameColor: $browseFrameColor; // Solid or dotted border applied to non-selected frames in a layout; move-bar on frame hover
$editFrameBorder: 1px dotted $editFrameColor;
$editFrameColorHov: $editUIColor; // Solid border hover on frames; hover should not be applied to selected objects
$editFrameBorderHov: 1px solid $editFrameColorHov; // Hover on selectable frames
$editFrameColorSelected: #ccc; // Border of selected frames
$editFrameColorHandleBg: $colorBodyBg; // Resize handle 'offset' color to make handle standout
$editFrameColorHandleFg: $editFrameColorSelected; // Resize handle main color
$editFrameSelectedShdw: rgba(black, 0.5) 0 1px 10px 1px;
$editFrameSelectedBorder: 1px dashed $editFrameColorSelected; // Selected frame element
$editFrameMovebarColorBg: $editFrameColor; // Movebar bg color
$editFrameMovebarColorFg: pullForward($editFrameMovebarColorBg, 20%); // Grippy lines, container size text
$editFrameHovMovebarColorBg: pullForward($editFrameMovebarColorBg, 10%); // Hover style
$editFrameHovMovebarColorFg: pullForward($editFrameMovebarColorFg, 10%);
$editFrameSelectedMovebarColorBg: pullForward($editFrameMovebarColorBg, 15%); // Selected style
$editFrameSelectedMovebarColorFg: pullForward($editFrameMovebarColorFg, 15%);
$editFrameMovebarH: 10px; // Height of move bar in layout frame
// Icons
$colorIconAlias: #4af6f3;
@@ -148,16 +162,16 @@ $colorIconAliasForKeyFilter: #aaa;
$colorTabsHolderBg: rgba(black, 0.2);
// Buttons and Controls
$colorBtnBg: lighten($colorBodyBg, 10%);
$colorBtnBgHov: lighten($colorBtnBg, 10%);
$colorBtnFg: lighten($colorBodyFg, 10%);
$colorBtnReverseFg: lighten($colorBtnFg, 10%);
$colorBtnReverseBg: lighten($colorBtnBg, 10%);
$colorBtnBg: pullForward($colorBodyBg, 10%);
$colorBtnBgHov: pullForward($colorBtnBg, 10%);
$colorBtnFg: pullForward($colorBodyFg, 10%);
$colorBtnReverseFg: pullForward($colorBtnFg, 10%);
$colorBtnReverseBg: pullForward($colorBtnBg, 10%);
$colorBtnFgHov: $colorBtnFg;
$colorBtnMajorBg: $colorKey;
$colorBtnMajorBgHov: $colorKeyHov;
$colorBtnMajorFg: $colorKeyFg;
$colorBtnMajorFgHov: darken($colorBtnMajorFg, 10%);
$colorBtnMajorFgHov: pushBack($colorBtnMajorFg, 10%);
$colorBtnCautionBg: #f16f6f;
$colorBtnCautionBgHov: #f1504e;
$colorBtnCautionFg: $colorBtnFg;
@@ -165,18 +179,20 @@ $colorClickIcon: $colorKey;
$colorClickIconBgHov: rgba($colorKey, 0.6);
$colorClickIconFgHov: $colorKeyHov;
$colorDropHint: $colorKey;
$colorDropHintBg: darken($colorDropHint, 10%);
$colorDropHintBg: pushBack($colorDropHint, 10%);
$colorDropHintBgHov: $colorDropHint;
$colorDropHintFg: lighten($colorDropHint, 40%);
$colorDropHintFg: pullForward($colorDropHint, 40%);
$colorDisclosureCtrl: rgba($colorBodyFg, 0.5);
$colorDisclosureCtrlHov: rgba($colorBodyFg, 0.7);
// Menus
$colorMenuBg: lighten($colorBodyBg, 15%);
$colorMenuFg: lighten($colorBodyFg, 30%);
$colorMenuIc: lighten($colorKey, 15%);
$colorMenuBg: pullForward($colorBodyBg, 15%);
$colorMenuFg: pullForward($colorBodyFg, 30%);
$colorMenuIc: pullForward($colorKey, 15%);
$colorMenuHovBg: $colorMenuIc;
$colorMenuHovFg: lighten($colorMenuFg, 10%);
$colorMenuHovFg: pullForward($colorMenuFg, 10%);
$colorMenuHovIc: $colorMenuHovFg;
$colorMenuElementHilite: lighten($colorMenuBg, 10%);
$colorMenuElementHilite: pullForward($colorMenuBg, 10%);
$shdwMenu: rgba(black, 0.5) 0 1px 5px;
$shdwMenuText: none;
$menuItemPad: $interiorMargin, floor($interiorMargin * 1.25);
@@ -198,21 +214,21 @@ $colorFormLines: rgba(#000, 0.1);
$colorFormSectionHeader: rgba(#000, 0.05);
$colorInputBg: rgba(black, 0.2);
$colorInputFg: $colorBodyFg;
$colorInputPlaceholder: darken($colorBodyFg, 20%);
$colorFormText: darken($colorBodyFg, 10%);
$colorInputIcon: darken($colorBodyFg, 25%);
$colorFieldHint: lighten($colorBodyFg, 40%);
$colorInputPlaceholder: pushBack($colorBodyFg, 20%);
$colorFormText: pushBack($colorBodyFg, 10%);
$colorInputIcon: pushBack($colorBodyFg, 25%);
$colorFieldHint: pullForward($colorBodyFg, 40%);
$shdwInput: inset rgba(black, 0.4) 0 0 1px;
$shdwInputHov: inset rgba(black, 0.7) 0 0 2px;
$shdwInputFoc: inset rgba(black, 0.8) 0 0.25px 3px;
// Inspector
$colorInspectorBg: lighten($colorBodyBg, 5%);
$colorInspectorBg: pullForward($colorBodyBg, 5%);
$colorInspectorFg: $colorBodyFg;
$colorInspectorPropName: darken($colorBodyFg, 20%);
$colorInspectorPropVal: lighten($colorInspectorFg, 15%);
$colorInspectorSectionHeaderBg: lighten($colorInspectorBg, 5%);
$colorInspectorSectionHeaderFg: lighten($colorInspectorBg, 40%);
$colorInspectorPropName: pushBack($colorBodyFg, 20%);
$colorInspectorPropVal: pullForward($colorInspectorFg, 15%);
$colorInspectorSectionHeaderBg: pullForward($colorInspectorBg, 5%);
$colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
// Overlay
$overlayColorBg: $colorMenuBg;
@@ -222,18 +238,31 @@ $overlayBrightnessAdjust: brightness(1.3);
// Indicator colors
$colorIndicatorAvailable: $colorKey;
$colorIndicatorDisabled: #444;
$colorIndicatorDisabled: #555555;
$colorIndicatorOn: $colorOk;
$colorIndicatorOff: #666;
$colorIndicatorOff: #777777;
// Limits and staleness colors//
$colorTelemFresh: lighten($colorBodyFg, 20%);
$colorTelemStale: darken($colorBodyFg, 20%);
// Staleness
$colorTelemFresh: pullForward($colorBodyFg, 20%);
$colorTelemStale: pushBack($colorBodyFg, 20%);
$styleTelemStale: italic;
$colorLimitYellowBg: rgba(#ffaa00, 0.3);
$colorLimitYellowIc: #ffaa00;
$colorLimitRedBg: rgba(red, 0.3);
$colorLimitRedIc: red;
// Limits
$colorLimitYellowBg: #ac7300;
$colorLimitYellowFg: #ffe64d;
$colorLimitYellowIc: #ffb607;
$colorLimitRedBg: #940000;
$colorLimitRedFg: #ffa489;
$colorLimitRedIc: #ff4222;
// Status
$colorAlert: #ff3c00;
$colorWarningHi: #990000;
$colorWarningLo: #ff9900;
$colorDiagnostic: #a4b442;
$colorCommand: #3693bd;
$colorInfo: #2294a2;
$colorOk: #33cc33;
// Bubble colors
$colorInfoBubbleBg: $colorMenuBg;
@@ -241,20 +270,22 @@ $colorInfoBubbleFg: #666;
// Items
$colorItemBg: buttonBg($colorBtnBg);
$colorItemBgHov: buttonBg(lighten($colorBtnBg, 5%));
$colorItemBgHov: buttonBg(pullForward($colorBtnBg, 5%));
$colorListItemBg: transparent;
$colorListItemBgHov: rgba($colorKey, 0.1);
$colorItemFg: $colorBtnFg;
$colorItemFgDetails: darken($colorItemFg, 20%);
$colorItemFgDetails: pushBack($colorItemFg, 20%);
$shdwItemText: none;
// Tabular
$colorTabBorder: lighten($colorBodyBg, 10%);
$colorTabBorder: pullForward($colorBodyBg, 10%);
$colorTabBodyBg: $colorBodyBg;
$colorTabBodyFg: lighten($colorBodyFg, 20%);
$colorTabHeaderBg: lighten($colorBodyBg, 10%);
$colorTabHeaderFg: lighten($colorBodyFg, 20%);
$colorTabBodyFg: pullForward($colorBodyFg, 20%);
$colorTabHeaderBg: pullForward($colorBodyBg, 10%);
$colorTabHeaderFg: $colorBodyFg;
$colorTabHeaderBorder: $colorBodyBg;
$colorTabGroupHeaderBg: pullForward($colorBodyBg, 5%);
$colorTabGroupHeaderFg: pushBack($colorTabHeaderFg, 10%);
// Plot
$colorPlotBg: rgba(black, 0.05);
@@ -263,25 +294,24 @@ $colorPlotHash: black;
$opacityPlotHash: 0.2;
$stylePlotHash: dashed;
$colorPlotAreaBorder: $colorInteriorBorder;
$colorPlotLabelFg: darken($colorPlotFg, 20%);
$legendCollapsedNameMaxW: 50%;
$colorPlotLabelFg: pushBack($colorPlotFg, 20%);
$legendHoverValueBg: rgba($colorBodyFg, 0.2);
// Tree
$colorTreeBg: transparent;
$colorItemTreeHoverBg: lighten($colorBodyBg, 10%);
$colorItemTreeHoverFg: lighten($colorBodyFg, 20%);
$colorItemTreeHoverBg: pullForward($colorBodyBg, 10%);
$colorItemTreeHoverFg: pullForward($colorBodyFg, 20%);
$colorItemTreeIcon: $colorKey; // Used
$colorItemTreeIconHover: $colorItemTreeIcon; // Used
$colorItemTreeFg: $colorBodyFg;
$colorItemTreeSelectedBg: darken($colorKey, 15%);
$colorItemTreeSelectedBg: pushBack($colorKey, 15%);
$colorItemTreeSelectedFg: $colorItemTreeHoverFg;
$colorItemTreeSelectedIcon: $colorItemTreeSelectedFg;
$colorItemTreeEditingBg: darken($editColor, 20%);
$colorItemTreeEditingFg: $editColorFg;
$colorItemTreeEditingIcon: $editColorFg;
$colorItemTreeVC: rgba($colorBodyFg, 0.5);
$colorItemTreeVCHover: $colorKey;
$colorItemTreeEditingBg: pushBack($editUIColor, 20%);
$colorItemTreeEditingFg: $editUIColor;
$colorItemTreeEditingIcon: $editUIColor;
$colorItemTreeVC: $colorDisclosureCtrl;
$colorItemTreeVCHover: $colorDisclosureCtrlHov;
$shdwItemTreeIcon: none;
// Images
@@ -291,18 +321,18 @@ $colorThumbHoverBg: $colorItemTreeHoverBg;
$scrollbarTrackSize: 7px;
$scrollbarTrackShdw: rgba(#000, 0.2) 0 1px 2px;
$scrollbarTrackColorBg: rgba(#000, 0.2);
$scrollbarThumbColor: darken($colorBodyBg, 50%);
$scrollbarThumbColor: pushBack($colorBodyBg, 50%);
$scrollbarThumbColorHov: $colorKey;
$scrollbarThumbColorMenu: lighten($colorMenuBg, 10%);
$scrollbarThumbColorMenuHov: lighten($scrollbarThumbColorMenu, 2%);
$scrollbarThumbColorMenu: pullForward($colorMenuBg, 10%);
$scrollbarThumbColorMenuHov: pullForward($scrollbarThumbColorMenu, 2%);
// Splitter
$splitterHandleD: 2px;
$splitterHandleHitMargin: 4px;
$colorSplitterBaseBg: $colorBodyBg;
$colorSplitterBg: lighten($colorSplitterBaseBg, 10%);
$colorSplitterBg: pullForward($colorBodyBg, 10%);
$colorSplitterFg: $colorBodyBg;
$colorSplitterHover: $colorKey;
$colorSplitterHover: $uiColor;
$colorSplitterActive: $colorKey;
$splitterBtnD: (16px, 35px); // height, width
$splitterBtnColorBg: $colorBtnBg;
@@ -314,7 +344,7 @@ $splitterCollapsedBtnColorBgHov: $colorKey;
$splitterCollapsedBtnColorFgHov: $colorKeyFg;
// Mobile
$colorMobilePaneLeft: darken($colorBodyBg, 2%);
$colorMobilePaneLeft: pushBack($colorBodyBg, 2%);
$colorMobilePaneLeftTreeItemBg: rgba($colorBodyFg, 0.1);
$colorMobilePaneLeftTreeItemFg: $colorItemTreeFg;
$colorMobileSelectListTreeItemBg: rgba(#000, 0.05);
@@ -351,7 +381,7 @@ $createBtnTextTransform: uppercase;
}
@mixin themedButton($c: $colorBtnBg) {
background: linear-gradient(lighten($c, 5%), $c);
background: linear-gradient(pullForward($c, 5%), $c);
box-shadow: rgba(black, 0.5) 0 0.5px 2px;
}
@@ -369,4 +399,4 @@ $createBtnTextTransform: uppercase;
border-right: $bLR !important;;
padding: 5px 10px 10px 10px !important;
}
}
}

View File

@@ -47,6 +47,14 @@ $bodyFont: $heroFont;
@return $c;
}
@function pullForward($val, $amt) {
@return darken($val, $amt);
}
@function pushBack($val, $amt) {
@return lighten($val, $amt);
}
// Constants
$fontBaseSize: 12px;
$smallCr: 2px;
@@ -56,6 +64,7 @@ $basicCr: 4px;
// Base colors
$colorBodyBg: #fcfcfc;
$colorBodyFg: #666;
$colorBodyFgEm: #333;
$colorGenBg: #fff;
$colorHeadBg: #eee;
$colorHeadFg: $colorBodyFg;
@@ -68,6 +77,7 @@ $colorKeyHov: #00c0f6;
$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;
$uiColor: #289fec; // Resize bars, splitter bars, etc.
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
$colorA: #999;
$colorAHov: $colorKey;
@@ -93,49 +103,52 @@ $colorPausedFg: #fff;
$colorOk: #33cc33;
// Base variations
$colorBodyBgSubtle: darken($colorBodyBg, 5%);
$colorBodyBgSubtleHov: lighten($colorKey, 50%);
$colorKeySubtle: lighten($colorKey, 50%);
$colorBodyBgSubtle: pullForward($colorBodyBg, 5%);
$colorBodyBgSubtleHov: pushBack($colorKey, 50%);
$colorKeySubtle: pushBack($colorKey, 10%);
// Time Colors
$colorTime: #618cff;
$colorTimeBg: $colorTime;
$colorTimeFg: $colorBodyBg;
$colorTimeHov: lighten($colorTime, 5%);
$colorTimeSubtle: lighten($colorTime, 20%);
$colorTimeHov: pushBack($colorTime, 5%);
$colorTimeSubtle: pushBack($colorTime, 20%);
$colorTOI: $colorBodyFg; // was $timeControllerToiLineColor
$colorTOIHov: $colorTime; // was $timeControllerToiLineColorHov
/************************************************** EDITING */
// Base Colors
$dlSpread: 20%;
$editColor: #00c7c3;
$editColorBgBase: darken($editColor, $dlSpread);
$editColorBg: darken($editColor, $dlSpread);
$editColorFg: lighten($editColor, $dlSpread);
$editColorHov: lighten($editColor, 20%);
// Canvas
$editCanvasColorBg: #e6ffff;
$editCanvasColorGrid: darken($editCanvasColorBg, 10%);
// Selectable
$editSelectableColor: #acdad6;
$editSelectableColorFg: darken($editSelectableColor, 20%);
$editSelectableColorHov: darken($editSelectableColor, 10%);
// Selectable selected
$editSelectableColorSelected: $editColor; //$editSelectableColorHov;
$editSelectableColorSelectedFg: lighten($editSelectableColorSelected, 50%);
$editSelectableColorFg: darken($editSelectableColor, 40%);
$editSelectableBorder: 1px dotted $editSelectableColor;
$editSelectableBorderHov: 1px dotted $editColor;
$editSelectableBorderSelected: 1px solid $editColor;
$editMoveableSelectedShdw: rgba($editColor, 0.5) 0 0 10px;
$editBorderDrilledIn: 1px dashed #9971ff;
$colorGridLines: rgba($editColor, 0.2);
/************************************************** BROWSING */
$browseBorderSelectableHov: 1px dotted rgba($colorBodyFg, 0.2);
$browseShdwSelectableHov: rgba($colorBodyFg, 0.2) 0 0 3px;
$browseBorderSelected: 1px solid rgba($colorBodyFg, 0.6);
$browseFrameColor: pullForward($colorBodyBg, 10%);
$browseFrameBorder: 1px solid $browseFrameColor; // Frames in Disp and Flex Layouts when frame is showing
$browseSelectableShdwHov: rgba($colorBodyFg, 0.3) 0 0 3px;
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.4);
/************************************************** EDITING */
$editUIColor: $uiColor; // Base color
$editUIColorHov: pullForward(saturate($uiColor, 10%), 20%); // Hover color when $editUIColor is applied as a base color
$editUIBaseColor: #cae1ff; // Base color, toolbar bg
$editUIBaseColorHov: pushBack($editUIBaseColor, 20%);
$editUIBaseColorFg: #4c4c4c; // Toolbar button icon colors, etc.
$editUIAreaBaseColor: pullForward(saturate($editUIBaseColor, 30%), 20%);
$editUIAreaShdw: $editUIAreaBaseColor 0 0 0 2px; // Edit area s-selected-parent
$editUIAreaShdwSelected: $editUIAreaBaseColor 0 0 0 3px; // Edit area s-selected
$editUIGridColorBg: rgba($editUIBaseColor, 0.2); // Background of layout editing area
$editUIGridColorFg: rgba($editUIBaseColor, 0.3); // Grid lines in layout editing area
$editFrameColor: $browseFrameColor; // Solid or dotted border applied to non-selected frames in a layout; move-bar on frame hover
$editFrameBorder: 1px dotted $editFrameColor;
$editFrameColorHov: $editUIColor; // Solid border hover on frames; hover should not be applied to selected objects
$editFrameBorderHov: 1px solid $editFrameColorHov; // Hover on selectable frames
$editFrameColorSelected: #333; // Border of selected frames
$editFrameColorHandleBg: $colorBodyBg; // Resize handle 'offset' color to make handle standout
$editFrameColorHandleFg: $editFrameColorSelected; // Resize handle main color
$editFrameSelectedShdw: rgba(black, 0.5) 0 1px 10px 1px;
$editFrameSelectedBorder: 1px dashed $editFrameColorSelected; // Selected frame element
$editFrameMovebarColorBg: $editFrameColor; // Movebar bg color
$editFrameMovebarColorFg: pullForward($editFrameMovebarColorBg, 20%); // Grippy lines, container size text
$editFrameHovMovebarColorBg: pullForward($editFrameMovebarColorBg, 10%); // Hover style
$editFrameHovMovebarColorFg: pullForward($editFrameMovebarColorFg, 10%);
$editFrameSelectedMovebarColorBg: pullForward($editFrameMovebarColorBg, 15%); // Selected style
$editFrameSelectedMovebarColorFg: pullForward($editFrameMovebarColorFg, 15%);
$editFrameMovebarH: 10px; // Height of move bar in layout frame
// Icons
$colorIconAlias: #4af6f3;
@@ -146,7 +159,7 @@ $colorTabsHolderBg: rgba($colorBodyFg, 0.2);
// Buttons and Controls
$colorBtnBg: #aaa;
$colorBtnBgHov: darken($colorBtnBg, 10%);
$colorBtnBgHov: pullForward($colorBtnBg, 10%);
$colorBtnFg: #fff;
$colorBtnReverseFg: $colorBodyBg;
$colorBtnReverseBg: $colorBodyFg;
@@ -154,7 +167,7 @@ $colorBtnFgHov: $colorBtnFg;
$colorBtnMajorBg: $colorKey;
$colorBtnMajorBgHov: $colorKeyHov;
$colorBtnMajorFg: $colorKeyFg;
$colorBtnMajorFgHov: lighten($colorBtnMajorFg, 10%);
$colorBtnMajorFgHov: pushBack($colorBtnMajorFg, 10%);
$colorBtnCautionBg: #f16f6f;
$colorBtnCautionBgHov: #f1504e;
$colorBtnCautionFg: $colorBtnFg;
@@ -162,13 +175,15 @@ $colorClickIcon: $colorKey;
$colorClickIconBgHov: rgba($colorKey, 0.2);
$colorClickIconFgHov: $colorKeyHov;
$colorDropHint: $colorKey;
$colorDropHintBg: lighten($colorDropHint, 30%);
$colorDropHintBgHov: lighten($colorDropHint, 40%);
$colorDropHintFg: lighten($colorDropHint, 0);
$colorDropHintBg: pushBack($colorDropHint, 10%);
$colorDropHintBgHov: pushBack($colorDropHint, 40%);
$colorDropHintFg: pushBack($colorDropHint, 0);
$colorDisclosureCtrl: rgba($colorBodyFg, 0.5);
$colorDisclosureCtrlHov: rgba($colorBodyFg, 0.7);
// Menus
$colorMenuBg: lighten($colorBodyBg, 10%);
$colorMenuFg: darken($colorMenuBg, 70%);
$colorMenuBg: pushBack($colorBodyBg, 10%);
$colorMenuFg: pullForward($colorMenuBg, 70%);
$colorMenuIc: $colorKey;
$colorMenuHovBg: $colorMenuIc;
$colorMenuHovFg: $colorMenuBg;
@@ -195,27 +210,27 @@ $colorFormLines: rgba(#000, 0.1);
$colorFormSectionHeader: rgba(#000, 0.05);
$colorInputBg: $colorGenBg;
$colorInputFg: $colorBodyFg;
$colorInputPlaceholder: lighten($colorBodyFg, 20%);
$colorFormText: lighten($colorBodyFg, 10%);
$colorInputIcon: lighten($colorBodyFg, 25%);
$colorFieldHint: darken($colorBodyFg, 40%);
$colorInputPlaceholder: pushBack($colorBodyFg, 20%);
$colorFormText: pushBack($colorBodyFg, 10%);
$colorInputIcon: pushBack($colorBodyFg, 25%);
$colorFieldHint: pullForward($colorBodyFg, 40%);
$shdwInput: inset rgba(black, 0.7) 0 0 1px;
$shdwInputHov: inset rgba(black, 0.7) 0 0 2px;
$shdwInputFoc: inset rgba(black, 0.8) 0 0.25px 3px;
// Inspector
$colorInspectorBg: darken($colorBodyBg, 5%);
$colorInspectorBg: pullForward($colorBodyBg, 5%);
$colorInspectorFg: $colorBodyFg;
$colorInspectorPropName: lighten($colorBodyFg, 20%);
$colorInspectorPropVal: darken($colorInspectorFg, 15%);
$colorInspectorSectionHeaderBg: darken($colorInspectorBg, 5%);
$colorInspectorSectionHeaderFg: darken($colorInspectorBg, 40%);
$colorInspectorPropName: pushBack($colorBodyFg, 20%);
$colorInspectorPropVal: pullForward($colorInspectorFg, 15%);
$colorInspectorSectionHeaderBg: pullForward($colorInspectorBg, 5%);
$colorInspectorSectionHeaderFg: pullForward($colorInspectorBg, 40%);
// Overlay
$overlayColorBg: $colorMenuBg;
$overlayColorFg: $colorMenuFg;
$overlayCr: $interiorMarginLg;
$overlayBrightnessAdjust: brightness(1);
$overlayBrightnessAdjust: brightness(1.3);
// Indicator colors
$colorIndicatorAvailable: $colorKey;
@@ -223,35 +238,50 @@ $colorIndicatorDisabled: #444;
$colorIndicatorOn: $colorOk;
$colorIndicatorOff: #666;
// Limits and staleness colors//
$colorTelemFresh: darken($colorBodyFg, 20%);
$colorTelemStale: lighten($colorBodyFg, 20%);
// Staleness
$colorTelemFresh: pullForward($colorBodyFg, 20%);
$colorTelemStale: pushBack($colorBodyFg, 20%);
$styleTelemStale: italic;
$colorLimitYellowBg: rgba(#ffaa00, 0.3);
$colorLimitYellowIc: #ffaa00;
$colorLimitRedBg: rgba(red, 0.3);
$colorLimitRedIc: red;
// Limits
$colorLimitYellowBg: #ffe64d;
$colorLimitYellowFg: #7f4f20;
$colorLimitYellowIc: #e7a115;
$colorLimitRedBg: #ff0000;
$colorLimitRedFg: #fff;
$colorLimitRedIc: #ffa99a;
// Status
$colorAlert: #ff3c00;
$colorWarningHi: #990000;
$colorWarningLo: #ff9900;
$colorDiagnostic: #a4b442;
$colorCommand: #3693bd;
$colorInfo: #2294a2;
$colorOk: #33cc33;
// Bubble colors
$colorInfoBubbleBg: $colorMenuBg;
$colorInfoBubbleFg: #666;
// Items
$colorItemBg: lighten($colorBtnBg, 20%);
$colorItemBgHov: lighten($colorItemBg, 5%);
$colorItemBg: pushBack($colorBtnBg, 20%);
$colorItemBgHov: pushBack($colorItemBg, 5%);
$colorListItemBg: transparent;
$colorListItemBgHov: rgba($colorKey, 0.1);
$colorItemFg: $colorBodyFg;
$colorItemFgDetails: lighten($colorItemFg, 15%);
$colorItemFgDetails: pushBack($colorItemFg, 15%);
$shdwItemText: none;
// Tabular
$colorTabBorder: darken($colorBodyBg, 10%);
$colorTabBorder: pullForward($colorBodyBg, 10%);
$colorTabBodyBg: $colorBodyBg;
$colorTabBodyFg: darken($colorBodyFg, 20%);
$colorTabHeaderBg: darken($colorBodyBg, 10%);
$colorTabHeaderFg: darken($colorBodyFg, 20%);
$colorTabBodyFg: pullForward($colorBodyFg, 20%);
$colorTabHeaderBg: pullForward($colorBodyBg, 10%);
$colorTabHeaderFg: pullForward($colorBodyFg, 20%);
$colorTabHeaderBorder: $colorBodyBg;
$colorTabGroupHeaderBg: pullForward($colorBodyBg, 5%);
$colorTabGroupHeaderFg: pullForward($colorTabGroupHeaderBg, 40%);
// Plot
$colorPlotBg: rgba(black, 0.05);
@@ -260,25 +290,24 @@ $colorPlotHash: black;
$opacityPlotHash: 0.2;
$stylePlotHash: dashed;
$colorPlotAreaBorder: $colorInteriorBorder;
$colorPlotLabelFg: lighten($colorPlotFg, 20%);
$legendCollapsedNameMaxW: 50%;
$colorPlotLabelFg: pushBack($colorPlotFg, 20%);
$legendHoverValueBg: rgba($colorBodyFg, 0.2);
// Tree
$colorTreeBg: transparent;
$colorItemTreeHoverBg: darken($colorBodyBg, 10%);
$colorItemTreeHoverFg: darken($colorBodyFg, 10%);
$colorItemTreeHoverBg: pullForward($colorBodyBg, 10%);
$colorItemTreeHoverFg: pullForward($colorBodyFg, 10%);
$colorItemTreeIcon: $colorKey; // Used
$colorItemTreeIconHover: $colorItemTreeIcon; // Used
$colorItemTreeFg: $colorBodyFg;
$colorItemTreeSelectedBg: lighten($colorKey, 15%);
$colorItemTreeSelectedBg: pushBack($colorKey, 15%);
$colorItemTreeSelectedFg: $colorBodyBg;
$colorItemTreeSelectedIcon: $colorItemTreeSelectedFg;
$colorItemTreeEditingBg: $editColor;
$colorItemTreeEditingFg: $editColorFg;
$colorItemTreeEditingIcon: $editColorFg;
$colorItemTreeVC: rgba($colorBodyFg, 0.5);
$colorItemTreeVCHover: $colorKey;
$colorItemTreeEditingBg: pushBack($editUIColor, 20%);
$colorItemTreeEditingFg: $editUIColor;
$colorItemTreeEditingIcon: $editUIColor;
$colorItemTreeVC: $colorDisclosureCtrl;
$colorItemTreeVCHover: $colorDisclosureCtrlHov;
$shdwItemTreeIcon: none;
// Images
@@ -288,16 +317,16 @@ $colorThumbHoverBg: $colorItemTreeHoverBg;
$scrollbarTrackSize: 7px;
$scrollbarTrackShdw: rgba(#000, 0.2) 0 1px 2px;
$scrollbarTrackColorBg: rgba(#000, 0.2);
$scrollbarThumbColor: darken($colorBodyBg, 50%);
$scrollbarThumbColor: pullForward($colorBodyBg, 50%);
$scrollbarThumbColorHov: $colorKey;
$scrollbarThumbColorMenu: darken($colorMenuBg, 10%);
$scrollbarThumbColorMenu: pullForward($colorMenuBg, 10%);
$scrollbarThumbColorMenuHov: darken($scrollbarThumbColorMenu, 2%);
// Splitter
$splitterHandleD: 2px;
$splitterHandleHitMargin: 4px;
$colorSplitterBaseBg: $colorBodyBg;
$colorSplitterBg: darken($colorSplitterBaseBg, 20%);
$colorSplitterBg: pullForward($colorSplitterBaseBg, 20%);
$colorSplitterFg: $colorBodyBg;
$colorSplitterHover: $colorKey;
$colorSplitterActive: $colorKey;
@@ -311,7 +340,7 @@ $splitterCollapsedBtnColorBgHov: $colorKey;
$splitterCollapsedBtnColorFgHov: $colorKeyFg;
// Mobile
$colorMobilePaneLeft: darken($colorBodyBg, 2%);
$colorMobilePaneLeft: pullForward($colorBodyBg, 2%);
$colorMobilePaneLeftTreeItemBg: rgba($colorBodyFg, 0.1);
$colorMobilePaneLeftTreeItemFg: $colorItemTreeFg;
$colorMobileSelectListTreeItemBg: rgba(#000, 0.05);
@@ -353,19 +382,6 @@ $createBtnTextTransform: uppercase;
/**************************************************** NOT USED, LEAVE FOR NOW */
// Slider controls, not in use
/*
$sliderColorBase: $colorKey;
$sliderColorRangeHolder: rgba(black, 0.07);
$sliderColorRange: rgba($sliderColorBase, 0.2);
$sliderColorRangeHov: rgba($sliderColorBase, 0.4);
$sliderColorKnob: lighten($sliderColorBase, 20%);
$sliderColorKnobHov: rgba($sliderColorBase, 0.7);
$sliderColorRangeValHovBg: $sliderColorRange;
$sliderColorRangeValHovFg: $colorBodyFg;
$sliderKnobW: 15px;
$sliderKnobR: 2px;
*/
// Content status
/*

View File

@@ -50,6 +50,15 @@ $gridItemMobile: 32px;
$tabularHeaderH: 22px;
$tabularTdPadLR: $itemPadLR;
$tabularTdPadTB: 2px;
/*************** Plots */
$plotYBarW: 60px;
$plotYLabelMinH: 20px;
$plotYLabelW: 10px;
$plotXBarH: 20px;
$plotLegendH: 20px;
$plotSwatchD: 8px;
$plotDisplayArea: (0, 0, $plotXBarH, $plotYBarW); // 1: Top, 2: right, 3: bottom, 4: left
$plotMinH: 95px;
/************************** MOBILE */
$mobileMenuIconD: 24px; // Used

View File

@@ -31,11 +31,13 @@ button {
@include cButton();
}
.c-button--menu {
&:after {
content: $glyph-icon-arrow-down;
font-family: symbolsfont;
opacity: 0.5;
.c-button {
&--menu {
&:after {
content: $glyph-icon-arrow-down;
font-family: symbolsfont;
opacity: 0.5;
}
}
}
@@ -44,23 +46,25 @@ button {
}
/********* Icon Buttons */
.c-click-icon {
.c-click-icon,
.c-click-swatch {
@include cClickIcon();
.c-click-icon__label {
margin-left: $interiorMargin;
}
&--menu {
&:after {
content: $glyph-icon-arrow-down;
font-family: symbolsfont;
font-size: 0.6em;
font-size: 0.7em;
margin-left: floor($interiorMarginSm * 0.8);
opacity: 0.5;
}
}
}
.c-click-icon {
.c-click-icon__label {
margin-left: $interiorMargin;
}
&--swatched {
// Color control, show swatch element
@@ -101,9 +105,10 @@ button {
}
/********* Disclosure Triangle */
// Provides an arrow icon that when clicked expands an element to reveal its contents.
// Used in tree items. Always placed BEFORE an element.
// Used in tree items, plot legends. Always placed BEFORE an element.
.c-disclosure-triangle {
$d: 12px;
color: $colorDisclosureCtrl;
display: flex;
align-items: center;
justify-content: center;
@@ -111,15 +116,22 @@ button {
width: $d;
position: relative;
&.is-enabled:before {
$s: .65;
content: $glyph-icon-arrow-right-equilateral;
display: block;
font-family: symbolsfont;
font-size: 1rem * $s;
position: absolute;
transform-origin: floor(($d / 2) * $s); // This is slightly better than 'center'
transition: transform 100ms ease-in-out;
&.is-enabled {
cursor: pointer;
&:hover {
color: $colorDisclosureCtrlHov;
}
&:before {
$s: .65;
content: $glyph-icon-arrow-right-equilateral;
display: block;
font-family: symbolsfont;
font-size: 1rem * $s;
transform-origin: center;
transition: transform 100ms ease-in-out;
}
}
&--expanded {
@@ -154,6 +166,11 @@ input[type=number]::-webkit-outer-spin-button {
}
.c-input {
&--flex {
width: 100%;
min-width: 20px;
}
&--datetime {
// Sized for values such as 2018-09-28 22:32:33.468Z
width: 160px;
@@ -252,6 +269,7 @@ input[type=number]::-webkit-outer-spin-button {
color: $colorMenuHovIc;
}
}
&:before {
color: $colorMenuIc;
font-size: 1em;
@@ -335,16 +353,16 @@ input[type=number]::-webkit-outer-spin-button {
&__items {
flex: 1 1 auto;
display: grid;
grid-template-columns: repeat(10, [col] auto );
grid-template-columns: repeat(auto-fill, 12px);
grid-gap: 1px;
}
&__item {
$d: 16px;
$d: 12px;
border: 1px solid transparent;
cursor: pointer;
width: 16px; height: 16px;
min-width: $d; min-height: $d;
transition: $transOut;
&:hover {
@@ -375,6 +393,12 @@ input[type=number]::-webkit-outer-spin-button {
}
}
/******************************************************** SWATCHES */
.c-color-swatch {
border: 1px solid rgba(#fff, 0.2);
box-shadow: rgba(#000, 0.2) 0 0 0 1px;
}
/******************************************************** TOOLBAR */
.c-ctrl-wrapper {
@include cCtrlWrapper();
@@ -397,21 +421,31 @@ input[type=number]::-webkit-outer-spin-button {
.c-toolbar {
$p: $interiorMargin;
border-top: 1px solid $colorInteriorBorder;
background: $editUIBaseColor;
border-radius: $basicCr;
height: $p + 24px; // Need to standardize the height
padding-top: $p;
padding: $p;
&__separator {
@include cToolbarSeparator();
}
.c-click-icon,
.c-labeled-input {
color: $editUIBaseColorFg;
}
.c-click-icon {
@include cControl();
$pLR: $interiorMargin - 1;
$pTB: 2px;
color: $colorBodyFg;
padding: $pTB $pLR;
&:hover {
background: $editUIBaseColorHov !important;
color: $editUIBaseColorFg !important;
}
&--swatched {
padding-bottom: floor($pTB / 2);
width: 2em; // Standardize the width
@@ -441,6 +475,10 @@ input[type=number]::-webkit-outer-spin-button {
margin-left: $interiorMargin;
}
}
.c-palette {
min-width: 136px;
}
}
/********* Button Sets */
@@ -453,10 +491,6 @@ input[type=number]::-webkit-outer-spin-button {
> * {
// Assume buttons are immediate descendants
flex: 0 0 auto;
+ * {
// margin-left: $interiorMarginSm;
}
}
+ .c-button-set {
@@ -497,6 +531,54 @@ input[type=number]::-webkit-outer-spin-button {
> * + * { margin-left: $interiorMargin; }
}
/******************************************************** SLIDERS AND RANGE */
@mixin sliderKnobRound() {
$h: 12px;
@include themedButton();
cursor: pointer;
width: $h;
height: $h;
border-radius: 50% !important;
transform: translateY(-42%);
}
input[type="range"] {
// HTML5 range inputs
-webkit-appearance: none; /* Hides the slider so that custom slider can be made */
background: transparent; /* Otherwise white in Chrome */
&:focus {
outline: none; /* Removes the blue border. */
}
// Thumb
&::-webkit-slider-thumb {
-webkit-appearance: none;
@include sliderKnobRound();
}
&::-moz-range-thumb {
border: none;
@include sliderKnobRound();
}
&::-ms-thumb {
border: none;
@include sliderKnobRound();
}
// Track
&::-webkit-slider-runnable-track {
width: 100%;
height: 3px;
@include sliderTrack();
}
&::-moz-range-track {
width: 100%;
height: 3px;
@include sliderTrack();
}
}
/***************************************************** DRAG AND DROP */
.c-drop-hint {
// Used in Tabs View, Flexible Grid Layouts
@@ -545,3 +627,27 @@ input[type=number]::-webkit-outer-spin-button {
opacity: 0.9;
}
}
/***************************************************** LEGACY */
.l-btn-set {
// Fixes
display: flex;
align-items: center;
}
.h-local-controls {
&-overlay-content {
box-shadow: $colorBodyBg 0 0 0 2px;
display: inline-block;
position: absolute;
right: $interiorMargin; top: $interiorMargin;
z-index: 2;
}
&-trans {
// Has a translucent background plate
background: rgba($colorBodyBg, 0.8);
border-radius: $controlCr;
}
}

View File

@@ -141,17 +141,22 @@ li {
// Local Controls: Controls placed in proximity to or overlaid on components and views
body.desktop .has-local-controls {
// Provides hover ability to show local controls
&:hover [class*="local-controls--hidden"] {
transition: opacity 50ms ease-in-out;
opacity: 1;
pointer-events: inherit;
}
[class*="local-controls--hidden"] {
[class*='local-controls--hidden'] {
transition: opacity 500ms ease-in-out;
opacity: 0;
pointer-events: none;
}
// Look down up to two levels and display hidden LC's on hover
&:hover {
> [class*='local-controls--hidden'],
> * > [class*='local-controls--hidden'],
> * > * > [class*='local-controls--hidden'] {
transition: opacity 50ms ease-in-out;
opacity: 1;
pointer-events: inherit;
}
}
}
/******************************************************** ICON BACKGROUNDS */
@@ -174,30 +179,6 @@ body.desktop .has-local-controls {
}
}
//[class*="local-controls"] {
// // An explicit outer holder for controls. Typically placed in upper right.
// //font-size: 0.7rem;
// display: flex;
// align-items: center;
// justify-content: flex-end;
//
//
// &.h-local-controls-overlay-content {
// // Imagery controls
// $p: $interiorMargin;
// position: absolute;
// top: $p; right: $p;
// z-index: 2;
// }
//.l-btn-set,
//.s-button {
// &:not(:first-child) {
// margin-left: $interiorMargin;
// }
//}
//}
/******************************************************** SELECTION AND EDITING */
// Provides supporting styles for Display Layouts and augmented legacy Fixed Position view
@@ -210,41 +191,24 @@ body.desktop .has-local-controls {
.c-grid {
pointer-events: none;
&__x { @include bgTicks($editCanvasColorGrid, 'x'); }
&__y { @include bgTicks($editCanvasColorGrid, 'y'); }
&__x { @include bgTicks($editUIGridColorFg, 'x'); }
&__y { @include bgTicks($editUIGridColorFg, 'y'); }
}
/*************************** SELECTION */
.u-inspectable {
&:hover {
box-shadow: $browseShdwSelectableHov;
box-shadow: $browseSelectableShdwHov;
}
&[s-selected] {
border: $browseSelectedBorder;
}
}
/**************************** EDITING */
.is-editing {
*:not(.is-drilled-in).c-frame {
border: $editSelectableBorder;
&:hover {
border: $editSelectableBorderHov;
}
&[s-selected],
&.is-selected {
border: $editSelectableBorderSelected;
> .c-frame-edit {
display: block; // Show the editing rect and handles
}
}
}
*.is-drilled-in {
border: $editBorderDrilledIn;
}
*[s-selected] {
.is-moveable {
cursor: move;
}
@@ -252,116 +216,8 @@ body.desktop .has-local-controls {
// Applied in markup to objects that provide links. Disable while editing.
pointer-events: none;
}
.c-frame-edit {
// In Layouts, this is the editing rect and handles
// In Fixed Position, this is a wrapper element
$z: 10;
@include abs();
display: none;
&__move {
@include abs();
box-shadow: $editMoveableSelectedShdw;
cursor: move;
z-index: $z;
}
&__handle {
$d: 8px;
$o: floor($d * -0.5);
background: rgba($editColor, 0.3);
border: 1px solid $editColor;
position: absolute;
width: $d; height: $d;
top: auto; right: auto; bottom: auto; left: auto;
z-index: $z + 1;
&:before {
// Extended hit area
$m: -5px;
content: '';
display: block;
position: absolute;
top: $m; right: $m; bottom: $m; left: $m;
z-index: -1;
}
&:hover {
background: $editColor;
}
&--nwse {
cursor: nwse-resize;
}
&--nw {
cursor: nw-resize;
left: $o; top: $o;
}
&--ne {
cursor: ne-resize;
right: $o; top: $o;
}
&--se {
cursor: se-resize;
right: $o; bottom: $o;
}
&--sw {
cursor: sw-resize;
left: $o; bottom: $o;
}
}
}
// TODO: move this into DisplayLayout and Fixed Position vue files respectively
.l-shell__main-container > .l-layout,
.l-shell__main-container > .c-object-view .l-fixed-position {
// Target the top-most layout container and color its background
background: $editCanvasColorBg;
}
.l-shell__main-container {
box-shadow: $colorBodyBg 0 0 0 1px, rgba($editColor, 0.7) 0 0 0 2px;
&[s-selected] {
// Provide a clearer selection context articulation
box-shadow: $colorBodyBg 0 0 0 1px, $editColor 0 0 0px 3px;
}
}
// Layouts
[s-selected],
[s-selected-parent] {
.l-layout {
// Show the layout grid for the top-most child of the current selection,
// and hide the grid for deeper nested levels.
[class*="__grid-holder"] {
display: block;
}
.l-layout [class*="__grid-holder"] {
display: none;
}
}
}
// Fixed position
.l-fixed-position {
&__grid-holder {
display: block;
}
.c-frame-edit {
display: block;
}
}
}
/************************** LEGACY */
mct-container {
@@ -526,42 +382,3 @@ a.disabled {
}
}
}
/************************** TEMP LEGACY FIXES */
.overlay {
.outer-holder {
background: $colorMenuBg;
color: $colorMenuFg !important;
}
}
.form .form-row {
.label {
color: $colorMenuFg !important;
}
.selector-list {
@include reactive-input();
background: $colorInputBg !important;
color: $colorInputFg !important;
}
}
.ui-symbol.view-control {
display: block;
transform-origin: center center;
&:before { content: $glyph-icon-arrow-right-equilateral; }
&.expanded {
transform: rotate(90deg);
}
}
.t-imagery {
display: contents;
}
.t-frame-outer {
min-width: 200px;
min-height: 200px;
}

627
src/styles-new/_legacy.scss Normal file
View File

@@ -0,0 +1,627 @@
/*****************************************************************************
* 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.
*****************************************************************************/
/********************************************************************* PLOTS */
mct-plot {
display: contents;
}
/********************************************* STACKED PLOT LAYOUT */
.t-plot-stacked {
.l-view-section {
// Make this a flex container
display: flex;
flex-flow: column nowrap;
.gl-plot.child-frame {
mct-plot {
display: flex;
flex: 1 1 auto;
height: 100%;
position: relative;
}
flex: 1 1 auto;
&:not(:first-child) {
margin-top: $interiorMargin;
}
}
}
.s-status-timeconductor-unsynced .holder-plot {
.t-object-alert.t-alert-unsynced {
display: block;
}
}
}
.gl-plot {
color: $colorPlotFg;
display: flex;
font-size: 0.7rem;
position: relative;
width: 100%;
height: 100%;
min-height: $plotMinH;
/********************************************* AXIS AND DISPLAY AREA */
.plot-wrapper-axis-and-display-area {
margin-top: $interiorMargin; // Keep the top tick label from getting clipped
position: relative;
flex: 1 1 auto;
.t-object-alert {
position: absolute;
display: block;
font-size: 1.5em;
top: $interiorMarginSm;
left: $interiorMarginSm;
z-index: 2;
}
}
.gl-plot-wrapper-display-area-and-x-axis {
// Holds the plot area and the X-axis only
position: absolute;
top: nth($plotDisplayArea, 1);
right:0;
bottom: 0;
left: nth($plotDisplayArea, 4);
.gl-plot-display-area {
position: absolute;
top: 0;
right: 0;
bottom: nth($plotDisplayArea, 3);
left: 0;
}
.gl-plot-axis-area.gl-plot-x {
top: auto;
right: 0;
bottom: 0;
left: 0;
height: $plotXBarH;
width: auto;
overflow: hidden;
}
}
.gl-plot-axis-area {
position: absolute;
&.gl-plot-y {
top: nth($plotDisplayArea, 1);
right: auto;
bottom: nth($plotDisplayArea, 3);
left: 0;
width: $plotYBarW;
}
}
.gl-plot-coords {
box-sizing: border-box;
border-radius: $controlCr;
background: black;
color: lighten($colorBodyFg, 30%);
padding: 2px 5px;
position: absolute;
top: nth($plotDisplayArea,1) + $interiorMarginLg;
right: auto;
bottom: auto;
left: nth($plotDisplayArea,4) + $interiorMarginLg;
z-index: 10;
&:empty {
display: none;
}
}
.gl-plot-label,
.l-plot-label {
color: $colorPlotLabelFg;
position: absolute;
text-align: center;
&.gl-plot-x-label,
&.l-plot-x-label {
top: auto;
right: 0;
bottom: 0;
left: 0;
height: auto;
}
&.gl-plot-y-label,
&.l-plot-y-label {
$x: -50%;
$r: -90deg;
transform-origin: 50% 0;
transform: translateX($x) rotate($r);
display: inline-block;
margin-left: $interiorMargin; // Kick off the left edge
left: 0;
top: 50%;
white-space: nowrap;
}
}
.gl-plot-x-options,
.gl-plot-y-options {
$h: 24px;
position: absolute;
height: $h;
min-height: $h;
z-index: 2;
}
.gl-plot-x-options {
transform: translateX(-50%);
bottom: 0;
left: 50%;
}
.gl-plot-y-options {
transform: translateY(-50%);
min-width: 150px; // Need this due to enclosure of .select
top: 50%;
left: $plotYLabelW + $interiorMargin * 2;
}
.t-plot-display-controls {
position: absolute;
top: $interiorMargin;
right: $interiorMargin;
}
.gl-plot-hash {
position: absolute;
opacity: $opacityPlotHash;
&.hash-v {
border-right: 1px $colorPlotHash $stylePlotHash;
height: 100%;
}
&.hash-h {
border-bottom: 1px $colorPlotHash $stylePlotHash;
width: 100%;
}
}
}
.gl-plot-display-area,
.plot-display-area {
@if $colorPlotBg != none {
background-color: $colorPlotBg;
}
cursor: crosshair;
border: 1px solid $colorPlotAreaBorder;
}
.tick {
position: absolute;
border: 0 $colorPlotHash solid;
&.tick-x {
border-right-width: 1px;
height: 100%; // Assumption is that the tick will be in a holder that will set it's height;
}
}
.gl-plot-tick,
.tick-label {
@include reverseEllipsis();
font-size: 0.7rem;
position: absolute;
&.gl-plot-x-tick-label,
&.tick-label-x {
right: auto;
bottom: auto;
left: auto;
height: auto;
width: 20%;
margin-left: -10%;
text-align: center;
}
&.gl-plot-y-tick-label,
&.tick-label-y {
top: auto;
height: 1em;
width: auto;
margin-bottom: -0.5em;
text-align: right;
}
}
.gl-plot-tick {
&.gl-plot-x-tick-label {
top: $interiorMargin;
}
&.gl-plot-y-tick-label {
right: $interiorMargin;
left: $interiorMargin;
}
}
.tick-label {
&.tick-label-x {
top: 0;
}
&.tick-label-y {
right: 0;
left: 0;
}
}
.export-plot {
$bg: white;
$fg: black;
$gry: #999;
background: $bg !important;
z-index: -10;
.l-view-section {
$m: $interiorMargin;
top: $m !important;
right: $m;
bottom: $m;
left: $m;
.s-status-timeconductor-unsynced .holder-plot {
.t-object-alert.t-alert-unsynced {
display: none;
}
}
}
.gl-plot-display-area {
background: none !important;
border-color: $gry !important;
.gl-plot-local-controls,
.h-local-controls {
opacity: 0;
}
}
.gl-plot {
color: $fg;
.gl-plot-hash {
opacity: 0.1;
border-color: $fg;
}
}
table {
thead {
border-bottom: none;
th {
background: #eee;
border-left-color: $bg;
color: #666;
}
tr {
border: none;
}
}
tbody {
tr {
border-top: 1px solid #ccc;
}
td {
color: $fg;
}
}
}
}
/*************************************************************************** _LEGEND.SCSS */
.gl-plot-legend {
display: flex;
align-items: flex-start;
&__view-control {
padding-top: 2px;
margin-right: $interiorMarginSm;
}
table {
table-layout: fixed;
th,
td {
@include ellipsize(); // Note: this won't work if table-layout uses anything other than fixed.
padding: 1px 3px; // Tighter than standard tabular padding
//width: 1%;
}
}
&.hover-on-plot {
// User is hovering over the plot to get a value at a point
.hover-value-enabled {
background-color: $legendHoverValueBg;
border-radius: $smallCr;
padding: 0 $interiorMarginSm;
&.value-to-display-min:before {
content: 'MIN ';
}
&.value-to-display-max:before {
content: 'MAX ';
}
}
}
}
/***************** GENERAL STYLES, ALL STATES */
.plot-legend-item {
// General styles for legend items, both expanded and collapsed legend states
.plot-series-color-swatch {
border-radius: $smallCr;
border: 1px solid $colorBodyBg;
display: inline-block;
height: $plotSwatchD;
width: $plotSwatchD;
}
.plot-series-name {
display: inline;
}
.plot-series-value {
@include ellipsize();
}
}
.plot-wrapper-expanded-legend {
flex: 1 1 auto;
}
.gl-plot {
&.plot-legend-collapsed .plot-wrapper-expanded-legend { display: none; }
&.plot-legend-expanded .plot-wrapper-collapsed-legend { display: none; }
/***************** GENERAL STYLES, COLLAPSED */
&.plot-legend-collapsed {
// .plot-legend-item is a span of spans.
&.plot-legend-top .gl-plot-legend { margin-bottom: $interiorMargin; }
&.plot-legend-bottom .gl-plot-legend { margin-top: $interiorMargin; }
&.plot-legend-right .gl-plot-legend { margin-left: $interiorMargin; }
&.plot-legend-left .gl-plot-legend { margin-right: $interiorMargin; }
.plot-legend-item {
display: flex;
align-items: center;
justify-content: stretch;
&:not(:first-child) {
margin-left: $interiorMarginLg;
}
.plot-series-swatch-and-name,
.plot-series-value {
@include ellipsize();
flex: 1 1 auto;
}
.plot-series-swatch-and-name {
margin-right: $interiorMarginSm;
}
.plot-series-value {
text-align: left;
}
}
}
/***************** GENERAL STYLES, EXPANDED */
&.plot-legend-expanded {
.gl-plot-legend {
max-height: 70%;
}
.plot-wrapper-expanded-legend {
overflow-y: auto;
}
}
/***************** TOP OR BOTTOM */
&.plot-legend-top,
&.plot-legend-bottom {
// General styles when legend is on the top or bottom
flex-direction: column;
&.plot-legend-collapsed {
// COLLAPSED ON TOP OR BOTTOM
.plot-wrapper-collapsed-legend {
display: flex;
flex: 1 1 auto;
overflow: hidden;
}
}
}
/***************** EITHER SIDE */
&.plot-legend-left,
&.plot-legend-right {
// If the legend is expanded, use flex-col instead so that the legend gets the width it needs.
&.plot-legend-expanded {
// EXPANDED, ON EITHER SIDE
flex-direction: column;
}
&.plot-legend-collapsed {
// COLLAPSED, ON EITHER SIDE
.gl-plot-legend {
max-height: inherit;
width: 25%;
}
.plot-wrapper-collapsed-legend {
display: flex;
flex-flow: column nowrap;
min-width: 0;
flex: 1 1 auto;
overflow-y: auto;
}
.plot-legend-item {
margin-bottom: 1px;
margin-left: 0;
flex-wrap: wrap;
.plot-series-swatch-and-name {
flex: 0 1 auto;
min-width: 20%;
}
.plot-series-value {
flex: 0 1 auto;
width: auto;
}
}
}
}
/***************** ON BOTTOM OR RIGHT */
&.plot-legend-right:not(.plot-legend-expanded),
&.plot-legend-bottom {
.gl-plot-legend {
order: 2;
}
.plot-wrapper-axis-and-display-area {
order: 1;
}
}
}
/********************************************************* CLOCKS AND TIMERS */
.c-clock,
.c-timer {
display: flex;
align-items: center;
font-size: 1.25em;
> * {
flex: 0 0 auto;
display: flex;
align-items: center;
}
&__value {
color: $colorBodyFgEm;
}
}
.c-clock {
> * + * { margin-left: $interiorMargin; }
}
.c-timer {
$ctrlW: 22px;
&__controls {
margin-right: 0;
min-width: 0;
overflow: hidden;
transition: $transOut;
width: 0;
.c-click-icon:before { font-size: 1em; }
}
&__direction {
font-size: 0.9em;
margin-right: $interiorMargin;
}
&__ng-controller {
font-size: 0;
width: 0;
}
&:hover {
.c-timer__controls {
transition: $transOut; // On purpose: want this to take a bit longer
margin-right: $interiorMargin;
width: $ctrlW * 2;
}
&.is-stopped .c-timer__controls { width: $ctrlW; }
}
&__direction,
&__value {
opacity: 0.5;
}
&.is-started {
.c-timer {
&__direction,
&__value {
opacity: 1;
}
}
}
}
/******************************************************************* VARIOUS */
.overlay {
.outer-holder {
background: $colorMenuBg;
color: $colorMenuFg !important;
}
}
.form .form-row {
.label {
color: $colorMenuFg !important;
}
.selector-list {
@include reactive-input();
background: $colorInputBg !important;
color: $colorInputFg !important;
}
}
.ui-symbol.view-control {
display: block;
transform-origin: center center;
&:before { content: $glyph-icon-arrow-right-equilateral; }
&.expanded {
transform: rotate(90deg);
}
}
.t-imagery {
display: contents;
}
.t-frame-outer {
min-width: 200px;
min-height: 200px;
}
/******************************************************************* EDITING */
.is-editing {
// Fixed position
.l-fixed-position {
&__grid-holder {
display: block;
}
.c-frame-edit {
display: block;
}
}
}

View File

@@ -80,8 +80,7 @@
transparent 50%, rgba($c, $a) 50%,
rgba($c, $a) 75%, transparent 75%,
transparent 100%
);
background-repeat: repeat;
) repeat;
background-size: $d $d;
}
@@ -91,8 +90,7 @@
transparent 50%, rgba($c, $a) 50%,
rgba($c, $a) 75%, transparent 75%,
transparent 100%
);
background-repeat: repeat;
) repeat;
background-size: $bgsize $bgsize;
}
@@ -102,6 +100,23 @@
cursor: default !important;
}
@mixin grippy($c: rgba(black, 0.5), $dir: 'x') {
$deg: 90deg;
$bgSize: 2px 100%;
@if $dir != 'x' {
// Grippy texture runs 'vertically'
$deg: 0deg;
$bgSize: 100% 2px;
}
background: linear-gradient($deg,
$c 1px, transparent 1px,
transparent 100%
) repeat;
background-size: $bgSize;
}
@mixin noColor() {
// A "no fill/stroke" selection option. Used in palettes.
$c: red;
@@ -133,6 +148,12 @@
background-repeat: $repeatDir;
}
@mixin sliderTrack($bg: $scrollbarTrackColorBg) {
border-radius: 2px;
box-sizing: border-box;
background-color: $bg;
}
@mixin bgVertStripes($c: yellow, $a: 0.1, $d: 40px) {
background-image: linear-gradient(-90deg,
rgba($c, $a) 0%, rgba($c, $a) 50%,
@@ -288,7 +309,7 @@
padding: $interiorMargin floor($interiorMargin * 1.25);
&:after,
> * {
> * + * {
margin-left: $interiorMarginSm;
}
@@ -323,13 +344,12 @@
// Make the icon bigger relative to its container
@include cControl();
$pLR: 4px;
$pTB: 3px;
$pTB: 4px;
background: none;
box-shadow: none;
border-radius: $controlCr;
color: $colorKey;
cursor: pointer;
padding: $pTB $pLR ;
padding: $pTB $pLR;
@include hover() {
background: $colorClickIconBgHov;
@@ -342,6 +362,10 @@
// Needed for c-togglebutton.
font-size: 1.25em;
}
&[class*="--major"] {
color: $colorKey;
}
}
@mixin cCtrlWrapper {
@@ -500,5 +524,7 @@
}
@mixin test($c: deeppink, $a: 0.3) {
background: rgba($c, $a) !important;
background-color: rgba($c, $a) !important;
box-shadow: deeppink 0 0 10px 1px !important;
}

113
src/styles-new/_status.scss Normal file
View File

@@ -0,0 +1,113 @@
/*****************************************************************************
* 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.
*****************************************************************************/
/*************************************************** MIXINS */
@mixin statusStyle($bg, $fg, $ic) {
background: $bg !important;
background-color: $bg !important;
color: $fg !important;
&:before {
color: $ic;
display: inline-block;
font-family: symbolsfont;
font-size: 0.7em;
margin-right: $interiorMargin;
}
}
@mixin elementStatusColors($c) {
// Sets bg and icon colors for elements
background: rgba($c, 0.5) !important;
&:before {
color: $c !important;
}
}
@mixin indicatorStatusColors($c) {
&:before, .count {
color: $c;
}
}
.is-limit--yellow {
@include statusStyle($colorLimitYellowBg, $colorLimitYellowFg, $colorLimitYellowIc);
&.is-limit--upr:before { content: $glyph-icon-arrow-up; }
&.is-limit--lwr:before { content: $glyph-icon-arrow-down; }
}
.is-limit--red {
@include statusStyle($colorLimitRedBg, $colorLimitRedFg, $colorLimitRedIc);
&.is-limit--upr:before { content: $glyph-icon-arrow-double-up; }
&.is-limit--lwr:before { content: $glyph-icon-arrow-double-down; }
}
/*************************************************** STATUS */
[class*='s-status'] {
&:before {
margin-right: $interiorMargin;
}
}
.s-status-warning-hi, .s-status-icon-warning-hi { @include elementStatusColors($colorWarningHi); }
.s-status-warning-lo, .s-status-icon-warning-lo { @include elementStatusColors($colorWarningLo); }
.s-status-diagnostic, .s-status-icon-diagnostic { @include elementStatusColors($colorDiagnostic); }
.s-status-info, .s-status-icon-info { @include elementStatusColors($colorInfo); }
.s-status-ok, .s-status-icon-ok { @include elementStatusColors($colorOk); }
.s-status-icon-warning-hi:before { content: $glyph-icon-alert-triangle; }
.s-status-icon-warning-lo:before { content: $glyph-icon-alert-rect; }
.s-status-icon-diagnostic:before { content: $glyph-icon-eye-open; }
.s-status-icon-info:before { content: $glyph-icon-info; }
.s-status-icon-ok:before { content: $glyph-icon-check; }
/*************************************************** INDICATOR COLORING */
.ls-indicator {
&.s-status-info {
@include indicatorStatusColors($colorInfo);
}
&.s-status-disabled {
@include indicatorStatusColors($colorIndicatorDisabled);
}
&.s-status-available {
@include indicatorStatusColors($colorIndicatorAvailable);
}
&.s-status-on,
&.s-status-enabled {
@include indicatorStatusColors($colorIndicatorOn);
}
&.s-status-off {
@include indicatorStatusColors($colorIndicatorOff);
}
&.s-status-caution,
&.s-status-warning,
&.s-status-alert {
@include indicatorStatusColors($colorStatusAlert);
}
&.s-status-error {
@include indicatorStatusColors($colorStatusError);
}
}

View File

@@ -21,15 +21,41 @@
*****************************************************************************/
/******************************************************** TABLE */
table {
$minW: 50px;
width: 100%;
thead {
background: $colorTabHeaderBg;
th + th {
border-left: 1px solid $colorTabHeaderBorder;
}
}
tbody {
tr + tr {
border-top: 1px solid $colorTabBorder;
}
}
th, td {
white-space: nowrap;
min-width: $minW;
padding: $tabularTdPadTB $tabularTdPadLR;
}
td {
vertical-align: top;
}
}
.c-table {
// Can be used by any type of table, scrolling, LAD, etc.
$min-w: 50px;
display: flex;
flex-flow: column nowrap;
justify-content: flex-start;
position: absolute;
top: 0; right: 0; bottom: 0; left: 0;
width: 100%;
&__control-bar,
&__headers-w {
@@ -37,21 +63,12 @@
}
/******************************* ELEMENTS */
th, td {
white-space: nowrap;
min-width: $min-w;
padding: $tabularTdPadTB $tabularTdPadLR;
}
td {
color: $colorTelemFresh;
vertical-align: top;
}
&__control-bar {
margin-bottom: $interiorMarginSm;
}
thead tr,
[class*="__header"] {
background: $colorTabHeaderBg;
@@ -62,14 +79,20 @@
}
}
tbody,
&__body {
tr {
&:not(:first-child) {
border-top: 1px solid $colorTabBorder;
}
tr:not(.c-table__group-header) + tr:not(.c-table__group-header) {
border-top: 1px solid $colorTabBorder;
}
}
&__group-header {
// tr element found in LAD Table Sets
border-top: 1px solid $colorTabHeaderBorder;
background: $colorTabGroupHeaderBg;
td { color: $colorTabGroupHeaderFg; }
}
&--sortable {
.is-sorting {
&:after {
@@ -88,4 +111,10 @@
cursor: pointer;
}
}
}
.c-lad-table {
th, td {
width: 33%; // Needed to prevent size jumping as values dynamically update
}
}

View File

@@ -26,7 +26,10 @@
/******************** RENDERS CSS */
@import "glyphs";
@import "global";
@import "status";
@import "controls";
@import "table";
@import "legacy";
/******************** LEGACY CSS */
$output-bourbon-deprecation-warnings: false;

View File

@@ -14,7 +14,7 @@
//@import "../styles/about";
//@import "../styles/text";
@import "../styles/icons";
@import "../styles/status";
//@import "../styles/status";
@import "../styles/data-status";
@import "../styles/helpers/bubbles";
@import "../styles/helpers/splitter";
@@ -57,8 +57,8 @@
//!********************************* VIEWS *!
@import "../styles/fixed-position";
//@import "../styles/lists/tabular";
@import "../styles/plots/plots-main";
@import "../styles/plots/legend";
//@import "../styles/plots/plots-main";
//@import "../styles/plots/legend";
@import "../styles/iframe";
@import "../styles/views";
@import "../styles/items/item";
@@ -69,11 +69,9 @@
//!********************************* TO BE MOVED *!
@import "../styles/autoflow";
@import "../styles/features/imagery";
@import "../styles/features/time-display";
//@import "../styles/features/time-display";
@import "../styles/widgets";
//
//!********************************* APP STARTUP *!
//@import "../styles/app-start";
@import "../styles/conductor/time-conductor-snow";
//@import "../styles/notebook/notebook-snow";

View File

@@ -53,7 +53,7 @@
}
> .abs.outer-holder {
z-index: 72;
z-index: 70;
> .abs.inner-holder {
$m: $overlayMargin;
top: $m;

View File

@@ -20,9 +20,10 @@
* at runtime from the About dialog for additional information.
*****************************************************************************/
<template>
<div class="u-contents c-so-view"
<div class="c-so-view has-local-controls"
:class="{
'c-so-view--no-frame': !hasFrame
'c-so-view--no-frame': !hasFrame,
'has-complex-content': complexContent
}">
<div class="c-so-view__header">
<div class="c-so-view__header__start">
@@ -47,10 +48,15 @@
@import "~styles/sass-base";
.c-so-view {
display: flex;
flex-direction: column;
/*************************** HEADER */
&__header {
flex: 0 0 auto;
display: flex;
align-items: center;
margin-bottom: $interiorMargin;
&__start,
&__end {
@@ -71,7 +77,7 @@
}
}
&--no-frame .c-so-view__header {
&--no-frame > .c-so-view__header {
display: none;
}
@@ -107,6 +113,11 @@
import ObjectView from './ObjectView.vue'
import ContextMenuDropDown from './contextMenuDropDown.vue';
const SIMPLE_CONTENT_TYPES = [
'clock',
'summary-widget'
];
export default {
inject: ['openmct'],
props: {
@@ -114,21 +125,19 @@
objectPath: Array,
hasFrame: Boolean,
},
computed: {
cssClass() {
if (!this.domainObject || !this.domainObject.type) {
return;
}
let objectType = this.openmct.types.get(this.domainObject.type);
if (!objectType || !objectType.definition) {
return; // TODO: return unknown icon type.
}
return objectType.definition.cssClass;
}
},
components: {
ObjectView,
ContextMenuDropDown,
},
data() {
let objectType = this.openmct.types.get(this.domainObject.type),
cssClass = objectType && objectType.definition ? objectType.definition.cssClass : 'icon-object-unknown',
complexContent = !SIMPLE_CONTENT_TYPES.includes(this.domainObject.type);
return {
cssClass,
complexContent
}
}
}
</script>

View File

@@ -2,6 +2,7 @@
<a class="c-tree__item__label"
draggable="true"
@dragstart="dragStart"
@click="navigateOrPreview"
:href="objectLink">
<div class="c-tree__item__type-icon"
:class="typeClass"></div>
@@ -13,12 +14,19 @@
import ObjectLink from '../mixins/object-link';
import ContextMenuGesture from '../mixins/context-menu-gesture';
import PreviewAction from '../preview/PreviewAction.js';
export default {
mixins: [ObjectLink, ContextMenuGesture],
inject: ['openmct'],
props: {
domainObject: Object
domainObject: Object,
objectPath: {
type: Array,
default() {
return [];
}
}
},
data() {
return {
@@ -32,6 +40,7 @@ export default {
});
this.$once('hook:destroyed', removeListener);
}
this.previewAction = new PreviewAction(this.openmct);
},
computed: {
typeClass() {
@@ -43,13 +52,32 @@ export default {
}
},
methods: {
navigateOrPreview(event) {
if (this.openmct.editor.isEditing()){
event.preventDefault();
this.preview();
}
},
preview() {
if (this.previewAction.appliesTo(this.objectPath)){
this.previewAction.invoke(this.objectPath);
}
},
dragStart(event) {
let navigatedObject = this.openmct.router.path[0];
let serializedObject = JSON.stringify(this.observedObject);
let serializedPath = JSON.stringify(this.objectPath);
/*
* Cannot inspect data transfer objects on dragover/dragenter so impossible to determine composability at
* that point. If dragged object can be composed by navigated object, then indicate with presence of
* 'composable-domain-object' in data transfer
*/
if (this.openmct.composition.checkPolicy(navigatedObject, this.observedObject)) {
event.dataTransfer.setData("openmct/composable-domain-object", serializedObject);
event.dataTransfer.setData("openmct/composable-domain-object", JSON.stringify(this.domainObject));
}
event.dataTransfer.setData("openmct/domain-object", serializedObject);
// serialize domain object anyway, because some views can drag-and-drop objects without composition
// (eg. notabook.)
event.dataTransfer.setData("openmct/domain-object-path", serializedPath);
}
}
}

View File

@@ -35,6 +35,11 @@
display: block;
}
}
input[type='text'],
input[type='search'] {
text-align: left;
}
}
</style>

View File

@@ -6,7 +6,7 @@
v-if="elements.length > 0">
<li :key="element.identifier.key" v-for="(element, index) in elements" @drop="moveTo(index)" @dragover="allowDrop">
<div class="c-tree__item c-elements-pool__item">
<span class="icon-grippy"
<span class="c-elements-pool__grippy"
v-if="elements.length > 1 && isEditing"
draggable="true"
@dragstart="moveFrom(index)">
@@ -42,12 +42,13 @@
overflow: auto;
}
&__item {
.icon-grippy {
font-size: 0.8em;
}
&__grippy {
$d: 8px;
@include grippy($c: $colorItemTreeVC, $dir: 'y');
margin-right: $interiorMarginSm;
transform: translateY(-2px);
width: $d; height: $d;
}
}
.js-last-place{
@@ -155,6 +156,7 @@ export default {
}
},
destroyed() {
this.openmct.selection.off('change', this.showSelection);
}
}
</script>

View File

@@ -49,6 +49,14 @@
}
}
.c-color-swatch {
$d: 12px;
display: block;
flex: 0 0 auto;
width: $d;
height: $d;
}
/************************************************************** LEGACY */
// TODO: refactor when legacy properties markup can be converted
.inspector-location {
@@ -128,9 +136,6 @@
grid-column: 1 / 3;
}
+ .c-properties {
// Margin between components
margin-top: $interiorMarginLg;
@@ -176,6 +181,27 @@
}
}
}
/********************************************* LEGACY SUPPORT */
.c-inspector {
li.grid-row + li.grid-row {
> * {
border-top: 1px solid $colorInspectorSectionHeaderBg;
}
}
li.grid-row .label {
color: $colorInspectorPropName;
}
li.grid-row .value {
color: $colorInspectorPropVal;
word-break: break-all;
&:first-child {
// If there is no preceding .label element, make value span columns
grid-column: 1 / 3;
}
}
}
</style>
<script>

View File

@@ -1,7 +1,9 @@
<template>
<div class="l-browse-bar">
<div class="l-browse-bar__start">
<button class="l-browse-bar__nav-to-parent-button c-click-icon icon-pointer-left"></button>
<button v-if="hasParent"
class="l-browse-bar__nav-to-parent-button c-click-icon c-click-icon--major icon-pointer-left"
@click="goToParent"></button>
<div class="l-browse-bar__object-name--w"
:class="type.cssClass">
<span
@@ -43,7 +45,7 @@
title="New Notebook entry"
@click="snapshot()">
</button>
<button class="l-browse-bar__actions__notebook-entry c-button c-button--major icon-pencil" title="Edit" v-if="!isEditing" @click="edit()"></button>
<button class="l-browse-bar__actions__notebook-entry c-button c-button--major icon-pencil" title="Edit" v-if="isViewEditable & !isEditing" @click="edit()"></button>
<button class="l-browse-bar__actions c-button c-button--major icon-save" title="Save and Finish Editing" v-if="isEditing" @click="saveAndFinishEditing()"></button>
<button class="l-browse-bar__actions c-button icon-x" title="Cancel Editing" v-if="isEditing" @click="cancelEditing()"></button>
</div>
@@ -53,6 +55,7 @@
<script>
import NotebookSnapshot from '../utils/notebook-snapshot';
const PLACEHOLDER_OBJECT = {};
export default {
inject: ['openmct'],
@@ -95,12 +98,15 @@ import NotebookSnapshot from '../utils/notebook-snapshot';
snapshot() {
let element = document.getElementsByClassName("l-shell__main-container")[0];
this.notebookSnapshot.capture(this.domainObject, element);
},
goToParent(){
window.location.hash = this.parentUrl;
}
},
data: function () {
return {
showViewMenu: false,
domainObject: {},
domainObject: PLACEHOLDER_OBJECT,
viewKey: undefined,
isEditing: this.openmct.editor.isEditing()
}
@@ -122,12 +128,29 @@ import NotebookSnapshot from '../utils/notebook-snapshot';
};
});
},
hasParent() {
return this.domainObject !== PLACEHOLDER_OBJECT &&
this.parentUrl !== '#/browse'
},
parentUrl() {
let objectKeyString = this.openmct.objects.makeKeyString(this.domainObject.identifier);
let hash = window.location.hash;
return hash.slice(0, hash.lastIndexOf('/' + objectKeyString));
},
type() {
let objectType = this.openmct.types.get(this.domainObject.type);
if (!objectType) {
return {}
}
return objectType.definition;
},
isViewEditable() {
let currentViewKey = this.currentView.key;
if (currentViewKey !== undefined) {
let currentViewProvider = this.openmct.objectViews.getByProviderKey(currentViewKey);
return currentViewProvider.canEdit && currentViewProvider.canEdit(this.domainObject);
}
return false;
}
},
mounted: function () {

View File

@@ -5,11 +5,11 @@
<div class="l-shell__head">
<CreateButton class="l-shell__create-button"></CreateButton>
<div class="l-shell__controls">
<button class="c-click-icon icon-new-window" title="Open in a new browser tab"
<button class="c-click-icon c-click-icon--major icon-new-window" title="Open in a new browser tab"
@click="openInNewTab"
target="_blank">
</button>
<button v-bind:class="['c-click-icon', fullScreen ? 'icon-fullscreen-collapse' : 'icon-fullscreen-expand']"
<button v-bind:class="['c-click-icon c-click-icon--major', fullScreen ? 'icon-fullscreen-collapse' : 'icon-fullscreen-expand']"
v-bind:title="`${fullScreen ? 'Exit' : 'Enable'} full screen mode`"
@click="fullScreenToggle">
</button>
@@ -184,7 +184,6 @@
}
/******************************* MAIN AREA */
&__main-container {
// Wrapper for main views
flex: 1 1 auto !important;
@@ -232,6 +231,17 @@
}
}
}
.is-editing {
.l-shell__main-container {
box-shadow: $colorBodyBg 0 0 0 1px, $editUIAreaShdw;
&[s-selected] {
// Provide a clearer selection context articulation for the main edit area
box-shadow: $colorBodyBg 0 0 0 1px, $editUIAreaShdwSelected;
}
}
}
</style>
<script>

View File

@@ -33,6 +33,7 @@
display: flex;
align-items: center;
cursor: pointer;
line-height: 110%;
padding: $interiorMargin - $aPad;
transition: background 150ms ease;
@@ -47,7 +48,7 @@
}
}
&.is-selected {
&.is-navigated-object {
background: $colorItemTreeSelectedBg;
.c-tree__item__type-icon:before {
color: $colorItemTreeIconHover;
@@ -71,7 +72,6 @@
}
&__view-control {
color: $colorItemTreeVC;
margin-right: $interiorMarginSm;
}

View File

@@ -1,7 +1,7 @@
<template>
<li class="c-tree__item-h">
<div class="c-tree__item"
:class="{ 'is-alias': isAlias }">
:class="{ 'is-alias': isAlias, 'is-navigated-object': isNavigated }">
<view-control class="c-tree__item__view-control"
:enabled="hasChildren"
v-model="expanded">
@@ -31,10 +31,13 @@
node: Object
},
data() {
this.pathToObject = this.buildPathString(this.node.objectPath);
return {
hasChildren: false,
isLoading: false,
loaded: false,
isNavigated: this.pathToObject === this.openmct.router.currentLocation.path,
children: [],
expanded: false
}
@@ -47,7 +50,7 @@
}
let parentKeyString = this.openmct.objects.makeKeyString(parent.identifier);
return parentKeyString !== this.node.object.location;
}
},
},
mounted() {
// TODO: should update on mutation.
@@ -65,11 +68,14 @@
if (this.openmct.composition.get(this.node.object)) {
this.hasChildren = true;
}
this.openmct.router.on('change:path', this.highlightIfNavigated);
},
destroy() {
if (this.composition) {
this.composition.off('add', this.addChild);
this.composition.off('remove', this.removeChild);
this.openmct.router.off('change:path', this.highlightIfNavigated);
delete this.composition;
}
},
@@ -102,6 +108,18 @@
finishLoading () {
this.isLoading = false;
this.loaded = true;
},
buildPathString(path) {
return '/browse/' + path.map(o => o && this.openmct.objects.makeKeyString(o.identifier))
.reverse()
.join('/');
},
highlightIfNavigated(newPath, oldPath){
if (newPath === this.pathToObject) {
this.isNavigated = true;
} else if (oldPath === this.pathToObject) {
this.isNavigated = false;
}
}
},
components: {

View File

@@ -61,4 +61,13 @@ export default class PreviewAction {
onDestroy: () => preview.$destroy()
});
}
appliesTo(objectPath) {
return !this._isNavigatedObject(objectPath)
}
_isNavigatedObject(objectPath) {
let targetObject = objectPath[0];
let navigatedObject = this._openmct.router.path[0];
return targetObject.identifier.namespace === navigatedObject.identifier.namespace &&
targetObject.identifier.key === navigatedObject.identifier.key;
}
}

View File

@@ -170,6 +170,18 @@ define([], function () {
* otherwise 'false'.
*/
/**
* An optional function that defines whether or not this view can be used to edit a given object.
* If not provided, will default to `false` and the view will not support editing.
*
* @method canEdit
* @memberof module:openmct.ViewProvider#
* @param {module:openmct.DomainObject} domainObject the domain object
* to be edited
* @returns {boolean} 'true' if the view can be used to edit the provided object,
* otherwise 'false'.
*/
/**
* Optional method determining the priority of a given view. If this
* function is not defined on a view provider, then a default priority

View File

@@ -67,7 +67,7 @@
if (formKeys.length > 0) {
toolbarItem.value = this.getFormValue(domainObject, toolbarItem);
} else {
toolbarItem.value = _.get(domainObject, item.property);
toolbarItem.value = _.get(domainObject, this.getItemProperty(item));
}
this.registerListener(domainObject);
@@ -116,7 +116,7 @@
if (toolbarItem.formKeys) {
toolbarItem.value = this.getFormValue(newObject, toolbarItem);
} else {
toolbarItem.value = _.get(newObject, item.property);
toolbarItem.value = _.get(newObject, this.getItemProperty(item));
}
}
}
@@ -135,10 +135,13 @@
getFormValue(domainObject, toolbarItem) {
let value = {};
toolbarItem.formKeys.map(key => {
value[key] = _.get(domainObject, toolbarItem.property + "." + key);
value[key] = _.get(domainObject, this.getItemProperty(toolbarItem) + "." + key);
});
return value;
},
getItemProperty(item) {
return (typeof item.property === "function") ? item.property() : item.property;
},
removeListeners() {
if (this.unObserveObjects) {
this.unObserveObjects.forEach((unObserveObject) => {
@@ -156,7 +159,7 @@
if (domainObject) {
let id = this.openmct.objects.makeKeyString(domainObject.identifier);
if (changedItemId === id && item.property === s.property) {
if (changedItemId === id && this.getItemProperty(item) === this.getItemProperty(s)) {
toolbarItem.value = value;
}
}
@@ -170,12 +173,12 @@
this.structure.map(s => {
if (s.formKeys) {
s.formKeys.forEach(key => {
this.openmct.objects.mutate(item.domainObject, item.property + "." + key, value[key]);
this.openmct.objects.mutate(item.domainObject, this.getItemProperty(item) + "." + key, value[key]);
});
}
});
} else {
this.openmct.objects.mutate(item.domainObject, item.property, value);
this.openmct.objects.mutate(item.domainObject, this.getItemProperty(item), value);
}
},
triggerMethod(item, event) {