mirror of
https://github.com/nasa/openmct.git
synced 2025-06-16 14:18:16 +00:00
[Plugins] Bring over timeline, clock plugins
WTD-1239
This commit is contained in:
79
platform/features/clock/src/controllers/ClockController.js
Normal file
79
platform/features/clock/src/controllers/ClockController.js
Normal file
@ -0,0 +1,79 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
['moment'],
|
||||
function (moment) {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Controller for views of a Clock domain object.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function ClockController($scope, tickerService) {
|
||||
var text,
|
||||
ampm,
|
||||
use24,
|
||||
lastTimestamp,
|
||||
unlisten,
|
||||
timeFormat;
|
||||
|
||||
function update() {
|
||||
var m = moment.utc(lastTimestamp);
|
||||
text = timeFormat && m.format(timeFormat);
|
||||
ampm = m.format("A"); // Just the AM or PM part
|
||||
}
|
||||
|
||||
function tick(timestamp) {
|
||||
lastTimestamp = timestamp;
|
||||
update();
|
||||
}
|
||||
|
||||
function updateFormat(clockFormat) {
|
||||
var baseFormat;
|
||||
|
||||
if (clockFormat !== undefined) {
|
||||
baseFormat = clockFormat[0];
|
||||
|
||||
use24 = clockFormat[1] === 'clock24';
|
||||
timeFormat = use24 ?
|
||||
baseFormat.replace('hh', "HH") : baseFormat;
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
// Pull in the clock format from the domain object model
|
||||
$scope.$watch('model.clockFormat', updateFormat);
|
||||
|
||||
// Listen for clock ticks ... and stop listening on destroy
|
||||
unlisten = tickerService.listen(tick);
|
||||
$scope.$on('$destroy', unlisten);
|
||||
|
||||
return {
|
||||
/**
|
||||
* Get the clock's time zone, as displayable text.
|
||||
* @returns {string}
|
||||
*/
|
||||
zone: function () {
|
||||
return "UTC";
|
||||
},
|
||||
/**
|
||||
* Get the current time, as displayable text.
|
||||
* @returns {string}
|
||||
*/
|
||||
text: function () {
|
||||
return text;
|
||||
},
|
||||
/**
|
||||
* Get the text to display to qualify a time as AM or PM.
|
||||
* @returns {string}
|
||||
*/
|
||||
ampm: function () {
|
||||
return use24 ? '' : ampm;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return ClockController;
|
||||
}
|
||||
);
|
@ -0,0 +1,29 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
[],
|
||||
function () {
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
* Continually refreshes the represented domain object.
|
||||
*
|
||||
* This is a short-term workaround to assure Timer views stay
|
||||
* up-to-date; should be replaced by a global auto-refresh.
|
||||
*/
|
||||
function RefreshingController($scope, tickerService) {
|
||||
var unlisten;
|
||||
|
||||
function triggerRefresh() {
|
||||
var persistence = $scope.domainObject &&
|
||||
$scope.domainObject.getCapability('persistence');
|
||||
return persistence && persistence.refresh();
|
||||
}
|
||||
|
||||
unlisten = tickerService.listen(triggerRefresh);
|
||||
$scope.$on('$destroy', unlisten);
|
||||
}
|
||||
|
||||
return RefreshingController;
|
||||
}
|
||||
);
|
146
platform/features/clock/src/controllers/TimerController.js
Normal file
146
platform/features/clock/src/controllers/TimerController.js
Normal file
@ -0,0 +1,146 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
['./TimerFormatter'],
|
||||
function (TimerFormatter) {
|
||||
"use strict";
|
||||
|
||||
var FORMATTER = new TimerFormatter();
|
||||
|
||||
|
||||
/**
|
||||
* Controller for views of a Timer domain object.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function TimerController($scope, $window, now) {
|
||||
var timerObject,
|
||||
relevantAction,
|
||||
sign = '',
|
||||
text = '',
|
||||
formatter,
|
||||
active = true,
|
||||
relativeTimestamp,
|
||||
lastTimestamp;
|
||||
|
||||
function update() {
|
||||
var timeDelta = lastTimestamp - relativeTimestamp;
|
||||
|
||||
if (formatter && !isNaN(timeDelta)) {
|
||||
text = formatter(timeDelta);
|
||||
sign = timeDelta < 0 ? "-" : timeDelta >= 1000 ? "+" : "";
|
||||
} else {
|
||||
text = "";
|
||||
sign = "";
|
||||
}
|
||||
}
|
||||
|
||||
function updateFormat(key) {
|
||||
formatter = FORMATTER[key] || FORMATTER.long;
|
||||
}
|
||||
|
||||
function updateTimestamp(timestamp) {
|
||||
relativeTimestamp = timestamp;
|
||||
}
|
||||
|
||||
function updateObject(domainObject) {
|
||||
var model = domainObject.getModel(),
|
||||
timestamp = model.timestamp,
|
||||
formatKey = model.timerFormat,
|
||||
actionCapability = domainObject.getCapability('action'),
|
||||
actionKey = (timestamp === undefined) ?
|
||||
'warp.timer.start' : 'warp.timer.restart';
|
||||
|
||||
updateFormat(formatKey);
|
||||
updateTimestamp(timestamp);
|
||||
|
||||
relevantAction = actionCapability &&
|
||||
actionCapability.getActions(actionKey)[0];
|
||||
|
||||
update();
|
||||
}
|
||||
|
||||
function handleObjectChange(domainObject) {
|
||||
if (domainObject) {
|
||||
updateObject(domainObject);
|
||||
}
|
||||
}
|
||||
|
||||
function handleModification() {
|
||||
handleObjectChange($scope.domainObject);
|
||||
}
|
||||
|
||||
function tick() {
|
||||
var lastSign = sign, lastText = text;
|
||||
lastTimestamp = now();
|
||||
update();
|
||||
// We're running in an animation frame, not in a digest cycle.
|
||||
// We need to trigger a digest cycle if our displayable data
|
||||
// changes.
|
||||
if (lastSign !== sign || lastText !== text) {
|
||||
$scope.$apply();
|
||||
}
|
||||
if (active) {
|
||||
$window.requestAnimationFrame(tick);
|
||||
}
|
||||
}
|
||||
|
||||
$window.requestAnimationFrame(tick);
|
||||
|
||||
// Pull in the timer format from the domain object model
|
||||
$scope.$watch('domainObject', handleObjectChange);
|
||||
$scope.$watch('model.modified', handleModification);
|
||||
|
||||
// When the scope is destroyed, stop requesting anim. frames
|
||||
$scope.$on('$destroy', function () {
|
||||
active = false;
|
||||
});
|
||||
|
||||
return {
|
||||
/**
|
||||
* Get the glyph to display for the start/restart button.
|
||||
* @returns {string} glyph to display
|
||||
*/
|
||||
buttonGlyph: function () {
|
||||
return relevantAction ?
|
||||
relevantAction.getMetadata().glyph : "";
|
||||
},
|
||||
/**
|
||||
* Get the text to show for the start/restart button
|
||||
* (e.g. in a tooltip)
|
||||
* @returns {string} name of the action
|
||||
*/
|
||||
buttonText: function () {
|
||||
return relevantAction ?
|
||||
relevantAction.getMetadata().name : "";
|
||||
},
|
||||
/**
|
||||
* Perform the action associated with the start/restart button.
|
||||
*/
|
||||
clickButton: function () {
|
||||
if (relevantAction) {
|
||||
relevantAction.perform();
|
||||
updateObject($scope.domainObject);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* Get the sign (+ or -) of the current timer value, as
|
||||
* displayable text.
|
||||
* @returns {string} sign of the current timer value
|
||||
*/
|
||||
sign: function () {
|
||||
return sign;
|
||||
},
|
||||
/**
|
||||
* Get the text to display for the current timer value.
|
||||
* @returns {string} current timer value
|
||||
*/
|
||||
text: function () {
|
||||
return text;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
return TimerController;
|
||||
}
|
||||
);
|
60
platform/features/clock/src/controllers/TimerFormatter.js
Normal file
60
platform/features/clock/src/controllers/TimerFormatter.js
Normal file
@ -0,0 +1,60 @@
|
||||
/*global define*/
|
||||
|
||||
define(
|
||||
['moment', 'moment-duration-format'],
|
||||
function (moment) {
|
||||
"use strict";
|
||||
|
||||
var SHORT_FORMAT = "HH:mm:ss",
|
||||
LONG_FORMAT = "d[D] HH:mm:ss";
|
||||
|
||||
/**
|
||||
* Provides formatting functions for Timers.
|
||||
*
|
||||
* Display formats for timers are a little different from what
|
||||
* moment.js provides, so we have custom logic here. This specifically
|
||||
* supports `TimerController`.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
function TimerFormatter() {
|
||||
|
||||
// Round this timestamp down to the second boundary
|
||||
// (e.g. 1124ms goes down to 1000ms, -2400ms goes down to -3000ms)
|
||||
function toWholeSeconds(duration) {
|
||||
return Math.abs(Math.floor(duration / 1000) * 1000);
|
||||
}
|
||||
|
||||
// Short-form format, e.g. 02:22:11
|
||||
function short(duration) {
|
||||
return moment.duration(toWholeSeconds(duration), 'ms')
|
||||
.format(SHORT_FORMAT, { trim: false });
|
||||
}
|
||||
|
||||
// Long-form format, e.g. 3d 02:22:11
|
||||
function long(duration) {
|
||||
return moment.duration(toWholeSeconds(duration), 'ms')
|
||||
.format(LONG_FORMAT, { trim: false });
|
||||
}
|
||||
|
||||
return {
|
||||
/**
|
||||
* Format a duration for display, using the short form.
|
||||
* (e.g. 03:33:11)
|
||||
* @param {number} duration the duration, in milliseconds
|
||||
* @param {boolean} sign true if positive
|
||||
*/
|
||||
short: short,
|
||||
/**
|
||||
* Format a duration for display, using the long form.
|
||||
* (e.g. 0d 03:33:11)
|
||||
* @param {number} duration the duration, in milliseconds
|
||||
* @param {boolean} sign true if positive
|
||||
*/
|
||||
long: long
|
||||
};
|
||||
}
|
||||
|
||||
return TimerFormatter;
|
||||
}
|
||||
);
|
Reference in New Issue
Block a user