Compare commits
	
		
			14 Commits
		
	
	
		
			fix-gha-pl
			...
			vue-conduc
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 41230cae82 | ||
|   | 2adf8f7666 | ||
|   | 2e0dba7ead | ||
|   | 8d0cafffe9 | ||
|   | c1ded09925 | ||
|   | 3f665fa193 | ||
|   | 9fc8456675 | ||
|   | 5c1d282326 | ||
|   | d298e614cf | ||
|   | e32a85b099 | ||
|   | 943e61cf8f | ||
|   | 15f6b75334 | ||
|   | 1ce79a76dd | ||
|   | 27783d8c27 | 
| @@ -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,179 @@ | ||||
|  * 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></ConductorMode> | ||||
|                 <ConductorTimeSystem></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; | ||||
|         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"; | ||||
|         align-items: center; | ||||
|  | ||||
| /*        grid-template-columns: 20px 160px 1fr 180px; | ||||
|         grid-template-areas: | ||||
|                 "tc-mode-icon tc-controls tc-controls tc-controls" | ||||
|                 "tc-start tc-start tc-ticks tc-end";*/ | ||||
|  | ||||
|         &__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; | ||||
|             justify-content: flex-end; | ||||
|         } | ||||
|  | ||||
|         &__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 +202,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 +217,8 @@ export default { | ||||
|         ConductorMode, | ||||
|         ConductorTimeSystem, | ||||
|         DatePicker, | ||||
|         ConductorAxis | ||||
|         ConductorAxis, | ||||
|         ConductorModeIcon | ||||
|     }, | ||||
|     data() { | ||||
|         let bounds = this.openmct.time.bounds(); | ||||
| @@ -155,7 +228,6 @@ export default { | ||||
|         let durationFormatter = this.getFormatter(timeSystem.durationFormat || DEFAULT_DURATION_FORMATTER); | ||||
|  | ||||
|         return { | ||||
|             currentZoom: this.calculateZoomFromBounds(), | ||||
|             timeFormatter: timeFormatter, | ||||
|             durationFormatter: durationFormatter, | ||||
|             offsets: { | ||||
| @@ -184,7 +256,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 +270,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 +285,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 +298,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 +353,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%; | ||||
|         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 | ||||
|                 font-size: 1em; | ||||
|                 paint-order: stroke; | ||||
|                 font-weight: bold; | ||||
|                 stroke-linecap: butt; | ||||
|                 stroke-linejoin: bevel; | ||||
|                 stroke-width: 6px; | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         .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 & { | ||||
|             background-size: 5px 2px; | ||||
|  | ||||
|             svg text { | ||||
|                 fill: $colorTime; | ||||
|                 stroke: $colorBodyBg; | ||||
|             } | ||||
|  | ||||
|         } | ||||
|     } | ||||
|  | ||||
|  | ||||
| </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,63 @@ | ||||
|  * 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="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="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> | ||||
|         <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> | ||||
|     </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 +107,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); | ||||
|  | ||||
|   | ||||
							
								
								
									
										118
									
								
								src/plugins/timeConductor/ConductorModeIcon.vue
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										118
									
								
								src/plugins/timeConductor/ConductorModeIcon.vue
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,118 @@ | ||||
| <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"> | ||||
|             <ul> | ||||
|                 <li @click="setTimeSystemFromView(timeSystem)" | ||||
|                     v-for="timeSystem in timeSystems" | ||||
|                     :key="timeSystem.key" | ||||
|                     :class="timeSystem.cssClass"> | ||||
|                         {{timeSystem.name}} | ||||
|                 </li> | ||||
|             </ul> | ||||
|         </div> | ||||
| <div class="holder flex-elem time-system 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}} | ||||
|             </li> | ||||
|         </ul> | ||||
|     </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,107 @@ | ||||
|  * 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> | ||||
|     <!-- TODOS: changeMonth doesn't appear to work, was ng-click --> | ||||
|     <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 +250,7 @@ export default { | ||||
|             this.date.year = cell.year; | ||||
|             this.date.day = cell.day; | ||||
|             this.updateFromView(); | ||||
|             this.showPicker = false; | ||||
|         }, | ||||
|  | ||||
|         dateEquals(d1, d2) { | ||||
| @@ -187,14 +260,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 +282,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 +303,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; | ||||
|  | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -20,6 +20,8 @@ | ||||
|  * at runtime from the About dialog for additional information. | ||||
|  *****************************************************************************/ | ||||
|  | ||||
| // VERSION MANUALLY MIGRATED FROM VUE-TOOLBAR | ||||
|  | ||||
| /************************** VISUALS */ | ||||
| @mixin ancillaryIcon($d, $c) { | ||||
|     // Used for small icons used in combination with larger icons, | ||||
| @@ -53,6 +55,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 +96,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 +164,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 +193,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 +269,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> | ||||
|   | ||||
		Reference in New Issue
	
	Block a user