mirror of
https://github.com/nasa/openmct.git
synced 2025-02-20 09:26:45 +00:00
Review and integrate Time Conductor Vue style conversion (#2180)
Styling updates for Vue version of Time Conductor
This commit is contained in:
parent
e6e5b6a64a
commit
56b9708ab7
@ -56,7 +56,7 @@ define([
|
||||
};
|
||||
|
||||
DurationFormat.prototype.validate = function (text) {
|
||||
return moment.utc(text, DATE_FORMATS).isValid();
|
||||
return moment.utc(text, DATE_FORMATS, true).isValid();
|
||||
};
|
||||
|
||||
return DurationFormat;
|
||||
|
@ -29,6 +29,7 @@ define([
|
||||
var DATE_FORMAT = "YYYY-MM-DD HH:mm:ss.SSS",
|
||||
DATE_FORMATS = [
|
||||
DATE_FORMAT,
|
||||
DATE_FORMAT + "Z",
|
||||
"YYYY-MM-DD HH:mm:ss",
|
||||
"YYYY-MM-DD HH:mm",
|
||||
"YYYY-MM-DD"
|
||||
@ -74,7 +75,7 @@ define([
|
||||
};
|
||||
|
||||
UTCTimeFormat.prototype.validate = function (text) {
|
||||
return moment.utc(text, DATE_FORMATS).isValid();
|
||||
return moment.utc(text, DATE_FORMATS, true).isValid();
|
||||
};
|
||||
|
||||
return UTCTimeFormat;
|
||||
|
@ -22,7 +22,7 @@
|
||||
</div>
|
||||
<div class="c-grid-item__controls">
|
||||
<div class="icon-people" title='Shared'></div>
|
||||
<div class="c-icon-button icon-info c-info-button" title='More Info'></div>
|
||||
<div class="c-click-icon icon-info c-info-button" title='More Info'></div>
|
||||
<div class="icon-pointer-right c-pointer-icon"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -28,7 +28,7 @@
|
||||
</div>
|
||||
|
||||
<div class="c-ne__local-controls--hidden">
|
||||
<a class="c-icon-button icon-trash"
|
||||
<a class="c-click-icon icon-trash"
|
||||
title="Delete this entry"
|
||||
v-on:click="deleteEntry"></a>
|
||||
</div>
|
||||
|
@ -20,106 +20,211 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<!-- Parent holder for time conductor. follow-mode | fixed-mode -->
|
||||
<div class="l-flex-row l-time-conductor"
|
||||
:class="[isFixed ? 'fixed-mode' : 'realtime-mode', panning ? 'status-panning' : '']">
|
||||
<div class="flex-elem holder time-conductor-icon">
|
||||
<div class="hand-little"></div>
|
||||
<div class="hand-big"></div>
|
||||
</div>
|
||||
<div class="c-conductor"
|
||||
:class="[isFixed ? 'is-fixed-mode' : 'is-realtime-mode', panning ? 'status-panning' : '']">
|
||||
<form class="u-contents" ref="conductorForm"
|
||||
@submit="isFixed ? setBoundsFromView($event) : setOffsetsFromView($event)">
|
||||
|
||||
<div class="flex-elem holder grows l-flex-col l-time-conductor-inner">
|
||||
<!-- Holds inputs and ticks -->
|
||||
<div class="l-time-conductor-inputs-and-ticks l-row-elem flex-elem no-margin">
|
||||
<form class="l-time-conductor-inputs-holder" ref="conductorForm"
|
||||
@submit="isFixed ? setBoundsFromView($event) : setOffsetsFromView($event)">
|
||||
<span class="l-time-range-w start-w">
|
||||
<span class="l-time-conductor-inputs">
|
||||
<span class="l-time-range-input-w start-date">
|
||||
<span class="title"></span>
|
||||
<span class="time-range-input">
|
||||
<input type="text" autocorrect="off" spellcheck="false"
|
||||
ref="startDate"
|
||||
v-model="formattedBounds.start"
|
||||
@keyup="validateBounds('start', $event.target)"
|
||||
@blur="setBoundsFromView()">
|
||||
<date-picker :default-date-time="formattedBounds.start" :formatter="timeFormatter" @date-selected="startDateSelected"></date-picker>
|
||||
</span>
|
||||
</span>
|
||||
<span class="l-time-range-input-w time-delta start-delta"
|
||||
:class="{'hide': isFixed}">
|
||||
-
|
||||
<span class="s-input-inline hrs-min-input">
|
||||
<input type="text" autocorrect="off" spellcheck="false"
|
||||
v-model="offsets.start"
|
||||
@keyup="validateOffsets($event)"
|
||||
@blur="setOffsetsFromView()">
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
<span class="l-time-range-w end-w">
|
||||
<span class="l-time-conductor-inputs">
|
||||
<span class="l-time-range-input-w end-date">
|
||||
<span class="title"></span>
|
||||
<span class="time-range-input">
|
||||
<input type="text" autocorrect="off" spellcheck="false"
|
||||
v-model="formattedBounds.end"
|
||||
:disabled="!isFixed"
|
||||
ref="endDate"
|
||||
@keyup="validateBounds('end', $event.target)"
|
||||
@blur="setBoundsFromView()">
|
||||
<date-picker :default-date-time="formattedBounds.end" :formatter="timeFormatter" @date-selected="endDateSelected"></date-picker>
|
||||
</span>
|
||||
</span>
|
||||
<span class="l-time-range-input-w time-delta end-delta"
|
||||
:class="{'hide': isFixed}">
|
||||
+
|
||||
<span class="s-input-inline hrs-min-input">
|
||||
<input type="text" autocorrect="off" spellcheck="false"
|
||||
v-model="offsets.end"
|
||||
@keyup="validateOffsets($event)"
|
||||
@blur="setOffsetsFromView()">
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
</span>
|
||||
<input type="submit" class="invisible">
|
||||
</form>
|
||||
<conductor-axis class="mobile-hide" :bounds="rawBounds" @panZoom="setViewFromBounds"></conductor-axis>
|
||||
</div>
|
||||
<ConductorModeIcon class="c-conductor__mode-icon"></ConductorModeIcon>
|
||||
|
||||
<!-- Holds time system and session selectors, and zoom control -->
|
||||
<div class="l-time-conductor-controls l-row-elem l-flex-row flex-elem">
|
||||
<ConductorMode></ConductorMode>
|
||||
<ConductorTimeSystem></ConductorTimeSystem>
|
||||
<!-- Zoom control -->
|
||||
<div v-if="isUTCBased && isFixed"
|
||||
class="l-time-conductor-zoom-w grows flex-elem l-flex-row">
|
||||
{{currentZoomText}}
|
||||
<span class="time-conductor-zoom-current-range flex-elem flex-fixed holder">{{timeUnits}}</span>
|
||||
<input class="time-conductor-zoom flex-elem" type="range"
|
||||
v-model="currentZoom"
|
||||
@change="setBoundsFromView()"
|
||||
min="0.01"
|
||||
step="0.01"
|
||||
max="0.99" />
|
||||
<div class="c-conductor__start-input">
|
||||
<!-- Start input and controls -->
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__start__fixed"
|
||||
v-if="isFixed">
|
||||
<!-- Fixed input -->
|
||||
<div class="c-conductor__start__fixed__label">Start</div>
|
||||
<input class="c-input--datetime"
|
||||
type="text" autocorrect="off" spellcheck="false"
|
||||
ref="startDate"
|
||||
v-model="formattedBounds.start"
|
||||
@change="validateBounds('start', $event.target); setBoundsFromView()" />
|
||||
<date-picker
|
||||
:default-date-time="formattedBounds.start"
|
||||
:formatter="timeFormatter"
|
||||
@date-selected="startDateSelected"></date-picker>
|
||||
</div>
|
||||
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__start__delta"
|
||||
v-if="!isFixed">
|
||||
<!-- RT input -->
|
||||
<div class="c-direction-indicator icon-minus"></div>
|
||||
<input class="c-input--hrs-min-sec"
|
||||
type="text" autocorrect="off"
|
||||
spellcheck="false"
|
||||
v-model="offsets.start"
|
||||
@change="validateOffsets($event); setOffsetsFromView()">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="c-conductor__end-input">
|
||||
<!-- End input and controls -->
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__end__fixed"
|
||||
v-if="isFixed">
|
||||
<!-- Fixed input -->
|
||||
<div class="c-conductor__end__fixed__label">End</div>
|
||||
<input class="c-input--datetime"
|
||||
type="text" autocorrect="off" spellcheck="false"
|
||||
v-model="formattedBounds.end"
|
||||
:disabled="!isFixed"
|
||||
ref="endDate"
|
||||
@change="validateBounds('end', $event.target); setBoundsFromView()">
|
||||
<date-picker
|
||||
class="c-ctrl-wrapper--menus-left"
|
||||
:default-date-time="formattedBounds.end"
|
||||
:formatter="timeFormatter"
|
||||
@date-selected="endDateSelected"></date-picker>
|
||||
</div>
|
||||
|
||||
<div class="c-ctrl-wrapper c-conductor-input c-conductor__end__delta"
|
||||
v-if="!isFixed">
|
||||
<!-- RT input -->
|
||||
<div class="c-direction-indicator icon-plus"></div>
|
||||
<input class="c-input--hrs-min-sec"
|
||||
type="text"
|
||||
autocorrect="off"
|
||||
spellcheck="false"
|
||||
v-model="offsets.end"
|
||||
@change="validateOffsets($event); setOffsetsFromView()">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<conductor-axis
|
||||
class="c-conductor__ticks"
|
||||
:bounds="rawBounds"
|
||||
@panAxis="setViewFromBounds"></conductor-axis>
|
||||
<div class="c-conductor__controls">
|
||||
<!-- Mode, time system menu buttons and duration slider -->
|
||||
<ConductorMode class="c-conductor__mode-select"></ConductorMode>
|
||||
<ConductorTimeSystem class="c-conductor__time-system-select"></ConductorTimeSystem>
|
||||
</div>
|
||||
<input type="submit" class="invisible">
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "~styles/sass-base";
|
||||
|
||||
.l-time-conductor-inputs input:invalid {
|
||||
border: 1px solid $colorFormInvalid !important;
|
||||
/*********************************************** CONDUCTOR LAYOUT */
|
||||
.c-conductor {
|
||||
display: grid;
|
||||
grid-column-gap: $interiorMargin;
|
||||
grid-row-gap: $interiorMargin;
|
||||
align-items: center;
|
||||
|
||||
|
||||
grid-template-rows: 1fr 1fr;
|
||||
grid-template-columns: 20px auto 1fr auto;
|
||||
grid-template-areas:
|
||||
"tc-mode-icon tc-start tc-ticks tc-end"
|
||||
"tc-controls tc-controls tc-controls tc-controls";
|
||||
|
||||
.c-conductor__end-input {
|
||||
justify-content: flex-end;
|
||||
}
|
||||
|
||||
body.phone.portrait & {
|
||||
&.is-fixed-mode {
|
||||
grid-row-gap: $interiorMargin;
|
||||
grid-template-rows: auto auto auto;
|
||||
grid-template-columns: 20px auto;
|
||||
grid-template-areas:
|
||||
"tc-mode-icon tc-start"
|
||||
"tc-mode-icon tc-end"
|
||||
"tc-mode-icon tc-controls";
|
||||
|
||||
.c-conductor {
|
||||
&__mode-icon {
|
||||
grid-row: 1;
|
||||
}
|
||||
|
||||
&__ticks,
|
||||
&__zoom {
|
||||
display: none;
|
||||
}
|
||||
|
||||
&-input [class*='__label'] {
|
||||
// Start and end are in separate columns; make the labels line up
|
||||
width: 40px;
|
||||
}
|
||||
|
||||
&__end-input {
|
||||
justify-content: flex-start;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&__mode-icon {
|
||||
grid-area: tc-mode-icon;
|
||||
}
|
||||
|
||||
&__start-input,
|
||||
&__end-input {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&__start-input {
|
||||
grid-area: tc-start;
|
||||
}
|
||||
|
||||
&__end-input {
|
||||
grid-area: tc-end;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&__ticks {
|
||||
grid-area: tc-ticks;
|
||||
}
|
||||
|
||||
&__controls {
|
||||
grid-area: tc-controls;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
> * + * {
|
||||
margin-left: $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
[class*='__delta'] {
|
||||
&:before {
|
||||
content: $glyph-icon-clock;
|
||||
font-family: symbolsfont;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.l-time-conductor-zoom-w {
|
||||
text-transform: capitalize;
|
||||
.c-conductor-input {
|
||||
color: $colorInputFg;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: flex-start;
|
||||
|
||||
> * + * {
|
||||
margin-left: $interiorMarginSm;
|
||||
}
|
||||
|
||||
&:before {
|
||||
// Realtime-mode clock icon symbol
|
||||
margin-right: $interiorMarginSm;
|
||||
}
|
||||
|
||||
.c-direction-indicator {
|
||||
// Holds realtime-mode + and - symbols
|
||||
font-size: 0.7em;
|
||||
}
|
||||
|
||||
input:invalid {
|
||||
background: rgba($colorFormInvalid, 0.3);
|
||||
}
|
||||
}
|
||||
|
||||
.is-realtime-mode {
|
||||
.c-conductor-input {
|
||||
&:before {
|
||||
color: $colorTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@ -129,14 +234,13 @@ import ConductorMode from './ConductorMode.vue';
|
||||
import ConductorTimeSystem from './ConductorTimeSystem.vue';
|
||||
import DatePicker from './DatePicker.vue';
|
||||
import ConductorAxis from './ConductorAxis.vue';
|
||||
import ConductorModeIcon from './ConductorModeIcon.vue';
|
||||
|
||||
const DEFAULT_DURATION_FORMATTER = 'duration';
|
||||
const SECONDS = 1000;
|
||||
const DAYS = 24 * 60 * 60 * SECONDS;
|
||||
const YEARS = 365 * DAYS;
|
||||
|
||||
const MAX_ZOOM_OUT = 10 * YEARS;
|
||||
const MAX_ZOOM_IN = 5 * SECONDS;
|
||||
const RESIZE_POLL_INTERVAL = 200;
|
||||
|
||||
export default {
|
||||
@ -145,7 +249,8 @@ export default {
|
||||
ConductorMode,
|
||||
ConductorTimeSystem,
|
||||
DatePicker,
|
||||
ConductorAxis
|
||||
ConductorAxis,
|
||||
ConductorModeIcon
|
||||
},
|
||||
data() {
|
||||
let bounds = this.openmct.time.bounds();
|
||||
@ -155,7 +260,6 @@ export default {
|
||||
let durationFormatter = this.getFormatter(timeSystem.durationFormat || DEFAULT_DURATION_FORMATTER);
|
||||
|
||||
return {
|
||||
currentZoom: this.calculateZoomFromBounds(),
|
||||
timeFormatter: timeFormatter,
|
||||
durationFormatter: durationFormatter,
|
||||
offsets: {
|
||||
@ -184,7 +288,7 @@ export default {
|
||||
this.isUTCBased = timeSystem.isUTCBased;
|
||||
},
|
||||
setOffsetsFromView($event) {
|
||||
if (this.offsetsChanged() && this.$refs.conductorForm.checkValidity()){
|
||||
if (this.$refs.conductorForm.checkValidity()){
|
||||
let startOffset = 0 - this.durationFormatter.parse(this.offsets.start);
|
||||
let endOffset = this.durationFormatter.parse(this.offsets.end);
|
||||
|
||||
@ -198,13 +302,8 @@ export default {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
offsetsChanged() {
|
||||
let currentOffsets = this.openmct.time.clockOffsets();
|
||||
return this.offsets.start !== currentOffsets.start ||
|
||||
this.offsets.end !== currentOffsets.end;
|
||||
},
|
||||
setBoundsFromView($event) {
|
||||
if (this.boundsChanged() && this.$refs.conductorForm.checkValidity()){
|
||||
if (this.$refs.conductorForm.checkValidity()){
|
||||
let start = this.timeFormatter.parse(this.formattedBounds.start);
|
||||
let end = this.timeFormatter.parse(this.formattedBounds.end);
|
||||
|
||||
@ -218,14 +317,6 @@ export default {
|
||||
return false;
|
||||
}
|
||||
},
|
||||
boundsChanged() {
|
||||
let currentBounds = this.openmct.time.bounds();
|
||||
return this.timeFormatter.parse(this.formattedBounds.start) !== currentBounds.start ||
|
||||
this.timeFormatter.parse(this.formattedBounds.end) !== currentBounds.end;
|
||||
},
|
||||
showValidityMessage($event) {
|
||||
$event.target.reportValidity();
|
||||
},
|
||||
setViewFromClock(clock) {
|
||||
this.isFixed = clock === undefined;
|
||||
},
|
||||
@ -239,9 +330,6 @@ export default {
|
||||
this.offsets.start = this.durationFormatter.format(Math.abs(offsets.start));
|
||||
this.offsets.end = this.durationFormatter.format(Math.abs(offsets.end));
|
||||
},
|
||||
showValidityMessage($event) {
|
||||
$event.target.reportValidity();
|
||||
},
|
||||
validateBounds(startOrEnd, input) {
|
||||
let validationResult = true;
|
||||
|
||||
@ -297,49 +385,8 @@ export default {
|
||||
this.validateBounds('end', this.$refs.endDate);
|
||||
this.setBoundsFromView();
|
||||
},
|
||||
zoomLevelToTimespan() {
|
||||
let minMaxDelta = MAX_ZOOM_OUT - MAX_ZOOM_IN;
|
||||
return minMaxDelta * Math.pow((1 - this.currentZoom), 4);
|
||||
},
|
||||
zoom() {
|
||||
let zoomTimespan = this.zoomLevelToTimespan();
|
||||
let start = this.openmct.time.bounds().start;
|
||||
let end = this.openmct.time.bounds().end
|
||||
let currentTimeSpan = end - start;
|
||||
let delta = currentTimeSpan - zoomTimespan;
|
||||
let bounds = {
|
||||
start: start + delta / 2,
|
||||
end: end - delta / 2
|
||||
};
|
||||
this.rawBounds = bounds;
|
||||
this.setViewFromBounds(bounds);
|
||||
this.zooming = false;
|
||||
},
|
||||
calculateZoomFromBounds() {
|
||||
let start = this.openmct.time.bounds().start;
|
||||
let end = this.openmct.time.bounds().end
|
||||
let zoomMaxMinDelta = MAX_ZOOM_OUT - MAX_ZOOM_IN;
|
||||
let currentBoundsDelta = end - start;
|
||||
|
||||
return 1 - Math.pow(currentBoundsDelta / zoomMaxMinDelta, 1 / 4);
|
||||
}
|
||||
|
||||
},
|
||||
computed: {
|
||||
currentZoomText() {
|
||||
return moment.duration(this.zoomLevelToTimespan()).humanize();
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
currentZoom() {
|
||||
if (!this.zooming) {
|
||||
this.zooming = true;
|
||||
requestAnimationFrame(this.zoom, RESIZE_POLL_INTERVAL);
|
||||
}
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
this.zooming = false;
|
||||
this.setTimeSystem(JSON.parse(JSON.stringify(this.openmct.time.timeSystem())));
|
||||
|
||||
this.openmct.time.on('bounds', this.setViewFromBounds);
|
||||
|
@ -20,14 +20,90 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<div class="l-axis-holder" ref="axisHolder"
|
||||
@mousedown="dragStart($event)"></div>
|
||||
<div class="c-conductor-axis"
|
||||
ref="axisHolder"
|
||||
@mousedown="dragStart($event)">
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.l-axis-holder {
|
||||
user-select: none;
|
||||
@import "~styles/sass-base";
|
||||
|
||||
.c-conductor-axis {
|
||||
$h: 18px;
|
||||
$tickYPos: ($h / 2) + 12px;
|
||||
|
||||
@include userSelectNone();
|
||||
@include bgTicks($c: rgba($colorBodyFg, 0.4));
|
||||
background-position: 0 50%;
|
||||
background-size: 5px 2px;
|
||||
height: $h;
|
||||
|
||||
svg {
|
||||
text-rendering: geometricPrecision;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
> g {
|
||||
// Overall Tick holder
|
||||
transform: translateY($tickYPos);
|
||||
path {
|
||||
// Domain line
|
||||
display: none;
|
||||
}
|
||||
|
||||
g {
|
||||
// Each tick. These move on drag.
|
||||
line {
|
||||
// Line beneath ticks
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text {
|
||||
// Tick labels
|
||||
fill: $colorBodyFg;
|
||||
font-size: 1em;
|
||||
paint-order: stroke;
|
||||
font-weight: bold;
|
||||
stroke: $colorBodyBg;
|
||||
stroke-linecap: butt;
|
||||
stroke-linejoin: bevel;
|
||||
stroke-width: 6px;
|
||||
}
|
||||
}
|
||||
|
||||
body.desktop .is-fixed-mode & {
|
||||
@include cursorGrab();
|
||||
background-size: 3px 30%;
|
||||
border-radius: $controlCr;
|
||||
background-color: $colorBodyBgSubtle;
|
||||
box-shadow: inset rgba(black, 0.2) 0 1px 1px;
|
||||
|
||||
svg text {
|
||||
fill: $colorBodyFg;
|
||||
stroke: $colorBodyBgSubtle;
|
||||
}
|
||||
|
||||
&:hover,
|
||||
&:active {
|
||||
$c: $colorKeySubtle;
|
||||
background-color: $c;
|
||||
svg text {
|
||||
stroke: $c;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.is-realtime-mode & {
|
||||
svg text {
|
||||
fill: $colorTime;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
|
||||
<script>
|
||||
@ -40,6 +116,8 @@ import utcMultiTimeFormat from './utcMultiTimeFormat.js';
|
||||
const PADDING = 1;
|
||||
const DEFAULT_DURATION_FORMATTER = 'duration';
|
||||
const RESIZE_POLL_INTERVAL = 200;
|
||||
const PIXELS_PER_TICK = 100;
|
||||
const PIXELS_PER_TICK_WIDE = 200;
|
||||
|
||||
export default {
|
||||
inject: ['openmct'],
|
||||
@ -62,6 +140,12 @@ export default {
|
||||
this.xScale.range([PADDING, this.width - PADDING * 2]);
|
||||
this.axisElement.call(this.xAxis);
|
||||
|
||||
if (this.width > 1800) {
|
||||
this.xAxis.ticks(this.width / PIXELS_PER_TICK_WIDE);
|
||||
} else {
|
||||
this.xAxis.ticks(this.width / PIXELS_PER_TICK);
|
||||
}
|
||||
|
||||
this.msPerPixel = (bounds.end - bounds.start) / this.width;
|
||||
},
|
||||
setViewFromTimeSystem(timeSystem) {
|
||||
@ -119,7 +203,7 @@ export default {
|
||||
start: newStart,
|
||||
end: newStart + deltaTime
|
||||
};
|
||||
this.$emit('panZoom', this.bounds);
|
||||
this.$emit('panAxis', this.bounds);
|
||||
this.dragging = false;
|
||||
})
|
||||
} else {
|
||||
|
@ -20,46 +20,62 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<div class="holder flex-elem menus-up time-system">
|
||||
<span>
|
||||
<div class="s-menu-button" @click="toggleMenu($event)">
|
||||
<span class="title-label">{{selectedMode.name}}</span>
|
||||
<div class="c-ctrl-wrapper c-ctrl-wrapper--menus-up">
|
||||
<div class="c-button--menu c-mode-button"
|
||||
@click="toggleMenu($event)">
|
||||
<span class="c-button__label">{{selectedMode.name}}</span>
|
||||
</div>
|
||||
<div class="menu super-menu mini l-mode-selector-menu"
|
||||
v-if="showMenu">
|
||||
<div class="w-menu">
|
||||
<div class="col menu-items">
|
||||
<ul>
|
||||
<li v-for="mode in modes"
|
||||
:key="mode.key"
|
||||
@click="setOption(mode)">
|
||||
<a @mouseover="hoveredMode = mode"
|
||||
@mouseleave="hoveredMode = {}"
|
||||
class="menu-item-a"
|
||||
:class="mode.cssClass">
|
||||
{{mode.name}}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="col menu-item-description">
|
||||
<div class="desc-area ui-symbol icon type-icon" :class="hoveredMode.cssClass"></div>
|
||||
<div class="w-title-desc">
|
||||
<div class="desc-area title">
|
||||
{{hoveredMode.name}}
|
||||
</div>
|
||||
<div class="desc-area description">
|
||||
{{hoveredMode.description}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="c-menu c-super-menu c-conductor__mode-menu"
|
||||
v-if="showMenu">
|
||||
<div class="c-super-menu__menu">
|
||||
<ul>
|
||||
<li v-for="mode in modes"
|
||||
:key="mode.key"
|
||||
@click="setOption(mode)"
|
||||
@mouseover="hoveredMode = mode"
|
||||
@mouseleave="hoveredMode = {}"
|
||||
class="menu-item-a"
|
||||
:class="mode.cssClass">
|
||||
{{mode.name}}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="c-super-menu__item-description">
|
||||
<div :class="['l-item-description__icon', 'bg-' + hoveredMode.cssClass]"></div>
|
||||
<div class="l-item-description__name">{{hoveredMode.name}}</div>
|
||||
<div class="l-item-description__description">{{hoveredMode.description}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "~styles/sass-base";
|
||||
|
||||
.c-conductor__mode-menu {
|
||||
max-height: 80vh;
|
||||
max-width: 500px;
|
||||
min-height: 250px;
|
||||
z-index: 70;
|
||||
|
||||
[class*="__icon"] {
|
||||
filter: $colorKeyFilter;
|
||||
}
|
||||
|
||||
[class*="__item-description"] {
|
||||
min-width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
.is-realtime-mode {
|
||||
.c-mode-button {
|
||||
background: $colorTimeBg;
|
||||
|
||||
&:hover {
|
||||
background: $colorTimeHov;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
@ -90,7 +106,7 @@ export default {
|
||||
* Populate the modes menu with metadata from the available clocks
|
||||
* "Fixed Mode" is always first, and has no defined clock
|
||||
*/
|
||||
this.modes = [this.getModeOptionForClock(undefined)]
|
||||
this.modes = [undefined]
|
||||
.concat(clocks)
|
||||
.map(this.getModeOptionForClock);
|
||||
|
||||
@ -105,7 +121,7 @@ export default {
|
||||
key: 'fixed',
|
||||
name: 'Fixed Timespan Mode',
|
||||
description: 'Query and explore data that falls between two fixed datetimes.',
|
||||
cssClass: 'icon-calendar'
|
||||
cssClass: 'icon-tabular'
|
||||
}
|
||||
} else {
|
||||
return {
|
||||
|
139
src/plugins/timeConductor/ConductorModeIcon.vue
Normal file
139
src/plugins/timeConductor/ConductorModeIcon.vue
Normal file
@ -0,0 +1,139 @@
|
||||
/*****************************************************************************
|
||||
* Open MCT Web, Copyright (c) 2014-2018, United States Government
|
||||
* as represented by the Administrator of the National Aeronautics and Space
|
||||
* Administration. All rights reserved.
|
||||
*
|
||||
* Open MCT Web 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 Web 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-clock-symbol">
|
||||
<div class="hand-little"></div>
|
||||
<div class="hand-big"></div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "~styles/sass-base";
|
||||
|
||||
@keyframes clock-hands {
|
||||
0% { transform: translate(-50%, -50%) rotate(0deg); }
|
||||
100% { transform: translate(-50%, -50%) rotate(360deg); }
|
||||
}
|
||||
|
||||
@keyframes clock-hands-sticky {
|
||||
0% { transform: translate(-50%, -50%) rotate(0deg); }
|
||||
7% { transform: translate(-50%, -50%) rotate(0deg); }
|
||||
8% { transform: translate(-50%, -50%) rotate(30deg); }
|
||||
15% { transform: translate(-50%, -50%) rotate(30deg); }
|
||||
16% { transform: translate(-50%, -50%) rotate(60deg); }
|
||||
24% { transform: translate(-50%, -50%) rotate(60deg); }
|
||||
25% { transform: translate(-50%, -50%) rotate(90deg); }
|
||||
32% { transform: translate(-50%, -50%) rotate(90deg); }
|
||||
33% { transform: translate(-50%, -50%) rotate(120deg); }
|
||||
40% { transform: translate(-50%, -50%) rotate(120deg); }
|
||||
41% { transform: translate(-50%, -50%) rotate(150deg); }
|
||||
49% { transform: translate(-50%, -50%) rotate(150deg); }
|
||||
50% { transform: translate(-50%, -50%) rotate(180deg); }
|
||||
57% { transform: translate(-50%, -50%) rotate(180deg); }
|
||||
58% { transform: translate(-50%, -50%) rotate(210deg); }
|
||||
65% { transform: translate(-50%, -50%) rotate(210deg); }
|
||||
66% { transform: translate(-50%, -50%) rotate(240deg); }
|
||||
74% { transform: translate(-50%, -50%) rotate(240deg); }
|
||||
75% { transform: translate(-50%, -50%) rotate(270deg); }
|
||||
82% { transform: translate(-50%, -50%) rotate(270deg); }
|
||||
83% { transform: translate(-50%, -50%) rotate(300deg); }
|
||||
90% { transform: translate(-50%, -50%) rotate(300deg); }
|
||||
91% { transform: translate(-50%, -50%) rotate(330deg); }
|
||||
99% { transform: translate(-50%, -50%) rotate(330deg); }
|
||||
100% { transform: translate(-50%, -50%) rotate(360deg); }
|
||||
}
|
||||
|
||||
|
||||
.c-clock-symbol {
|
||||
$c: $colorBtnBg; //$colorObjHdrIc;
|
||||
$d: 18px;
|
||||
height: $d;
|
||||
width: $d;
|
||||
position: relative;
|
||||
|
||||
&:before {
|
||||
font-family: symbolsfont;
|
||||
color: $c;
|
||||
content: $glyph-icon-brackets;
|
||||
font-size: $d;
|
||||
line-height: normal;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
// Clock hands
|
||||
div[class*="hand"] {
|
||||
$handW: 2px;
|
||||
$handH: $d * 0.4;
|
||||
animation-iteration-count: infinite;
|
||||
animation-timing-function: linear;
|
||||
transform-origin: bottom;
|
||||
position: absolute;
|
||||
height: $handW;
|
||||
width: $handW;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
z-index: 2;
|
||||
&:before {
|
||||
background: $c;
|
||||
content: '';
|
||||
display: block;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
bottom: -1px;
|
||||
}
|
||||
&.hand-little {
|
||||
z-index: 2;
|
||||
animation-duration: 12s;
|
||||
transform: translate(-50%, -50%) rotate(120deg);
|
||||
&:before {
|
||||
height: ceil($handH * 0.6);
|
||||
}
|
||||
}
|
||||
&.hand-big {
|
||||
z-index: 1;
|
||||
animation-duration: 1s;
|
||||
transform: translate(-50%, -50%);
|
||||
&:before {
|
||||
height: $handH;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Modes
|
||||
.is-realtime-mode &,
|
||||
.is-lad-mode & {
|
||||
&:before {
|
||||
// Brackets icon
|
||||
color: $colorTime;
|
||||
}
|
||||
div[class*="hand"] {
|
||||
animation-name: clock-hands;
|
||||
&:before {
|
||||
background: $colorTime;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
@ -20,30 +20,38 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<div class="holder flex-elem menus-up time-system">
|
||||
<div class="s-menu-button menu-element"
|
||||
:class="selectedTimeSystem.cssClass">
|
||||
|
||||
<span class="l-click-area" @click="toggleMenu($event)"></span>
|
||||
<span class="title-label" v-if="selectedTimeSystem.name">
|
||||
{{selectedTimeSystem.name}}
|
||||
</span>
|
||||
|
||||
<div class="menu" v-if="showMenu">
|
||||
<div class="c-ctrl-wrapper c-ctrl-wrapper--menus-up"
|
||||
v-if="selectedTimeSystem.name">
|
||||
<div class="c-button--menu c-time-system-button"
|
||||
:class="selectedTimeSystem.cssClass"
|
||||
@click="toggleMenu($event)">
|
||||
<span class="c-button__label">{{selectedTimeSystem.name}}</span>
|
||||
</div>
|
||||
<div class="c-menu" v-if="showMenu">
|
||||
<ul>
|
||||
<li @click="setTimeSystemFromView(timeSystem)"
|
||||
v-for="timeSystem in timeSystems"
|
||||
:key="timeSystem.key"
|
||||
:class="timeSystem.cssClass">
|
||||
{{timeSystem.name}}
|
||||
{{timeSystem.name}}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "~styles/sass-base";
|
||||
|
||||
.is-realtime-mode {
|
||||
.c-time-system-button {
|
||||
background: $colorTimeBg;
|
||||
|
||||
&:hover {
|
||||
background: $colorTimeHov;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
@ -66,7 +74,7 @@ export default {
|
||||
},
|
||||
|
||||
setTimeSystemFromView(timeSystem) {
|
||||
if (timeSystem !== this.selectedTimeSystem) {
|
||||
if (timeSystem.key !== this.selectedTimeSystem.key) {
|
||||
let activeClock = this.openmct.time.clock();
|
||||
let configuration = this.getMatchingConfig({
|
||||
clock: activeClock && activeClock.key,
|
||||
|
@ -20,35 +20,106 @@
|
||||
* at runtime from the About dialog for additional information.
|
||||
*****************************************************************************/
|
||||
<template>
|
||||
<span class="menus-up">
|
||||
<a class="ui-symbol icon icon-calendar" ref="calendarButton" @click="togglePicker($event)"></a>
|
||||
<div class="l-datetime-picker s-datetime-picker s-menu" v-if="showPicker" ref="popup">
|
||||
<div class="holder">
|
||||
<div class="l-month-year-pager">
|
||||
<a class="pager prev" ng-click="changeMonth(-1)"></a>
|
||||
<span class="val">{{model.month}} {{model.year}}</span>
|
||||
<a class="pager next" ng-click="changeMonth(1)"></a>
|
||||
<div class="c-ctrl-wrapper c-ctrl-wrapper--menus-up" ref="calendarHolder">
|
||||
<a class="c-click-icon icon-calendar"
|
||||
@click="togglePicker()"></a>
|
||||
<div class="c-menu c-datetime-picker"
|
||||
v-if="showPicker">
|
||||
<div class="c-datetime-picker__month-year-pager c-pager l-month-year-pager">
|
||||
<div class="c-pager__prev c-click-icon icon-arrow-left"
|
||||
@click="changeMonth(-1)"></div>
|
||||
<div class="c-pager__month-year">{{model.month}} {{model.year}}</div>
|
||||
<div class="c-pager__next c-click-icon icon-arrow-right"
|
||||
@click="changeMonth(1)"></div>
|
||||
</div>
|
||||
<div class="l-calendar">
|
||||
<ul class="l-cal-row l-header">
|
||||
<li v-for="day in ['Su','Mo','Tu','We','Th','Fr','Sa']" :key="day">{{day}}</li>
|
||||
<div class="c-datetime-picker__calendar c-calendar">
|
||||
<ul class="c-calendar__row--header l-cal-row">
|
||||
<li v-for="day in ['Su','Mo','Tu','We','Th','Fr','Sa']"
|
||||
:key="day">{{day}}</li>
|
||||
</ul>
|
||||
<ul class="l-cal-row l-body" v-for="(row, index) in table" :key="index">
|
||||
<ul class="c-calendar__row--body"
|
||||
v-for="(row, index) in table"
|
||||
:key="index">
|
||||
<li v-for="(cell, index) in row"
|
||||
:key="index"
|
||||
@click="select(cell)"
|
||||
:class='{ "in-month": isInCurrentMonth(cell), selected: isSelected(cell) }'>
|
||||
<div class="prime">{{cell.day}}</div>
|
||||
<div class="sub">{{cell.dayOfYear}}</div>
|
||||
:class="{ 'is-in-month': isInCurrentMonth(cell), selected: isSelected(cell) }">
|
||||
<div class="c-calendar__day--prime">{{cell.day}}</div>
|
||||
<div class="c-calendar__day--sub">{{cell.dayOfYear}}</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
@import "~styles/sass-base";
|
||||
|
||||
/******************************************************** PICKER */
|
||||
.c-datetime-picker {
|
||||
@include userSelectNone();
|
||||
padding: $interiorMarginLg !important;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
> * + * {
|
||||
border-top: 1px solid $colorInteriorBorder;
|
||||
margin-top: $interiorMargin;
|
||||
}
|
||||
}
|
||||
|
||||
.c-pager {
|
||||
display: grid;
|
||||
grid-column-gap: $interiorMargin;
|
||||
grid-template-rows: 1fr;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
align-items: center;
|
||||
|
||||
.c-click-icon {
|
||||
font-size: 0.8em;
|
||||
}
|
||||
|
||||
&__month-year {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************** CALENDAR */
|
||||
.c-calendar {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(7, min-content);
|
||||
grid-template-rows: auto;
|
||||
grid-gap: 1px;
|
||||
|
||||
$mutedOpacity: 0.7;
|
||||
|
||||
ul {
|
||||
display: contents;
|
||||
&[class*='--header'] {
|
||||
pointer-events: none;
|
||||
li {
|
||||
opacity: $mutedOpacity;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: $interiorMargin;
|
||||
|
||||
&.is-in-month {
|
||||
background: rgba($colorBodyFg, 0.1);
|
||||
}
|
||||
}
|
||||
|
||||
&__day {
|
||||
&--sub {
|
||||
opacity: $mutedOpacity;
|
||||
font-size: 0.8em;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
@ -178,6 +249,7 @@ export default {
|
||||
this.date.year = cell.year;
|
||||
this.date.day = cell.day;
|
||||
this.updateFromView();
|
||||
this.showPicker = false;
|
||||
},
|
||||
|
||||
dateEquals(d1, d2) {
|
||||
@ -187,14 +259,14 @@ export default {
|
||||
},
|
||||
|
||||
changeMonth(delta) {
|
||||
picker.month += delta;
|
||||
if (picker.month > 11) {
|
||||
picker.month = 0;
|
||||
picker.year += 1;
|
||||
this.picker.month += delta;
|
||||
if (this.picker.month > 11) {
|
||||
this.picker.month = 0;
|
||||
this.picker.year += 1;
|
||||
}
|
||||
if (picker.month < 0) {
|
||||
picker.month = 11;
|
||||
picker.year -= 1;
|
||||
if (this.picker.month < 0) {
|
||||
this.picker.month = 11;
|
||||
this.picker.year -= 1;
|
||||
}
|
||||
this.picker.interacted = true;
|
||||
this.updateViewForMonth();
|
||||
@ -209,26 +281,20 @@ export default {
|
||||
},
|
||||
|
||||
hidePicker(event) {
|
||||
if (event.srcElement !== this.$refs.calendarButton){
|
||||
let path = event.composedPath();
|
||||
if (path.indexOf(this.$refs.calendarHolder) === -1) {
|
||||
this.showPicker = false;
|
||||
}
|
||||
},
|
||||
|
||||
togglePicker(event) {
|
||||
togglePicker() {
|
||||
this.showPicker = !this.showPicker;
|
||||
|
||||
if (this.showPicker) {
|
||||
document.addEventListener('click', this.hidePicker, {
|
||||
capture: true,
|
||||
once: true,
|
||||
passive: true
|
||||
capture: true
|
||||
});
|
||||
this.$nextTick().then(this.setPopupPosition);
|
||||
}
|
||||
},
|
||||
|
||||
setPopupPosition() {
|
||||
this.$refs.popup.style.bottom = this.$refs.popup.offsetHeight + 20 + 'px';
|
||||
}
|
||||
},
|
||||
mounted: function () {
|
||||
@ -236,6 +302,9 @@ export default {
|
||||
this.updateViewForMonth();
|
||||
},
|
||||
destroyed: function () {
|
||||
document.addEventListener('click', this.hidePicker, {
|
||||
capture: true
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -25,8 +25,8 @@ $colorKeyFilterHov: brightness(1) sepia(1) hue-rotate(145deg) saturate(7);
|
||||
$colorKeySelectedBg: $colorKey;
|
||||
$colorKeyFg: #fff;
|
||||
$colorKeyHov: #00c0f6;
|
||||
$colorEditAreaBg: #eafaff;
|
||||
$colorEditAreaFg: #4bb1c7;
|
||||
$colorEditAreaBg: #eafaff; // Deprecated, use $editColor instead
|
||||
$colorEditAreaFg: #4bb1c7; // Deprecated, use $editColor instead
|
||||
$colorInteriorBorder: rgba($colorBodyFg, 0.2);
|
||||
$colorA: #999;
|
||||
$colorAHov: $colorKey;
|
||||
@ -38,6 +38,16 @@ $smallCr: 2px;
|
||||
$overlayCr: 11px;
|
||||
$shdwTextSubtle: rgba(black, 0.2) 0 1px 2px;
|
||||
|
||||
// Variations
|
||||
$colorBodyBgSubtle: pullForward($colorBodyBg, 5%);
|
||||
$colorBodyBgSubtleHov: pushBack($colorKey, 50%);
|
||||
$colorKeySubtle: pushBack($colorKey, 50%);
|
||||
$colorTime: #618cff;
|
||||
$colorTimeBg: $colorTime;
|
||||
$colorTimeFg: $colorBodyBg;
|
||||
$colorTimeHov: pushBack($colorTime, 5%);
|
||||
$colorTimeSubtle: pushBack($colorTime, 20%);
|
||||
|
||||
// Buttons and Controls
|
||||
$btnPad: $interiorMargin, $interiorMargin * 1.25;
|
||||
$colorBtnBg: #aaaaaa;
|
||||
@ -50,6 +60,9 @@ $colorBtnMajorBg: $colorKey;
|
||||
$colorBtnMajorBgHov: $colorKeyHov;
|
||||
$colorBtnMajorFg: $colorKeyFg;
|
||||
$colorBtnMajorFgHov: pushBack($colorBtnMajorFg, $hoverRatioPercent);
|
||||
$colorBtnCautionBg: #f16f6f;
|
||||
$colorBtnCautionBgHov: #f1504e;
|
||||
$colorBtnCautionFg: $colorBtnFg;
|
||||
$colorClickIcon: $colorKey;
|
||||
$colorClickIconHov: $colorKeyHov;
|
||||
$colorToggleIcon: rgba($colorClickIcon, 0.5);
|
||||
@ -70,7 +83,7 @@ $sliderColorRangeValHovFg: $colorBodyFg;
|
||||
$sliderKnobW: 15px;
|
||||
$sliderKnobR: 2px;
|
||||
$timeControllerToiLineColor: $colorBodyFg;
|
||||
$timeControllerToiLineColorHov: #0052b5;
|
||||
$timeControllerToiLineColorHov: $colorTime;
|
||||
$colorTransLucBg: #666; // Used as a visual blocking element over variable backgrounds, like imagery
|
||||
$createBtnTextTransform: uppercase;
|
||||
|
||||
@ -88,13 +101,20 @@ $colorIconAliasForKeyFilter: #aaa;
|
||||
$colorPausedBg: #ff9900;
|
||||
$colorPausedFg: #fff;
|
||||
$colorCreateBtn: $colorKey;
|
||||
$colorGridLines: rgba(#000, 0.05);
|
||||
$colorInvokeMenu: #fff;
|
||||
$colorObjHdrTxt: $colorBodyFg;
|
||||
$colorObjHdrIc: lighten($colorObjHdrTxt, 30%);
|
||||
$colorTick: rgba(black, 0.2);
|
||||
$colorSelectableSelectedPrimary: $colorKey;
|
||||
$colorSelectableHov: rgba($colorBodyFg, 0.4);
|
||||
|
||||
$editColor: #00c7c3;
|
||||
$browseBorderSelectableHov: 1px dotted rgba($colorBodyFg, 0.2);
|
||||
$browseShdwSelectableHov: rgba($colorBodyFg, 0.2) 0 0 3px;
|
||||
$browseBorderSelected: 1px solid rgba($colorBodyFg, 0.6);
|
||||
$editBorderSelectable: 1px dotted rgba($editColor, 1);
|
||||
$editBorderSelectableHov: 1px dashed rgba($editColor, 1);
|
||||
$editBorderSelected: 1px solid $editColor;
|
||||
$editBorderDrilledIn: 1px dashed #ff4d9a;
|
||||
$colorGridLines: rgba($editColor, 0.2);
|
||||
|
||||
// Menus
|
||||
$colorMenuBg: pushBack($colorBodyBg, 10%);
|
||||
@ -109,6 +129,11 @@ $colorCreateMenuLgIcon: $colorKey;
|
||||
$colorCreateMenuText: $colorBodyFg;
|
||||
$menuItemPad: ($interiorMargin, nth($btnPad, 2));
|
||||
|
||||
// Palettes and Swatches
|
||||
$paletteItemBorderOuterColorSelected: black;
|
||||
$paletteItemBorderInnerColorSelected: white;
|
||||
$paletteItemBorderInnerColor: rgba($paletteItemBorderOuterColorSelected, 0.3);
|
||||
|
||||
// Form colors
|
||||
$colorCheck: $colorKey;
|
||||
$colorFormRequired: $colorKey;
|
||||
@ -125,6 +150,9 @@ $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 1px;
|
||||
$shdwInputFoc: inset rgba(black, 0.7) 0 0 3px;
|
||||
|
||||
// Inspector
|
||||
$colorInspectorBg: pullForward($colorBodyBg, 5%);
|
||||
@ -282,12 +310,6 @@ $colorCalCellSelectedBg: $colorItemTreeSelectedBg;
|
||||
$colorCalCellSelectedFg: $colorItemTreeSelectedFg;
|
||||
$colorCalCellInMonthBg: pullForward($colorMenuBg, 5%);
|
||||
|
||||
// Palettes
|
||||
$colorPaletteFg: pullForward($colorMenuBg, 30%);
|
||||
$colorPaletteSelected: #333;
|
||||
$shdwPaletteFg: none;
|
||||
$shdwPaletteSelected: inset 0 0 0 1px #fff;
|
||||
|
||||
// About Screen
|
||||
$colorAboutLink: #84b3ff;
|
||||
|
||||
|
@ -152,7 +152,7 @@ $glyph-icon-notebook: '\e1131';
|
||||
$bg-icon-activity: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M288 32H160l160 160H174.872C152.74 153.742 111.377 128 64 128H0v256h64c47.377 0 88.74-25.742 110.872-64H320L160 480h128l224-224L288 32z'/%3e%3c/svg%3e");
|
||||
$bg-icon-activity-mode: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M256 0C148.6 0 56.6 66.2 18.6 160H64c28.4 0 54 12.4 71.5 32H256l-96-96h128l160 160-160 160H160l96-96H135.5C118 339.6 92.4 352 64 352H18.6c38 93.8 129.9 160 237.4 160 141.4 0 256-114.6 256-256S397.4 0 256 0z'/%3e%3c/svg%3e");
|
||||
$bg-icon-autoflow-tabular: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M96 0C43.2 0 0 43.2 0 96v320c0 52.8 43.2 96 96 96h32V0H96zM192 0h128v512H192zM416 0h-32v352h128V96c0-52.8-43.2-96-96-96z'/%3e%3c/svg%3e");
|
||||
$bg-icon-clock: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M256 0C114.62 0 0 114.62 0 256s114.62 256 256 256 256-114.62 256-256S397.38 0 256 0zm135 345a36 36 0 0 1-31.21 18 35.83 35.83 0 0 1-18-4.83l-110.85-64-.14-.08q-.6-.35-1.19-.73l-.43-.28-.93-.64-.63-.45-.63-.48-.85-.67-.32-.27c-.36-.3-.72-.61-1.07-.92a35.76 35.76 0 0 1-6.52-7.9c-.14-.23-.27-.47-.41-.7s-.29-.49-.43-.74a35.75 35.75 0 0 1-3.58-9.59v-.06c-.1-.46-.19-.92-.27-1.38 0-.14-.05-.28-.08-.42-.06-.35-.11-.71-.15-1.07s-.07-.52-.1-.79-.05-.51-.07-.77l-.09-1.12v-.52-1.39V81a36 36 0 0 1 36-36 36 36 0 0 1 36 36v161.22l92.85 53.61A36 36 0 0 1 391 345z' fill='%2300a14b'/%3e%3c/svg%3e");
|
||||
$bg-icon-clock: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M256 0C114.6 0 0 114.6 0 256s114.6 256 256 256 256-114.6 256-256S397.4 0 256 0zm135 345c-6.4 11.1-18.3 18-31.2 18-6.3 0-12.5-1.7-18-4.8l-110.9-64-.1-.1c-.4-.2-.8-.5-1.2-.7l-.4-.3-.9-.6-.6-.5-.6-.5-.9-.7-.3-.3c-.4-.3-.7-.6-1.1-.9-2.5-2.3-4.7-5-6.5-7.9-.1-.2-.3-.5-.4-.7s-.3-.5-.4-.7c-1.6-3-2.9-6.2-3.6-9.6v-.1c-.1-.5-.2-.9-.3-1.4 0-.1 0-.3-.1-.4-.1-.3-.1-.7-.1-1.1s-.1-.5-.1-.8 0-.5-.1-.8-.1-.8-.1-1.1v-.5-1.4V81c0-19.9 16.1-36 36-36s36 16.1 36 36v161.2l92.9 53.6c17.1 10 22.9 32 13 49.2z'/%3e%3c/svg%3e");
|
||||
$bg-icon-database: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M256 256C114.615 256 0 213.019 0 160v256c0 53.019 114.615 96 256 96s256-42.981 256-96V160c0 53.019-114.615 96-256 96z'/%3e%3cellipse fill='%23666666' cx='256' cy='96' rx='256' ry='96'/%3e%3c/svg%3e");
|
||||
$bg-icon-database-query: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M341.76 409.643C316.369 423.871 287.118 432 256 432c-97.047 0-176-78.953-176-176S158.953 80 256 80s176 78.953 176 176c0 31.118-8.129 60.369-22.357 85.76l95.846 95.846C509.747 430.661 512 423.429 512 416V96c0-53.019-114.615-96-256-96S0 42.981 0 96v320c0 53.019 114.615 96 256 96 63.055 0 120.774-8.554 165.388-22.73l-79.628-79.627z'/%3e%3cpath fill='%23666666' d='M176 256c0 44.112 35.888 80 80 80s80-35.888 80-80-35.888-80-80-80-80 35.888-80 80z'/%3e%3c/svg%3e");
|
||||
$bg-icon-dataset: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3e%3cpath fill='%23666666' d='M448 96H288l-54.6-54.6-18.7-18.7C202.2 10.2 177.6 0 160 0H32C14.4 0 0 14.4 0 32v192c0-35.2 28.8-64 64-64h384c35.2 0 64 28.8 64 64v-64c0-35.2-28.8-64-64-64zM448 224H64c-35.2 0-64 28.8-64 64v160c0 35.2 28.8 64 64 64h384c35.2 0 64-28.8 64-64V288c0-35.2-28.8-64-64-64zM160 448H96V288h64v160zm128 0h-64V288h64v160zm128 0h-64V288h64v160z'/%3e%3c/svg%3e");
|
||||
|
@ -1,12 +1,35 @@
|
||||
/******************************************************** BUTTONS */
|
||||
%c-control {
|
||||
@include userSelectNone();
|
||||
/*****************************************************************************
|
||||
* 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.
|
||||
*****************************************************************************/
|
||||
|
||||
// VERSION MANUALLY MIGRATED FROM VUE-TOOLBAR
|
||||
|
||||
/******************************************************** PLACEHOLDERS */
|
||||
@mixin cControl() {
|
||||
$fs: 1em;
|
||||
@include userSelectNone();
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
font-size: $fs;
|
||||
justify-content: start;
|
||||
cursor: pointer;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
|
||||
&:before,
|
||||
&:after {
|
||||
@ -20,17 +43,19 @@
|
||||
}
|
||||
|
||||
[class*="__label"] {
|
||||
@include ellipsize();
|
||||
display: block;
|
||||
line-height: $fs; // Remove effect on top and bottom padding
|
||||
font-size: $fs;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
%c-button {
|
||||
@extend %c-control;
|
||||
@mixin cButton() {
|
||||
@include cControl();
|
||||
background: $colorBtnBg;
|
||||
border-radius: $controlCr;
|
||||
color: $colorBtnFg;
|
||||
cursor: pointer;
|
||||
padding: nth($btnPad, 1) nth($btnPad, 2);
|
||||
|
||||
&:hover {
|
||||
@ -47,119 +72,121 @@
|
||||
color: $colorBtnMajorFgHov;
|
||||
}
|
||||
}
|
||||
|
||||
&[class*='--caution'] {
|
||||
background: $colorBtnCautionBg;
|
||||
color: $colorBtnCautionFg;
|
||||
|
||||
&:hover {
|
||||
background: $colorBtnCautionBgHov;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********* Buttons */
|
||||
// Optionally can include icon in :before via markup
|
||||
.c-button,
|
||||
button {
|
||||
@extend %c-button;
|
||||
}
|
||||
|
||||
/********* Icon Buttons */
|
||||
.c-icon-button {
|
||||
@mixin cClickIcon() {
|
||||
// A clickable element that just includes the icon, no background
|
||||
// Padding is included to facilitate a bigger hit area
|
||||
// Make the icon bigger relative to its container
|
||||
@extend %c-control;
|
||||
@include cControl();
|
||||
$pLR: 3px;
|
||||
$pTB: 3px;
|
||||
border-radius: $controlCr;
|
||||
color: $colorKey;
|
||||
font-size: $fontBaseSize * 1.2;
|
||||
cursor: pointer;
|
||||
padding: $pTB $pLR ;
|
||||
|
||||
&:hover {
|
||||
background: rgba($colorKey, 0.2);
|
||||
}
|
||||
|
||||
&:before {
|
||||
font-size: 1.1em;
|
||||
&:before,
|
||||
*:before {
|
||||
// *:before handles any nested containers that may contain glyph elements
|
||||
// Needed for c-togglebutton.
|
||||
font-size: 1.3em;
|
||||
}
|
||||
}
|
||||
|
||||
/********* Button Sets */
|
||||
.c-button-set {
|
||||
// Buttons are smashed together with minimal margin
|
||||
// c-buttons don't have border-radius between buttons, creates a tool-button-strip look
|
||||
// c-icon-buttons get grouped more closely together
|
||||
// When one set is adjacent to another, provides a divider between
|
||||
@mixin cCtrlWrapper {
|
||||
// Provides a wrapper around buttons and other controls
|
||||
// Contains control and provides positioning context for contained menu/palette.
|
||||
// Wraps --menu elements, contains button and menu
|
||||
overflow: visible;
|
||||
|
||||
display: inline-flex;
|
||||
.c-menu {
|
||||
// Default position of contained menu
|
||||
top: 100%; left: 0;
|
||||
}
|
||||
|
||||
&[class*='--menus-up'] {
|
||||
.c-menu {
|
||||
top: auto; bottom: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&[class*='--menus-left'] {
|
||||
.c-menu {
|
||||
left: auto; right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********* Buttons */
|
||||
// Optionally can include icon in :before via markup
|
||||
.c-button,
|
||||
.c-button--menu,
|
||||
button {
|
||||
@include cButton();
|
||||
}
|
||||
|
||||
.c-button--menu {
|
||||
$m: $interiorMargin;
|
||||
|
||||
&:before,
|
||||
> * {
|
||||
// Assume buttons are immediate descendants
|
||||
flex: 0 0 auto;
|
||||
|
||||
&[class^="c-button"] {
|
||||
// Only apply the following to buttons that have background, eg. c-button
|
||||
border-radius: 0;
|
||||
|
||||
+ * {
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-top-left-radius: $controlCr;
|
||||
border-bottom-left-radius: $controlCr;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-top-right-radius: $controlCr;
|
||||
border-bottom-right-radius: $controlCr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ .c-button-set {
|
||||
$m: $interiorMarginSm;
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
width: $m;
|
||||
border-right: 1px solid $colorInteriorBorder;
|
||||
margin-right: $m;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********* Menu Buttons */
|
||||
// Always includes :after dropdown arrow
|
||||
// Optionally can include icon in :before
|
||||
// Default menu position is down and to the right
|
||||
// Apply c-menu-button--menus-up and c-menu-button--menus-left to --w wrapper element to modify menu position
|
||||
.c-menu-button {
|
||||
$m: $interiorMarginSm;
|
||||
@extend %c-button;
|
||||
|
||||
&:before {
|
||||
margin-right: $m;
|
||||
}
|
||||
|
||||
&:after {
|
||||
content: $glyph-icon-arrow-down;
|
||||
font-family: symbolsfont;
|
||||
margin-left: $m;
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
&--w {
|
||||
// Wraps c-menu-button, contains button and menu
|
||||
.c-menu {
|
||||
// Default position
|
||||
top: 100%; left: 0;
|
||||
/********* Icon Buttons */
|
||||
.c-click-icon {
|
||||
@include cClickIcon();
|
||||
|
||||
&--menu {
|
||||
&:after {
|
||||
content: $glyph-icon-arrow-down;
|
||||
font-family: symbolsfont;
|
||||
font-size: 0.6em;
|
||||
margin-left: floor($interiorMarginSm * 0.8);
|
||||
opacity: 0.5;
|
||||
}
|
||||
}
|
||||
|
||||
&--swatched {
|
||||
// Color control, show swatch element
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
> [class*='swatch'] {
|
||||
box-shadow: inset rgba(black, 0.2) 0 0 1px;
|
||||
flex: 0 0 auto;
|
||||
height: 4px;
|
||||
width: 100%;
|
||||
margin-top: 1px;
|
||||
}
|
||||
|
||||
&.c-menu-button--menus-up {
|
||||
.c-menu {
|
||||
top: auto; bottom: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
&.c-menu-button--menus-left {
|
||||
.c-menu {
|
||||
left: auto; right: 0;
|
||||
}
|
||||
&:before {
|
||||
// Reduce size of icon to make a bit of room
|
||||
flex: 1 1 auto;
|
||||
font-size: 1.1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -169,7 +196,7 @@ button {
|
||||
// Provides a downward arrow icon that when clicked displays a context menu
|
||||
// Always placed AFTER an element
|
||||
.c-disclosure-button {
|
||||
@extend .c-icon-button;
|
||||
@include cClickIcon();
|
||||
margin-left: $interiorMarginSm;
|
||||
|
||||
&:before {
|
||||
@ -208,13 +235,39 @@ button {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/******************************************************** FORM ELEMENTS */
|
||||
/********* Inline inputs */
|
||||
input, textarea {
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
letter-spacing: inherit;
|
||||
}
|
||||
|
||||
input[type=text],
|
||||
input[type=search],
|
||||
input[type=number] {
|
||||
@include reactive-input();
|
||||
padding: $inputTextP;
|
||||
&.numeric {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
.c-input {
|
||||
&--datetime {
|
||||
// Sized for values such as 2018-09-28 22:32:33.468Z
|
||||
width: 160px;
|
||||
}
|
||||
|
||||
&--hrs-min-sec {
|
||||
// Sized for values such as 00:25:00
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
&-inline,
|
||||
&--inline {
|
||||
// A text input or contenteditable element that indicates edit affordance on hover and looks like an input on focus
|
||||
.c-input-inline {
|
||||
@include input-base();
|
||||
border: 1px solid transparent;
|
||||
@include reactive-input();
|
||||
box-shadow: none;
|
||||
display: block !important;
|
||||
min-width: 0;
|
||||
padding-left: 0;
|
||||
@ -232,12 +285,38 @@ button {
|
||||
padding-left: $inputTextPLeftRight;
|
||||
padding-right: $inputTextPLeftRight;
|
||||
}
|
||||
&:hover {
|
||||
border-color: rgba($colorBodyFg, 0.2);
|
||||
}
|
||||
|
||||
&--labeled {
|
||||
// TODO: replace .c-labeled-input with this
|
||||
// An input used in the Toolbar
|
||||
// Assumes label is before the input
|
||||
@include cControl();
|
||||
|
||||
input {
|
||||
margin-left: $interiorMarginSm;
|
||||
}
|
||||
&:focus {
|
||||
@include nice-input($shdw: rgba(0, 0, 0, 0.6) 0 1px 3px);
|
||||
border-color: transparent;
|
||||
}
|
||||
}
|
||||
|
||||
.c-labeled-input {
|
||||
// An input used in the Toolbar
|
||||
// Assumes label is before the input
|
||||
@include cControl();
|
||||
|
||||
input {
|
||||
margin-left: $interiorMarginSm;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************** HYPERLINKS AND HYPERLINK BUTTONS */
|
||||
.c-hyperlink {
|
||||
&--link {
|
||||
color: $colorKey;
|
||||
}
|
||||
|
||||
&--button {
|
||||
@include cButton();
|
||||
}
|
||||
}
|
||||
|
||||
@ -256,8 +335,10 @@ button {
|
||||
@mixin menuInner() {
|
||||
color: $colorMenuFg;
|
||||
li {
|
||||
@extend %c-control;
|
||||
@include cControl();
|
||||
justify-content: start;
|
||||
color: $colorMenuFg;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
padding: nth($menuItemPad, 1) nth($menuItemPad, 2);
|
||||
transition: $transIn;
|
||||
@ -281,11 +362,6 @@ button {
|
||||
.c-menu {
|
||||
@include menuOuter();
|
||||
@include menuInner();
|
||||
li {
|
||||
&:not(:first-child) {
|
||||
border-top: 1px solid pullForward($colorMenuBg, 10%);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.c-super-menu {
|
||||
@ -354,3 +430,161 @@ button {
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************** PALETTES */
|
||||
.c-palette {
|
||||
display: flex;
|
||||
flex-flow: column nowrap;
|
||||
|
||||
&__items {
|
||||
flex: 1 1 auto;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(10, [col] auto );
|
||||
grid-gap: 1px;
|
||||
}
|
||||
|
||||
&__item {
|
||||
$d: 16px;
|
||||
|
||||
border: 1px solid transparent;
|
||||
cursor: pointer;
|
||||
width: 16px; height: 16px;
|
||||
transition: $transOut;
|
||||
|
||||
&:hover {
|
||||
transition: $transIn;
|
||||
$o: 0.7;
|
||||
border-color: rgba($paletteItemBorderOuterColorSelected, $o);
|
||||
box-shadow: inset rgba($paletteItemBorderInnerColorSelected, $o) 0 0 0 1px;
|
||||
}
|
||||
|
||||
&.is-selected {
|
||||
border-color: $paletteItemBorderOuterColorSelected !important;
|
||||
border-width: 2px;
|
||||
box-shadow: inset rgba($paletteItemBorderInnerColorSelected, 1) 0 0 0 1px;
|
||||
}
|
||||
}
|
||||
|
||||
&__item-none {
|
||||
flex: 0 0 auto;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: $interiorMarginSm;
|
||||
|
||||
.c-palette__item {
|
||||
@include noColor();
|
||||
border-color: $paletteItemBorderInnerColor;
|
||||
margin-right: $interiorMarginSm;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************** TOOLBAR */
|
||||
.c-ctrl-wrapper {
|
||||
@include cCtrlWrapper();
|
||||
}
|
||||
|
||||
.c-toolbar,
|
||||
.c-toolbar .c-ctrl-wrapper {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.c-toolbar {
|
||||
height: 24px; // Need to standardize the height
|
||||
|
||||
.c-click-icon {
|
||||
@include cControl();
|
||||
$pLR: $interiorMargin - 1;
|
||||
$pTB: 2px;
|
||||
color: $colorBodyFg;
|
||||
padding: $pTB $pLR;
|
||||
|
||||
&--swatched {
|
||||
padding-bottom: floor($pTB / 2);
|
||||
width: 2em; // Standardize the width
|
||||
}
|
||||
|
||||
&[class*='--caution'] {
|
||||
&:before {
|
||||
color: $colorBtnCautionBg;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
background: rgba($colorBtnCautionBgHov, 0.2);
|
||||
:before {
|
||||
color: $colorBtnCautionBgHov;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.c-labeled-input {
|
||||
font-size: 0.9em;
|
||||
input[type='number'] {
|
||||
width: 40px; // Number input sucks and must have size set using this method
|
||||
}
|
||||
|
||||
+ .c-labeled-input {
|
||||
margin-left: $interiorMargin;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/********* Button Sets */
|
||||
.c-button-set {
|
||||
// When one set is adjacent to another, provides a divider between
|
||||
|
||||
display: inline-flex;
|
||||
flex: 0 0 auto;
|
||||
|
||||
> * {
|
||||
// Assume buttons are immediate descendants
|
||||
flex: 0 0 auto;
|
||||
|
||||
+ * {
|
||||
// margin-left: $interiorMarginSm;
|
||||
}
|
||||
}
|
||||
|
||||
+ .c-button-set {
|
||||
$m: $interiorMargin;
|
||||
$b: 1px;
|
||||
&:before {
|
||||
content: '';
|
||||
display: block;
|
||||
width: $m + $b; // Allow for border
|
||||
border-right: $b solid $colorInteriorBorder;
|
||||
margin-right: $m;
|
||||
}
|
||||
}
|
||||
|
||||
&[class*='--strip'] {
|
||||
// Buttons are smashed together with minimal margin
|
||||
// c-buttons don't have border-radius between buttons, creates a tool-button-strip look
|
||||
// c-click-icons get grouped more closely together
|
||||
&[class^="c-button"] {
|
||||
// Only apply the following to buttons that have background, eg. c-button
|
||||
border-radius: 0;
|
||||
|
||||
+ * {
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
&:first-child {
|
||||
border-top-left-radius: $controlCr;
|
||||
border-bottom-left-radius: $controlCr;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
border-top-right-radius: $controlCr;
|
||||
border-bottom-right-radius: $controlCr;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/***************************************************** SLIDERS */
|
||||
.c-slider {
|
||||
@include cControl();
|
||||
> * + * { margin-left: $interiorMargin; }
|
||||
}
|
||||
|
@ -118,22 +118,6 @@ em {
|
||||
font-style: normal;
|
||||
}
|
||||
|
||||
input, textarea {
|
||||
font-family: inherit;
|
||||
font-weight: inherit;
|
||||
letter-spacing: inherit;
|
||||
}
|
||||
|
||||
input[type=text],
|
||||
input[type=search],
|
||||
input[type=number] {
|
||||
@include nice-input();
|
||||
padding: $inputTextP;
|
||||
&.numeric {
|
||||
text-align: right;
|
||||
}
|
||||
}
|
||||
|
||||
h1, h2, h3 {
|
||||
letter-spacing: 0.04em;
|
||||
margin: 0;
|
||||
|
@ -53,6 +53,37 @@
|
||||
background-size: $bgsize $bgsize;
|
||||
}
|
||||
|
||||
@mixin noColor() {
|
||||
// A "no fill/stroke" selection option. Used in palettes.
|
||||
$c: red;
|
||||
$s: 48%;
|
||||
$e: 52%;
|
||||
background-image: linear-gradient(-45deg,
|
||||
transparent $s - 5%,
|
||||
$c $s,
|
||||
$c $e,
|
||||
transparent $e + 5%
|
||||
);
|
||||
background-repeat: no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
|
||||
@mixin bgTicks($c: $colorBodyFg, $repeatDir: 'x') {
|
||||
$deg: 90deg;
|
||||
@if ($repeatDir != 'x') {
|
||||
$deg: 0deg;
|
||||
$repeatDir: repeat-y;
|
||||
} @else {
|
||||
$repeatDir: repeat-x;
|
||||
}
|
||||
|
||||
background-image: linear-gradient($deg,
|
||||
$c 1px, transparent 1px,
|
||||
transparent 100%
|
||||
);
|
||||
background-repeat: $repeatDir;
|
||||
}
|
||||
|
||||
@mixin bgVertStripes($c: yellow, $a: 0.1, $d: 40px) {
|
||||
@include background-image(linear-gradient(-90deg,
|
||||
rgba($c, $a) 0%, rgba($c, $a) 50%,
|
||||
@ -63,6 +94,11 @@
|
||||
}
|
||||
|
||||
/************************** LAYOUT */
|
||||
@mixin abs($m: 0) {
|
||||
position: absolute;
|
||||
top: $m; right: $m; bottom: $m; left: $m;
|
||||
}
|
||||
|
||||
@mixin gridTwoColumn() {
|
||||
display: grid;
|
||||
grid-row-gap: 0;
|
||||
@ -126,15 +162,28 @@
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@mixin nice-input($bg: $colorInputBg, $fg: $colorInputFg, $shdw: rgba(black, 0.5) 0 0px 2px) {
|
||||
@mixin nice-input($bg: $colorInputBg, $fg: $colorInputFg, $shdw: rgba(black, 0.5) 0 0 2px) {
|
||||
@include input-base();
|
||||
background: $bg;
|
||||
color: $fg;
|
||||
box-shadow: inset $shdw;
|
||||
}
|
||||
|
||||
@mixin reactive-input($bg: $colorInputBg, $fg: $colorInputFg) {
|
||||
@include input-base();
|
||||
background: $bg;
|
||||
box-shadow: $shdwInput;
|
||||
color: $fg;
|
||||
|
||||
&:hover {
|
||||
box-shadow: $shdwInputHov;
|
||||
}
|
||||
|
||||
&:focus {
|
||||
box-shadow: $shdwInputFoc;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin button($bg: $colorBtnBg, $fg: $colorBtnFg, $radius: $controlCr, $shdw: none) {
|
||||
background: $bg;
|
||||
color: $fg;
|
||||
@ -142,6 +191,63 @@
|
||||
box-shadow: $shdw;
|
||||
}
|
||||
|
||||
@mixin wrappedInput() {
|
||||
// An input that is wrapped. Optionally includes a __label or icon element.
|
||||
// Based on .c-search.
|
||||
@include nice-input();
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
|
||||
&:before,
|
||||
[class*='__label'] {
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
&:before {
|
||||
// Adds an icon. Content defined in class.
|
||||
direction: rtl; // Aligns glyph to right-hand side of container, for transition
|
||||
display: block;
|
||||
font-family: symbolsfont;
|
||||
flex: 0 0 auto;
|
||||
overflow: hidden;
|
||||
padding: 2px 0; // Prevents clipping
|
||||
transition: width 250ms ease;
|
||||
width: 1em;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
box-shadow: inset rgba(black, 0.8) 0 0px 2px;
|
||||
&:before {
|
||||
opacity: 0.9;
|
||||
}
|
||||
}
|
||||
|
||||
&--major {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
&__input,
|
||||
input[type='text'],
|
||||
input[type='search'],
|
||||
input[type='number'] {
|
||||
background: none !important;
|
||||
box-shadow: none !important; // !important needed to override default for [input]
|
||||
flex: 1 1 auto;
|
||||
padding-left: 2px !important;
|
||||
padding-right: 2px !important;
|
||||
min-width: 10px; // Must be set to allow input to collapse below browser min
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
&:before {
|
||||
padding: 2px 0px;
|
||||
width: 0px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/************************** MATH */
|
||||
@function percentToDecimal($p) {
|
||||
@return $p / 100%;
|
||||
@ -161,4 +267,13 @@
|
||||
|
||||
@mixin userSelectNone() {
|
||||
@include browserPrefix(user-select, none);
|
||||
}
|
||||
}
|
||||
|
||||
@mixin cursorGrab() {
|
||||
cursor: grab;
|
||||
cursor: -webkit-grab;
|
||||
&:active {
|
||||
cursor: grabbing;
|
||||
cursor: -webkit-grabbing;
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
<template>
|
||||
<div class="c-create-button--w">
|
||||
<div class="c-create-button c-menu-button c-button--major icon-plus"
|
||||
<div class="c-create-button c-button--menu c-button--major icon-plus"
|
||||
@click="toggleCreateMenu">
|
||||
<span class="c-button__label">Create</span>
|
||||
</div>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<div class="l-browse-bar">
|
||||
<div class="l-browse-bar__start">
|
||||
<a class="l-browse-bar__nav-to-parent-button c-icon-button icon-pointer-left"></a>
|
||||
<a class="l-browse-bar__nav-to-parent-button c-click-icon icon-pointer-left"></a>
|
||||
<div class="l-browse-bar__object-name--w"
|
||||
:class="type.cssClass">
|
||||
<span
|
||||
@ -15,9 +15,9 @@
|
||||
</div>
|
||||
|
||||
<div class="l-browse-bar__end">
|
||||
<div class="l-browse-bar__view-switcher c-menu-button--w c-menu-button--menus-left"
|
||||
<div class="l-browse-bar__view-switcher c-ctrl-wrapper c-ctrl-wrapper--menus-left"
|
||||
v-if="views.length > 1">
|
||||
<div class="c-menu-button"
|
||||
<div class="c-button--menu"
|
||||
:class="currentView.cssClass"
|
||||
title="Switch view type"
|
||||
@click="toggleViewMenu">
|
||||
|
@ -3,11 +3,11 @@
|
||||
<div class="l-shell__head">
|
||||
<CreateButton class="l-shell__create-button"></CreateButton>
|
||||
<div class="l-shell__controls">
|
||||
<a class="c-icon-button icon-new-window" title="Open in a new browser tab"
|
||||
<a class="c-click-icon icon-new-window" title="Open in a new browser tab"
|
||||
@click="openInNewTab"
|
||||
target="_blank">
|
||||
</a>
|
||||
<a v-bind:class="['c-icon-button', fullScreen ? 'icon-fullscreen-expand' : 'icon-fullscreen-collapse']"
|
||||
<a v-bind:class="['c-click-icon', fullScreen ? 'icon-fullscreen-expand' : 'icon-fullscreen-collapse']"
|
||||
v-bind:title="`${fullScreen ? 'Exit' : 'Enable'} full screen mode`"
|
||||
@click="fullScreenToggle">
|
||||
</a>
|
||||
@ -179,7 +179,7 @@
|
||||
&__time-conductor {
|
||||
border-top: 1px solid $colorInteriorBorder;
|
||||
flex: 0 0 auto;
|
||||
padding: $interiorMargin;
|
||||
padding-top: $interiorMargin;
|
||||
}
|
||||
|
||||
body.desktop & {
|
||||
|
Loading…
x
Reference in New Issue
Block a user