diff --git a/platform/commonUI/general/res/fonts/symbols/icomoon-project-openmct-symbols-16px.json b/platform/commonUI/general/res/fonts/symbols/icomoon-project-openmct-symbols-16px.json
index 68f8f5ea5e..22c74333b8 100644
--- a/platform/commonUI/general/res/fonts/symbols/icomoon-project-openmct-symbols-16px.json
+++ b/platform/commonUI/general/res/fonts/symbols/icomoon-project-openmct-symbols-16px.json
@@ -811,6 +811,14 @@
"id": 29,
"code": 921897,
"tempChar": ""
+ },
+ {
+ "order": 121,
+ "prevSize": 24,
+ "name": "icon-stop",
+ "id": 89,
+ "code": 921637,
+ "tempChar": ""
}
],
"metadata": {
@@ -3085,6 +3093,31 @@
{}
]
}
+ },
+ {
+ "paths": [
+ "M0 0h24v24H0z"
+ ],
+ "grid": 16,
+ "tags": [
+ "icon-stop"
+ ],
+ "defaultCode": 114,
+ "id": 89,
+ "attrs": [
+ {
+ "fill": "rgb(0, 161, 75)"
+ }
+ ],
+ "isMulticolor": false,
+ "isMulticolor2": false,
+ "colorPermutations": {
+ "1161751207457516161751": [
+ {
+ "f": 1
+ }
+ ]
+ }
}
],
"colorThemes": [
diff --git a/platform/commonUI/general/res/fonts/symbols/openmct-symbols-16px.svg b/platform/commonUI/general/res/fonts/symbols/openmct-symbols-16px.svg
index 0a33d43fa3..458504f884 100755
--- a/platform/commonUI/general/res/fonts/symbols/openmct-symbols-16px.svg
+++ b/platform/commonUI/general/res/fonts/symbols/openmct-symbols-16px.svg
@@ -107,4 +107,5 @@
+
\ No newline at end of file
diff --git a/platform/commonUI/general/res/sass/_glyphs.scss b/platform/commonUI/general/res/sass/_glyphs.scss
index c8a369e6e7..8ea5e3c704 100644
--- a/platform/commonUI/general/res/sass/_glyphs.scss
+++ b/platform/commonUI/general/res/sass/_glyphs.scss
@@ -107,6 +107,7 @@ $glyph-icon-timeline: '\e1126';
$glyph-icon-timer: '\e1127';
$glyph-icon-topic: '\e1128';
$glyph-icon-box-with-dashed-lines: '\e1129';
+$glyph-icon-stop: '\e1130';
/************************** 16 PX CLASSES */
@@ -210,6 +211,7 @@ $glyph-icon-box-with-dashed-lines: '\e1129';
.icon-timer { @include glyph($glyph-icon-timer); }
.icon-topic { @include glyph($glyph-icon-topic); }
.icon-box-with-dashed-lines { @include glyph($glyph-icon-box-with-dashed-lines); }
+.icon-stop { @include glyph($glyph-icon-stop); }
/************************** 12 PX CLASSES */
diff --git a/platform/features/clock/bundle.js b/platform/features/clock/bundle.js
index 5699527e36..8dae9c07ba 100644
--- a/platform/features/clock/bundle.js
+++ b/platform/features/clock/bundle.js
@@ -28,6 +28,7 @@ define([
"./src/controllers/RefreshingController",
"./src/actions/StartTimerAction",
"./src/actions/RestartTimerAction",
+ "./src/actions/StopTimerAction",
"text!./res/templates/clock.html",
"text!./res/templates/timer.html",
'legacyRegistry'
@@ -39,6 +40,7 @@ define([
RefreshingController,
StartTimerAction,
RestartTimerAction,
+ StopTimerAction,
clockTemplate,
timerTemplate,
legacyRegistry
@@ -149,6 +151,17 @@ define([
"name": "Restart at 0",
"cssclass": "icon-refresh",
"priority": "preferred"
+ },
+ {
+ "key": "timer.stop",
+ "implementation": StopTimerAction,
+ "depends": [
+ "now"
+ ],
+ "category": "contextual",
+ "name": "Stop",
+ "cssclass": "icon-box",
+ "priority": "preferred"
}
],
"types": [
diff --git a/platform/features/clock/src/actions/StopTimerAction.js b/platform/features/clock/src/actions/StopTimerAction.js
new file mode 100644
index 0000000000..1c56d7a1e0
--- /dev/null
+++ b/platform/features/clock/src/actions/StopTimerAction.js
@@ -0,0 +1,73 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2009-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(
+ ['./AbstractTimerAction'],
+ function (AbstractTimerAction) {
+
+ /**
+ * Implements the "Start" action for timers.
+ *
+ * Sets the reference timestamp in a timer to the current
+ * time, such that it begins counting up.
+ *
+ * @extends {platform/features/clock.AbstractTimerAction}
+ * @implements {Action}
+ * @memberof platform/features/clock
+ * @constructor
+ * @param {Function} now a function which returns the current
+ * time (typically wrapping `Date.now`)
+ * @param {ActionContext} context the context for this action
+ */
+ function StopTimerAction(now, context) {
+ AbstractTimerAction.apply(this, [now, context]);
+ }
+
+ StopTimerAction.prototype =
+ Object.create(AbstractTimerAction.prototype);
+
+ StopTimerAction.appliesTo = function (context) {
+ var model =
+ (context.domainObject && context.domainObject.getModel()) ||
+ {};
+
+
+ // We show this variant for timers which do not yet have
+ // a target time.
+ return model.type === 'timer' &&
+ model.timestamp !== undefined;
+ };
+
+ StopTimerAction.prototype.perform = function () {
+ var domainObject = this.domainObject;
+
+ function setTimestamp(model) {
+ model.timestamp = undefined;
+ }
+
+ return domainObject.useCapability('mutation', setTimestamp);
+ };
+
+ return StopTimerAction;
+
+ }
+);
diff --git a/platform/features/clock/test/actions/StopTimerActionSpec.js b/platform/features/clock/test/actions/StopTimerActionSpec.js
new file mode 100644
index 0000000000..6b86a0bdcf
--- /dev/null
+++ b/platform/features/clock/test/actions/StopTimerActionSpec.js
@@ -0,0 +1,86 @@
+/*****************************************************************************
+ * Open MCT, Copyright (c) 2009-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(
+ ["../../src/actions/StopTimerAction"],
+ function (StopTimerAction) {
+
+ describe("A timer's stop action", function () {
+ var mockNow,
+ mockDomainObject,
+ testModel,
+ testContext,
+ action;
+
+ function asPromise(value) {
+ return (value || {}).then ? value : {
+ then: function (callback) {
+ return asPromise(callback(value));
+ }
+ };
+ }
+
+ beforeEach(function () {
+ mockNow = jasmine.createSpy('now');
+ mockDomainObject = jasmine.createSpyObj(
+ 'domainObject',
+ ['getCapability', 'useCapability', 'getModel']
+ );
+
+ mockDomainObject.useCapability.andCallFake(function (c, v) {
+ if (c === 'mutation') {
+ testModel = v(testModel) || testModel;
+ return asPromise(true);
+ }
+ });
+ mockDomainObject.getModel.andCallFake(function () {
+ return testModel;
+ });
+
+ testModel = {};
+ testContext = { domainObject: mockDomainObject };
+
+ action = new StopTimerAction(mockNow, testContext);
+ });
+
+ it("updates the model with a timestamp", function () {
+ mockNow.andReturn(12000);
+ action.perform();
+ expect(testModel.timestamp).toEqual(12000);
+ });
+
+ it("applies only to timers without a target time", function () {
+ testModel.type = 'timer';
+ testModel.timestamp = 12000;
+ expect(StopTimerAction.appliesTo(testContext)).toBeTruthy();
+
+ testModel.type = 'timer';
+ testModel.timestamp = undefined;
+ expect(StopTimerAction.appliesTo(testContext)).toBeFalsy();
+
+ testModel.type = 'clock';
+ testModel.timestamp = 12000;
+ expect(StopTimerAction.appliesTo(testContext)).toBeFalsy();
+ });
+ });
+ }
+);