From a7948ce83e3c903f3ee5cd9ba32670bb8fe7eaf1 Mon Sep 17 00:00:00 2001 From: Andrew Henry Date: Thu, 22 Nov 2018 15:53:50 -0800 Subject: [PATCH] Implemented context menu action registry --- src/MCT.js | 2 + src/api/api.js | 5 +- src/api/contextMenu/ContextMenuRegistry.js | 75 ++++++++++++++++++ .../displayLayout/DisplayLayoutToolbar.js | 2 +- src/selection/ContextManager.js | 78 ------------------- src/selection/HoverGesture.js | 58 -------------- src/selection/SelectGesture.js | 60 -------------- src/ui/components/controls/ContextMenu.vue | 25 ++---- src/ui/components/controls/ObjectLabel.vue | 5 +- 9 files changed, 93 insertions(+), 217 deletions(-) create mode 100644 src/api/contextMenu/ContextMenuRegistry.js delete mode 100644 src/selection/ContextManager.js delete mode 100644 src/selection/HoverGesture.js delete mode 100644 src/selection/SelectGesture.js diff --git a/src/MCT.js b/src/MCT.js index d937099cc4..0ed10e099b 100644 --- a/src/MCT.js +++ b/src/MCT.js @@ -222,6 +222,8 @@ define([ this.overlays = new OverlayAPI.default(); + this.contextMenu = new api.ContextMenuRegistry(); + this.legacyRegistry = defaultRegistry; this.install(this.plugins.Plot()); this.install(this.plugins.TelemetryTable()); diff --git a/src/api/api.js b/src/api/api.js index c609c83ea8..81717f587a 100644 --- a/src/api/api.js +++ b/src/api/api.js @@ -28,6 +28,7 @@ define([ './telemetry/TelemetryAPI', './indicators/IndicatorAPI', './notifications/NotificationAPI', + './contextMenu/ContextMenuRegistry', './Editor' ], function ( @@ -38,6 +39,7 @@ define([ TelemetryAPI, IndicatorAPI, NotificationAPI, + ContextMenuRegistry, EditorAPI ) { return { @@ -48,6 +50,7 @@ define([ TelemetryAPI: TelemetryAPI, IndicatorAPI: IndicatorAPI, NotificationAPI: NotificationAPI.default, - EditorAPI: EditorAPI + EditorAPI: EditorAPI, + ContextMenuRegistry: ContextMenuRegistry.default }; }); diff --git a/src/api/contextMenu/ContextMenuRegistry.js b/src/api/contextMenu/ContextMenuRegistry.js new file mode 100644 index 0000000000..57ff3d9944 --- /dev/null +++ b/src/api/contextMenu/ContextMenuRegistry.js @@ -0,0 +1,75 @@ +import ContextMenuComponent from '../../ui/components/controls/ContextMenu.vue'; +import Vue from 'vue'; + +class ContextMenuRegistry { + constructor() { + this._allActions = []; + this._activeContextMenu = undefined; + + this._hideActiveContextMenu = this._hideActiveContextMenu.bind(this); + } + + registerAction(actionDefinition) { + this._allActions.push(actionDefinition); + } + + attachTo(targetElement, objectPath) { + let showContextMenu = (event) => { + this._showContextMenuForObjectPath(event, objectPath); + }; + + targetElement.addEventListener('contextmenu', showContextMenu); + + return function detach() { + targetElement.removeEventListener('contextMenu', showContextMenu); + } + } + + /** + * @private + */ + _showContextMenuForObjectPath(event, objectPath) { + let applicableActions = this._allActions.filter( + (action) => action.appliesTo(objectPath)); + + event.preventDefault(); + + if (this._activeContextMenu) { + this._hideActiveContextMenu(); + } + + this._activeContextMenu = this._createContextMenuFromActions(applicableActions); + this._activeContextMenu.$mount(); + this._activeContextMenu.$el.style.left = `${event.clientX}px`; + this._activeContextMenu.$el.style.top = `${event.clientY}px`; + + document.body.appendChild(this._activeContextMenu.$el); + document.addEventListener('click', this._hideActiveContextMenu); + } + + /** + * @private + */ + _hideActiveContextMenu() { + document.removeEventListener('click', this._hideActiveContextMenu); + document.body.removeChild(this._activeContextMenu.$el); + this._activeContextMenu.$destroy(); + this._activeContextMenu = undefined; + } + + /** + * @private + */ + _createContextMenuFromActions(actions) { + return new Vue({ + components: { + ContextMenu: ContextMenuComponent + }, + provide: { + actions: actions + }, + template: '' + }); + } +} +export default ContextMenuRegistry; diff --git a/src/plugins/displayLayout/DisplayLayoutToolbar.js b/src/plugins/displayLayout/DisplayLayoutToolbar.js index 5c5206d4c7..1df3a42377 100644 --- a/src/plugins/displayLayout/DisplayLayoutToolbar.js +++ b/src/plugins/displayLayout/DisplayLayoutToolbar.js @@ -148,4 +148,4 @@ define([], function () { } return DisplayLayoutToolbar; -}); \ No newline at end of file +}); diff --git a/src/selection/ContextManager.js b/src/selection/ContextManager.js deleted file mode 100644 index 942d8d8f6b..0000000000 --- a/src/selection/ContextManager.js +++ /dev/null @@ -1,78 +0,0 @@ -/***************************************************************************** - * Open MCT, Copyright (c) 2014-2018, United States Government - * as represented by the Administrator of the National Aeronautics and Space - * Administration. All rights reserved. - * - * Open MCT is licensed under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Open MCT includes source code licensed under additional open source - * licenses. See the Open Source Licenses file (LICENSES.md) included with - * this source code distribution or the Licensing information page available - * at runtime from the About dialog for additional information. - *****************************************************************************/ - -define(['zepto'], function ($) { - /** - * @typedef Context - * @property {*} item - * @property {HTMLElement} element - * @property {Context} parent the containing context (may be undefined) - * @memberof module:openmct - */ - - - function ContextManager() { - this.counter = 0; - this.contexts = {}; - } - - ContextManager.prototype.nextId = function () { - this.counter += 1; - return "context-" + this.counter; - }; - - ContextManager.prototype.context = function (item, htmlElement) { - var $element = $(htmlElement); - var id = $element.attr('data-context') || this.nextId(); - - $element.attr('data-context', id); - - if (this.contexts[id] && this.contexts[id].item !== item) { - this.release(htmlElement); - } - - if (!this.contexts[id]) { - var $parent = $element.closest('[data-context]'); - var parentId = $parent.attr('data-context'); - var parentContext = parentId ? this.contexts[parentId] : undefined; - this.contexts[id] = { - item: item, - element: htmlElement, - parent: parentContext - }; - } - - return this.contexts[id]; - }; - - ContextManager.prototype.release = function (htmlElement) { - var $element = $(htmlElement); - var id = $element.attr('data-context'); - - if (id) { - delete this.contexts[id]; - $element.removeAttr('data-context'); - } - }; - - return ContextManager; -}); diff --git a/src/selection/HoverGesture.js b/src/selection/HoverGesture.js deleted file mode 100644 index e11680fdaa..0000000000 --- a/src/selection/HoverGesture.js +++ /dev/null @@ -1,58 +0,0 @@ -/***************************************************************************** - * Open MCT, Copyright (c) 2014-2018, United States Government - * as represented by the Administrator of the National Aeronautics and Space - * Administration. All rights reserved. - * - * Open MCT is licensed under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Open MCT includes source code licensed under additional open source - * licenses. See the Open Source Licenses file (LICENSES.md) included with - * this source code distribution or the Licensing information page available - * at runtime from the About dialog for additional information. - *****************************************************************************/ - -define(['zepto'], function ($) { - function HoverGesture(hoverManager) { - this.hoverManager = hoverManager; - } - - HoverGesture.prototype.apply = function (htmlElement) { - var $element = $(htmlElement); - var hoverManager = this.hoverManager; - - function update() { - $(hoverManager.all()).removeClass('hovering'); - $(hoverManager.top()).addClass('hovering'); - } - - function enter() { - hoverManager.add(htmlElement); - update(); - } - - function leave() { - hoverManager.remove(htmlElement); - update(); - } - - $element.on('mouseenter', enter); - $element.on('mouseleave', leave); - - return function () { - leave(); - $element.off('mouseenter', enter); - $element.off('mouseleave', leave); - }.bind(this); - }; - - return HoverGesture; -}); diff --git a/src/selection/SelectGesture.js b/src/selection/SelectGesture.js deleted file mode 100644 index 1fe2db0e0d..0000000000 --- a/src/selection/SelectGesture.js +++ /dev/null @@ -1,60 +0,0 @@ -/***************************************************************************** - * Open MCT, Copyright (c) 2014-2018, United States Government - * as represented by the Administrator of the National Aeronautics and Space - * Administration. All rights reserved. - * - * Open MCT is licensed under the Apache License, Version 2.0 (the - * "License"); you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * http://www.apache.org/licenses/LICENSE-2.0. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations - * under the License. - * - * Open MCT includes source code licensed under additional open source - * licenses. See the Open Source Licenses file (LICENSES.md) included with - * this source code distribution or the Licensing information page available - * at runtime from the About dialog for additional information. - *****************************************************************************/ - -define(['zepto'], function ($) { - function SelectGesture(selection, contextManager) { - this.selection = selection; - this.contextManager = contextManager; - } - - SelectGesture.prototype.apply = function (htmlElement, item) { - var $element = $(htmlElement); - var contextManager = this.contextManager; - var selection = this.selection; - var path = contextManager.path(item, htmlElement); - - function select() { - selection.add(path); - } - - function change() { - var selected = selection.primary(); - $element.toggleClass( - 'selected', - selected && path.matches(selected) - ); - } - - $element.addClass('selectable'); - $element.on('click', select); - selection.on('change', change); - change(); // Initialize - - return function () { - contextManager.release(htmlElement); - $element.off('click', select); - selection.off('change', change); - }; - }; - - return SelectGesture; -}); diff --git a/src/ui/components/controls/ContextMenu.vue b/src/ui/components/controls/ContextMenu.vue index c52fc040f1..aabc02f488 100644 --- a/src/ui/components/controls/ContextMenu.vue +++ b/src/ui/components/controls/ContextMenu.vue @@ -1,29 +1,20 @@ \ No newline at end of file diff --git a/src/ui/components/controls/ObjectLabel.vue b/src/ui/components/controls/ObjectLabel.vue index 866eab6d09..edf7e834bc 100644 --- a/src/ui/components/controls/ObjectLabel.vue +++ b/src/ui/components/controls/ObjectLabel.vue @@ -11,11 +11,10 @@