Merge branch 'open933' into vista-r3-builds

This commit is contained in:
Pete Richards 2016-08-05 17:20:43 -07:00
commit f239b7c3f7
68 changed files with 3803 additions and 361 deletions

View File

@ -18,6 +18,8 @@
"node-uuid": "^1.4.7",
"comma-separated-values": "^3.6.4",
"FileSaver.js": "^0.0.2",
"zepto": "^1.1.6"
"zepto": "^1.1.6",
"eventemitter3": "^1.2.0",
"d3": "~4.1.0"
}
}

View File

@ -0,0 +1,48 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define([
"./src/LocalTimeSystem",
"./src/LocalTimeFormat",
'legacyRegistry'
], function (
LocalTimeSystem,
LocalTimeFormat,
legacyRegistry
) {
legacyRegistry.register("example/localTimeSystem", {
"extensions": {
"formats": [
{
"key": "local-format",
"implementation": LocalTimeFormat
}
],
"timeSystems": [
{
"implementation": LocalTimeSystem,
"depends": ["$timeout"]
}
]
}
});
});

View File

@ -0,0 +1,46 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define(['../../../platform/features/conductor-v2/conductor/src/timeSystems/LocalClock'], function (LocalClock) {
/**
* @implements TickSource
* @constructor
*/
function LADTickSource ($timeout, period) {
LocalClock.call(this, $timeout, period);
this.metadata = {
key: 'test-lad',
cssclass: 'icon-clock',
label: 'Latest Available Data',
name: 'Latest available data',
description: 'Monitor real-time streaming data as it comes in. The Time Conductor and displays will automatically advance themselves based on a UTC clock.'
};
}
LADTickSource.prototype = Object.create(LocalClock.prototype);
LADTickSource.prototype.type = function () {
return 'data';
};
return LADTickSource;
});

View File

@ -0,0 +1,112 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define([
'moment'
], function (
moment
) {
var DATE_FORMAT = "YYYY-MM-DD h:mm:ss.SSS a",
DATE_FORMATS = [
DATE_FORMAT,
"YYYY-MM-DD h:mm:ss a",
"YYYY-MM-DD h:mm a",
"YYYY-MM-DD"
];
/**
* @typedef Scale
* @property {number} min the minimum scale value, in ms
* @property {number} max the maximum scale value, in ms
*/
/**
* Formatter for UTC timestamps. Interprets numeric values as
* milliseconds since the start of 1970.
*
* @implements {Format}
* @constructor
* @memberof platform/commonUI/formats
*/
function LocalTimeFormat() {
}
/**
* Returns an appropriate time format based on the provided value and
* the threshold required.
* @private
*/
function getScaledFormat (d) {
var m = moment.utc(d);
/**
* Uses logic from d3 Time-Scales, v3 of the API. See
* https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Scales.md
*
* Licensed
*/
return [
[".SSS", function(m) { return m.milliseconds(); }],
[":ss", function(m) { return m.seconds(); }],
["hh:mma", function(m) { return m.minutes(); }],
["hha", function(m) { return m.hours(); }],
["ddd DD", function(m) {
return m.days() &&
m.date() != 1;
}],
["MMM DD", function(m) { return m.date() != 1; }],
["MMMM", function(m) {
return m.month();
}],
["YYYY", function() { return true; }]
].filter(function (row){
return row[1](m);
})[0][0];
};
/**
*
* @param value
* @param {Scale} [scale] Optionally provides context to the
* format request, allowing for scale-appropriate formatting.
* @returns {string} the formatted date
*/
LocalTimeFormat.prototype.format = function (value, scale) {
if (scale !== undefined){
var scaledFormat = getScaledFormat(value, scale);
if (scaledFormat) {
return moment.utc(value).format(scaledFormat);
}
}
return moment(value).format(DATE_FORMAT);
};
LocalTimeFormat.prototype.parse = function (text) {
return moment(text, DATE_FORMATS).valueOf();
};
LocalTimeFormat.prototype.validate = function (text) {
return moment(text, DATE_FORMATS).isValid();
};
return LocalTimeFormat;
});

View File

@ -0,0 +1,81 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define([
'../../../platform/features/conductor-v2/conductor/src/timeSystems/TimeSystem',
'../../../platform/features/conductor-v2/conductor/src/timeSystems/LocalClock',
'./LADTickSource'
], function (TimeSystem, LocalClock, LADTickSource) {
var FIFTEEN_MINUTES = 15 * 60 * 1000,
THIRTY_MINUTES = 30 * 60 * 1000,
ONE_HOUR = 60 * 60 * 1000,
DEFAULT_PERIOD = 1000;
/**
* This time system supports UTC dates and provides a ticking clock source.
* @implements TimeSystem
* @constructor
*/
function LocalTimeSystem ($timeout) {
TimeSystem.call(this);
/**
* Some metadata, which will be used to identify the time system in
* the UI
* @type {{key: string, name: string, glyph: string}}
*/
this.metadata = {
'key': 'local',
'name': 'Local',
'glyph': '\u0043'
};
this._formats = ['local-format'];
this._tickSources = [new LocalClock($timeout, DEFAULT_PERIOD), new LADTickSource($timeout, DEFAULT_PERIOD)];
}
LocalTimeSystem.prototype = Object.create(TimeSystem.prototype);
LocalTimeSystem.prototype.formats = function () {
return this._formats;
};
LocalTimeSystem.prototype.deltaFormat = function () {
return 'duration';
};
LocalTimeSystem.prototype.tickSources = function () {
return this._tickSources;
};
LocalTimeSystem.prototype.defaults = function (key) {
var now = Math.ceil(Date.now() / 1000) * 1000;
return {
key: 'local-default',
name: 'Local 12 hour time system defaults',
deltas: {start: THIRTY_MINUTES, end: 0},
bounds: {start: now - THIRTY_MINUTES, end: now}
};
};
return LocalTimeSystem;
});

16
main.js
View File

@ -28,13 +28,15 @@ requirejs.config({
"angular-route": "bower_components/angular-route/angular-route.min",
"csv": "bower_components/comma-separated-values/csv.min",
"es6-promise": "bower_components/es6-promise/promise.min",
"EventEmitter": "bower_components/eventemitter3/index",
"moment": "bower_components/moment/moment",
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
"screenfull": "bower_components/screenfull/dist/screenfull.min",
"text": "bower_components/text/text",
"uuid": "bower_components/node-uuid/uuid",
"zepto": "bower_components/zepto/zepto.min"
"zepto": "bower_components/zepto/zepto.min",
"d3": "bower_components/d3/d3.min"
},
"shim": {
"angular": {
@ -43,6 +45,9 @@ requirejs.config({
"angular-route": {
"deps": ["angular"]
},
"EventEmitter": {
"exports": "EventEmitter"
},
"moment-duration-format": {
"deps": ["moment"]
},
@ -51,6 +56,9 @@ requirejs.config({
},
"zepto": {
"exports": "Zepto"
},
"d3": {
"exports": "d3"
}
}
});
@ -83,6 +91,10 @@ define([
'./platform/features/pages/bundle',
'./platform/features/plot/bundle',
'./platform/features/timeline/bundle',
//'./platform/features/conductor/bundle',
'./platform/features/conductor-v2/conductor/bundle',
'./platform/features/conductor-v2/compatibility/bundle',
'./platform/features/conductor-v2/utcTimeSystem/bundle',
'./platform/features/table/bundle',
'./platform/forms/bundle',
'./platform/identity/bundle',
@ -94,6 +106,8 @@ define([
'./platform/search/bundle',
'./platform/status/bundle',
'./platform/commonUI/regions/bundle'
//'./example/localTimeSystem/bundle'
], function (Main, legacyRegistry) {
return {
legacyRegistry: legacyRegistry,

View File

@ -43,7 +43,7 @@
</mct-representation>
</div>
</div>
<div class="holder l-flex-col flex-elem grows l-object-wrapper">
<div class="holder l-flex-col flex-elem grows l-object-wrapper l-controls-visible l-time-controller-visible">
<div class="holder l-flex-col flex-elem grows l-object-wrapper-inner">
<!-- Toolbar and Save/Cancel buttons -->
<div class="l-edit-controls flex-elem l-flex-row flex-align-end">
@ -59,4 +59,8 @@
</mct-representation>
</div>
</div>
<mct-representation mct-object="domainObject"
key="'time-conductor'"
class="abs holder flex-elem flex-fixed l-flex-row l-time-conductor-holder">
</mct-representation>
</div>

View File

@ -22,7 +22,8 @@
<span class='type-icon flex-elem {{type.getCssClass()}}'></span>
<span class="l-elem-wrapper l-flex-row flex-elem grows">
<span ng-if="parameters.mode" class='action flex-elem'>{{parameters.mode}}</span>
<span class='title-label flex-elem flex-can-shrink'>{{model.name}}</span>
<span class='title-label flex-elem holder flex-can-shrink'>{{model.name}}</span>
<span class='t-object-alert t-alert-unsynced flex-elem holder' title='This object is not currently displaying real-time data'></span>
<mct-representation
key="'menu-arrow'"
mct-object='domainObject'

View File

@ -66,4 +66,9 @@
</mct-representation>
</div><!--/ l-object-wrapper-inner -->
</div>
<mct-representation mct-object="domainObject"
key="'time-conductor'"
class="abs holder flex-elem flex-fixed l-flex-row l-time-conductor-holder">
</mct-representation>
</div>

View File

@ -23,10 +23,12 @@
define([
"./src/FormatProvider",
"./src/UTCTimeFormat",
"./src/DurationFormat",
'legacyRegistry'
], function (
FormatProvider,
UTCTimeFormat,
DurationFormat,
legacyRegistry
) {
@ -48,6 +50,10 @@ define([
{
"key": "utc",
"implementation": UTCTimeFormat
},
{
"key": "duration",
"implementation": DurationFormat
}
],
"constants": [
@ -55,6 +61,17 @@ define([
"key": "DEFAULT_TIME_FORMAT",
"value": "utc"
}
],
"licenses": [
{
"name": "d3",
"version": "3.0.0",
"description": "Incorporates modified code from d3 Time Scales",
"author": "Mike Bostock",
"copyright": "Copyright 2010-2016 Mike Bostock. " +
"All rights reserved.",
"link": "https://github.com/d3/d3/blob/master/LICENSE"
}
]
}
});

View File

@ -0,0 +1,62 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define([
'moment'
], function (
moment
) {
var DATE_FORMAT = "HH:mm:ss",
DATE_FORMATS = [
DATE_FORMAT
];
/**
* Formatter for duration. Uses moment to produce a date from a given
* value, but output is formatted to display only time. Can be used for
* specifying a time duration. For specifying duration, it's best to
* specify a date of January 1, 1970, as the ms offset will equal the
* duration represented by the time.
*
* @implements {Format}
* @constructor
* @memberof platform/commonUI/formats
*/
function DurationFormat() {
}
DurationFormat.prototype.format = function (value) {
return moment.utc(value).format(DATE_FORMAT);
};
DurationFormat.prototype.parse = function (text) {
return moment.duration(text).asMilliseconds();
};
DurationFormat.prototype.validate = function (text) {
return moment.utc(text, DATE_FORMATS).isValid();
};
return DurationFormat;
});

View File

@ -58,6 +58,10 @@ define([
* @method format
* @memberof Format#
* @param {number} value the numeric value to format
* @param {number} [threshold] Optionally provides context to the
* format request, allowing for scale-appropriate formatting. This value
* should be the minimum unit to be represented by this format, in ms. For
* example, to display seconds, a threshold of 1 * 1000 should be provided.
* @returns {string} the text representation of the value
*/

View File

@ -34,6 +34,11 @@ define([
"YYYY-MM-DD"
];
/**
* @typedef Scale
* @property {number} min the minimum scale value, in ms
* @property {number} max the maximum scale value, in ms
*/
/**
* Formatter for UTC timestamps. Interprets numeric values as
@ -46,7 +51,52 @@ define([
function UTCTimeFormat() {
}
UTCTimeFormat.prototype.format = function (value) {
/**
* Returns an appropriate time format based on the provided value and
* the threshold required.
* @private
*/
function getScaledFormat (d) {
var m = moment.utc(d);
/**
* Uses logic from d3 Time-Scales, v3 of the API. See
* https://github.com/d3/d3-3.x-api-reference/blob/master/Time-Scales.md
*
* Licensed
*/
return [
[".SSS", function(m) { return m.milliseconds(); }],
[":ss", function(m) { return m.seconds(); }],
["HH:mm", function(m) { return m.minutes(); }],
["HH", function(m) { return m.hours(); }],
["ddd DD", function(m) {
return m.days() &&
m.date() != 1;
}],
["MMM DD", function(m) { return m.date() != 1; }],
["MMMM", function(m) {
return m.month();
}],
["YYYY", function() { return true; }]
].filter(function (row){
return row[1](m);
})[0][0];
};
/**
*
* @param value
* @param {Scale} [scale] Optionally provides context to the
* format request, allowing for scale-appropriate formatting.
* @returns {string} the formatted date
*/
UTCTimeFormat.prototype.format = function (value, scale) {
if (scale !== undefined){
var scaledFormat = getScaledFormat(value, scale);
if (scaledFormat) {
return moment.utc(value).format(scaledFormat);
}
}
return moment.utc(value).format(DATE_FORMAT) + "Z";
};

View File

@ -0,0 +1,91 @@
@include keyframes(rotation) {
100% { @include transform(rotate(360deg)); }
}
@include keyframes(rotation-centered) {
0% { @include transform(translate(-50%, -50%) rotate(0deg)); }
100% { @include transform(translate(-50%, -50%) rotate(360deg)); }
}
@include keyframes(clock-hands) {
0% { @include transform(translate(-50%, -50%) rotate(0deg)); }
100% { @include transform(translate(-50%, -50%) rotate(360deg)); }
}
@include keyframes(clock-hands-sticky) {
0% {
@include transform(translate(-50%, -50%) rotate(0deg));
}
7% {
@include transform(translate(-50%, -50%) rotate(0deg));
}
8% {
@include transform(translate(-50%, -50%) rotate(30deg));
}
15% {
@include transform(translate(-50%, -50%) rotate(30deg));
}
16% {
@include transform(translate(-50%, -50%) rotate(60deg));
}
24% {
@include transform(translate(-50%, -50%) rotate(60deg));
}
25% {
@include transform(translate(-50%, -50%) rotate(90deg));
}
32% {
@include transform(translate(-50%, -50%) rotate(90deg));
}
33% {
@include transform(translate(-50%, -50%) rotate(120deg));
}
40% {
@include transform(translate(-50%, -50%) rotate(120deg));
}
41% {
@include transform(translate(-50%, -50%) rotate(150deg));
}
49% {
@include transform(translate(-50%, -50%) rotate(150deg));
}
50% {
@include transform(translate(-50%, -50%) rotate(180deg));
}
57% {
@include transform(translate(-50%, -50%) rotate(180deg));
}
58% {
@include transform(translate(-50%, -50%) rotate(210deg));
}
65% {
@include transform(translate(-50%, -50%) rotate(210deg));
}
66% {
@include transform(translate(-50%, -50%) rotate(240deg));
}
74% {
@include transform(translate(-50%, -50%) rotate(240deg));
}
75% {
@include transform(translate(-50%, -50%) rotate(270deg));
}
82% {
@include transform(translate(-50%, -50%) rotate(270deg));
}
83% {
@include transform(translate(-50%, -50%) rotate(300deg));
}
90% {
@include transform(translate(-50%, -50%) rotate(300deg));
}
91% {
@include transform(translate(-50%, -50%) rotate(330deg));
}
99% {
@include transform(translate(-50%, -50%) rotate(330deg));
}
100% {
@include transform(translate(-50%, -50%) rotate(360deg));
}
}

View File

@ -108,6 +108,9 @@
&.grows {
@include flex(1 1 auto);
}
&.contents-align-right {
text-align: right;
}
}
.flex-container {
// Apply to wrapping elements, mct-includes, etc.

View File

@ -49,7 +49,6 @@ $uePaneMiniTabFontSize: 8px;
$uePaneMiniTabCollapsedW: 18px;
$ueEditLeftPaneW: 75%;
$treeSearchInputBarH: 25px;
$ueTimeControlH: (33px, 18px, 20px);
/*************** Panes */
$ueBrowseLeftPaneTreeMinW: 150px;
$ueBrowseLeftPaneTreeMaxW: 35%;
@ -109,6 +108,7 @@ $bubbleMaxW: 300px;
$reqSymbolW: 15px;
$reqSymbolM: $interiorMargin * 2;
$reqSymbolFontSize: 0.75em;
$inputTextP: 3px 5px;
/*************** Wait Spinner Defaults */
$waitSpinnerD: 32px;
$waitSpinnerTreeD: 20px;

View File

@ -4,4 +4,3 @@
@include s-stale();
}
}

View File

@ -39,20 +39,20 @@
@include pulse($animName: pulse-subtle, $dur: 500ms, $opacity0: 0.7);
}
@mixin animTo($animName, $propName, $propValStart, $propValEnd, $dur: 500ms, $delay: 0) {
@mixin animTo($animName, $propName, $propValStart, $propValEnd, $dur: 500ms, $delay: 0, $dir: normal, $count: 1) {
@include keyframes($animName) {
from { #{propName}: $propValStart; }
to { #{$propName}: $propValEnd; }
}
@include animToParams($animName, $dur: 500ms, $delay: 0)
@include animToParams($animName, $dur: $dur, $delay: $delay, $dir: $dir, $count: $count)
}
@mixin animToParams($animName, $dur: 500ms, $delay: 0) {
@mixin animToParams($animName, $dur: 500ms, $delay: 0, $dir: normal, $count: 1) {
@include animation-name($animName);
@include animation-duration($dur);
@include animation-delay($delay);
@include animation-fill-mode(both);
@include animation-direction(normal);
@include animation-iteration-count(1);
@include animation-direction($dir);
@include animation-iteration-count($count);
@include animation-timing-function(ease-in-out);
}

View File

@ -82,7 +82,7 @@ input, textarea {
input[type="text"],
input[type="search"] {
vertical-align: baseline;
padding: 3px 5px;
padding: $inputTextP;
}
h1, h2, h3 {

View File

@ -30,6 +30,7 @@
.ui-symbol {
font-family: 'symbolsfont';
-webkit-font-smoothing: antialiased;
}
.ui-symbol.icon {
@ -70,10 +71,21 @@
line-height: inherit;
position: relative;
&.l-icon-link {
.t-item-icon-glyph {
&:after {
color: $colorIconLink;
content: $glyph-icon-link;
height: auto; width: auto;
position: absolute;
left: 0; top: 0; right: 0; bottom: 20%;
@include transform-origin(bottom left);
@include transform(scale(0.3));
z-index: 2;
}
/* .t-item-icon-glyph {
&:after {
color: $colorIconLink;
content: $glyph-icon-link;
content: '\e921'; //$glyph-icon-link;
height: auto; width: auto;
position: absolute;
left: 0; top: 0; right: 0; bottom: 20%;
@ -81,6 +93,6 @@
@include transform(scale(0.3));
z-index: 2;
}
}
}*/
}
}

View File

@ -22,6 +22,7 @@
@import "effects";
@import "global";
@import "glyphs";
@import "animations";
@import "archetypes";
@import "about";
@import "text";
@ -41,7 +42,6 @@
@import "controls/lists";
@import "controls/menus";
@import "controls/messages";
@import "controls/time-controller";
@import "mobile/controls/menus";
/********************************* FORMS */

View File

@ -185,21 +185,15 @@
}
@mixin sliderTrack($bg: $scrollbarTrackColorBg) {
//$b: 1px solid lighten($bg, 30%);
border-radius: 2px;
box-sizing: border-box;
@include boxIncised(0.7);
background-color: $bg;
//border-bottom: $b;
//border-right: $b;
}
@mixin controlGrippy($b, $direction: horizontal, $w: 1px, $style: dotted) {
//&:before {
//@include trans-prop-nice("border-color", 25ms);
content: '';
display: block;
//height: auto;
pointer-events: none;
position: absolute;
z-index: 2;
@ -274,16 +268,6 @@
text-shadow: rgba(black, $sVal) 0 3px 7px;
}
@function pullForward($c, $p: 20%) {
// For dark interfaces, lighter things come forward
@return lighten($c, $p);
}
@function pushBack($c, $p: 20%) {
// For dark interfaces, darker things move back
@return darken($c, $p);
}
@function percentToDecimal($p) {
@return $p / 100%;
}
@ -304,7 +288,6 @@
border-radius: $controlCr;
box-sizing: border-box;
color: $fg;
//display: inline-block;
}
@mixin btnBase($bg: $colorBtnBg, $bgHov: $colorBtnBgHov, $fg: $colorBtnFg, $fgHov: $colorBtnFgHov, $ic: $colorBtnIcon, $icHov: $colorBtnIconHov) {

View File

@ -295,8 +295,6 @@ input[type="search"] {
.title-label {
color: $colorObjHdrTxt;
@include ellipsize();
@include webkitProp(flex, '0 1 auto');
padding-right: 0.35em; // For context arrow. Done with em's so pad is relative to the scale of the text.
}
.context-available-w {
@ -307,6 +305,10 @@ input[type="search"] {
font-size: 0.7em;
@include flex(0 0 1);
}
.t-object-alert {
display: none;
}
}
/******************************************************** PROGRESS BAR */
@ -440,6 +442,63 @@ input[type="search"] {
}
}
@mixin sliderKnob() {
$h: 16px;
cursor: pointer;
width: floor($h/1.75);
height: $h;
margin-top: 1 + floor($h/2) * -1;
@include btnSubtle(pullForward($colorBtnBg, 10%));
//border-radius: 50% !important;
}
@mixin sliderKnobRound() {
$h: 12px;
cursor: pointer;
width: $h;
height: $h;
margin-top: 1 + floor($h/2) * -1;
@include btnSubtle(pullForward($colorBtnBg, 10%));
border-radius: 50% !important;
}
input[type="range"] {
// HTML5 range inputs
-webkit-appearance: none; /* Hides the slider so that custom slider can be made */
background: transparent; /* Otherwise white in Chrome */
&:focus {
outline: none; /* Removes the blue border. */
}
// Thumb
&::-webkit-slider-thumb {
-webkit-appearance: none;
@include sliderKnobRound();
}
&::-moz-range-thumb {
border: none;
@include sliderKnobRound();
}
&::-ms-thumb {
border: none;
@include sliderKnobRound();
}
// Track
&::-webkit-slider-runnable-track {
width: 100%;
height: 3px;
@include sliderTrack();
}
&::-moz-range-track {
width: 100%;
height: 3px;
@include sliderTrack();
}
}
/******************************************************** DATETIME PICKER */
.l-datetime-picker {
$r1H: 15px;

View File

@ -178,7 +178,7 @@
}
.pane {
box-sizing: border-box;
&.left {
&.menu-items {
border-right: 1px solid pullForward($colorMenuBg, 10%);
left: 0;
padding-right: $interiorMargin;
@ -194,38 +194,53 @@
}
}
}
&.right {
&.menu-item-description {
left: auto;
right: 0;
padding: $interiorMargin * 5;
width: $prw;
.desc-area {
&.icon {
color: $colorCreateMenuLgIcon;
font-size: 8em;
margin-bottom: $interiorMargin * 3;
position: relative;
text-align: center;
}
&.title {
color: $colorCreateMenuText;
font-size: 1.2em;
margin-bottom: $interiorMargin * 2;
}
&.description {
color: pushBack($colorCreateMenuText, 20%);
font-size: 0.8em;
line-height: 1.5em;
}
}
}
}
.menu-item-description {
.desc-area {
&.icon {
$h: 150px;
color: $colorCreateMenuLgIcon;
position: relative;
font-size: 8em;
left: 0;
height: $h;
line-height: $h;
margin-bottom: $interiorMargin * 5;
text-align: center;
}
&.title {
color: $colorCreateMenuText;
font-size: 1.2em;
margin-bottom: 0.5em;
}
&.description {
color: $colorCreateMenuText;
font-size: 0.8em;
line-height: 1.5em;
}
}
}
&.mini {
width: 400px;
height: 300px;
.pane {
&.menu-items {
font-size: 0.8em;
}
&.menu-item-description {
padding: $interiorMargin * 3;
.desc-area {
&.icon {
font-size: 4em;
}
&.title {
font-size: 1em;
}
}
}
}
}
}
.context-menu {
font-size: 0.80rem;
@ -262,3 +277,7 @@
right: 0;
width: auto;
}
.menus-up .menu {
bottom: $btnStdH; top: auto;
}

View File

@ -345,3 +345,29 @@ body.desktop .t-message-single {
body.desktop .t-message-list {
.message-contents .l-message { margin-right: $interiorMarginLg; }
}
// Alert elements in views
.s-unsynced {
$c: $colorPausedBg;
border: 1px solid $c;
@include animTo($animName: pulsePaused, $propName: border-color, $propValStart: rgba($c, 0.8), $propValEnd: rgba($c, 0.5), $dur: $animPausedPulseDur, $dir: alternate, $count: infinite);
}
.s-status-timeconductor-unsynced {
// Plot areas
.gl-plot .gl-plot-display-area {
@extend .s-unsynced;
}
// Object headers
.object-header {
.t-object-alert {
display: inline;
&.t-alert-unsynced {
@extend .icon-alert-triangle;
color: $colorPausedBg;
}
}
}
}

View File

@ -1,266 +0,0 @@
@mixin toiLineHovEffects() {
&:before,
&:after {
background-color: $timeControllerToiLineColorHov;
}
}
.l-time-controller {
$minW: 500px;
$knobHOffset: 0px;
$knobM: ($sliderKnobW + $knobHOffset) * -1;
$rangeValPad: $interiorMargin;
$rangeValOffset: $sliderKnobW + $interiorMargin;
$timeRangeSliderLROffset: 150px + ($sliderKnobW * 2);
$r1H: nth($ueTimeControlH,1); // Not currently used
$r2H: nth($ueTimeControlH,2);
$r3H: nth($ueTimeControlH,3);
min-width: $minW;
font-size: 0.8rem;
.l-time-range-inputs-holder,
.l-time-range-slider-holder,
.l-time-range-ticks-holder
{
box-sizing: border-box;
position: relative;
&:not(:first-child) {
margin-top: $interiorMargin;
}
}
.l-time-range-slider,
.l-time-range-ticks {
@include absPosDefault(0, visible);
left: $timeRangeSliderLROffset; right: $timeRangeSliderLROffset;
}
.l-time-range-inputs-holder {
border-top: 1px solid $colorInteriorBorder;
padding-top: $interiorMargin;
&.l-flex-row,
.l-flex-row {
@include align-items(center);
.flex-elem {
height: auto;
line-height: normal;
}
}
.type-icon {
font-size: 120%;
vertical-align: middle;
}
.l-time-range-input-w,
.l-time-range-inputs-elem {
margin-right: $interiorMargin;
.lbl {
color: $colorPlotLabelFg;
}
.ui-symbol.icon {
font-size: 11px;
}
}
.l-time-range-input-w {
// Wraps a datetime text input field
position: relative;
input[type="text"] {
width: 200px;
&.picker-icon {
padding-right: 20px;
}
}
.icon-calendar {
position: absolute;
right: 5px;
top: 5px;
}
}
}
.l-time-range-slider-holder {
height: $r2H;
.range-holder {
box-shadow: none;
background: none;
border: none;
.range {
.toi-line {
$myC: $timeControllerToiLineColor;
$myW: 8px;
@include transform(translateX(50%));
position: absolute;
top: 0; right: 0; bottom: 0px; left: auto;
width: $myW;
height: auto;
z-index: 2;
&:before {
// Vert line
background-color: $myC;
position: absolute;
content: "";
top: 0; right: auto; bottom: -10px; left: floor($myW/2) - 1;
width: 1px;
}
}
&:hover .toi-line {
@include toiLineHovEffects;
}
}
}
&:not(:active) {
.knob,
.range {
@include transition-property(left, right);
@include transition-duration(500ms);
@include transition-timing-function(ease-in-out);
}
}
}
.l-time-range-ticks-holder {
height: $r3H;
.l-time-range-ticks {
border-top: 1px solid $colorTick;
.tick {
background-color: $colorTick;
border:none;
height: 5px;
width: 1px;
margin-left: -1px;
position: absolute;
&:first-child {
margin-left: 0;
}
.l-time-range-tick-label {
@include webkitProp(transform, translateX(-50%));
color: $colorPlotLabelFg;
display: inline-block;
font-size: 0.7rem;
position: absolute;
top: 5px;
white-space: nowrap;
z-index: 2;
}
}
}
}
.knob {
z-index: 2;
&:before {
$mTB: 2px;
$grippyW: 3px;
$mLR: ($sliderKnobW - $grippyW)/2;
@include bgStripes($c: pullForward($sliderColorKnob, 20%), $a: 1, $bgsize: 4px, $angle: 0deg);
content: '';
display: block;
position: absolute;
top: $mTB; right: $mLR; bottom: $mTB; left: $mLR;
}
.range-value {
@include trans-prop-nice-fade(.25s);
font-size: 0.7rem;
position: absolute;
height: $r2H;
line-height: $r2H;
white-space: nowrap;
z-index: 1;
}
&:hover {
.range-value {
color: $sliderColorKnobHov;
}
}
&.knob-l {
margin-left: $knobM;
.range-value {
text-align: right;
right: $rangeValOffset;
}
}
&.knob-r {
margin-right: $knobM;
.range-value {
left: $rangeValOffset;
}
&:hover + .range-holder .range .toi-line {
@include toiLineHovEffects;
}
}
}
.l-time-domain-selector {
position: absolute;
right: 0px;
top: $interiorMargin;
}
}
.s-time-range-val {
border-radius: $controlCr;
background-color: $colorInputBg;
padding: 1px 1px 0 $interiorMargin;
}
/******************************************************************** MOBILE */
@include phoneandtablet {
.l-time-controller {
min-width: 0;
.l-time-range-slider-holder,
.l-time-range-ticks-holder {
display: none;
}
}
}
@include phone {
.l-time-controller {
.l-time-range-inputs-holder {
&.l-flex-row,
.l-flex-row {
@include align-items(flex-start);
}
.l-time-range-inputs-elem {
&.type-icon {
margin-top: 3px;
}
}
.t-inputs-w {
@include flex-direction(column);
.l-time-range-input-w:not(:first-child) {
&:not(:first-child) {
margin-top: $interiorMargin;
}
margin-right: 0;
}
.l-time-range-inputs-elem {
&.lbl { display: none; }
}
}
}
}
}
@include phonePortrait {
.l-time-controller {
.l-time-range-inputs-holder {
.t-inputs-w {
@include flex(1 1 auto);
padding-top: 25px; // Make room for the ever lovin' Time Domain Selector
.flex-elem {
@include flex(1 1 auto);
width: 100%;
}
input[type="text"] {
width: 100%;
}
}
}
}
.l-time-domain-selector {
right: auto;
left: 20px;
}
}

View File

@ -74,7 +74,7 @@
.s-image-main {
border: 1px solid transparent;
&.paused {
border-color: $colorPausedBg;
@extend .s-unsynced;
}
}

View File

@ -19,15 +19,6 @@
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
@include keyframes(rotation) {
100% { @include transform(rotate(360deg)); }
}
@include keyframes(rotation-centered) {
0% { @include transform(translate(-50%, -50%) rotate(0deg)); }
100% { @include transform(translate(-50%, -50%) rotate(360deg)); }
}
@mixin spinner($b: 5px, $c: $colorKey) {
@include transform-origin(center);
@include animation-name(rotation-centered);

View File

@ -129,6 +129,8 @@
}
.primary-pane {
// Clip element that have min-widths
overflow: hidden;
// Need to lift up this pane to ensure that 'collapsed' panes don't block user interactions
z-index: 4;
}

View File

@ -23,6 +23,8 @@
<input type="text"
ng-model="textValue"
ng-blur="restoreTextValue(); ngBlur()"
ng-mouseup="ngMouseup()"
ng-disabled="ngDisabled"
ng-class="{
error: textInvalid ||
(structure.validate &&

View File

@ -61,8 +61,8 @@ $colorCreateBtn: $colorKey;
$colorGridLines: rgba(#fff, 0.05);
$colorInvokeMenu: #fff;
$colorObjHdrTxt: $colorBodyFg;
$colorObjHdrIc: pullForward($colorObjHdrTxt, 20%);
$colorTick: rgba(white, 0.2);
$colorObjHdrIc: darken($colorObjHdrTxt, 20%);
$colorTick: pullForward($colorBodyBg, 20%);
// Menu colors
$colorMenuBg: pullForward($colorBodyBg, 23%);
@ -113,6 +113,7 @@ $colorProgressBarAmt: $colorKey;
$progressBarHOverlay: 15px;
$progressBarStripeW: 20px;
$shdwStatusIc: rgba(black, 0.4) 0 1px 2px;
$animPausedPulseDur: 500ms;
// Selects
$colorSelectBg: $colorBtnBg;
@ -229,4 +230,4 @@ $colorAboutLink: #84b3ff;
// Loading
$colorLoadingFg: $colorAlt1;
$colorLoadingBg: rgba($colorBodyFg, 0.2);
$colorLoadingBg: rgba($colorBodyFg, 0.2);

View File

@ -61,8 +61,8 @@ $colorCreateBtn: $colorKey;
$colorGridLines: rgba(#000, 0.05);
$colorInvokeMenu: #fff;
$colorObjHdrTxt: $colorBodyFg;
$colorObjHdrIc: pushBack($colorObjHdrTxt, 30%);
$colorTick: rgba(black, 0.2);
$colorObjHdrIc: lighten($colorObjHdrTxt, 20%);
$colorTick: lighten($colorBodyFg, 10%);
// Menu colors
$colorMenuBg: pushBack($colorBodyBg, 10%);
@ -113,6 +113,7 @@ $colorProgressBarAmt: #0a0;
$progressBarHOverlay: 15px;
$progressBarStripeW: 20px;
$shdwStatusIc: rgba(white, 0.8) 0 0px 5px;
$animPausedPulseDur: 1s;
// Selects
$colorSelectBg: $colorBtnBg;

View File

@ -0,0 +1,66 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define([
"./src/ConductorTelemetryDecorator",
"./src/ConductorRepresenter",
"./src/ConductorService",
'legacyRegistry'
], function (
ConductorTelemetryDecorator,
ConductorRepresenter,
ConductorService,
legacyRegistry
) {
legacyRegistry.register("platform/features/conductor-v2/compatibility", {
"extensions": {
"services": [
{
"key": "conductorService",
"implementation": ConductorService,
"depends": [
"timeConductorService"
]
}
],
"representers": [
{
"implementation": ConductorRepresenter,
"depends": [
"timeConductorService"
]
}
],
"components": [
{
"type": "decorator",
"provides": "telemetryService",
"implementation": ConductorTelemetryDecorator,
"depends": [
"timeConductorService"
]
}
]
}
});
});

View File

@ -0,0 +1,93 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define(
[],
function () {
/**
* Representer that provides a compatibility layer between the new
* time conductor and existing representations / views. Listens to
* the v2 time conductor API and generates v1 style events using the
* Angular event bus. This is transitional code code and will be
* removed.
*
* Deprecated immediately as this is temporary code
*
* @deprecated
* @constructor
*/
function ConductorRepresenter(
conductorService,
scope,
element
) {
this.conductor = conductorService.conductor();
this.scope = scope;
this.element = element;
this.boundsListener = this.boundsListener.bind(this);
this.timeSystemListener = this.timeSystemListener.bind(this);
this.followListener = this.followListener.bind(this);
}
ConductorRepresenter.prototype.boundsListener = function (bounds) {
this.scope.$broadcast('telemetry:display:bounds', {
start: bounds.start,
end: bounds.end,
domain: this.conductor.timeSystem().metadata.key
}, this.conductor.follow());
};
ConductorRepresenter.prototype.timeSystemListener = function (timeSystem) {
var bounds = this.conductor.bounds();
this.scope.$broadcast('telemetry:display:bounds', {
start: bounds.start,
end: bounds.end,
domain: timeSystem.metadata.key
}, this.conductor.follow());
};
ConductorRepresenter.prototype.followListener = function () {
this.boundsListener(this.conductor.bounds());
};
// Handle a specific representation of a specific domain object
ConductorRepresenter.prototype.represent = function represent(representation) {
if (representation.key === 'browse-object') {
this.destroy();
this.conductor.on("bounds", this.boundsListener);
this.conductor.on("timeSystem", this.timeSystemListener);
this.conductor.on("follow", this.followListener)
}
};
ConductorRepresenter.prototype.destroy = function destroy() {
this.conductor.off("bounds", this.boundsListener);
this.conductor.off("timeSystem", this.timeSystemListener);
};
return ConductorRepresenter;
}
);

View File

@ -0,0 +1,72 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define([
], function (
) {
function Conductor(timeConductorService) {
this.timeConductor = timeConductorService.conductor();
}
Conductor.prototype.displayStart = function () {
return this.timeConductor.bounds().start;
};
Conductor.prototype.displayEnd = function () {
return this.timeConductor.bounds().end;
};
Conductor.prototype.domainOptions = function () {
throw new Error([
'domainOptions not implemented in compatibility layer,',
' you must be using some crazy unknown code'
].join(''));
};
Conductor.prototype.domain = function () {
var system = this.timeConductor.timeSystem();
return {
key: system.metadata.key,
name: system.metadata.name,
format: system.formats()[0]
};
};
/**
* Small compatibility layer that implements old conductor service by
* wrapping new time conductor. This allows views that previously depended
* directly on the conductor service to continue to do so without
* modification.
*/
function ConductorService(timeConductor) {
this.tc = new Conductor(timeConductor);
}
ConductorService.prototype.getConductor = function () {
return this.tc;
}
return ConductorService;
});

View File

@ -0,0 +1,87 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define(
function () {
/**
* Decorates the `telemetryService` such that requests are
* mediated by the time conductor. This is a modified version of the
* decorator used in the old TimeConductor that integrates with the
* new TimeConductor API.
*
* @constructor
* @memberof platform/features/conductor
* @implements {TelemetryService}
* @param {platform/features/conductor.TimeConductor} conductor
* the service which exposes the global time conductor
* @param {TelemetryService} telemetryService the decorated service
*/
function ConductorTelemetryDecorator(conductorService, telemetryService) {
this.conductor = conductorService.conductor();
this.telemetryService = telemetryService;
this.amendRequests = ConductorTelemetryDecorator.prototype.amendRequests.bind(this);
}
function amendRequest(request, bounds, timeSystem) {
request = request || {};
request.start = bounds.start;
request.end = bounds.end;
request.domain = timeSystem.metadata.key;
return request;
}
ConductorTelemetryDecorator.prototype.amendRequests = function (requests) {
var bounds = this.conductor.bounds(),
timeSystem = this.conductor.timeSystem();
return (requests || []).map(function (request) {
return amendRequest(request, bounds, timeSystem);
});
};
ConductorTelemetryDecorator.prototype.requestTelemetry = function (requests) {
return this.telemetryService
.requestTelemetry(this.amendRequests(requests));
};
ConductorTelemetryDecorator.prototype.subscribe = function (callback, requests) {
var unsubscribeFunc = this.telemetryService.subscribe(callback, this.amendRequests(requests)),
conductor = this.conductor,
self = this;
function amendRequests() {
return self.amendRequests(requests);
}
conductor.on('bounds', amendRequests);
return function() {
unsubscribeFunc();
conductor.off('bounds', amendRequests);
}
};
return ConductorTelemetryDecorator;
}
);

View File

@ -0,0 +1,113 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define([
"./src/ui/TimeConductorService",
"./src/ui/TimeConductorController",
"./src/ui/MCTConductorAxis",
"./src/ui/NumberFormat",
"text!./res/templates/time-conductor.html",
"text!./res/templates/mode-selector/mode-selector.html",
"text!./res/templates/mode-selector/mode-menu.html",
'legacyRegistry'
], function (
TimeConductorService,
TimeConductorController,
MCTConductorAxis,
NumberFormat,
timeConductorTemplate,
modeSelectorTemplate,
modeMenuTemplate,
legacyRegistry
) {
legacyRegistry.register("platform/features/conductor-v2/conductor", {
"extensions": {
"services": [
{
"key": "timeConductor",
"implementation": function (timeConductorService) {
return timeConductorService.conductor();
},
"depends": [
"timeConductorService"
]
},
{
"key": "timeConductorService",
"implementation": TimeConductorService
}
],
"controllers": [
{
"key": "TimeConductorController",
"implementation": TimeConductorController,
"depends": [
"$scope",
"timeConductorService",
"timeSystems[]"
]
}
],
"directives": [
{
"key": "mctConductorAxis",
"implementation": MCTConductorAxis,
"depends": [
"timeConductorService",
"formatService"
]
}
],
"stylesheets": [
{
"stylesheetUrl": "css/time-conductor-espresso.css",
"theme": "espresso"
},
{
"stylesheetUrl": "css/time-conductor-snow.css",
"theme": "snow"
}
],
"representations": [
{
"key": "time-conductor",
"template": timeConductorTemplate
},
{
"key": "mode-selector",
"template": modeSelectorTemplate
},
{
"key": "mode-menu",
"template": modeMenuTemplate
}
],
"formats": [
{
"key": "number",
"implementation": NumberFormat
}
]
}
});
});

View File

@ -0,0 +1,3 @@
$ueTimeConductorH: (25px, 15px, 20px);
$timeCondInputTimeSysDefW: 165px; // Default width for datetime value inputs
$timeCondInputDeltaDefW: 60px; // Default width for delta value inputs, typically 00:00:00

View File

@ -0,0 +1,433 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2015, 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.
*****************************************************************************/
@mixin toiLineHovEffects() {
&:before,
&:after {
background-color: $timeControllerToiLineColorHov;
}
}
.l-time-conductor-holder {
$minW: 500px;
border-top: 1px solid $colorInteriorBorder;
min-width: $minW;
padding-top: $interiorMargin;
}
.time-conductor-icon {
$c: $colorObjHdrIc;
$d: 18px;
height: $d !important;
width: $d;
position: relative;
&:before {
@extend .ui-symbol;
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; //8px;
@include transform(translate(-50%, -50%));
@include animation-iteration-count(infinite);
@include animation-timing-function(linear);
position: absolute;
height: $handW;
width: $handW;
left: 50%;
top: 50%;
z-index: 2;
&:before {
background: $colorObjHdrIc;
content: '';
display: block;
position: absolute;
width: 100%;
bottom: -1px;
}
&.hand-little {
z-index: 2;
@include animation-duration(12s);
&:before {
height: ceil($handH * 0.7);
}
}
&.hand-big {
z-index: 1;
@include animation-duration(1s);
&:before {
height: $handH;
}
}
}
}
.l-time-conductor {
$knobHOffset: 0px;
$rangeValPad: $interiorMargin;
$rangeValOffset: $sliderKnobW + $interiorMargin;
$r1H: nth($ueTimeConductorH, 1);
$r2H: nth($ueTimeConductorH, 2);
$r3H: nth($ueTimeConductorH, 3);
position: relative;
> .l-row-elem {
// First order row elements
box-sizing: border-box;
width: 100%;
position: relative;
}
.mode-selector .s-menu-button,
.time-delta {
&:before {
@extend .ui-symbol;
}
}
.time-delta {
&:before {
color: $colorTimeCondKeyBg;
}
}
.l-time-conductor-inputs-holder,
.l-time-conductor-inputs-and-ticks,
.l-time-conductor-zoom-w {
font-size: 0.8rem;
}
.l-time-conductor-inputs-holder {
$ticksBlockerFadeW: 50px;
$iconCalendarW: 16px;
$wBgColor: $colorBodyBg;
height: $r1H;
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
z-index: 1;
.l-time-range-w {
// Wraps a datetime text input field
height: 100%;
position: absolute;
.title {
display: inline-block;
margin-right: $interiorMarginSm;
}
&.start-w {
@include background-image(linear-gradient(270deg, transparent, $wBgColor $ticksBlockerFadeW));
padding-right: $ticksBlockerFadeW;
.title:before {
content: 'Start';
}
}
&.end-w {
@include background-image(linear-gradient(90deg, transparent, $wBgColor $ticksBlockerFadeW));
padding-left: $ticksBlockerFadeW;
right: 0;
.title:before {
content: 'End';
}
}
input[type="text"] {
@include trans-prop-nice(padding, 250ms);
}
.time-range-input input[type="text"] {
width: $timeCondInputTimeSysDefW;
}
.hrs-min-input input[type="text"] {
width: $timeCondInputDeltaDefW;
}
.icon-calendar {
margin-top: 4px;
}
}
}
.l-time-conductor-inputs-and-ticks {
$c: $colorTimeCondTicks; //$colorTick;
height: $r1H;
mct-conductor-axis {
display: block;
position: relative;
width: 100%;
}
.l-axis-holder {
height: $r1H;
position: relative;
width: 100%;
svg {
text-rendering: geometricPrecision;
width: 100%;
height: 100%;
> g {
font-size: 0.9em;
}
path {
// Line beneath ticks
display: none;
}
line {
// Tick marks
stroke: $c;
}
text {
// Tick labels
fill: $c;
}
}
}
}
.l-data-visualization {
background: $colorTimeCondDataVisBg;
height: $r2H;
}
.l-time-conductor-controls {
align-items: center;
margin-top: $interiorMargin;
.l-time-conductor-zoom-w {
@include justify-content(flex-end);
.time-conductor-zoom {
display: none; // TEMP per request from Andrew 8/1/16
height: $r3H;
min-width: 100px;
width: 20%;
}
.time-conductor-zoom-current-range {
display: none; // TEMP per request from Andrew 8/1/16
color: $colorTick;
}
}
}
// Real-time, latest modes
&.realtime-mode,
&.latest-mode {
.time-conductor-icon {
&:before { color: $colorTimeCondKeyBg; }
div[class*="hand"] {
@include animation-name(clock-hands);
&:before {
background: $colorTimeCondKeyBg;
}
}
}
.l-time-conductor-inputs-holder {
.l-time-range-input-w {
input[type="text"]:not(.error) {
background: transparent;
box-shadow: none;
border-radius: 0;
padding-left: 0;
padding-right: 0;
&:hover,
&:focus {
@include nice-input();
padding: $inputTextP;
}
}
.icon-calendar {
display: none;
}
&.start-date {
display: none;
}
&.end-date {
pointer-events: none;
input[type="text"] {
color: pullForward($colorTimeCondKeyBg, 5%);
margin-right: $interiorMargin;
tab-index: -1;
}
}
}
}
.l-data-visualization {
background: $colorTimeCondDataVisRtBg !important
}
.mode-selector .s-menu-button {
$fg: $colorTimeCondKeyFg;
@include btnSubtle($bg: $colorTimeCondKeyBg, $bgHov: pullForward($colorTimeCondKeyBg, $ltGamma), $fg: $colorTimeCondKeyFg);
&:before { color: $fg !important; };
color: $fg !important;
}
}
// Fixed mode
&.fixed-mode {
$i: $glyph-icon-calendar;
.time-conductor-icon div[class*="hand"] {
&.hand-little {
@include transform(rotate(120deg));
}
}
.mode-selector .s-menu-button:before {
content: $i;
}
}
// Realtime mode
&.realtime-mode {
$i: $glyph-icon-clock;
.time-conductor-icon div[class*="hand"] {
@include animation-name(clock-hands);
}
.time-delta:before {
content: $i;
}
.l-time-conductor-inputs-holder .l-time-range-w.end-w .title:before {
content: 'Now';
}
.mode-selector .s-menu-button:before {
content: $i;
}
}
// LAD mode
&.latest-mode {
$i: $glyph-icon-database;
.time-conductor-icon div[class*="hand"] {
@include animation-name(clock-hands-sticky);
&.hand-big {
@include animation-duration(5s);
}
&.hand-little {
@include animation-duration(60s);
}
}
.time-delta:before {
content: $i;
}
.l-time-conductor-inputs-holder .l-time-range-w.end-w .title:before {
content: 'LAD';
}
.mode-selector .s-menu-button:before {
content: $i;
}
}
}
/******************************************************************** MOBILE */
@include phoneandtablet {
.l-time-conductor-holder { min-width: 0 !important; }
.super-menu.mini {
width: 200px;
height: 100px;
.pane.menu-item-description {
display: none;
}
}
}
@include phone {
.l-time-conductor {
min-width: 0;
.l-time-conductor-inputs-and-ticks {
.l-time-conductor-inputs-holder {
.l-time-range-w {
background-image: none !important;
}
}
mct-conductor-axis {
display: none;
}
}
}
}
@include phonePortrait {
.l-time-conductor {
.l-data-visualization,
.l-time-conductor-zoom-w,
.time-delta {
display: none;
}
.l-time-conductor-inputs-and-ticks {
height: auto !important;
.l-time-conductor-inputs-holder {
position: relative;
height: auto !important;
.l-time-range-w {
background-image: none !important;
display: block;
height: auto !important;
padding: 0 !important;
position: relative;
text-align: left;
&:not(:first-child) {
margin-top: $interiorMargin;
}
}
}
}
// Fixed mode
&.fixed-mode {
.l-time-conductor-inputs-and-ticks {
.l-time-range-w {
.title {
width: 30px;
}
}
}
}
// Real-time, latest modes
&.realtime-mode,
&.latest-mode {
.l-time-conductor-inputs-and-ticks {
.l-time-range-w {
&.start-w {
display: none;
}
&.end-w {
margin-top: 0;
.end-date input[type="text"] {
margin: 0;
text-align: left;
}
}
}
}
}
}
}

View File

@ -0,0 +1,39 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2015, 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.
*****************************************************************************/
@import "bourbon";
@import "../../../../../commonUI/general/res/sass/constants";
@import "../../../../../commonUI/general/res/sass/mixins";
@import "../../../../../commonUI/general/res/sass/mobile/constants";
@import "../../../../../commonUI/general/res/sass/mobile/mixins";
@import "../../../../../commonUI/themes/espresso/res/sass/constants";
@import "../../../../../commonUI/themes/espresso/res/sass/mixins";
@import "../../../../../commonUI/general/res/sass/glyphs";
@import "../../../../../commonUI/general/res/sass/icons";
@import "constants";
// Thematic constants
$colorTimeCondTicks: pullForward($colorBodyBg, 30%);
$colorTimeCondKeyBg: #4e70dc;
$colorTimeCondKeyFg: #fff;
$colorTimeCondDataVisBg: pullForward($colorBodyBg, 10%);
$colorTimeCondDataVisRtBg: pushBack($colorTimeCondKeyBg, 10%);
@import "time-conductor-base";

View File

@ -0,0 +1,39 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2015, 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.
*****************************************************************************/
@import "bourbon";
@import "../../../../../commonUI/general/res/sass/constants";
@import "../../../../../commonUI/general/res/sass/mixins";
@import "../../../../../commonUI/general/res/sass/mobile/constants";
@import "../../../../../commonUI/general/res/sass/mobile/mixins";
@import "../../../../../commonUI/themes/snow/res/sass/constants";
@import "../../../../../commonUI/themes/snow/res/sass/mixins";
@import "../../../../../commonUI/general/res/sass/glyphs";
@import "../../../../../commonUI/general/res/sass/icons";
@import "constants";
// Thematic constants
$colorTimeCondTicks: pullForward($colorBodyBg, 30%);
$colorTimeCondKeyBg: #6178dc;
$colorTimeCondKeyFg: #fff;
$colorTimeCondDataVisBg: pullForward($colorBodyBg, 10%);
$colorTimeCondDataVisRtBg: pushBack($colorTimeCondKeyBg, 30%);
@import "time-conductor-base";

View File

@ -0,0 +1,44 @@
<!--
Open MCT Web, Copyright (c) 2014-2015, 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.
-->
<div class="contents">
<div class="pane left menu-items">
<ul>
<li ng-repeat="(key, metadata) in ngModel.options"
ng-click="ngModel.selectedKey=key">
<a ng-mouseover="representation.activeMetadata = metadata"
ng-mouseleave="representation.activeMetadata = undefined"
class="menu-item-a {{metadata.cssclass}}">
{{metadata.name}}
</a>
</li>
</ul>
</div>
<div class="pane right menu-item-description">
<div class="desc-area ui-symbol icon type-icon {{representation.activeMetadata.cssclass}}"></div>
<div class="desc-area title">
{{representation.activeMetadata.name}}
</div>
<div class="desc-area description">
{{representation.activeMetadata.description}}
</div>
</div>
</div>

View File

@ -0,0 +1,35 @@
<!--
Open MCT Web, Copyright (c) 2014-2015, 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.
-->
<span ng-controller="ClickAwayController as modeController">
<div class="s-menu-button"
ng-click="modeController.toggle()">
<span class="title-label">{{ngModel.options[ngModel.selectedKey]
.label}}</span>
</div>
<div class="menu super-menu mini mode-selector-menu"
ng-show="modeController.isActive()">
<mct-representation mct-object="domainObject"
key="'mode-menu'"
ng-model="ngModel">
</mct-representation>
</div>
</span>

View File

@ -0,0 +1,109 @@
<!-- Parent holder for time conductor. follow-mode | fixed-mode -->
<div ng-controller="TimeConductorController as tcController"
class="holder grows flex-elem l-flex-row l-time-conductor {{modeModel.selectedKey}}-mode {{timeSystemModel.selected.metadata.key}}-time-system">
<div class="flex-elem holder time-conductor-icon">
<div class="hand-little"></div>
<div class="hand-big"></div>
</div>
<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"
ng-submit="tcController.updateBoundsFromForm(formModel)">
<span class="l-time-range-w start-w">
<span class="l-time-range-input-w start-date">
<span class="title"></span>
<mct-control key="'datetime-field'"
structure="{
format: timeSystemModel.format,
validate: tcController.validation.validateStart
}"
ng-model="formModel"
ng-blur="tcController.updateBoundsFromForm(formModel)"
field="'start'"
class="time-range-input">
</mct-control>
</span>
<span class="l-time-range-input-w time-delta start-delta"
ng-class="{'hide':(modeModel.selectedKey === 'fixed')}">
-
<mct-control key="'datetime-field'"
structure="{
format: timeSystemModel.deltaFormat,
validate: tcController.validation.validateStartDelta
}"
ng-model="formModel"
ng-blur="tcController.updateDeltasFromForm(formModel)"
field="'startDelta'"
class="hrs-min-input">
</mct-control>
</span>
</span>
<span class="l-time-range-w end-w">
<span class="l-time-range-input-w end-date"
ng-controller="ToggleController as t2">
<span class="title"></span>
<mct-control key="'datetime-field'"
structure="{
format: timeSystemModel.format,
validate: tcController.validation.validateEnd
}"
ng-model="formModel"
ng-blur="tcController.updateBoundsFromForm(formModel)"
ng-disabled="modeModel.selectedKey !== 'fixed'"
field="'end'"
class="time-range-input">
</mct-control>
</span>
<span class="l-time-range-input-w time-delta end-delta"
ng-class="{'hide':(modeModel.selectedKey === 'fixed')}">
+
<mct-control key="'datetime-field'"
structure="{
format: timeSystemModel.deltaFormat,
validate: tcController.validation.validateEndDelta
}"
ng-model="formModel"
ng-blur="tcController.updateDeltasFromForm(formModel)"
field="'endDelta'"
class="hrs-min-input">
</mct-control>
</span>
</span>
<input type="submit" class="hidden">
</form>
<mct-conductor-axis></mct-conductor-axis>
</div>
<!-- Holds data availability, time of interest -->
<div class="l-data-visualization l-row-elem flex-elem"></div>
<!-- Holds time system and session selectors, and zoom control -->
<div class="l-time-conductor-controls l-row-elem l-flex-row flex-elem">
<mct-representation
key="'mode-selector'"
mct-object="domainObject"
ng-model="modeModel"
class="holder flex-elem menus-up mode-selector">
</mct-representation>
<mct-control
key="'menu-button'"
class="holder flex-elem menus-up time-system"
structure="{
text: timeSystemModel.selected.metadata.name,
click: tcController.selectTimeSystemByKey,
options: timeSystemModel.options
}">
</mct-control>
<!-- Zoom control -->
<div class="l-time-conductor-zoom-w grows flex-elem l-flex-row">
<span class="time-conductor-zoom-current-range flex-elem flex-fixed holder">Mars Minutes</span>
<input class="time-conductor-zoom flex-elem" type="range" />
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,182 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define(['EventEmitter'], function (EventEmitter) {
/**
* The public API for setting and querying time conductor state. The
* time conductor is the means by which the temporal bounds of a view
* are controlled. Time-sensitive views will typically respond to
* changes to bounds or other properties of the time conductor and
* update the data displayed based on the time conductor state.
*
* The TimeConductor extends the EventEmitter class. A number of events are
* fired when properties of the time conductor change, which are
* documented below.
* @constructor
*/
function TimeConductor() {
EventEmitter.call(this);
//The Time System
this.system = undefined;
//The Time Of Interest
this.toi = undefined;
this.boundsVal = {
start: undefined,
end: undefined
};
//Default to fixed mode
this.followMode = false;
}
TimeConductor.prototype = Object.create(EventEmitter.prototype);
/**
* Validate the given bounds. This can be used for pre-validation of
* bounds, for example by views validating user inputs.
* @param bounds The start and end time of the conductor.
* @returns {string | true} A validation error, or true if valid
*/
TimeConductor.prototype.validateBounds = function (bounds) {
if ((bounds.start === undefined) ||
(bounds.end === undefined) ||
isNaN(bounds.start) ||
isNaN(bounds.end)
) {
return "Start and end must be specified as integer values";
} else if (bounds.start > bounds.end) {
return "Specified start date exceeds end bound";
}
return true;
};
/**
* Get or set the follow mode of the time conductor. In follow mode the
* time conductor ticks, regularly updating the bounds from a timing
* source appropriate to the selected time system and mode of the time
* conductor.
* @fires TimeConductor#follow
* @param {boolean} followMode
* @returns {boolean}
*/
TimeConductor.prototype.follow = function (followMode) {
if (arguments.length > 0) {
this.followMode = followMode;
/**
* @event TimeConductor#follow The TimeConductor has toggled
* into or out of follow mode.
* @property {boolean} followMode true if follow mode is
* enabled, otherwise false.
*/
this.emit('follow', this.followMode);
}
return this.followMode;
};
/**
* @typedef {Object} TimeConductorBounds
* @property {number} start The start time displayed by the time conductor in ms since epoch. Epoch determined by current time system
* @property {number} end The end time displayed by the time conductor in ms since epoch.
*/
/**
* Get or set the start and end time of the time conductor. Basic validation
* of bounds is performed.
*
* @param {TimeConductorBounds} newBounds
* @throws {Error} Validation error
* @fires TimeConductor#bounds
* @returns {TimeConductorBounds}
*/
TimeConductor.prototype.bounds = function (newBounds) {
if (arguments.length > 0) {
var validationResult = this.validateBounds(newBounds);
if (validationResult !== true){
throw new Error(validationResult);
}
//Create a copy to avoid direct mutation of conductor bounds
this.boundsVal = JSON.parse(JSON.stringify(newBounds));
/**
* @event TimeConductor#bounds The start time, end time, or
* both have been updated
* @property {TimeConductorBounds} bounds
*/
this.emit('bounds', this.boundsVal);
}
//Return a copy to prevent direct mutation of time conductor bounds.
return JSON.parse(JSON.stringify(this.boundsVal));
};
/**
* Get or set the time system of the TimeConductor. Time systems determine
* units, epoch, and other aspects of time representation. When changing
* the time system in use, new valid bounds must also be provided.
* @param {TimeSystem} newTimeSystem
* @param {TimeConductorBounds} bounds
* @fires TimeConductor#timeSystem
* @returns {TimeSystem} The currently applied time system
*/
TimeConductor.prototype.timeSystem = function (newTimeSystem, bounds) {
if (arguments.length >= 2) {
this.system = newTimeSystem;
/**
* @event TimeConductor#timeSystem The time system used by the time
* conductor has changed. A change in Time System will always be
* followed by a bounds event specifying new query bounds
* @property {TimeSystem} The value of the currently applied
* Time System
* */
this.emit('timeSystem', this.system);
// Do something with bounds here. Try and convert between
// time systems? Or just set defaults when time system changes?
// eg.
this.bounds(bounds);
} else if (arguments.length === 1) {
throw new Error('Must set bounds when changing time system');
}
return this.system;
};
/**
* Get or set the Time of Interest. The Time of Interest is the temporal
* focus of the current view. It can be manipulated by the user from the
* time conductor or from other views.
* @fires TimeConductor#timeOfInterest
* @param newTOI
* @returns {number} the current time of interest
*/
TimeConductor.prototype.timeOfInterest = function (newTOI) {
if (arguments.length > 0) {
this.toi = newTOI;
/**
* @event TimeConductor#timeOfInterest The Time of Interest has moved.
* @property {number} Current time of interest
*/
this.emit('timeOfInterest', this.toi);
}
return this.toi;
};
return TimeConductor;
});

View File

@ -0,0 +1,110 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define(['./TimeConductor'], function (TimeConductor) {
describe("The Time Conductor", function () {
var tc,
timeSystem,
bounds,
eventListener,
toi,
follow;
beforeEach(function () {
tc = new TimeConductor();
timeSystem = {};
bounds = {start: 0, end: 0};
eventListener = jasmine.createSpy("eventListener");
toi = 111;
follow = true;
});
it("Supports setting and querying of time of interest and and follow mode", function () {
expect(tc.timeOfInterest()).not.toBe(toi);
tc.timeOfInterest(toi);
expect(tc.timeOfInterest()).toBe(toi);
expect(tc.follow()).not.toBe(follow);
tc.follow(follow);
expect(tc.follow()).toBe(follow);
});
it("Allows setting of valid bounds", function () {
bounds = {start: 0, end: 1};
expect(tc.bounds()).not.toBe(bounds);
expect(tc.bounds.bind(tc, bounds)).not.toThrow();
expect(tc.bounds()).toBe(bounds);
});
it("Disallows setting of invalid bounds", function () {
bounds = {start: 1, end: 0};
expect(tc.bounds()).not.toBe(bounds);
expect(tc.bounds.bind(tc, bounds)).toThrow();
expect(tc.bounds()).not.toBe(bounds);
bounds = {start: 1};
expect(tc.bounds()).not.toBe(bounds);
expect(tc.bounds.bind(tc, bounds)).toThrow();
expect(tc.bounds()).not.toBe(bounds);
});
it("Allows setting of time system with bounds", function () {
expect(tc.timeSystem()).not.toBe(timeSystem);
expect(tc.timeSystem.bind(tc, timeSystem, bounds)).not.toThrow();
expect(tc.timeSystem()).toBe(timeSystem);
});
it("Disallows setting of time system without bounds", function () {
expect(tc.timeSystem()).not.toBe(timeSystem);
expect(tc.timeSystem.bind(tc, timeSystem)).toThrow();
expect(tc.timeSystem()).not.toBe(timeSystem);
});
it("Emits an event when time system changes", function () {
expect(eventListener).not.toHaveBeenCalled();
tc.on("timeSystem", eventListener);
tc.timeSystem(timeSystem, bounds);
expect(eventListener).toHaveBeenCalledWith(timeSystem);
});
it("Emits an event when time of interest changes", function () {
expect(eventListener).not.toHaveBeenCalled();
tc.on("timeOfInterest", eventListener);
tc.timeOfInterest(toi);
expect(eventListener).toHaveBeenCalledWith(toi);
});
it("Emits an event when bounds change", function () {
expect(eventListener).not.toHaveBeenCalled();
tc.on("bounds", eventListener);
tc.bounds(bounds);
expect(eventListener).toHaveBeenCalledWith(bounds);
});
it("Emits an event when follow mode changes", function () {
expect(eventListener).not.toHaveBeenCalled();
tc.on("follow", eventListener);
tc.follow(follow);
expect(eventListener).toHaveBeenCalledWith(follow);
});
});
});

View File

@ -0,0 +1,92 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define(['./TickSource'], function (TickSource) {
/**
* @implements TickSource
* @constructor
*/
function LocalClock ($timeout, period) {
TickSource.call(this);
this.metadata = {
key: 'real-time',
cssclass: 'icon-clock',
label: 'Real-time',
name: 'Real-time Mode',
description: 'Monitor real-time streaming data as it comes in. The Time Conductor and displays will automatically advance themselves based on a UTC clock.'
};
this.period = period;
this.$timeout = $timeout;
this.timeoutHandle = undefined;
}
LocalClock.prototype = Object.create(TickSource.prototype);
LocalClock.prototype.start = function () {
this.timeoutHandle = this.$timeout(this.tick.bind(this), this.period);
};
LocalClock.prototype.stop = function () {
if (this.timeoutHandle) {
this.$timeout.cancel(this.timeoutHandle);
}
};
LocalClock.prototype.tick = function () {
var now = Date.now();
this.listeners.forEach(function (listener){
listener(now);
});
this.timeoutHandle = this.$timeout(this.tick.bind(this), this.period);
};
/**
* Register a listener for the local clock. When it ticks, the local
* clock will provide the current local system time
*
* @param listener
* @returns {function} a function for deregistering the provided listener
*/
LocalClock.prototype.listen = function (listener) {
var listeners = this.listeners;
listeners.push(listener);
if (listeners.length === 1){
this.start();
}
return function () {
listeners.splice(listeners.indexOf(listener));
if (listeners.length === 0) {
this.stop();
}
}.bind(this);
};
LocalClock.prototype.type = function () {
return 'clock';
};
return LocalClock;
});

View File

@ -0,0 +1,56 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define([], function () {
/**
* A tick source is an event generator such as a timing signal, or
* indicator of data availability, which can be used to advance the Time
* Conductor. Usage is simple, a listener registers a callback which is
* invoked when this source 'ticks'.
*
* @interface
* @constructor
*/
function TickSource () {
this.listeners = [];
}
/**
* @param callback Function to be called when this tick source ticks.
* @returns an 'unlisten' function that will remove the callback from
* the registered listeners
*/
TickSource.prototype.listen = function (callback) {
throw new Error('Not implemented');
};
/**
* What does this source tick on? A clock, or data availability.
* Information is required to support time conductor modes.
* @returns {string} type One of 'clock' or 'data'
*/
TickSource.prototype.type = function () {
throw new Error('Not implemented');
}
return TickSource;
});

View File

@ -0,0 +1,94 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define([], function () {
/**
* @interface
* @constructor
*/
function TimeSystem () {
/**
* @typedef TimeSystemMetadata
* @property {string} key
* @property {string} name
* @property {string} description
*
* @type {TimeSystemMetadata}
*/
this.metadata = undefined;
this._tickSources = [];
}
/**
* Time formats are defined as extensions. Time systems that implement
* this interface should provide an array of format keys supported by them.
*
* @returns {string[]} An array of time format keys
*/
TimeSystem.prototype.formats = function () {
throw new Error('Not implemented');
};
/**
* @typedef DeltaFormat
* @property {string} type the type of MctControl used to represent this
* field. Typically 'datetime-field' for UTC based dates, or 'textfield'
* otherwise
* @property {string} [format] An optional field specifying the
* Format to use for delta fields in this time system.
*/
/**
* Specifies a format for deltas in this time system.
*
* @returns {DeltaFormat} a delta format specifier
*/
TimeSystem.prototype.deltaFormat = function () {
throw new Error('Not implemented');
};
/**
* Returns the tick sources supported by this time system. Tick sources
* are event generators that can be used to advance the time conductor
* @returns {TickSource[]} The tick sources supported by this time system.
*/
TimeSystem.prototype.tickSources = function () {
throw new Error('Not implemented');
};
/**
*
* @returns {TimeSystemDefault[]} At least one set of default values for
* this time system.
*/
TimeSystem.prototype.defaults = function () {
throw new Error('Not implemented');
};
/**
* @return {boolean}
*/
TimeSystem.prototype.isUTCBased = function () {
return true;
};
return TimeSystem;
});

View File

@ -0,0 +1,123 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define(
[
"zepto",
"d3"
],
function ($, d3) {
/**
* The mct-conductor-axis renders a horizontal axis with regular
* labelled 'ticks'. It requires 'start' and 'end' integer values to
* be specified as attributes.
*/
function MCTConductorAxis(conductorService, formatService) {
var conductor = conductorService.conductor();
function link(scope, element, attrs, ngModelController) {
var target = element[0].firstChild,
height = target.offsetHeight,
padding = 1;
var vis = d3.select(target)
.append('svg:svg')
.attr('width', '100%')
.attr('height', height);
var xAxis = d3.axisTop();
// draw x axis with labels and move to the bottom of the chart area
var axisElement = vis.append("g")
.attr("transform", "translate(0," + (height - padding) + ")");
function setScale() {
var xScale = undefined;
var width = target.offsetWidth;
var timeSystem = conductor.timeSystem();
var bounds = conductor.bounds();
if (timeSystem.isUTCBased()) {
xScale = d3.scaleUtc();
xScale.domain([new Date(bounds.start), new Date(bounds.end)]);
} else {
xScale = d3.scaleLinear();
xScale.domain([bounds.start, bounds.end]);
}
xScale.range([padding, width - padding * 2]);
xAxis.scale(xScale);
axisElement.call(xAxis);
}
function changeTimeSystem(timeSystem) {
var key = timeSystem.formats()[0];
if (key !== undefined) {
var format = formatService.getFormat(key);
var b = conductor.bounds();
//Define a custom format function
xAxis.tickFormat(function (tickValue) {
// Normalize date representations to numbers
if (tickValue instanceof Date){
tickValue = tickValue.getTime();
}
return format.format(tickValue, {
min: b.start,
max: b.end
});
});
axisElement.call(xAxis);
}
}
scope.resize = setScale;
conductor.on('timeSystem', changeTimeSystem);
//On conductor bounds changes, redraw ticks
conductor.on('bounds', function (bounds) {
setScale();
});
setScale();
if (conductor.timeSystem() !== undefined) {
changeTimeSystem(conductor.timeSystem());
}
}
return {
// Only show at the element level
restrict: "E",
template: "<div class=\"l-axis-holder\" mct-resize=\"resize()\"></div>",
// ngOptions is terminal, so we need to be higher priority
priority: 1000,
// Link function
link: link
};
}
return MCTConductorAxis;
}
);

View File

@ -0,0 +1,57 @@
/*****************************************************************************
* Open MCT, Copyright (c) 2014-2016, United States Government
* as represented by the Administrator of the National Aeronautics and Space
* Administration. All rights reserved.
*
* Open MCT is licensed under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0.
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
* Open MCT includes source code licensed under additional open source
* licenses. See the Open Source Licenses file (LICENSES.md) included with
* this source code distribution or the Licensing information page available
* at runtime from the About dialog for additional information.
*****************************************************************************/
define([
'moment'
], function (
moment
) {
/**
* Formatter for basic numbers. Provides basic support for non-UTC
* numbering systems
*
* @implements {Format}
* @constructor
* @memberof platform/commonUI/formats
*/
function NumberFormat() {
}
NumberFormat.prototype.format = function (value) {
if (isNaN(value)){
return '';
} else {
return '' + value;
}
};
NumberFormat.prototype.parse = function (text) {
return parseFloat(text);
};
NumberFormat.prototype.validate = function (text) {
return !isNaN(text);
};
return NumberFormat;
});

View File

@ -0,0 +1,345 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define(
[
'./modes/FixedMode',
'./modes/FollowMode',
'./TimeConductorValidation'
],
function (FixedMode, FollowMode, TimeConductorValidation) {
function TimeConductorController($scope, conductorService, timeSystems) {
var self = this;
//Bind all class functions to 'this'
Object.keys(TimeConductorController.prototype).filter(function (key) {
return typeof TimeConductorController.prototype[key] === 'function';
}).forEach(function (key) {
self[key] = self[key].bind(self);
});
this.conductorService = conductorService;
this.conductor = conductorService.conductor();
this.conductor.on('bounds', this.setBounds);
this.conductor.on('follow', function (follow){
$scope.followMode = follow;
});
// Construct the provided time system definitions
this._timeSystems = timeSystems.map(function (timeSystemConstructor){
return timeSystemConstructor();
});
this.modes = {
'fixed': {
cssclass: 'icon-calendar',
label: 'Fixed',
name: 'Fixed Timespan Mode',
description: 'Query and explore data that falls between two fixed datetimes.'
}
};
//Only show 'real-time mode' if a clock source is available
if (this.timeSystemsForSourceType('clock').length > 0 ) {
this.modes['realtime'] = {
cssclass: 'icon-clock',
label: 'Real-time',
name: 'Real-time Mode',
tickSourceType: 'clock',
description: 'Monitor real-time streaming data as it comes in. The Time Conductor and displays will automatically advance themselves based on a UTC clock.'
};
}
//Only show 'real-time mode' if a clock source is available
if (this.timeSystemsForSourceType('data').length > 0) {
this.modes['latest'] = {
cssclass: 'icon-database',
label: 'LAD',
name: 'LAD Mode',
tickSourceType: 'data',
description: 'Latest Available Data mode monitors real-time streaming data as it comes in. The Time Conductor and displays will only advance when data becomes available.'
};
}
this.validation = new TimeConductorValidation(this.conductor);
this.$scope = $scope;
/*
Set time Conductor bounds in the form
*/
$scope.formModel = this.conductor.bounds();
/*
Represents the various time system options, and the currently
selected time system in the view. Additionally holds the
default format from the selected time system for convenience
of access from the template.
*/
$scope.timeSystemModel = {};
if (this.conductor.timeSystem()) {
$scope.timeSystemModel.selected = this.conductor.timeSystem();
$scope.timeSystemModel.format = this.conductor.timeSystem().formats()[0];
$scope.timeSystemModel.deltaFormat = this.conductor.timeSystem().deltaFormat();
}
/*
Represents the various modes, and the currently
selected mode in the view
*/
$scope.modeModel = {
options: this.modes
};
var mode = conductorService.mode();
if (mode) {
$scope.modeModel.selectedKey = mode.key();
var deltas = mode.deltas && mode.deltas();
if (deltas) {
$scope.formModel.startDelta = deltas.start;
$scope.formModel.endDelta = deltas.end;
}
// Show filtered list of time systems available for the
// current mode
var tickSourceType = this.modes[mode.key()].tickSourceType;
$scope.timeSystemModel.options = this.timeSystemsForSourceType(tickSourceType).map(function (t) {
return t.metadata;
});
} else {
// Default to fixed mode
this.setMode('fixed');
}
$scope.$watch('modeModel.selectedKey', this.setMode);
$scope.$watch('timeSystem', this.setTimeSystem);
}
/**
* Called when the bounds change in the time conductor. Synchronizes
* the bounds values in the time conductor with those in the form
* @param bounds
*/
TimeConductorController.prototype.setBounds = function (bounds) {
this.$scope.formModel.start = bounds.start;
this.$scope.formModel.end = bounds.end;
if (!this.pendingUpdate) {
this.pendingUpdate = true;
requestAnimationFrame(function () {
this.pendingUpdate = false;
this.$scope.$digest();
}.bind(this));
}
};
/**
* Called when form values are changed. Synchronizes the form with
* the time conductor
* @param formModel
*/
TimeConductorController.prototype.updateBoundsFromForm = function (formModel) {
var newBounds = {
start: formModel.start,
end: formModel.end
};
if (this.conductor.validateBounds(newBounds) === true) {
this.conductor.bounds(newBounds);
}
};
/**
* Called when the delta values in the form change. Validates and
* sets the new deltas on the Mode.
* @param formModel
* @see TimeConductorMode
*/
TimeConductorController.prototype.updateDeltasFromForm = function (formModel) {
var mode = this.conductorService.mode(),
deltas = mode.deltas();
if (deltas !== undefined && this.validation.validateDeltas(formModel.startDelta, formModel.endDelta)) {
//Sychronize deltas between form and mode
mode.deltas({start: parseFloat(formModel.startDelta), end: parseFloat(formModel.endDelta)});
}
};
/**
* @private
*/
TimeConductorController.prototype.timeSystemsForSourceType = function(type){
if (!type) {
return this._timeSystems;
} else {
return this._timeSystems.filter(function (timeSystem){
return timeSystem.tickSources().some(function (tickSource){
return tickSource.type() === type;
});
});
}
};
TimeConductorController.prototype.selectTickSource = function (timeSystem, sourceType) {
return timeSystem.tickSources().filter(function (source){
return source.type() === sourceType;
})[0];
}
/**
* Change the selected Time Conductor mode. This will call destroy
* and initialization functions on the relevant modes, setting
* default values for bound and deltas in the form.
* @param newModeKey
* @param oldModeKey
*/
TimeConductorController.prototype.setMode = function (newModeKey, oldModeKey) {
if (newModeKey !== oldModeKey) {
var newMode = undefined;
var timeSystems = [];
var timeSystem = undefined;
var $scope = this.$scope;
var tickSourceType = this.modes[newModeKey].tickSourceType;
this.$scope.modeModel.selectedKey = newModeKey;
if (this.conductorService.mode()) {
this.conductorService.mode().destroy();
}
switch (newModeKey) {
case 'fixed':
timeSystems = this._timeSystems;
timeSystem = timeSystems[0];
newMode = new FixedMode(this.conductor, timeSystem, newModeKey);
break;
case 'realtime':
// Filter time systems to only those with clock tick
// sources
timeSystems = this.timeSystemsForSourceType(tickSourceType);
//Retain currently selected time system if available
timeSystem = timeSystems.filter(function (t) {
return t.metadata.key === $scope.timeSystemModel.selected.metadata.key;
})[0];
//Default to first available time system
timeSystem = timeSystem || timeSystems[0];
newMode = new FollowMode(this.conductor, timeSystem, newModeKey);
newMode.tickSource(this.selectTickSource(timeSystem, tickSourceType));
break;
case 'latest':
// Filter time systems to only those with data tick
// sources
timeSystems = this.timeSystemsForSourceType(tickSourceType);
//Retain currently selected time system if available
timeSystem = timeSystems.filter(function (t) {
return t.metadata.key === $scope.timeSystemModel.selected.metadata.key;
})[0];
//Default to first available time system
timeSystem = timeSystem || timeSystems[0];
newMode = new FollowMode(this.conductor, timeSystem, newModeKey);
newMode.tickSource(this.selectTickSource(timeSystem, tickSourceType));
break;
}
newMode.initialize();
this.setDeltasFromDefaults(newMode.defaults());
this.conductorService.mode(newMode);
//Synchronize scope with time system on mode
this.$scope.timeSystemModel.options = timeSystems.map(function (t) {
return t.metadata;
});
this.setTimeSystem(timeSystem);
}
};
/**
* @private
*/
TimeConductorController.prototype.setDeltasFromDefaults = function (defaults) {
var deltas = defaults.deltas;
/*
* If the selected mode defines deltas, set them in the form
*/
if (deltas !== undefined) {
this.$scope.formModel.startDelta = deltas.start;
this.$scope.formModel.endDelta = deltas.end;
} else {
this.$scope.formModel.startDelta = 0;
this.$scope.formModel.endDelta = 0;
}
};
/**
* Allows time system to be changed by key. This supports selection
* from the menu. Resolves a TimeSystem object and then invokes
* TimeConductorController#setTimeSystem
* @param key
* @see TimeConductorController#setTimeSystem
*/
TimeConductorController.prototype.selectTimeSystemByKey = function(key){
var selected = this._timeSystems.find(function (timeSystem){
return timeSystem.metadata.key === key;
});
this.setTimeSystem(selected);
};
/**
* Sets the selected time system. Will populate form with the default
* bounds and deltas defined in the selected time system.
* @param newTimeSystem
*/
TimeConductorController.prototype.setTimeSystem = function (newTimeSystem) {
if (newTimeSystem && newTimeSystem !== this.$scope.timeSystemModel.selected) {
var mode = this.conductorService.mode();
mode.timeSystem(newTimeSystem);
var defaults = mode.defaults();
this.$scope.timeSystemModel.selected = newTimeSystem;
this.$scope.timeSystemModel.format = newTimeSystem.formats()[0];
this.$scope.timeSystemModel.deltaFormat = newTimeSystem.deltaFormat();
this.setDeltasFromDefaults(defaults);
// If current mode supports ticking, set an appropriate tick
// source from the new time system
if (mode.tickSource) {
var tickSourceType = this.modes[mode.key()].tickSourceType;
mode.tickSource(this.selectTickSource(newTimeSystem, tickSourceType));
}
}
};
return TimeConductorController;
}
);

View File

@ -0,0 +1,45 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define(
['../TimeConductor'],
function (TimeConductor) {
function TimeConductorService() {
this._conductor = new TimeConductor();
this._mode = undefined;
}
TimeConductorService.prototype.mode = function (mode) {
if (arguments.length === 1) {
this._mode = mode;
}
return this._mode;
};
TimeConductorService.prototype.conductor = function () {
return this._conductor;
};
return TimeConductorService;
}
);

View File

@ -0,0 +1,79 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define(
[],
function () {
/**
* Form validation for the TimeConductorController.
* @param conductor
* @constructor
*/
function TimeConductorValidation(conductor) {
var self = this;
this.conductor = conductor
/*
* Bind all class functions to 'this'
*/
Object.keys(TimeConductorValidation.prototype).filter(function (key) {
return typeof TimeConductorValidation.prototype[key] === 'function';
}).forEach(function (key) {
self[key] = self[key].bind(self);
});
}
TimeConductorValidation.prototype.validateStart = function (start) {
var bounds = this.conductor.bounds();
return this.conductor.validateBounds({start: start, end: bounds.end}) === true;
};
TimeConductorValidation.prototype.validateEnd = function (end) {
var bounds = this.conductor.bounds();
return this.conductor.validateBounds({start: bounds.start, end: end}) === true;
};
TimeConductorValidation.prototype.validateStartDelta = function (startDelta) {
return !isNaN(startDelta) && startDelta > 0;
};
TimeConductorValidation.prototype.validateEndDelta = function (endDelta) {
return !isNaN(endDelta) && endDelta >= 0;
};
/**
* Validates the delta values in the form model. Deltas are offsets
* from a fixed point in time, and are used in follow modes as the
* primary determinant of conductor bounds.
* @param formModel
* @returns {*}
*/
TimeConductorValidation.prototype.validateDeltas = function (startDelta, endDelta) {
// Validate that start Delta is some non-zero value, and that end
// delta is zero or positive (ie. 'now' or some time in the future).
return this.validateStartDelta(startDelta) && this.validateEndDelta(endDelta);
};
return TimeConductorValidation;
}
);

View File

@ -0,0 +1,70 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define(
['./TimeConductorMode'],
function (TimeConductorMode) {
/**
* Handles time conductor behavior when it is in 'fixed' mode. In
* fixed mode, the time conductor is bound by two dates and does not
* progress.
* @param conductor
* @param timeSystems
* @constructor
*/
function FixedMode(conductor, timeSystem, key) {
TimeConductorMode.call(this, conductor, timeSystem, key);
}
FixedMode.prototype = Object.create(TimeConductorMode.prototype);
FixedMode.prototype.initialize = function () {
TimeConductorMode.prototype.initialize.apply(this);
this.conductor.follow(false);
};
/**
* Defines behavior to occur when selected time system changes. In
* this case, sets default bounds on the time conductor.
* @param timeSystem
* @returns {*}
*/
FixedMode.prototype.timeSystem = function (timeSystem){
TimeConductorMode.prototype.timeSystem.apply(this, arguments);
if (timeSystem) {
var defaults = this.defaults();
var bounds = {
start: defaults.bounds.start,
end: defaults.bounds.end
};
this.conductor.timeSystem(timeSystem, bounds);
}
return this._timeSystem;
};
return FixedMode;
}
);

View File

@ -0,0 +1,149 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define(
['./TimeConductorMode'],
function (TimeConductorMode) {
/**
* A parent class for Realtime and LAD modes, which both advance the
* time conductor bounds over time. The event that advances the time
* conductor is abstracted to a TickSource. Unlike FixedMode, the
* two 'follow' modes define 'deltas' which are offsets from a fixed
* end point. Thus, in follow mode, the end time of the conductor is
* the mode relevant, with both offsets defined relative to it.
* @constructor
*/
function FollowMode(conductor, timeSystem, key) {
TimeConductorMode.call(this, conductor, timeSystem, key);
this._deltas = undefined;
this._tickSource = undefined;
this._tickSourceUnlisten = undefined;
}
FollowMode.prototype = Object.create(TimeConductorMode.prototype);
FollowMode.prototype.initialize = function () {
TimeConductorMode.prototype.initialize.apply(this);
this.conductor.follow(true);
};
/**
* @private
* @param time
*/
FollowMode.prototype.tick = function (time) {
var deltas = this.deltas();
this.conductor.bounds({
start: time - deltas.start,
end: time + deltas.end
});
};
/**
* Get or set tick source. Setting tick source will also start
* listening to it and unlisten from any existing tick source
* @param tickSource
* @returns {TickSource}
*/
FollowMode.prototype.tickSource = function (tickSource) {
if (tickSource) {
if (this._tickSourceUnlisten) {
this._tickSourceUnlisten();
}
this._tickSource = tickSource;
this._tickSourceUnlisten = tickSource.listen(this.tick.bind(this));
}
return this._tickSource;
};
/**
* On time system change, default the bounds values in the time
* conductor, using the deltas associated with this mode.
* @param timeSystem
* @returns {TimeSystem}
*/
FollowMode.prototype.timeSystem = function (timeSystem) {
TimeConductorMode.prototype.timeSystem.apply(this, arguments);
if (timeSystem) {
var defaults = this.defaults();
if (arguments.length > 0) {
var bounds = {
start: defaults.bounds.start,
end: defaults.bounds.end
};
if (defaults.deltas) {
bounds.start = bounds.end - defaults.deltas.start;
bounds.end = bounds.end + defaults.deltas.end;
this._deltas = JSON.parse(JSON.stringify(defaults.deltas));
}
this.conductor.timeSystem(timeSystem, bounds);
}
}
return this._timeSystem;
};
/**
* Get or set the current value for the deltas used by this time system.
* On change, the new deltas will be used to calculate and set the
* bounds on the time conductor.
* @param deltas
* @returns {TimeSystemDeltas}
*/
FollowMode.prototype.deltas = function (deltas) {
if (arguments.length !== 0) {
var oldEnd = this.conductor.bounds().end;
if (this._deltas && this._deltas.end){
//Calculate the previous 'true' end value (without delta)
oldEnd = oldEnd - this._deltas.end;
}
this._deltas = deltas;
var newBounds = {
start: oldEnd - this._deltas.start,
end: oldEnd + this._deltas.end
};
this.conductor.bounds(newBounds);
}
return this._deltas;
};
/**
* Stop listening to tick sources
*/
FollowMode.prototype.destroy = function () {
if (this._tickSourceUnlisten) {
this._tickSourceUnlisten();
}
};
return FollowMode;
}
);

View File

@ -0,0 +1,79 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define(
[],
function () {
/**
* Supports mode-specific time conductor behavior. This class
* defines a parent with default behavior that specific modes are
* expected to override.
*
* @interface
* @constructor
* @param {TimeConductorMetadata} metadata
*/
function TimeConductorMode(conductor, timeSystem, key) {
this.conductor = conductor;
this._timeSystem = timeSystem;
this._key = key;
}
/**
* Function is called when mode becomes active (ie. is selected)
*/
TimeConductorMode.prototype.initialize = function () {
this.timeSystem(this._timeSystem);
};
/**
* Get or set the currently selected time system
* @param timeSystem
* @returns {TimeSystem} the currently selected time system
*/
TimeConductorMode.prototype.timeSystem = function (timeSystem) {
if (arguments.length > 0) {
this._timeSystem = timeSystem;
}
return this._timeSystem;
};
TimeConductorMode.prototype.key = function () {
return this._key;
};
TimeConductorMode.prototype.defaults = function () {
var timeSystem = this.timeSystem(),
key = this.key();
if (timeSystem) {
return timeSystem.defaults(key);
}
};
TimeConductorMode.prototype.destroy = function () {
};
return TimeConductorMode;
}
);

View File

@ -0,0 +1,40 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define([
"./src/UTCTimeSystem",
'legacyRegistry'
], function (
UTCTimeSystem,
legacyRegistry
) {
legacyRegistry.register("platform/features/conductor-v2/utcTimeSystem", {
"extensions": {
"timeSystems": [
{
"implementation": UTCTimeSystem,
"depends": ["$timeout"]
}
]
}
});
});

View File

@ -0,0 +1,78 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
define([
'../../conductor/src/timeSystems/TimeSystem',
'../../conductor/src/timeSystems/LocalClock'
], function (TimeSystem, LocalClock) {
var FIFTEEN_MINUTES = 15 * 60 * 1000,
DEFAULT_PERIOD = 1000;
/**
* This time system supports UTC dates and provides a ticking clock source.
* @implements TimeSystem
* @constructor
*/
function UTCTimeSystem ($timeout) {
TimeSystem.call(this);
/**
* Some metadata, which will be used to identify the time system in
* the UI
* @type {{key: string, name: string, cssclass: string}}
*/
this.metadata = {
'key': 'utc',
'name': 'UTC',
'cssclass': 'icon-clock'
};
this._formats = ['utc'];
this._tickSources = [new LocalClock($timeout, DEFAULT_PERIOD)];
}
UTCTimeSystem.prototype = Object.create(TimeSystem.prototype);
UTCTimeSystem.prototype.formats = function () {
return this._formats;
};
UTCTimeSystem.prototype.deltaFormat = function () {
return 'duration';
};
UTCTimeSystem.prototype.tickSources = function () {
return this._tickSources;
};
UTCTimeSystem.prototype.defaults = function (key) {
var now = Math.ceil(Date.now() / 1000) * 1000;
return {
key: 'utc-default',
name: 'UTC time system defaults',
deltas: {start: FIFTEEN_MINUTES, end: 0},
bounds: {start: now - FIFTEEN_MINUTES, end: now}
};
};
return UTCTimeSystem;
});

View File

@ -47,6 +47,11 @@ define([
]
}
],
"stylesheets": [
{
"stylesheetUrl": "css/time-conductor.css"
}
],
"components": [
{
"type": "decorator",

View File

@ -0,0 +1,300 @@
/*****************************************************************************
* Open MCT Web, Copyright (c) 2014-2015, 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.
*****************************************************************************/
@import "bourbon";
@import "../../../../commonUI/general/res/sass/constants";
@import "../../../../commonUI/general/res/sass/mixins";
@import "../../../../commonUI/general/res/sass/mobile/constants";
@import "../../../../commonUI/general/res/sass/mobile/mixins";
@import "../../../../commonUI/themes/espresso/res/sass/constants";
@import "../../../../commonUI/themes/espresso/res/sass/mixins";
$ueTimeConductorH: (33px, 18px, 20px);
@mixin toiLineHovEffects() {
&:before,
&:after {
background-color: $timeControllerToiLineColorHov;
}
}
.l-time-controller {
$minW: 500px;
$knobHOffset: 0px;
$knobM: ($sliderKnobW + $knobHOffset) * -1;
$rangeValPad: $interiorMargin;
$rangeValOffset: $sliderKnobW + $interiorMargin;
$timeRangeSliderLROffset: 150px + ($sliderKnobW * 2);
$r1H: nth($ueTimeConductorH,1);
$r2H: nth($ueTimeConductorH,2);
$r3H: nth($ueTimeConductorH,3);
min-width: $minW;
font-size: 0.8rem;
.l-time-range-inputs-holder,
.l-time-range-slider-holder,
.l-time-range-ticks-holder
{
box-sizing: border-box;
position: relative;
&:not(:first-child) {
margin-top: $interiorMargin;
}
}
.l-time-range-slider,
.l-time-range-ticks {
@include absPosDefault(0, visible);
left: $timeRangeSliderLROffset; right: $timeRangeSliderLROffset;
}
.l-time-range-inputs-holder {
border-top: 1px solid $colorInteriorBorder;
padding-top: $interiorMargin;
&.l-flex-row,
.l-flex-row {
@include align-items(center);
.flex-elem {
height: auto;
line-height: normal;
}
}
.type-icon {
font-size: 120%;
vertical-align: middle;
}
.l-time-range-input-w,
.l-time-range-inputs-elem {
margin-right: $interiorMargin;
.lbl {
color: $colorPlotLabelFg;
}
.ui-symbol.icon {
font-size: 11px;
}
}
.l-time-range-input-w {
// Wraps a datetime text input field
position: relative;
input[type="text"] {
width: 200px;
&.picker-icon {
padding-right: 20px;
}
}
.icon-calendar {
position: absolute;
right: 5px;
top: 5px;
}
}
}
.l-time-range-slider-holder {
height: $r2H;
.range-holder {
box-shadow: none;
background: none;
border: none;
.range {
.toi-line {
$myC: $timeControllerToiLineColor;
$myW: 8px;
@include transform(translateX(50%));
position: absolute;
top: 0; right: 0; bottom: 0px; left: auto;
width: $myW;
height: auto;
z-index: 2;
&:before {
// Vert line
background-color: $myC;
position: absolute;
content: "";
top: 0; right: auto; bottom: -10px; left: floor($myW/2) - 1;
width: 1px;
}
}
&:hover .toi-line {
@include toiLineHovEffects;
}
}
}
&:not(:active) {
.knob,
.range {
@include transition-property(left, right);
@include transition-duration(500ms);
@include transition-timing-function(ease-in-out);
}
}
}
.l-time-range-ticks-holder {
height: $r3H;
.l-time-range-ticks {
border-top: 1px solid $colorTick;
.tick {
background-color: $colorTick;
border:none;
height: 5px;
width: 1px;
margin-left: -1px;
position: absolute;
&:first-child {
margin-left: 0;
}
.l-time-range-tick-label {
@include webkitProp(transform, translateX(-50%));
color: $colorPlotLabelFg;
display: inline-block;
font-size: 0.7rem;
position: absolute;
top: 5px;
white-space: nowrap;
z-index: 2;
}
}
}
}
.knob {
z-index: 2;
&:before {
$mTB: 2px;
$grippyW: 3px;
$mLR: ($sliderKnobW - $grippyW)/2;
@include bgStripes($c: pullForward($sliderColorKnob, 20%), $a: 1, $bgsize: 4px, $angle: 0deg);
content: '';
display: block;
position: absolute;
top: $mTB; right: $mLR; bottom: $mTB; left: $mLR;
}
.range-value {
@include trans-prop-nice-fade(.25s);
font-size: 0.7rem;
position: absolute;
height: $r2H;
line-height: $r2H;
white-space: nowrap;
z-index: 1;
}
&:hover {
.range-value {
color: $sliderColorKnobHov;
}
}
&.knob-l {
margin-left: $knobM;
.range-value {
text-align: right;
right: $rangeValOffset;
}
}
&.knob-r {
margin-right: $knobM;
.range-value {
left: $rangeValOffset;
}
&:hover + .range-holder .range .toi-line {
@include toiLineHovEffects;
}
}
}
.l-time-domain-selector {
position: absolute;
right: 0px;
top: $interiorMargin;
}
}
.s-time-range-val {
border-radius: $controlCr;
background-color: $colorInputBg;
padding: 1px 1px 0 $interiorMargin;
}
/******************************************************************** MOBILE */
@include phoneandtablet {
.l-time-controller {
min-width: 0;
.l-time-range-slider-holder,
.l-time-range-ticks-holder {
display: none;
}
}
}
@include phone {
.l-time-controller {
.l-time-range-inputs-holder {
&.l-flex-row,
.l-flex-row {
@include align-items(flex-start);
}
.l-time-range-inputs-elem {
&.type-icon {
margin-top: 3px;
}
}
.t-inputs-w,
.l-time-range-inputs-elem {
@include flex-direction(column);
.l-time-range-input-w:not(:first-child) {
&:not(:first-child) {
margin-top: $interiorMargin;
}
margin-right: 0;
}
.l-time-range-inputs-elem {
&.lbl { display: none; }
}
}
}
}
}
@include phonePortrait {
.l-time-controller {
.l-time-range-inputs-holder {
.t-inputs-w,
.l-time-range-inputs-elem {
@include flex(1 1 auto);
padding-top: 25px; // Make room for the ever lovin' Time Domain Selector
.flex-elem {
@include flex(1 1 auto);
width: 100%;
}
input[type="text"] {
width: 100%;
}
}
}
}
.l-time-domain-selector {
right: auto;
left: 20px;
}
}

View File

@ -26,11 +26,10 @@
ng-repeat="childObject in composition"
ng-style="controller.getFrameStyle(childObject.getId())">
<div class="frame child-frame holder contents abs">
<mct-representation key="'frame'"
mct-object="childObject">
</mct-representation>
</div>
<mct-representation key="'frame'"
class="frame child-frame holder contents abs"
mct-object="childObject">
</mct-representation>
<!-- Drag handles -->
<span ng-show="domainObject.hasCapability('editor')">

View File

@ -227,13 +227,19 @@ define(
}
// Respond to a display bounds change (requery for data)
function changeDisplayBounds(event, bounds) {
var domainAxis = $scope.axes[0];
function changeDisplayBounds(event, bounds, follow) {
//'hack' for follow mode
if (follow === true){
setBasePanZoom(bounds);
} else {
var domainAxis = $scope.axes[0];
domainAxis.chooseOption(bounds.domain);
updateDomainFormat();
setBasePanZoom(bounds);
requery();
domainAxis.chooseOption(bounds.domain);
updateDomainFormat();
setBasePanZoom(bounds);
requery();
}
self.updateStatus($scope.domainObject, follow);
}
this.modeOptions = new PlotModeOptions([], subPlotFactory);
@ -364,6 +370,12 @@ define(
return this.pending;
};
PlotController.prototype.updateStatus = function (domainObject, follow) {
if (domainObject.hasCapability('status')) {
domainObject.getCapability('status').set('timeconductor-unsynced', follow && this.isZoomed());
}
};
return PlotController;
}
);

View File

@ -63,6 +63,28 @@ define(
this.$scope.loading = false;
};
/**
* @private
*/
HistoricalTableController.prototype.registerChangeListeners = function () {
TableController.prototype.registerChangeListeners.call(this);
//Change of bounds in time conductor
this.changeListeners.push(this.$scope.$on('telemetry:display:bounds',
this.boundsChange.bind(this))
);
};
/**
* @private
*/
HistoricalTableController.prototype.boundsChange = function (event, bounds, follow) {
// If in follow mode, don't bother re-subscribing, data will be
// received from existing subscription.
if (follow!==true) {
this.subscribe();
}
};
/**
* Processes an array of objects, formatting the telemetry available
* for them and setting it on scope when done

View File

@ -96,11 +96,6 @@ define(
}
})
);
//Change of bounds in time conductor
this.changeListeners.push(this.$scope.$on('telemetry:display:bounds',
this.subscribe.bind(this))
);
};
/**

View File

@ -24,6 +24,7 @@
<input type="text"
ng-required="ngRequired"
ng-model="ngModel[field]"
ng-blur="ngBlur()"
ng-pattern="ngPattern"
size="{{structure.size}}"
name="mctControl">

View File

@ -71,6 +71,9 @@ define(
// Allow controls to trigger blur-like events
ngBlur: "&",
// Allow controls to trigger blur-like events
ngMouseup: "&",
// The state of the form value itself
ngModel: "=",

View File

@ -54,13 +54,14 @@ requirejs.config({
"angular-route": "bower_components/angular-route/angular-route.min",
"csv": "bower_components/comma-separated-values/csv.min",
"es6-promise": "bower_components/es6-promise/promise.min",
"EventEmitter": "bower_components/eventemitter3/index",
"moment": "bower_components/moment/moment",
"moment-duration-format": "bower_components/moment-duration-format/lib/moment-duration-format",
"saveAs": "bower_components/FileSaver.js/FileSaver.min",
"screenfull": "bower_components/screenfull/dist/screenfull.min",
"text": "bower_components/text/text",
"uuid": "bower_components/node-uuid/uuid",
"zepto": "bower_components/zepto/zepto.min"
"zepto": "bower_components/zepto/zepto.min",
},
"shim": {
@ -70,6 +71,9 @@ requirejs.config({
"angular-route": {
"deps": [ "angular" ]
},
"EventEmitter": {
"exports": "EventEmitter"
},
"moment-duration-format": {
"deps": [ "moment" ]
},