mirror of
https://github.com/nasa/openmct.git
synced 2025-01-31 08:25:31 +00:00
Handles static and mixed styles for multiple items in a layout (#2907)
* Show non specific styles when updating multiple item styles * Save sub object styles to it's domain object * Layout UI tweak * Fixes flexible layout bug. * Fixes font size bug in telemetry view * Fixes issues with newly places TVOs including transparent properties. * Fixes #2908 * Say NO to 'transparent' === '__no_value' - Fixes #2895; * Ensure styles are correctly applied to domain objects and drawing objects when selected individually * Ensure none treatment is correctly applied to objects when multple selecting * Fix intial box border * Tweaks to c-text-view layout - Vertically center text; - Normalize padding; - Overflow: hidden; * Tweaks to Clock and Timer layout - Fixes #2893; - Vertically center text; - Normalize padding; - Overflow: hidden; - `position: absolute` when in Layout; Co-authored-by: charlesh88 <charlesh88@gmail.com> Co-authored-by: Andrew Henry <akhenry@gmail.com>
This commit is contained in:
parent
da7b93f9b3
commit
766f48c1ba
@ -109,7 +109,7 @@ export default class StyleRuleManager extends EventEmitter {
|
||||
} else {
|
||||
if (this.currentStyle) {
|
||||
Object.keys(this.currentStyle).forEach(key => {
|
||||
this.currentStyle[key] = 'transparent';
|
||||
this.currentStyle[key] = '__no_value';
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ import ConditionDescription from "@/plugins/condition/components/ConditionDescri
|
||||
import ConditionError from "@/plugins/condition/components/ConditionError.vue";
|
||||
import Vue from 'vue';
|
||||
import PreviewAction from "@/ui/preview/PreviewAction.js";
|
||||
import {getInitialStyleForItem} from "@/plugins/condition/utils/styleUtils";
|
||||
import {getApplicableStylesForItem} from "@/plugins/condition/utils/styleUtils";
|
||||
|
||||
export default {
|
||||
name: 'ConditionalStylesView',
|
||||
@ -130,9 +130,7 @@ export default {
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
if (this.stopObserving) {
|
||||
this.stopObserving();
|
||||
}
|
||||
this.removeListeners();
|
||||
},
|
||||
mounted() {
|
||||
this.itemId = '';
|
||||
@ -164,7 +162,8 @@ export default {
|
||||
layoutItem = this.selection[0][0].context.layoutItem;
|
||||
const item = this.selection[0][0].context.item;
|
||||
this.canHide = true;
|
||||
if (item && this.isItemType('subobject-view', layoutItem)) {
|
||||
if (item &&
|
||||
(!layoutItem || (this.isItemType('subobject-view', layoutItem)))) {
|
||||
domainObject = item;
|
||||
} else {
|
||||
domainObject = this.selection[0][1].context.item;
|
||||
@ -176,12 +175,21 @@ export default {
|
||||
domainObject = this.selection[0][0].context.item;
|
||||
}
|
||||
this.domainObject = domainObject;
|
||||
this.initialStyles = getInitialStyleForItem(domainObject, layoutItem);
|
||||
this.initialStyles = getApplicableStylesForItem(domainObject, layoutItem);
|
||||
this.$nextTick(() => {
|
||||
this.removeListeners();
|
||||
if (this.domainObject) {
|
||||
this.stopObserving = this.openmct.objects.observe(this.domainObject, '*', newDomainObject => this.domainObject = newDomainObject);
|
||||
this.stopObservingItems = this.openmct.objects.observe(this.domainObject, 'configuration.items', this.updateDomainObjectItemStyles);
|
||||
}
|
||||
});
|
||||
},
|
||||
removeListeners() {
|
||||
if (this.stopObserving) {
|
||||
this.stopObserving();
|
||||
}
|
||||
if (this.domainObject) {
|
||||
this.stopObserving = this.openmct.objects.observe(this.domainObject, '*', newDomainObject => this.domainObject = newDomainObject);
|
||||
if (this.stopObservingItems) {
|
||||
this.stopObservingItems();
|
||||
}
|
||||
},
|
||||
initialize(conditionSetDomainObject) {
|
||||
@ -280,6 +288,36 @@ export default {
|
||||
|
||||
this.persist(domainObjectStyles);
|
||||
},
|
||||
updateDomainObjectItemStyles(newItems) {
|
||||
//check that all items that have been styles still exist. Otherwise delete those styles
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
let itemsToRemove = [];
|
||||
let keys = Object.keys(domainObjectStyles);
|
||||
keys.forEach((key) => {
|
||||
if ((key !== 'styles') &&
|
||||
(key !== 'staticStyle') &&
|
||||
(key !== 'conditionSetIdentifier')) {
|
||||
if (!(newItems.find(item => item.id === key))) {
|
||||
itemsToRemove.push(key);
|
||||
}
|
||||
}
|
||||
});
|
||||
if (itemsToRemove.length) {
|
||||
this.removeItemStyles(itemsToRemove, domainObjectStyles);
|
||||
}
|
||||
},
|
||||
removeItemStyles(itemIds, domainObjectStyles) {
|
||||
itemIds.forEach(itemId => {
|
||||
if (domainObjectStyles[itemId]) {
|
||||
domainObjectStyles[itemId] = undefined;
|
||||
delete domainObjectStyles[this.itemId];
|
||||
}
|
||||
});
|
||||
if (_.isEmpty(domainObjectStyles)) {
|
||||
domainObjectStyles = undefined;
|
||||
}
|
||||
this.persist(domainObjectStyles);
|
||||
},
|
||||
initializeConditionalStyles() {
|
||||
if (!this.conditions) {
|
||||
this.conditions = {};
|
||||
@ -305,9 +343,15 @@ export default {
|
||||
},
|
||||
initializeStaticStyle(objectStyles) {
|
||||
let staticStyle = objectStyles && objectStyles.staticStyle;
|
||||
this.staticStyle = staticStyle || {
|
||||
style: Object.assign({}, this.initialStyles)
|
||||
};
|
||||
if (staticStyle) {
|
||||
this.staticStyle = {
|
||||
style: Object.assign({}, this.initialStyles, staticStyle.style)
|
||||
};
|
||||
} else {
|
||||
this.staticStyle = {
|
||||
style: Object.assign({}, this.initialStyles)
|
||||
};
|
||||
}
|
||||
},
|
||||
findStyleByConditionId(id) {
|
||||
return this.conditionalStyles.find(conditionalStyle => conditionalStyle.conditionId === id);
|
||||
|
@ -0,0 +1,269 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT, Copyright (c) 2014-2020, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT is licensed under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
* http://www.apache.org/licenses/LICENSE-2.0.
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
* License for the specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
* Open MCT includes source code licensed under additional open source
|
||||
* licenses. See the Open Source Licenses file (LICENSES.md) included with
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
|
||||
<template>
|
||||
<div class="c-inspector__styles c-inspect-styles">
|
||||
<div class="c-inspect-styles__header">
|
||||
Object Style
|
||||
</div>
|
||||
<div class="c-inspect-styles__content">
|
||||
<div v-if="isStaticAndConditionalStyles"
|
||||
class="c-inspect-styles__mixed-static-and-conditional u-alert u-alert--block u-alert--with-icon"
|
||||
>
|
||||
Your selection includes one or more items that use Conditional Styling. Applying a static style below will replace any Conditional Styling with the new choice.
|
||||
</div>
|
||||
<div v-if="staticStyle"
|
||||
class="c-inspect-styles__style"
|
||||
>
|
||||
<style-editor class="c-inspect-styles__editor"
|
||||
:style-item="staticStyle"
|
||||
:is-editing="isEditing"
|
||||
:mixed-styles="mixedStyles"
|
||||
@persist="updateStaticStyle"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
import StyleEditor from "./StyleEditor.vue";
|
||||
import PreviewAction from "@/ui/preview/PreviewAction.js";
|
||||
import { getApplicableStylesForItem, getConsolidatedStyleValues, getConditionalStyleForItem } from "@/plugins/condition/utils/styleUtils";
|
||||
|
||||
export default {
|
||||
name: 'MultiSelectStylesView',
|
||||
components: {
|
||||
StyleEditor
|
||||
},
|
||||
inject: [
|
||||
'openmct',
|
||||
'selection'
|
||||
],
|
||||
data() {
|
||||
return {
|
||||
staticStyle: undefined,
|
||||
isEditing: this.openmct.editor.isEditing(),
|
||||
mixedStyles: [],
|
||||
isStaticAndConditionalStyles: false
|
||||
}
|
||||
},
|
||||
destroyed() {
|
||||
this.removeListeners();
|
||||
},
|
||||
mounted() {
|
||||
this.items = [];
|
||||
this.previewAction = new PreviewAction(this.openmct);
|
||||
this.getObjectsAndItemsFromSelection();
|
||||
this.initializeStaticStyle();
|
||||
this.openmct.editor.on('isEditing', this.setEditState);
|
||||
},
|
||||
methods: {
|
||||
isItemType(type, item) {
|
||||
return item && (item.type === type);
|
||||
},
|
||||
hasConditionalStyles(domainObject, id) {
|
||||
return getConditionalStyleForItem(domainObject, id) !== undefined;
|
||||
},
|
||||
getObjectsAndItemsFromSelection() {
|
||||
let domainObject;
|
||||
let subObjects = [];
|
||||
|
||||
//multiple selection
|
||||
let itemInitialStyles = [];
|
||||
let itemStyle;
|
||||
this.selection.forEach((selectionItem) => {
|
||||
const item = selectionItem[0].context.item;
|
||||
const layoutItem = selectionItem[0].context.layoutItem;
|
||||
if (item && this.isItemType('subobject-view', layoutItem)) {
|
||||
subObjects.push(item);
|
||||
itemStyle = getApplicableStylesForItem(item);
|
||||
if (!this.isStaticAndConditionalStyles) {
|
||||
this.isStaticAndConditionalStyles = this.hasConditionalStyles(item);
|
||||
}
|
||||
} else {
|
||||
domainObject = selectionItem[1].context.item;
|
||||
itemStyle = getApplicableStylesForItem(domainObject, layoutItem || item);
|
||||
this.items.push({
|
||||
id: layoutItem.id,
|
||||
applicableStyles: itemStyle
|
||||
});
|
||||
if (!this.isStaticAndConditionalStyles) {
|
||||
this.isStaticAndConditionalStyles = this.hasConditionalStyles(domainObject, layoutItem.id);
|
||||
}
|
||||
}
|
||||
itemInitialStyles.push(itemStyle);
|
||||
});
|
||||
const {styles, mixedStyles} = getConsolidatedStyleValues(itemInitialStyles);
|
||||
this.initialStyles = styles;
|
||||
this.mixedStyles = mixedStyles;
|
||||
|
||||
this.domainObject = domainObject;
|
||||
this.removeListeners();
|
||||
if (this.domainObject) {
|
||||
this.stopObserving = this.openmct.objects.observe(this.domainObject, '*', newDomainObject => this.domainObject = newDomainObject);
|
||||
this.stopObservingItems = this.openmct.objects.observe(this.domainObject, 'configuration.items', this.updateDomainObjectItemStyles);
|
||||
}
|
||||
|
||||
subObjects.forEach(this.registerListener);
|
||||
},
|
||||
updateDomainObjectItemStyles(newItems) {
|
||||
//check that all items that have been styles still exist. Otherwise delete those styles
|
||||
let keys = Object.keys(this.domainObject.configuration.objectStyles || {});
|
||||
keys.forEach((key) => {
|
||||
if ((key !== 'styles') &&
|
||||
(key !== 'staticStyle') &&
|
||||
(key !== 'conditionSetIdentifier')) {
|
||||
if (!(newItems.find(item => item.id === key))) {
|
||||
this.removeItemStyles(key);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
registerListener(domainObject) {
|
||||
let id = this.openmct.objects.makeKeyString(domainObject.identifier);
|
||||
|
||||
if (!this.domainObjectsById) {
|
||||
this.domainObjectsById = {};
|
||||
}
|
||||
|
||||
if (!this.domainObjectsById[id]) {
|
||||
this.domainObjectsById[id] = domainObject;
|
||||
this.observeObject(domainObject, id);
|
||||
}
|
||||
},
|
||||
observeObject(domainObject, id) {
|
||||
let unobserveObject = this.openmct.objects.observe(domainObject, '*', function (newObject) {
|
||||
this.domainObjectsById[id] = JSON.parse(JSON.stringify(newObject));
|
||||
}.bind(this));
|
||||
this.unObserveObjects.push(unobserveObject);
|
||||
},
|
||||
removeListeners() {
|
||||
if (this.stopObserving) {
|
||||
this.stopObserving();
|
||||
}
|
||||
if (this.stopObservingItems) {
|
||||
this.stopObservingItems();
|
||||
}
|
||||
if (this.unObserveObjects) {
|
||||
this.unObserveObjects.forEach((unObserveObject) => {
|
||||
unObserveObject();
|
||||
});
|
||||
}
|
||||
this.unObserveObjects = [];
|
||||
},
|
||||
removeItemStyles(itemId) {
|
||||
let domainObjectStyles = (this.domainObject.configuration && this.domainObject.configuration.objectStyles) || {};
|
||||
if (itemId && domainObjectStyles[itemId]) {
|
||||
domainObjectStyles[itemId] = undefined;
|
||||
delete domainObjectStyles[this.itemId];
|
||||
|
||||
if (_.isEmpty(domainObjectStyles)) {
|
||||
domainObjectStyles = undefined;
|
||||
}
|
||||
this.persist(this.domainObject, domainObjectStyles);
|
||||
}
|
||||
},
|
||||
removeConditionalStyles(domainObjectStyles, itemId) {
|
||||
if (itemId) {
|
||||
domainObjectStyles[itemId].conditionSetIdentifier = undefined;
|
||||
delete domainObjectStyles[itemId].conditionSetIdentifier;
|
||||
domainObjectStyles[itemId].styles = undefined;
|
||||
delete domainObjectStyles[itemId].styles;
|
||||
} else {
|
||||
domainObjectStyles.conditionSetIdentifier = undefined;
|
||||
delete domainObjectStyles.conditionSetIdentifier;
|
||||
domainObjectStyles.styles = undefined;
|
||||
delete domainObjectStyles.styles;
|
||||
}
|
||||
},
|
||||
setEditState(isEditing) {
|
||||
this.isEditing = isEditing;
|
||||
},
|
||||
initializeStaticStyle() {
|
||||
this.staticStyle = {
|
||||
style: Object.assign({}, this.initialStyles)
|
||||
};
|
||||
},
|
||||
updateStaticStyle(staticStyle, property) {
|
||||
//update the static style for each of the layoutItems as well as each sub object item
|
||||
this.staticStyle = staticStyle;
|
||||
this.persist(this.domainObject, this.getDomainObjectStyle(this.domainObject, property, this.items));
|
||||
if (this.domainObjectsById) {
|
||||
const keys = Object.keys(this.domainObjectsById);
|
||||
keys.forEach(key => {
|
||||
let domainObject = this.domainObjectsById[key];
|
||||
this.persist(domainObject, this.getDomainObjectStyle(domainObject, property));
|
||||
});
|
||||
}
|
||||
this.isStaticAndConditionalStyles = false;
|
||||
let foundIndex = this.mixedStyles.indexOf(property);
|
||||
if (foundIndex > -1) {
|
||||
this.mixedStyles.splice(foundIndex, 1);
|
||||
}
|
||||
},
|
||||
getDomainObjectStyle(domainObject, property, items) {
|
||||
let domainObjectStyles = (domainObject.configuration && domainObject.configuration.objectStyles) || {};
|
||||
|
||||
if (items) {
|
||||
items.forEach(item => {
|
||||
let itemStaticStyle = {};
|
||||
if (domainObjectStyles[item.id] && domainObjectStyles[item.id].staticStyle) {
|
||||
itemStaticStyle = domainObjectStyles[item.id].staticStyle.style;
|
||||
}
|
||||
Object.keys(item.applicableStyles).forEach(key => {
|
||||
if (property === key) {
|
||||
itemStaticStyle[key] = this.staticStyle.style[key];
|
||||
}
|
||||
});
|
||||
if (this.isStaticAndConditionalStyles) {
|
||||
this.removeConditionalStyles(domainObjectStyles, item.id);
|
||||
}
|
||||
if (_.isEmpty(itemStaticStyle)) {
|
||||
itemStaticStyle = undefined;
|
||||
domainObjectStyles[item.id] = undefined;
|
||||
} else {
|
||||
domainObjectStyles[item.id] = Object.assign({}, { staticStyle: { style: itemStaticStyle } });
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (!domainObjectStyles.staticStyle) {
|
||||
domainObjectStyles.staticStyle = {
|
||||
style: {}
|
||||
}
|
||||
}
|
||||
if (this.isStaticAndConditionalStyles) {
|
||||
this.removeConditionalStyles(domainObjectStyles);
|
||||
}
|
||||
domainObjectStyles.staticStyle.style[property] = this.staticStyle.style[property];
|
||||
}
|
||||
|
||||
return domainObjectStyles;
|
||||
},
|
||||
|
||||
persist(domainObject, style) {
|
||||
this.openmct.objects.mutate(domainObject, 'configuration.objectStyles', style);
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
@ -22,12 +22,15 @@
|
||||
|
||||
<template>
|
||||
<div class="c-style">
|
||||
<span class="c-style-thumb"
|
||||
:class="{ 'is-style-invisible': styleItem.style.isStyleInvisible }"
|
||||
<span :class="[
|
||||
{ 'is-style-invisible': styleItem.style.isStyleInvisible },
|
||||
{ 'c-style-thumb--mixed': mixedStyles.indexOf('backgroundColor') > -1 }
|
||||
]"
|
||||
:style="[styleItem.style.imageUrl ? { backgroundImage:'url(' + styleItem.style.imageUrl + ')'} : itemStyle ]"
|
||||
class="c-style-thumb"
|
||||
>
|
||||
<span class="c-style-thumb__text"
|
||||
:class="{ 'hide-nice': !styleItem.style.color }"
|
||||
:class="{ 'hide-nice': !hasProperty(styleItem.style.color) }"
|
||||
>
|
||||
ABC
|
||||
</span>
|
||||
@ -68,6 +71,7 @@ import ToolbarColorPicker from "@/ui/toolbar/components/toolbar-color-picker.vue
|
||||
import ToolbarButton from "@/ui/toolbar/components/toolbar-button.vue";
|
||||
import ToolbarToggleButton from "@/ui/toolbar/components/toolbar-toggle-button.vue";
|
||||
import {STYLE_CONSTANTS} from "@/plugins/condition/utils/constants";
|
||||
import {getStylesWithoutNoneValue} from "@/plugins/condition/utils/styleUtils";
|
||||
|
||||
export default {
|
||||
name: 'StyleEditor',
|
||||
@ -83,6 +87,12 @@ export default {
|
||||
isEditing: {
|
||||
type: Boolean
|
||||
},
|
||||
mixedStyles: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
styleItem: {
|
||||
type: Object,
|
||||
required: true
|
||||
@ -90,21 +100,17 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
itemStyle() {
|
||||
let style = {};
|
||||
const keys = Object.keys(this.styleItem.style);
|
||||
keys.forEach(key => {
|
||||
style[key] = this.normalizeValue(this.styleItem.style[key]);
|
||||
});
|
||||
return style;
|
||||
return getStylesWithoutNoneValue(this.styleItem.style);
|
||||
},
|
||||
borderColorOption() {
|
||||
let value = this.styleItem.style.border.replace('1px solid ', '');
|
||||
return {
|
||||
icon: 'icon-line-horz',
|
||||
title: STYLE_CONSTANTS.borderColorTitle,
|
||||
value: this.normalizeValue(value),
|
||||
value: this.normalizeValueForSwatch(value),
|
||||
property: 'border',
|
||||
isEditing: this.isEditing
|
||||
isEditing: this.isEditing,
|
||||
nonSpecific: this.mixedStyles.indexOf('border') > -1
|
||||
}
|
||||
},
|
||||
backgroundColorOption() {
|
||||
@ -112,9 +118,10 @@ export default {
|
||||
return {
|
||||
icon: 'icon-paint-bucket',
|
||||
title: STYLE_CONSTANTS.backgroundColorTitle,
|
||||
value: this.normalizeValue(value),
|
||||
value: this.normalizeValueForSwatch(value),
|
||||
property: 'backgroundColor',
|
||||
isEditing: this.isEditing
|
||||
isEditing: this.isEditing,
|
||||
nonSpecific: this.mixedStyles.indexOf('backgroundColor') > -1
|
||||
}
|
||||
},
|
||||
colorOption() {
|
||||
@ -122,9 +129,10 @@ export default {
|
||||
return {
|
||||
icon: 'icon-font',
|
||||
title: STYLE_CONSTANTS.textColorTitle,
|
||||
value: this.normalizeValue(value),
|
||||
value: this.normalizeValueForSwatch(value),
|
||||
property: 'color',
|
||||
isEditing: this.isEditing
|
||||
isEditing: this.isEditing,
|
||||
nonSpecific: this.mixedStyles.indexOf('color') > -1
|
||||
}
|
||||
},
|
||||
imageUrlOption() {
|
||||
@ -149,7 +157,8 @@ export default {
|
||||
property: 'imageUrl',
|
||||
formKeys: ['url'],
|
||||
value: {url: this.styleItem.style.imageUrl},
|
||||
isEditing: this.isEditing
|
||||
isEditing: this.isEditing,
|
||||
nonSpecific: this.mixedStyles.indexOf('imageUrl') > -1
|
||||
}
|
||||
},
|
||||
isStyleInvisibleOption() {
|
||||
@ -177,13 +186,20 @@ export default {
|
||||
hasProperty(property) {
|
||||
return property !== undefined;
|
||||
},
|
||||
normalizeValue(value) {
|
||||
if (!value) {
|
||||
return 'transparent';
|
||||
normalizeValueForSwatch(value) {
|
||||
if (value && value.indexOf('__no_value') > -1) {
|
||||
return value.replace('__no_value', 'transparent');
|
||||
}
|
||||
return value;
|
||||
},
|
||||
normalizeValueForStyle(value) {
|
||||
if (value && value === 'transparent') {
|
||||
return '__no_value';
|
||||
}
|
||||
return value;
|
||||
},
|
||||
updateStyleValue(value, item) {
|
||||
value = this.normalizeValueForStyle(value);
|
||||
if (item.property === 'border') {
|
||||
value = '1px solid ' + value;
|
||||
}
|
||||
@ -192,7 +208,7 @@ export default {
|
||||
} else {
|
||||
this.styleItem.style[item.property] = value;
|
||||
}
|
||||
this.$emit('persist', this.styleItem);
|
||||
this.$emit('persist', this.styleItem, item.property);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
* this source code distribution or the Licensing information page available
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
const NONE_VALUE = 'transparent';
|
||||
const NONE_VALUE = '__no_value';
|
||||
|
||||
const styleProps = {
|
||||
backgroundColor: {
|
||||
@ -46,7 +46,7 @@ const styleProps = {
|
||||
},
|
||||
color: {
|
||||
svgProperty: 'color',
|
||||
noneValue: 'NONE_VALUE',
|
||||
noneValue: NONE_VALUE,
|
||||
applicableForType: type => {
|
||||
return !type ? true : (type === 'text-view' ||
|
||||
type === 'telemetry-view'||
|
||||
@ -62,19 +62,74 @@ const styleProps = {
|
||||
}
|
||||
};
|
||||
|
||||
const aggregateStyleValues = (accumulator, currentStyle) => {
|
||||
const styleKeys = Object.keys(currentStyle);
|
||||
const properties = Object.keys(styleProps);
|
||||
properties.forEach((property) => {
|
||||
if (!accumulator[property]) {
|
||||
accumulator[property] = [];
|
||||
}
|
||||
const found = styleKeys.find(key => key === property);
|
||||
if (found) {
|
||||
accumulator[property].push(currentStyle[found]);
|
||||
}
|
||||
});
|
||||
return accumulator;
|
||||
};
|
||||
|
||||
// Returns a union of styles used by multiple items.
|
||||
// Styles that are common to all items but don't have the same value are added to the mixedStyles list
|
||||
export const getConsolidatedStyleValues = (multipleItemStyles) => {
|
||||
let aggregatedStyleValues = multipleItemStyles.reduce(aggregateStyleValues, {});
|
||||
|
||||
let styleValues = {};
|
||||
let mixedStyles = [];
|
||||
const properties = Object.keys(styleProps);
|
||||
properties.forEach((property) => {
|
||||
const values = aggregatedStyleValues[property];
|
||||
if (values.length) {
|
||||
if (values.every(value => value === values[0])) {
|
||||
styleValues[property] = values[0];
|
||||
} else {
|
||||
styleValues[property] = '';
|
||||
mixedStyles.push(property);
|
||||
}
|
||||
}
|
||||
});
|
||||
return {
|
||||
styles: styleValues,
|
||||
mixedStyles
|
||||
};
|
||||
};
|
||||
|
||||
const getStaticStyleForItem = (domainObject, id) => {
|
||||
let domainObjectStyles = domainObject && domainObject.configuration && domainObject.configuration.objectStyles;
|
||||
if (domainObjectStyles) {
|
||||
if (id && domainObjectStyles[id] && domainObjectStyles[id].staticStyle) {
|
||||
return domainObjectStyles[id].staticStyle.style;
|
||||
if (id) {
|
||||
if(domainObjectStyles[id] && domainObjectStyles[id].staticStyle) {
|
||||
return domainObjectStyles[id].staticStyle.style;
|
||||
}
|
||||
} else if (domainObjectStyles.staticStyle) {
|
||||
return domainObjectStyles.staticStyle.style;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export const getConditionalStyleForItem = (domainObject, id) => {
|
||||
let domainObjectStyles = domainObject && domainObject.configuration && domainObject.configuration.objectStyles;
|
||||
if (domainObjectStyles) {
|
||||
if (id) {
|
||||
if (domainObjectStyles[id] && domainObjectStyles[id].conditionSetIdentifier) {
|
||||
return domainObjectStyles[id].styles;
|
||||
}
|
||||
} else if (domainObjectStyles.staticStyle) {
|
||||
return domainObjectStyles.styles;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//Returns either existing static styles or uses SVG defaults if available
|
||||
export const getInitialStyleForItem = (domainObject, item) => {
|
||||
export const getApplicableStylesForItem = (domainObject, item) => {
|
||||
const type = item && item.type;
|
||||
const id = item && item.id;
|
||||
let style = {};
|
||||
@ -97,3 +152,21 @@ export const getInitialStyleForItem = (domainObject, item) => {
|
||||
|
||||
return style;
|
||||
};
|
||||
|
||||
export const getStylesWithoutNoneValue = (style) => {
|
||||
if (_.isEmpty(style) || !style) {
|
||||
return;
|
||||
}
|
||||
let styleObj = {};
|
||||
const keys = Object.keys(style);
|
||||
keys.forEach(key => {
|
||||
if ((typeof style[key] === 'string')) {
|
||||
if (style[key].indexOf('__no_value') > -1) {
|
||||
style[key] = '';
|
||||
} else {
|
||||
styleObj[key] = style[key];
|
||||
}
|
||||
}
|
||||
});
|
||||
return styleObj;
|
||||
};
|
||||
|
@ -43,7 +43,7 @@ export default {
|
||||
makeDefinition() {
|
||||
return {
|
||||
fill: '#717171',
|
||||
stroke: 'transparent',
|
||||
stroke: '',
|
||||
x: 1,
|
||||
y: 1,
|
||||
width: 10,
|
||||
@ -74,13 +74,14 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
return Object.assign({
|
||||
backgroundColor: this.item.fill,
|
||||
border: '1px solid ' + this.item.stroke
|
||||
}, this.itemStyle);
|
||||
},
|
||||
styleClass() {
|
||||
return this.itemStyle && this.itemStyle.isStyleInvisible;
|
||||
if (this.itemStyle) {
|
||||
return this.itemStyle;
|
||||
} else {
|
||||
return {
|
||||
backgroundColor: this.item.fill,
|
||||
border: this.item.stroke ? '1px solid ' + this.item.stroke : ''
|
||||
};
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -74,13 +74,18 @@ export default {
|
||||
},
|
||||
computed: {
|
||||
style() {
|
||||
let backgroundImage = 'url(' + this.item.url + ')';
|
||||
let border = '1px solid ' + this.item.stroke;
|
||||
if (this.itemStyle) {
|
||||
if (this.itemStyle.imageUrl !== undefined) {
|
||||
backgroundImage = 'url(' + this.itemStyle.imageUrl + ')';
|
||||
}
|
||||
border = this.itemStyle.border;
|
||||
}
|
||||
return {
|
||||
backgroundImage: this.itemStyle ? ('url(' + this.itemStyle.imageUrl + ')') : 'url(' + this.item.url + ')',
|
||||
border: (this.itemStyle && this.itemStyle.border) ? this.itemStyle.border : ('1px solid ' + this.item.stroke)
|
||||
backgroundImage,
|
||||
border
|
||||
};
|
||||
},
|
||||
styleClass() {
|
||||
return this.itemStyle && this.itemStyle.isStyleInvisible;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -127,8 +127,11 @@ export default {
|
||||
return {x, y, x2, y2};
|
||||
},
|
||||
stroke() {
|
||||
if (this.itemStyle && this.itemStyle.border) {
|
||||
return this.itemStyle.border.replace('1px solid ', '');
|
||||
if (this.itemStyle) {
|
||||
if (this.itemStyle.border) {
|
||||
return this.itemStyle.border.replace('1px solid ', '');
|
||||
}
|
||||
return '';
|
||||
} else {
|
||||
return this.item.stroke;
|
||||
}
|
||||
@ -146,9 +149,6 @@ export default {
|
||||
height: `${height}px`
|
||||
};
|
||||
},
|
||||
styleClass() {
|
||||
return this.itemStyle && this.itemStyle.isStyleInvisible;
|
||||
},
|
||||
startHandleClass() {
|
||||
return START_HANDLE_QUADRANTS[this.vectorQuadrant];
|
||||
},
|
||||
|
@ -31,7 +31,7 @@
|
||||
v-if="domainObject"
|
||||
class="c-telemetry-view"
|
||||
:class="styleClass"
|
||||
:style="telemetryObjectStyle || styleObject"
|
||||
:style="styleObject"
|
||||
@contextmenu.prevent="showContextMenu"
|
||||
>
|
||||
<div
|
||||
@ -79,8 +79,8 @@ export default {
|
||||
height: DEFAULT_TELEMETRY_DIMENSIONS[1],
|
||||
displayMode: 'all',
|
||||
value: metadata.getDefaultDisplayValue(),
|
||||
stroke: "transparent",
|
||||
fill: "transparent",
|
||||
stroke: "",
|
||||
fill: "",
|
||||
color: "",
|
||||
size: "13px"
|
||||
};
|
||||
@ -125,27 +125,10 @@ export default {
|
||||
return displayMode === 'all' || displayMode === 'value';
|
||||
},
|
||||
styleObject() {
|
||||
return {
|
||||
backgroundColor: this.item.fill,
|
||||
borderColor: this.item.stroke,
|
||||
color: this.item.color,
|
||||
return Object.assign({}, {
|
||||
fontSize: this.item.size
|
||||
}
|
||||
},
|
||||
styleClass() {
|
||||
return this.telemetryObjectStyle && this.telemetryObjectStyle.isStyleInvisible;
|
||||
},
|
||||
telemetryObjectStyle() {
|
||||
let styleObj = Object.assign({}, this.itemStyle);
|
||||
let keys = Object.keys(styleObj);
|
||||
keys.forEach(key => {
|
||||
if ((typeof styleObj[key] === 'string') && (styleObj[key].indexOf('transparent') > -1)) {
|
||||
if (styleObj[key]) {
|
||||
styleObj[key] = '';
|
||||
}
|
||||
}
|
||||
});
|
||||
return styleObj;
|
||||
}, this.itemStyle);
|
||||
|
||||
},
|
||||
fieldName() {
|
||||
return this.valueMetadata && this.valueMetadata.name;
|
||||
|
@ -32,7 +32,7 @@
|
||||
:class="[styleClass]"
|
||||
:style="style"
|
||||
>
|
||||
{{ item.text }}
|
||||
<div class="c-text-view__text">{{ item.text }}</div>
|
||||
</div>
|
||||
</layout-frame>
|
||||
</template>
|
||||
@ -44,8 +44,8 @@ import conditionalStylesMixin from "../mixins/objectStyles-mixin";
|
||||
export default {
|
||||
makeDefinition(openmct, gridSize, element) {
|
||||
return {
|
||||
fill: 'transparent',
|
||||
stroke: 'transparent',
|
||||
fill: '',
|
||||
stroke: '',
|
||||
size: '13px',
|
||||
color: '',
|
||||
x: 1,
|
||||
@ -80,14 +80,8 @@ export default {
|
||||
computed: {
|
||||
style() {
|
||||
return Object.assign({
|
||||
backgroundColor: this.item.fill,
|
||||
border: '1px solid ' + this.item.stroke,
|
||||
color: this.item.color,
|
||||
fontSize: this.item.size
|
||||
}, this.itemStyle);
|
||||
},
|
||||
styleClass() {
|
||||
return this.itemStyle && this.itemStyle.isStyleInvisible;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -16,6 +16,8 @@
|
||||
.is-editing {
|
||||
/******************* STYLES FOR C-FRAME WHILE EDITING */
|
||||
.c-frame {
|
||||
border: 1px solid rgba($editFrameColorHov, 0.3);
|
||||
|
||||
&:not([s-selected]) {
|
||||
&:hover {
|
||||
border: $editFrameBorderHov;
|
||||
|
@ -1,6 +1,8 @@
|
||||
.c-text-view {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
align-items: center; // Vertically center text
|
||||
overflow: hidden;
|
||||
padding: $interiorMargin;
|
||||
|
||||
.c-frame & {
|
||||
@include abs();
|
||||
|
@ -21,12 +21,14 @@
|
||||
*****************************************************************************/
|
||||
|
||||
import StyleRuleManager from "@/plugins/condition/StyleRuleManager";
|
||||
import {getStylesWithoutNoneValue} from "@/plugins/condition/utils/styleUtils";
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
data() {
|
||||
return {
|
||||
itemStyle: this.itemStyle
|
||||
itemStyle: undefined,
|
||||
styleClass: ''
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
@ -69,13 +71,8 @@ export default {
|
||||
});
|
||||
},
|
||||
updateStyle(style) {
|
||||
this.itemStyle = style;
|
||||
let keys = Object.keys(this.itemStyle);
|
||||
keys.forEach((key) => {
|
||||
if ((typeof this.itemStyle[key] === 'string') && (this.itemStyle[key].indexOf('transparent') > -1)) {
|
||||
delete this.itemStyle[key];
|
||||
}
|
||||
});
|
||||
this.itemStyle = getStylesWithoutNoneValue(style);
|
||||
this.styleClass = this.itemStyle && this.itemStyle.isStyleInvisible;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -122,13 +122,8 @@ button {
|
||||
margin-left: $interiorMargin;
|
||||
}
|
||||
|
||||
$c1: nth($mixedSettingBg, 1);
|
||||
$c2: nth($mixedSettingBg, 2);
|
||||
$mixedBgD: $mixedSettingBgSize $mixedSettingBgSize;
|
||||
|
||||
&--mixed {
|
||||
// E.g. click-icons in toolbar that apply to multiple selected items with different settings
|
||||
@include bgStripes2Color($c1, $c2, $bgSize: $mixedBgD);
|
||||
@include mixedBg();
|
||||
}
|
||||
|
||||
&--swatched {
|
||||
@ -151,13 +146,6 @@ button {
|
||||
flex: 1 1 auto;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
|
||||
&--mixed {
|
||||
// Styling for swatched buttons when settings are mixed
|
||||
> [class*='swatch'] {
|
||||
@include bgStripes2Color($c1, $c2, $bgSize: $mixedBgD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -821,6 +809,10 @@ select {
|
||||
box-shadow: rgba($colorBodyFg, 0.4) 0 0 3px;
|
||||
flex: 0 0 auto;
|
||||
padding: $interiorMargin $interiorMarginLg;
|
||||
|
||||
&--mixed {
|
||||
@include mixedBg();
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************** SLIDERS */
|
||||
|
@ -72,6 +72,7 @@
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: 1.25em;
|
||||
overflow: hidden;
|
||||
|
||||
> * {
|
||||
flex: 0 0 auto;
|
||||
@ -82,6 +83,12 @@
|
||||
&__value {
|
||||
color: $colorBodyFgEm;
|
||||
}
|
||||
|
||||
.c-frame & {
|
||||
// When in a Display or Flexible Layout
|
||||
@include abs();
|
||||
padding: $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
.c-clock {
|
||||
|
@ -50,6 +50,14 @@
|
||||
}
|
||||
|
||||
/************************** EFFECTS */
|
||||
@mixin mixedBg() {
|
||||
$c1: nth($mixedSettingBg, 1);
|
||||
$c2: nth($mixedSettingBg, 2);
|
||||
$mixedBgD: $mixedSettingBgSize $mixedSettingBgSize;
|
||||
@include bgStripes2Color($c1, $c2, $bgSize: $mixedBgD);
|
||||
}
|
||||
|
||||
|
||||
@mixin pulse($animName: pulse, $dur: 500ms, $iteration: infinite, $opacity0: 0.5, $opacity100: 1) {
|
||||
@keyframes #{$animName} {
|
||||
0% { opacity: $opacity0; }
|
||||
|
@ -104,7 +104,7 @@ export default {
|
||||
keys.forEach(key => {
|
||||
let firstChild = this.$el.querySelector(':first-child');
|
||||
if (firstChild) {
|
||||
if ((typeof styleObj[key] === 'string') && (styleObj[key].indexOf('transparent') > -1)) {
|
||||
if ((typeof styleObj[key] === 'string') && (styleObj[key].indexOf('__no_value') > -1)) {
|
||||
if (firstChild.style[key]) {
|
||||
firstChild.style[key] = '';
|
||||
}
|
||||
|
@ -26,6 +26,7 @@
|
||||
|
||||
<script>
|
||||
import ConditionalStylesView from '../../plugins/condition/components/inspector/ConditionalStylesView.vue';
|
||||
import MultiSelectStylesView from '../../plugins/condition/components/inspector/MultiSelectStylesView.vue';
|
||||
import Vue from 'vue';
|
||||
|
||||
export default {
|
||||
@ -45,6 +46,7 @@ export default {
|
||||
methods: {
|
||||
updateSelection(selection) {
|
||||
if (selection.length > 0 && selection[0].length > 0) {
|
||||
let template = selection.length > 1 ? '<multi-select-styles-view></multi-select-styles-view>' : '<conditional-styles-view></conditional-styles-view>';
|
||||
if (this.component) {
|
||||
this.component.$destroy();
|
||||
this.component = undefined;
|
||||
@ -59,9 +61,10 @@ export default {
|
||||
},
|
||||
el: viewContainer,
|
||||
components: {
|
||||
ConditionalStylesView
|
||||
ConditionalStylesView,
|
||||
MultiSelectStylesView
|
||||
},
|
||||
template: '<conditional-styles-view></conditional-styles-view>'
|
||||
template: template
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user