Compare commits

...

12 Commits

Author SHA1 Message Date
charlesh88
6db1833a45 Merge branch 'topic-core-refactor' into misc-ui-4 2019-01-15 16:42:03 -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
charlesh88
8b2edaa6fd Toolbar styling, edit colors
- Toolbar now with color bg for better tie-in with edit area visually;
- Edit colors refined for Snow theme, WIP;
2019-01-10 17:35:22 -08:00
charlesh88
8caeed2ce5 Telemetry Table editing styles
- Headers now have hover effects;
2019-01-08 14:42:02 -08:00
charlesh88
03be582b54 List View fixes
- Ellipsizing now works;
- Better icon and text alignment;
2019-01-04 17:56:10 -08:00
charlesh88
1ce84ee56b Styling for selects
- New cleaner styling approach;
- New cSelect and appearanceNone mixins;
- Converted selects in Notebook, plot-options-edit;
2019-01-04 17:06:26 -08:00
charlesh88
cb39ad8500 Merge branch 'topic-core-refactor' into misc-ui-4 2019-01-04 14:39:57 -08:00
charlesh88
74be02b6de Various improvements
- Tighten up search inputs;
- Fix icon/label spacing regression in c-button--menu;
- Better icon and text alignment in c-button and related;
2018-12-21 23:50:19 -08:00
34 changed files with 311 additions and 185 deletions

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

@@ -28,6 +28,11 @@ export default class Editor extends EventEmitter {
super();
this.editing = false;
this.openmct = openmct;
document.addEventListener('drop', (event) => {
if (!this.isEditing()) {
this.edit();
}
}, {capture: true});
}
/**

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

@@ -177,13 +177,13 @@
this.openmct.objects.mutate(this.internalDomainObject, path, value);
},
handleDrop($event) {
if (!$event.dataTransfer.types.includes('domainobject')) {
if (!$event.dataTransfer.types.includes('openmct/domain-object-path')) {
return;
}
$event.preventDefault();
let domainObject = JSON.parse($event.dataTransfer.getData('domainobject'));
let domainObject = JSON.parse($event.dataTransfer.getData('openmct/domain-object-path'))[0];
let elementRect = this.$el.getBoundingClientRect();
let droppedObjectPosition = [
Math.floor(($event.pageX - elementRect.left) / this.gridSize[0]),

View File

@@ -100,7 +100,7 @@ export default {
},
methods: {
allowDrop(event, index) {
if (event.dataTransfer.getData('domainObject')) {
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('domainobject')) {
if (event.dataTransfer.types.includes('openmct/domain-object-path')) {
// create frame using domain object
let domainObject = JSON.parse(event.dataTransfer.getData('domainObject'));
let domainObject = JSON.parse(event.dataTransfer.getData('openmct/domain-object-path'))[0];
this.$emit(
'create-frame',
this.index,

View File

@@ -21,8 +21,7 @@
*****************************************************************************/
<template>
<div v-if="isEditing"
v-show="isValidTarget">
<div v-show="isValidTarget">
<div class="c-drop-hint c-drop-hint--always-show"
:class="{'is-mouse-over': isMouseOver}"
@dragenter="dragenter"
@@ -37,8 +36,6 @@
</style>
<script>
import isEditingMixin from '../mixins/isEditing';
export default {
props:{
index: Number,
@@ -47,7 +44,6 @@ export default {
required: true
}
},
mixins: [isEditingMixin],
data() {
return {
isMouseOver: false,

View File

@@ -44,6 +44,7 @@ define([
containers: [new Container.default(50), new Container.default(50)],
rowsLayout: false
};
domainObject.composition = [];
}
});

View File

@@ -4,9 +4,8 @@
@click="navigate">
<td class="c-list-item__name">
<a :href="objectLink" ref="objectLink">
<div class="c-list-item__type-icon"
:class="item.type.cssClass"></div>
{{item.model.name}}
<div class="c-list-item__type-icon" :class="item.type.cssClass"></div>
<div class="c-list-item__name-value">{{item.model.name}}</div>
</a>
</td>
<td class="c-list-item__type">{{ item.type.name }}</td>
@@ -20,17 +19,24 @@
/******************************* LIST ITEM */
.c-list-item {
&__name {
@include ellipsize();
&__name a {
display: flex;
> * + * { margin-left: $interiorMarginSm; }
}
&__type-icon {
// Have to do it this way instead of using icon-* class, due to need to apply alias to the icon
color: $colorKey;
display: inline-block;
width: 1em;
margin-right:$interiorMarginSm;
}
&__name-value {
@include ellipsize();
}
&.is-alias {
// Object is an alias to an original.
[class*='__type-icon'] {
@@ -48,7 +54,6 @@
}
}
}
</style>
<script>

View File

@@ -78,9 +78,12 @@
td {
$p: floor($interiorMargin * 1.5);
font-size: 1.1em;
@include ellipsize();
line-height: 120%; // Needed for icon alignment
max-width: 0;
padding-top: $p;
padding-bottom: $p;
width: 25%;
&:not(.c-list-item__name) {
color: $colorItemFgDetails;

View File

@@ -5,21 +5,17 @@
@input="search"
@clear="search">
</search>
<div class="c-notebook__controls">
<div class="select c-notebook__controls__time">
<select v-model="showTime">
<option value="0" selected="selected">Show all</option>
<option value="1">Last hour</option>
<option value="8">Last 8 hours</option>
<option value="24">Last 24 hours</option>
</select>
</div>
<div class="select c-notebook__controls__sort">
<select v-model="sortEntries">
<option value="newest" :selected="sortEntries === 'newest'">Newest first</option>
<option value="oldest" :selected="sortEntries === 'oldest'">Oldest first</option>
</select>
</div>
<div class="c-notebook__controls ">
<select class="c-notebook__controls__time" v-model="showTime">
<option value="0" selected="selected">Show all</option>
<option value="1">Last hour</option>
<option value="8">Last 8 hours</option>
<option value="24">Last 24 hours</option>
</select>
<select class="c-notebook__controls__time" v-model="sortEntries">
<option value="newest" :selected="sortEntries === 'newest'">Newest first</option>
<option value="oldest" :selected="sortEntries === 'oldest'">Oldest first</option>
</select>
</div>
</div>
<div class="c-notebook__drag-area icon-plus"

View File

@@ -107,10 +107,10 @@ function (
EntryController.prototype.dropOnEntry = function (entryid, event) {
var data = event.dataTransfer.getData('domainObject');
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('domainObject')) {
var selectedObject = JSON.parse(event.dataTransfer.getData('domainObject')),
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

@@ -41,28 +41,24 @@
<div class="grid-cell label"
title="The field to be plotted as a value for this series.">Value</div>
<div class="grid-cell value">
<div class="select">
<select ng-model="form.yKey">
<option ng-repeat="option in yKeyOptions"
value="{{option.value}}"
ng-selected="option.value == form.yKey">
{{option.name}}
</option>
</select>
</div>
<select ng-model="form.yKey">
<option ng-repeat="option in yKeyOptions"
value="{{option.value}}"
ng-selected="option.value == form.yKey">
{{option.name}}
</option>
</select>
</div>
</li>
<li class="grid-row">
<div class="grid-cell label"
title="The line rendering style for this series.">Line Style</div>
<div class="grid-cell value">
<div class="select">
<select ng-model="form.interpolate">
<option value="none">None</option>
<option value="linear">Linear interpolate</option>
<option value="stepAfter">Step after</option>
</select>
</div>
<select ng-model="form.interpolate">
<option value="none">None</option>
<option value="linear">Linear interpolate</option>
<option value="stepAfter">Step after</option>
</select>
</div>
</li>
<li class="grid-row">
@@ -160,15 +156,13 @@
<div class="grid-cell label"
title="The position of the legend relative to the plot display area.">Position</div>
<div class="grid-cell value">
<div class="select">
<select ng-model="form.position">
<option value="hidden">Hidden</option>
<option value="top">Top</option>
<option value="right">Right</option>
<option value="bottom">Bottom</option>
<option value="left">Left</option>
</select>
</div>
<select ng-model="form.position">
<option value="hidden">Hidden</option>
<option value="top">Top</option>
<option value="right">Right</option>
<option value="bottom">Bottom</option>
<option value="left">Left</option>
</select>
</div>
</li>
<li class="grid-row">
@@ -180,15 +174,13 @@
<div class="grid-cell label"
title="What to display in the legend when it's collapsed.">When collapsed show</div>
<div class="grid-cell value">
<div class="select">
<select ng-model="form.valueToShowWhenCollapsed">
<option value="none">nothing</option>
<option value="nearestTimestamp">nearest timestamp</option>
<option value="nearestValue">nearest Value</option>
<option value="min">minimum value</option>
<option value="max">maximum value</option>
</select>
</div>
<select ng-model="form.valueToShowWhenCollapsed">
<option value="none">Nothing</option>
<option value="nearestTimestamp">Nearest timestamp</option>
<option value="nearestValue">Nearest value</option>
<option value="min">Minimum value</option>
<option value="max">Maximum value</option>
</select>
</div>
</li>
<li class="grid-row">

View File

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

View File

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

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

@@ -34,7 +34,7 @@
<div class="c-telemetry-table__headers-w js-table__headers-w" ref="headersTable" :style="{ 'max-width': widthWithScroll}">
<table class="c-table__headers c-telemetry-table__headers">
<thead>
<tr>
<tr class="c-telemetry-table__headers__name">
<table-column-header
v-for="(title, key, headerIndex) in headers"
:key="key"
@@ -50,7 +50,7 @@
:sortOptions="sortOptions"
>{{title}}</table-column-header>
</tr>
<tr>
<tr class="c-telemetry-table__headers__filter">
<table-column-header
v-for="(title, key, headerIndex) in headers"
:key="key"
@@ -214,6 +214,22 @@
}
}
/******************************* EDITING */
.is-editing {
.c-telemetry-table__headers__name {
th[draggable],
th[draggable] > * {
cursor: move;
}
th[draggable]:hover {
$b: $editSelectableColor;
background: $b;
> * { background: $b; }
}
}
}
/******************************* LEGACY */
.s-status-taking-snapshot,
.overlay.snapshot {

View File

@@ -55,7 +55,7 @@ $basicCr: 4px;
// Base colors
$colorBodyBg: #393939;
$colorBodyFg: #aaa;
$colorBodyFg: #aaaaaa;
$colorBodyFgEm: #fff;
$colorGenBg: #222;
$colorHeadBg: #262626;
@@ -65,7 +65,7 @@ $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;
@@ -116,13 +116,16 @@ $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%);
$editCanvasColorBg: $editColorBg;
$editCanvasColorGrid: rgba($editColorBgBase, 0.4);
// Selectable
$editSelectableColor: #006563;
$editSelectableColorFg: lighten($editSelectableColor, 20%);
$editSelectableColorHov: lighten($editSelectableColor, 10%);
// Selectable selected
$editSelectableColorSelected: $editSelectableColorHov;
$editSelectableColorSelectedFg: lighten($editSelectableColorSelected, 30%);
@@ -222,6 +225,13 @@ $overlayColorFg: $colorMenuFg;
$overlayCr: $interiorMarginLg;
$overlayBrightnessAdjust: brightness(1.3);
// Toolbar
$toolBarEditColorBg: darken($editColorBgBase, 5%);
$toolBarEditColorFg: lighten($editColorBgBase, 20%);
$toolBarEditColorBtnFg: $toolBarEditColorFg;
$toolBarEditColorBtnBgHover: lighten($toolBarEditColorBg, 10%);
$toolBarEditColorBtnFgHover: lighten($toolBarEditColorFg, 10%);
// Indicator colors
$colorIndicatorAvailable: $colorKey;
$colorIndicatorDisabled: #555555;
@@ -371,17 +381,6 @@ $createBtnTextTransform: uppercase;
box-shadow: rgba(black, 0.5) 0 0.5px 2px;
}
/**************************************************** 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: darken($sliderColorBase, 20%);
$sliderColorKnobHov: rgba($sliderColorBase, 0.7);
$sliderColorRangeValHovBg: $sliderColorRange;
$sliderColorRangeValHovFg: $colorBodyFg;
$sliderKnobW: 15px;
$sliderKnobR: 2px;
*/
@mixin themedSelect($bg: $colorBtnBg, $fg: $colorBtnFg) {
@include cSelect(linear-gradient(lighten($bg, 5%), $bg), $fg, lighten($bg, 20%), rgba(black, 0.5) 0 0.5px 3px);
}

View File

@@ -69,7 +69,7 @@ $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;
@@ -120,13 +120,16 @@ $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%);
$editCanvasColorBg: $editColorBg;
$editCanvasColorGrid: rgba($editColorBgBase, 0.4);
// Selectable
$editSelectableColor: #006563;
$editSelectableColorFg: lighten($editSelectableColor, 20%);
$editSelectableColorHov: lighten($editSelectableColor, 10%);
// Selectable selected
$editSelectableColorSelected: $editSelectableColorHov;
$editSelectableColorSelectedFg: lighten($editSelectableColorSelected, 30%);
@@ -142,7 +145,7 @@ $colorGridLines: rgba($editColor, 0.2);
/************************************************** BROWSING */
$browseSelectableBorderHov: 1px dotted rgba($colorBodyFg, 0.2);
$browseSelectableShdwHov: rgba($colorBodyFg, 0.2) 0 0 3px;
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.6);
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.5);
// Icons
$colorIconAlias: #4af6f3;
@@ -226,6 +229,13 @@ $overlayColorFg: $colorMenuFg;
$overlayCr: $interiorMarginLg;
$overlayBrightnessAdjust: brightness(1.3);
// Toolbar
$toolBarEditColorBg: darken($editColorBgBase, 5%);
$toolBarEditColorFg: lighten($editColorBgBase, 20%);
$toolBarEditColorBtnFg: $toolBarEditColorFg;
$toolBarEditColorBtnBgHover: lighten($toolBarEditColorBg, 10%);
$toolBarEditColorBtnFgHover: lighten($toolBarEditColorFg, 10%);
// Indicator colors
$colorIndicatorAvailable: $colorKey;
$colorIndicatorDisabled: #555555;
@@ -375,6 +385,10 @@ $createBtnTextTransform: uppercase;
box-shadow: rgba(black, 0.5) 0 0.5px 2px;
}
@mixin themedSelect($bg: $colorBtnBg, $fg: $colorBtnFg) {
@include cSelect(linear-gradient(lighten($bg, 5%), $bg), $fg, lighten($bg, 20%), rgba(black, 0.5) 0 0.5px 3px);
}
/**************************************************** OVERRIDES */
.c-frame {
&:not(.no-frame) {

View File

@@ -110,26 +110,29 @@ $colorTOIHov: $colorTime; // was $timeControllerToiLineColorHov
/************************************************** EDITING */
// Base Colors
$dlSpread: 20%;
$editColor: #00c7c3;
$editColor: #6afdff;
$editColorAlt: #9971ff;
$editColorBgBase: darken($editColor, $dlSpread);
$editColorBg: darken($editColor, $dlSpread);
$editColorFg: lighten($editColor, $dlSpread);
$editColorBgBase: lighten($editColor, 20%);
$editColorBg: $editColor;
$editColorFg: darken($editColor, $dlSpread);
$editColorHov: lighten($editColor, 20%);
// Canvas
$editCanvasColorBg: #e6ffff;
$editCanvasColorGrid: darken($editCanvasColorBg, 10%);
$editCanvasColorBg: lighten($editColorBgBase, 5%);
$editCanvasColorGrid: $editColorBgBase;
// Selectable
$editSelectableColor: #acdad6;
$editSelectableColor: #00b3b1;
$editSelectableColorFg: darken($editSelectableColor, 20%);
$editSelectableColorHov: darken($editSelectableColor, 10%);
$editSelectableColorHov: darken($editSelectableColor, 20%);
// Selectable selected
$editSelectableColorSelected: $editColor;
$editSelectableColorSelected: #c60; //$editSelectableColorHov;
$editSelectableColorSelectedFg: lighten($editSelectableColorSelected, 50%);
$editSelectableColorFg: darken($editSelectableColor, 40%);
$editSelectableBorder: 1px dotted $editSelectableColor;
$editSelectableBorderHov: 1px dotted $editColorAlt;
$editSelectableBorderSelected: 1px solid $editColor;
$editSelectableBorderSelected: 1px solid $editSelectableColorSelected;
$editSelectableShdwSelected: rgba($editColor, 0.75) 0 0 0 1px;
$editMoveableSelectedShdw: rgba($editColor, 0.5) 0 0 10px;
$editBorderDrilledIn: 1px dashed $editColorAlt;
@@ -138,7 +141,7 @@ $colorGridLines: rgba($editColor, 0.2);
/************************************************** BROWSING */
$browseSelectableBorderHov: 1px dotted rgba($colorBodyFg, 0.2);
$browseSelectableShdwHov: rgba($colorBodyFg, 0.2) 0 0 3px;
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.6);
$browseSelectedBorder: 1px solid rgba($colorBodyFg, 0.5);
// Icons
$colorIconAlias: #4af6f3;
@@ -222,6 +225,13 @@ $overlayColorFg: $colorMenuFg;
$overlayCr: $interiorMarginLg;
$overlayBrightnessAdjust: brightness(1);
// Toolbar
$toolBarEditColorBg: darken($editColorBgBase, 5%);
$toolBarEditColorFg: rgba(black, 0.7);
$toolBarEditColorBtnFg: $toolBarEditColorFg;
$toolBarEditColorBtnBgHover: lighten($toolBarEditColorBg, 10%);
$toolBarEditColorBtnFgHover: rgba(black, 0.9);
// Indicator colors
$colorIndicatorAvailable: $colorKey;
$colorIndicatorDisabled: #444;
@@ -370,16 +380,6 @@ $createBtnTextTransform: uppercase;
background: $c;
}
/**************************************************** NOT USED, LEAVE FOR NOW */
// Content status
/*
$colorAlert: #ff3c00;
$colorWarningHi: #990000;
$colorWarningLo: #ff9900;
$colorDiagnostic: #a4b442;
$colorCommand: #3693bd;
$colorInfo: #2294a2;
$colorOk: #33cc33;
*/
@mixin themedSelect($bg: $colorBtnBg, $fg: $colorBtnFg) {
@include cSelect($bg, $fg, lighten($bg, 20%), none);
}

View File

@@ -228,6 +228,17 @@ input[type=number]::-webkit-outer-spin-button {
}
}
// SELECTS
select {
@include appearanceNone();
@include themedSelect();
background-repeat: no-repeat, no-repeat;
background-position: right .4em top 90%, 0 0;
border: none;
border-radius: $controlCr;
padding: 1px 20px 1px $interiorMargin;
}
/******************************************************** HYPERLINKS AND HYPERLINK BUTTONS */
.c-hyperlink {
&--link {
@@ -421,21 +432,31 @@ input[type=number]::-webkit-outer-spin-button {
.c-toolbar {
$p: $interiorMargin;
border-top: 1px solid $colorInteriorBorder;
background: $toolBarEditColorBg;
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: $toolBarEditColorBtnFg;
}
.c-click-icon {
@include cControl();
$pLR: $interiorMargin - 1;
$pTB: 2px;
color: $colorBodyFg;
padding: $pTB $pLR;
&:hover {
background: $toolBarEditColorBtnBgHover !important;
color: $toolBarEditColorBtnFgHover !important;
}
&--swatched {
padding-bottom: floor($pTB / 2);
width: 2em; // Standardize the width
@@ -535,7 +556,7 @@ input[type=number]::-webkit-outer-spin-button {
input[type="range"] {
// HTML5 range inputs
-webkit-appearance: none; /* Hides the slider so that custom slider can be made */
@include appearanceNone(); /* Hides the slider so that custom slider can be made */
background: transparent; /* Otherwise white in Chrome */
&:focus {
outline: none; /* Removes the blue border. */

View File

@@ -60,6 +60,16 @@
width: $d;
}
@mixin appearanceNone() {
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
&:focus {
outline: none;
}
}
@mixin isAlias() {
&:after {
color:$colorIconAlias;
@@ -194,7 +204,7 @@
}
@mixin htmlInputReset() {
appearance: none;
@include appearanceNone();
background: transparent;
border: none;
border-radius: 0;
@@ -263,6 +273,7 @@
display: inline-flex;
align-items: center;
justify-content: center;
line-height: $fs; // Remove effect on top and bottom padding
overflow: hidden;
&:before,
@@ -272,6 +283,10 @@
flex: 0 0 auto;
}
&:before {
font-size: 0.9em;
}
&:after {
font-size: 0.8em;
}
@@ -279,15 +294,18 @@
[class*="__label"] {
@include ellipsize();
display: block;
line-height: $fs; // Remove effect on top and bottom padding
font-size: $fs;
}
&[class*='icon'] > [class*="__label"] {
// When button holds both an icon and a label, provide margin between them.
margin-left: $interiorMarginSm;
}
}
@mixin cButton() {
@include cControl();
@include themedButton();
//@include buttonBehavior();
border-radius: $controlCr;
color: $colorBtnFg;
cursor: pointer;
@@ -329,12 +347,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;
cursor: pointer;
padding: $pTB $pLR ;
padding: $pTB $pLR;
@include hover() {
background: $colorClickIconBgHov;
@@ -421,6 +439,13 @@
}
}
@mixin cSelect($bg, $fg, $arwClr, $shdw) {
$svgArwClr: str-slice(inspect($arwClr), 2, str-length(inspect($arwClr))); // Remove initial # in color value
background: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' width='10' height='10'%3e%3cpath fill='%23#{$svgArwClr}' d='M5 5l5-5H0z'/%3e%3c/svg%3e"), $bg;
color: $fg;
box-shadow: $shdw;
}
@mixin wrappedInput() {
// An input that is wrapped. Optionally includes a __label or icon element.
// Based on .c-search.

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,8 +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) {
event.dataTransfer.setData("domainObject", JSON.stringify(this.observedObject));
let navigatedObject = this.openmct.router.path[0];
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", JSON.stringify(this.domainObject));
}
// 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

@@ -88,26 +88,25 @@ export default {
this.updateView(immediatelySelect);
},
onDragOver(event) {
event.preventDefault();
if (this.hasComposableDomainObject(event)) {
event.preventDefault();
}
},
onDrop(event) {
let parentObject = this.currentObject;
let d = event.dataTransfer.getData("domainObject");
if (d) {
let childObject = JSON.parse(d);
if (this.openmct.composition.checkPolicy(parentObject, childObject)){
if (!this.openmct.editor.isEditing() && parentObject.type !== 'folder'){
this.openmct.editor.edit();
}
parentObject.composition.push(childObject.identifier);
this.openmct.objects.mutate(parentObject, 'composition', parentObject.composition);
}
if (this.hasComposableDomainObject(event)) {
let composableDomainObject = this.getComposableDomainObject(event);
this.currentObject.composition.push(composableDomainObject.identifier);
this.openmct.objects.mutate(this.currentObject, 'composition', this.currentObject.composition);
event.preventDefault();
event.stopPropagation();
}
},
hasComposableDomainObject(event) {
return event.dataTransfer.types.includes('openmct/composable-domain-object')
},
getComposableDomainObject(event) {
let serializedDomainObject = event.dataTransfer.getData('openmct/composable-domain-object');
return JSON.parse(serializedDomainObject);
}
}
}

View File

@@ -18,9 +18,6 @@
.c-search {
@include wrappedInput();
padding-top: 2px;
padding-bottom: 2px;
&:before {
// Mag glass icon
content: $glyph-icon-magnify;

View File

@@ -184,7 +184,6 @@
}
/******************************* MAIN AREA */
&__main-container {
// Wrapper for main views
flex: 1 1 auto !important;

View File

@@ -47,7 +47,7 @@
}
}
&.is-selected {
&.is-navigated-object {
background: $colorItemTreeSelectedBg;
.c-tree__item__type-icon:before {
color: $colorItemTreeIconHover;

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;
}
}