mirror of
https://github.com/nasa/openmct.git
synced 2025-02-22 10:11:06 +00:00
Vue toolbar (#2191)
* Add a toolbar provider for display layout. * Move toolbar provider to the plugin * basic toolbar generation * componentize different toolbar control types Break toolbar control types down into different parts and provide a test toolbar generator in index.html that utilizes all the controls. * Get the 'Show frame' checkbox working in the toolbar * - Remove extra listener. - Display toolbar only when editing. * Modify the Selection API to set s-selected and s-selected-parent attributes instead of adding to the css class names. * Move the logic for allowing the toolbar in the edit mode to the provider. * Use toggle-button component to toggle frame * Delete old files * Remove MCTToolbar * Modify the toggle button component to return the computed value * Remove reload=true * Revert to the original setting * use value from props * Always update toolbars on edit status change * restore fixed position bundle * bring back reload when hmr unavailable
This commit is contained in:
parent
64b9d4c24a
commit
d48cc2deee
2
app.js
2
app.js
@ -46,7 +46,7 @@ webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin());
|
|||||||
webpackConfig.plugins.push(function() { this.plugin('watch-run', function(watching, callback) { console.log('Begin compile at ' + new Date()); callback(); }) });
|
webpackConfig.plugins.push(function() { this.plugin('watch-run', function(watching, callback) { console.log('Begin compile at ' + new Date()); callback(); }) });
|
||||||
|
|
||||||
webpackConfig.entry.openmct = [
|
webpackConfig.entry.openmct = [
|
||||||
'webpack-hot-middleware/client',
|
'webpack-hot-middleware/client?reload=true',
|
||||||
webpackConfig.entry.openmct
|
webpackConfig.entry.openmct
|
||||||
];
|
];
|
||||||
|
|
||||||
|
198
index.html
198
index.html
@ -79,5 +79,203 @@
|
|||||||
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
|
openmct.time.clock('local', {start: -THIRTY_MINUTES, end: 0});
|
||||||
openmct.time.timeSystem('utc');
|
openmct.time.timeSystem('utc');
|
||||||
openmct.start();
|
openmct.start();
|
||||||
|
|
||||||
|
// openmct.toolbars.addProvider({
|
||||||
|
// name: "Testing Toolbar",
|
||||||
|
// key: "testing",
|
||||||
|
// description: "a mock toolbar that exercises all controls",
|
||||||
|
// forSelection: function (selection) {
|
||||||
|
// return true; // always applies.
|
||||||
|
// },
|
||||||
|
// toolbar: function (selection) {
|
||||||
|
// return [
|
||||||
|
// {
|
||||||
|
// control: 'menu',
|
||||||
|
// icon: 'icon-plus',
|
||||||
|
// label: 'Add',
|
||||||
|
// options: [
|
||||||
|
// { name: 'Box', class: 'icon-box', title: 'Add Box' },
|
||||||
|
// { name: 'Line', class: 'icon-line-horz', title: 'Add Line' },
|
||||||
|
// { name: 'Text', class: 'icon-font', title: 'Add Text' },
|
||||||
|
// { name: 'Image', class: 'icon-image', title: 'Add Image' }
|
||||||
|
// ]
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'separator'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'color-picker',
|
||||||
|
// icon: 'icon-paint-bucket',
|
||||||
|
// value: '#33ff00',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'color-picker',
|
||||||
|
// icon: 'icon-pencil',
|
||||||
|
// value: '#ffffff',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'color-picker',
|
||||||
|
// icon: 'icon-font',
|
||||||
|
// value: '#333333',
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// control: 'separator'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'select-menu',
|
||||||
|
// value: 11,
|
||||||
|
// options: [
|
||||||
|
// { value: 9, name: '9 px' },
|
||||||
|
// { value: 10, name: '10 px' },
|
||||||
|
// { value: 11, name: '11 px' },
|
||||||
|
// { value: 12, name: '12 px' },
|
||||||
|
// { value: 13, name: '13 px' },
|
||||||
|
// { value: 14, name: '14 px' },
|
||||||
|
// { value: 16, name: '16 px' },
|
||||||
|
// { value: 18, name: '18 px' },
|
||||||
|
// { value: 20, name: '20 px' },
|
||||||
|
// { value: 24, name: '24 px' },
|
||||||
|
// { value: 28, name: '28 px' },
|
||||||
|
// { value: 32, name: '32 px' },
|
||||||
|
// { value: 40, name: '40 px' },
|
||||||
|
// { value: 48, name: '48 px' },
|
||||||
|
// { value: 56, name: '56 px' },
|
||||||
|
// { value: 64, name: '64 px' },
|
||||||
|
// { value: 72, name: '72 px' },
|
||||||
|
// { value: 80, name: '80 px' },
|
||||||
|
// { value: 88, name: '88 px' },
|
||||||
|
// { value: 96, name: '96 px' },
|
||||||
|
// { value: 128, name: '128 px' },
|
||||||
|
// { value: 160, name: '160 px' }
|
||||||
|
// ]
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// control: 'separator'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'menu',
|
||||||
|
// icon: 'icon-layers',
|
||||||
|
// options: [
|
||||||
|
// { name: 'Move to top', class: 'icon-arrow-double-up', title: 'Move to top' },
|
||||||
|
// { name: 'Move up', class: 'icon-arrow-up', title: 'Move up' },
|
||||||
|
// { name: 'Move down', class: 'icon-arrow-down', title: 'Move down' },
|
||||||
|
// { name: 'Move to bottom', class: 'icon-arrow-double-down', title: 'Move to bottom' }
|
||||||
|
// ]
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// control: 'separator'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'button',
|
||||||
|
// icon: 'icon-gear'
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// control: 'separator'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'input',
|
||||||
|
// type: 'number',
|
||||||
|
// label: 'X',
|
||||||
|
// value: 1,
|
||||||
|
// title: 'X position'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'input',
|
||||||
|
// type: 'number',
|
||||||
|
// label: 'Y',
|
||||||
|
// value: 2,
|
||||||
|
// title: 'Y position'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'input',
|
||||||
|
// type: 'number',
|
||||||
|
// label: 'W',
|
||||||
|
// value: 3,
|
||||||
|
// title: 'Width'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'input',
|
||||||
|
// type: 'number',
|
||||||
|
// label: 'H',
|
||||||
|
// value: 4,
|
||||||
|
// title: 'Height'
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// control: 'separator'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'button',
|
||||||
|
// icon: 'icon-trash',
|
||||||
|
// label: 'delete',
|
||||||
|
// modifier: 'caution'
|
||||||
|
// },
|
||||||
|
//
|
||||||
|
// {
|
||||||
|
// control: 'separator'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'checkbox',
|
||||||
|
// name: 'this is a checkbox',
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'separator'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'toggle-button',
|
||||||
|
// title: 'Toggle Frame',
|
||||||
|
// property: 'hideFrame',
|
||||||
|
// value: false,
|
||||||
|
// options: [
|
||||||
|
// {
|
||||||
|
// value: true,
|
||||||
|
// icon: 'icon-frame-hide'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// value: false,
|
||||||
|
// icon: 'icon-frame-show'
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'toggle-button',
|
||||||
|
// title: 'Snap to grid',
|
||||||
|
// property: 'snapToGrid',
|
||||||
|
// value: true,
|
||||||
|
// options: [
|
||||||
|
// {
|
||||||
|
// value: true,
|
||||||
|
// icon: 'icon-grid-snap-to'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// value: false,
|
||||||
|
// icon: 'icon-grid-snap-no'
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// control: 'toggle-button',
|
||||||
|
// title: 'Toggle label',
|
||||||
|
// property: 'showLabel',
|
||||||
|
// value: true,
|
||||||
|
// options: [
|
||||||
|
// {
|
||||||
|
// value: true,
|
||||||
|
// icon: 'icon-two-parts-both'
|
||||||
|
// },
|
||||||
|
// {
|
||||||
|
// value: false,
|
||||||
|
// icon: 'icon-two-parts-one-only'
|
||||||
|
// }
|
||||||
|
// ]
|
||||||
|
// }
|
||||||
|
// ];
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
</html>
|
</html>
|
||||||
|
@ -1,254 +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(
|
|
||||||
[
|
|
||||||
'../../../../../src/api/objects/object-utils',
|
|
||||||
'lodash'
|
|
||||||
],
|
|
||||||
function (
|
|
||||||
objectUtils,
|
|
||||||
_
|
|
||||||
) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provides initial structure and state (as suitable for provision
|
|
||||||
* to the `mct-toolbar` directive) for a view's toolbar, based on
|
|
||||||
* that view's declaration of what belongs in its toolbar and on
|
|
||||||
* the current selection.
|
|
||||||
*
|
|
||||||
* @param $scope the Angular scope
|
|
||||||
* @param {Object} openmct the openmct object
|
|
||||||
* @param structure the toolbar structure
|
|
||||||
* @memberof platform/commonUI/edit
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function EditToolbar($scope, openmct, structure) {
|
|
||||||
this.toolbarStructure = [];
|
|
||||||
this.properties = [];
|
|
||||||
this.toolbarState = [];
|
|
||||||
this.openmct = openmct;
|
|
||||||
this.domainObjectsById = {};
|
|
||||||
this.unobserveObjects = [];
|
|
||||||
this.stateTracker = [];
|
|
||||||
|
|
||||||
$scope.$watchCollection(this.getState.bind(this), this.handleStateChanges.bind(this));
|
|
||||||
$scope.$on("$destroy", this.destroy.bind(this));
|
|
||||||
|
|
||||||
this.updateToolbar(structure);
|
|
||||||
this.registerListeners(structure);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates the toolbar with a new structure.
|
|
||||||
*
|
|
||||||
* @param {Array} structure the toolbar structure
|
|
||||||
*/
|
|
||||||
EditToolbar.prototype.updateToolbar = function (structure) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
function addKey(item) {
|
|
||||||
self.stateTracker.push({
|
|
||||||
id: objectUtils.makeKeyString(item.domainObject.identifier),
|
|
||||||
domainObject: item.domainObject,
|
|
||||||
property: item.property
|
|
||||||
});
|
|
||||||
self.properties.push(item.property);
|
|
||||||
|
|
||||||
return self.properties.length - 1; // Return index of property
|
|
||||||
}
|
|
||||||
|
|
||||||
function convertItem(item) {
|
|
||||||
var converted = Object.create(item || {});
|
|
||||||
|
|
||||||
if (item.property) {
|
|
||||||
converted.key = addKey(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (item.method) {
|
|
||||||
converted.click = function (value) {
|
|
||||||
item.method(value);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return converted;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get initial value for a given property
|
|
||||||
function initializeState(property) {
|
|
||||||
var result;
|
|
||||||
structure.forEach(function (item) {
|
|
||||||
if (item.property === property) {
|
|
||||||
result = _.get(item.domainObject, item.property);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Tracks the domain object and property for every element in the state array
|
|
||||||
this.stateTracker = [];
|
|
||||||
this.toolbarStructure = structure.map(convertItem);
|
|
||||||
this.toolbarState = this.properties.map(initializeState);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the structure of the toolbar, as appropriate to
|
|
||||||
* pass to `mct-toolbar`.
|
|
||||||
*
|
|
||||||
* @returns {Array} the toolbar structure
|
|
||||||
*/
|
|
||||||
EditToolbar.prototype.getStructure = function () {
|
|
||||||
return this.toolbarStructure;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the current state of the toolbar, as appropriate
|
|
||||||
* to two-way bind to the state handled by `mct-toolbar`.
|
|
||||||
*
|
|
||||||
* @returns {Array} state of the toolbar
|
|
||||||
*/
|
|
||||||
EditToolbar.prototype.getState = function () {
|
|
||||||
return this.toolbarState;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Mutates the domain object's property with a new value.
|
|
||||||
*
|
|
||||||
* @param {Object} dominObject the domain object
|
|
||||||
* @param {string} property the domain object's property to update
|
|
||||||
* @param value the property's new value
|
|
||||||
*/
|
|
||||||
EditToolbar.prototype.updateDomainObject = function (domainObject, property, value) {
|
|
||||||
this.openmct.objects.mutate(domainObject, property, value);
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Updates state with the new value.
|
|
||||||
*
|
|
||||||
* @param {number} index the index of the corresponding
|
|
||||||
* element in the state array
|
|
||||||
* @param value the new value to update the state array with
|
|
||||||
*/
|
|
||||||
EditToolbar.prototype.updateState = function (index, value) {
|
|
||||||
this.toolbarState[index] = value;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register listeners for domain objects to watch for updates.
|
|
||||||
*
|
|
||||||
* @param {Array} the toolbar structure
|
|
||||||
*/
|
|
||||||
EditToolbar.prototype.registerListeners = function (structure) {
|
|
||||||
var self = this;
|
|
||||||
|
|
||||||
function observeObject(domainObject, id) {
|
|
||||||
var unobserveObject = self.openmct.objects.observe(domainObject, '*', function (newObject) {
|
|
||||||
self.domainObjectsById[id].newObject = JSON.parse(JSON.stringify(newObject));
|
|
||||||
self.scheduleStateUpdate();
|
|
||||||
});
|
|
||||||
self.unobserveObjects.push(unobserveObject);
|
|
||||||
}
|
|
||||||
|
|
||||||
structure.forEach(function (item) {
|
|
||||||
var domainObject = item.domainObject;
|
|
||||||
var id = objectUtils.makeKeyString(domainObject.identifier);
|
|
||||||
|
|
||||||
if (!self.domainObjectsById[id]) {
|
|
||||||
self.domainObjectsById[id] = {
|
|
||||||
domainObject: domainObject,
|
|
||||||
properties: []
|
|
||||||
};
|
|
||||||
observeObject(domainObject, id);
|
|
||||||
}
|
|
||||||
|
|
||||||
self.domainObjectsById[id].properties.push(item.property);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delays updating the state.
|
|
||||||
*/
|
|
||||||
EditToolbar.prototype.scheduleStateUpdate = function () {
|
|
||||||
if (this.stateUpdateScheduled) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.stateUpdateScheduled = true;
|
|
||||||
setTimeout(this.updateStateAfterMutation.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
EditToolbar.prototype.updateStateAfterMutation = function () {
|
|
||||||
this.stateTracker.forEach(function (state, index) {
|
|
||||||
if (!this.domainObjectsById[state.id].newObject) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var domainObject = this.domainObjectsById[state.id].domainObject;
|
|
||||||
var newObject = this.domainObjectsById[state.id].newObject;
|
|
||||||
var currentValue = _.get(domainObject, state.property);
|
|
||||||
var newValue = _.get(newObject, state.property);
|
|
||||||
|
|
||||||
state.domainObject = newObject;
|
|
||||||
|
|
||||||
if (currentValue !== newValue) {
|
|
||||||
this.updateState(index, newValue);
|
|
||||||
}
|
|
||||||
}, this);
|
|
||||||
|
|
||||||
Object.values(this.domainObjectsById).forEach(function (tracker) {
|
|
||||||
if (tracker.newObject) {
|
|
||||||
tracker.domainObject = tracker.newObject;
|
|
||||||
}
|
|
||||||
delete tracker.newObject;
|
|
||||||
});
|
|
||||||
this.stateUpdateScheduled = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the listeners.
|
|
||||||
*/
|
|
||||||
EditToolbar.prototype.deregisterListeners = function () {
|
|
||||||
this.unobserveObjects.forEach(function (unobserveObject) {
|
|
||||||
unobserveObject();
|
|
||||||
});
|
|
||||||
this.unobserveObjects = [];
|
|
||||||
};
|
|
||||||
|
|
||||||
EditToolbar.prototype.handleStateChanges = function (state) {
|
|
||||||
(state || []).map(function (newValue, index) {
|
|
||||||
var domainObject = this.stateTracker[index].domainObject;
|
|
||||||
var property = this.stateTracker[index].property;
|
|
||||||
var currentValue = _.get(domainObject, property);
|
|
||||||
|
|
||||||
if (currentValue !== newValue) {
|
|
||||||
this.updateDomainObject(domainObject, property, newValue);
|
|
||||||
}
|
|
||||||
}, this);
|
|
||||||
};
|
|
||||||
|
|
||||||
EditToolbar.prototype.destroy = function () {
|
|
||||||
this.deregisterListeners();
|
|
||||||
};
|
|
||||||
|
|
||||||
return EditToolbar;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,75 +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(
|
|
||||||
['../../src/representers/EditToolbar'],
|
|
||||||
function (EditToolbar) {
|
|
||||||
|
|
||||||
describe("An Edit mode toolbar", function () {
|
|
||||||
var mockOpenMCT,
|
|
||||||
mockScope,
|
|
||||||
mockObjects,
|
|
||||||
mockDomainObject,
|
|
||||||
testStructure,
|
|
||||||
toolbar;
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockOpenMCT = jasmine.createSpy('openmct', ['objects']);
|
|
||||||
mockObjects = jasmine.createSpyObj('objects', ['observe']);
|
|
||||||
mockObjects.observe.and.returnValue();
|
|
||||||
mockOpenMCT.objects = mockObjects;
|
|
||||||
mockScope = jasmine.createSpyObj("$scope", [
|
|
||||||
"$watchCollection",
|
|
||||||
"$on"
|
|
||||||
]);
|
|
||||||
mockScope.$watchCollection.and.returnValue();
|
|
||||||
mockDomainObject = jasmine.createSpyObj("domainObject", [
|
|
||||||
'identifier'
|
|
||||||
]);
|
|
||||||
|
|
||||||
testStructure = [
|
|
||||||
{ name: "A", property: "a", domainObject: mockDomainObject },
|
|
||||||
{ name: "B", property: "b", domainObject: mockDomainObject },
|
|
||||||
{ name: "C", property: "c", domainObject: mockDomainObject },
|
|
||||||
{ name: "X", property: "x", domainObject: mockDomainObject },
|
|
||||||
{ name: "Y", property: "y", domainObject: mockDomainObject },
|
|
||||||
{ name: "Z", property: "z", domainObject: mockDomainObject },
|
|
||||||
{ name: "M", method: "m", domainObject: mockDomainObject }
|
|
||||||
];
|
|
||||||
|
|
||||||
toolbar = new EditToolbar(mockScope, mockOpenMCT, testStructure);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("adds click functions when a method is specified", function () {
|
|
||||||
var structure = toolbar.getStructure();
|
|
||||||
expect(structure[6].click).toBeDefined();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("adds key for controls that define a property", function () {
|
|
||||||
var structure = toolbar.getStructure();
|
|
||||||
expect(structure[0].key).toEqual(0);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
|
|
@ -21,10 +21,24 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
define([
|
define([
|
||||||
"../layout/res/templates/fixed.html",
|
"./src/FixedController",
|
||||||
'legacyRegistry'
|
"./templates/fixed.html",
|
||||||
|
"./templates/frame.html",
|
||||||
|
"./templates/elements/telemetry.html",
|
||||||
|
"./templates/elements/box.html",
|
||||||
|
"./templates/elements/line.html",
|
||||||
|
"./templates/elements/text.html",
|
||||||
|
"./templates/elements/image.html",
|
||||||
|
"legacyRegistry"
|
||||||
], function (
|
], function (
|
||||||
|
FixedController,
|
||||||
fixedTemplate,
|
fixedTemplate,
|
||||||
|
frameTemplate,
|
||||||
|
telemetryTemplate,
|
||||||
|
boxTemplate,
|
||||||
|
lineTemplate,
|
||||||
|
textTemplate,
|
||||||
|
imageTemplate,
|
||||||
legacyRegistry
|
legacyRegistry
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@ -39,10 +53,46 @@ define([
|
|||||||
"cssClass": "icon-box-with-dashed-lines",
|
"cssClass": "icon-box-with-dashed-lines",
|
||||||
"type": "telemetry.fixed",
|
"type": "telemetry.fixed",
|
||||||
"template": fixedTemplate,
|
"template": fixedTemplate,
|
||||||
"uses": [],
|
"uses": ["composition"],
|
||||||
"editable": true
|
"editable": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"templates": [
|
||||||
|
{
|
||||||
|
"key": "fixed.telemetry",
|
||||||
|
"template": telemetryTemplate
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "fixed.box",
|
||||||
|
"template": boxTemplate
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "fixed.line",
|
||||||
|
"template": lineTemplate
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "fixed.text",
|
||||||
|
"template": textTemplate
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"key": "fixed.image",
|
||||||
|
"template": imageTemplate
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"controllers": [
|
||||||
|
{
|
||||||
|
"key": "FixedController",
|
||||||
|
"implementation": FixedController,
|
||||||
|
"depends": [
|
||||||
|
"$scope",
|
||||||
|
"$q",
|
||||||
|
"dialogService",
|
||||||
|
"openmct",
|
||||||
|
"$element"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
"toolbars": [
|
"toolbars": [
|
||||||
{
|
{
|
||||||
name: "Fixed Position Toolbar",
|
name: "Fixed Position Toolbar",
|
||||||
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.5 KiB |
@ -1,356 +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([
|
|
||||||
"./src/LayoutController",
|
|
||||||
"./src/FixedController",
|
|
||||||
"./src/LayoutCompositionPolicy",
|
|
||||||
'./src/MCTTriggerModal',
|
|
||||||
"./res/templates/layout.html",
|
|
||||||
"./res/templates/fixed.html",
|
|
||||||
"./res/templates/frame.html",
|
|
||||||
"./res/templates/elements/telemetry.html",
|
|
||||||
"./res/templates/elements/box.html",
|
|
||||||
"./res/templates/elements/line.html",
|
|
||||||
"./res/templates/elements/text.html",
|
|
||||||
"./res/templates/elements/image.html",
|
|
||||||
'legacyRegistry'
|
|
||||||
], function (
|
|
||||||
LayoutController,
|
|
||||||
FixedController,
|
|
||||||
LayoutCompositionPolicy,
|
|
||||||
MCTTriggerModal,
|
|
||||||
layoutTemplate,
|
|
||||||
fixedTemplate,
|
|
||||||
frameTemplate,
|
|
||||||
telemetryTemplate,
|
|
||||||
boxTemplate,
|
|
||||||
lineTemplate,
|
|
||||||
textTemplate,
|
|
||||||
imageTemplate,
|
|
||||||
legacyRegistry
|
|
||||||
) {
|
|
||||||
|
|
||||||
legacyRegistry.register("platform/features/layout", {
|
|
||||||
"name": "Layout components.",
|
|
||||||
"description": "Plug in adding Layout capabilities.",
|
|
||||||
"extensions": {
|
|
||||||
"views": [
|
|
||||||
{
|
|
||||||
"key": "layout",
|
|
||||||
"name": "Display Layout",
|
|
||||||
"cssClass": "icon-layout",
|
|
||||||
"type": "layout",
|
|
||||||
"template": layoutTemplate,
|
|
||||||
"editable": true,
|
|
||||||
"uses": []
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "fixed",
|
|
||||||
"name": "Fixed Position",
|
|
||||||
"cssClass": "icon-box-with-dashed-lines",
|
|
||||||
"type": "telemetry.panel",
|
|
||||||
"template": fixedTemplate,
|
|
||||||
"uses": [
|
|
||||||
"composition"
|
|
||||||
],
|
|
||||||
"toolbar": {
|
|
||||||
"sections": [
|
|
||||||
{
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"method": "add",
|
|
||||||
"cssClass": "icon-plus",
|
|
||||||
"control": "menu-button",
|
|
||||||
"text": "Add",
|
|
||||||
"title": "Add",
|
|
||||||
"description": "Add new items",
|
|
||||||
"options": [
|
|
||||||
{
|
|
||||||
"name": "Box",
|
|
||||||
"cssClass": "icon-box",
|
|
||||||
"key": "fixed.box"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Line",
|
|
||||||
"cssClass": "icon-line-horz",
|
|
||||||
"key": "fixed.line"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Text",
|
|
||||||
"cssClass": "icon-T",
|
|
||||||
"key": "fixed.text"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Image",
|
|
||||||
"cssClass": "icon-image",
|
|
||||||
"key": "fixed.image"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"method": "order",
|
|
||||||
"cssClass": "icon-layers",
|
|
||||||
"control": "menu-button",
|
|
||||||
"title": "Layering",
|
|
||||||
"description": "Move the selected object above or below other objects",
|
|
||||||
"options": [
|
|
||||||
{
|
|
||||||
"name": "Move to Top",
|
|
||||||
"cssClass": "icon-arrow-double-up",
|
|
||||||
"key": "top"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Move Up",
|
|
||||||
"cssClass": "icon-arrow-up",
|
|
||||||
"key": "up"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Move Down",
|
|
||||||
"cssClass": "icon-arrow-down",
|
|
||||||
"key": "down"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Move to Bottom",
|
|
||||||
"cssClass": "icon-arrow-double-down",
|
|
||||||
"key": "bottom"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"property": "fill",
|
|
||||||
"cssClass": "icon-paint-bucket",
|
|
||||||
"title": "Fill color",
|
|
||||||
"description": "Set fill color",
|
|
||||||
"control": "color"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"property": "stroke",
|
|
||||||
"cssClass": "icon-line-horz",
|
|
||||||
"title": "Border color",
|
|
||||||
"description": "Set border color",
|
|
||||||
"control": "color"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"property": "color",
|
|
||||||
"cssClass": "icon-T",
|
|
||||||
"title": "Text color",
|
|
||||||
"description": "Set text color",
|
|
||||||
"mandatory": true,
|
|
||||||
"control": "color"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"property": "url",
|
|
||||||
"cssClass": "icon-image",
|
|
||||||
"control": "dialog-button",
|
|
||||||
"title": "Image Properties",
|
|
||||||
"description": "Edit image properties",
|
|
||||||
"dialog": {
|
|
||||||
"control": "textfield",
|
|
||||||
"name": "Image URL",
|
|
||||||
"cssClass": "l-input-lg",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"property": "text",
|
|
||||||
"cssClass": "icon-gear",
|
|
||||||
"control": "dialog-button",
|
|
||||||
"title": "Text Properties",
|
|
||||||
"description": "Edit text properties",
|
|
||||||
"dialog": {
|
|
||||||
"control": "textfield",
|
|
||||||
"name": "Text",
|
|
||||||
"required": true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"method": "showTitle",
|
|
||||||
"cssClass": "icon-two-parts-both",
|
|
||||||
"control": "button",
|
|
||||||
"title": "Show title",
|
|
||||||
"description": "Show telemetry element title"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"method": "hideTitle",
|
|
||||||
"cssClass": "icon-two-parts-one-only",
|
|
||||||
"control": "button",
|
|
||||||
"title": "Hide title",
|
|
||||||
"description": "Hide telemetry element title"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"method": "remove",
|
|
||||||
"control": "button",
|
|
||||||
"cssClass": "icon-trash",
|
|
||||||
"title": "Delete",
|
|
||||||
"description": "Delete the selected item"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"representations": [
|
|
||||||
{
|
|
||||||
"key": "frame",
|
|
||||||
"template": frameTemplate
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"directives": [
|
|
||||||
{
|
|
||||||
"key": "mctTriggerModal",
|
|
||||||
"implementation": MCTTriggerModal,
|
|
||||||
"depends": [
|
|
||||||
"$document"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"controllers": [
|
|
||||||
{
|
|
||||||
"key": "LayoutController",
|
|
||||||
"implementation": LayoutController,
|
|
||||||
"depends": [
|
|
||||||
"$scope",
|
|
||||||
"$element",
|
|
||||||
"openmct"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "FixedController",
|
|
||||||
"implementation": FixedController,
|
|
||||||
"depends": [
|
|
||||||
"$scope",
|
|
||||||
"$q",
|
|
||||||
"dialogService",
|
|
||||||
"openmct",
|
|
||||||
"$element"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"templates": [
|
|
||||||
{
|
|
||||||
"key": "fixed.telemetry",
|
|
||||||
"template": telemetryTemplate
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "fixed.box",
|
|
||||||
"template": boxTemplate
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "fixed.line",
|
|
||||||
"template": lineTemplate
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "fixed.text",
|
|
||||||
"template": textTemplate
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"key": "fixed.image",
|
|
||||||
"template": imageTemplate
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"policies": [
|
|
||||||
{
|
|
||||||
"category": "composition",
|
|
||||||
"implementation": LayoutCompositionPolicy
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"toolbars": [
|
|
||||||
{
|
|
||||||
name: "Display Layout Toolbar",
|
|
||||||
key: "layout",
|
|
||||||
description: "A toolbar for objects inside a display layout.",
|
|
||||||
forSelection: function (selection) {
|
|
||||||
// Apply the layout toolbar if the selected object is inside a layout.
|
|
||||||
return (selection && selection[1] && selection[1].context.item.type === 'layout');
|
|
||||||
},
|
|
||||||
toolbar: function (selection) {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
control: "checkbox",
|
|
||||||
name: "Show frame",
|
|
||||||
domainObject: selection[1].context.item,
|
|
||||||
property: "configuration.layout.panels[" + selection[0].context.oldItem.id + "].hasFrame"
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"types": [
|
|
||||||
{
|
|
||||||
"key": "layout",
|
|
||||||
"name": "Display Layout",
|
|
||||||
"cssClass": "icon-layout",
|
|
||||||
"description": "Assemble other objects and components together into a reusable screen layout. Working in a simple canvas workspace, simply drag in the objects you want, position and size them. Save your design and view or edit it at any time.",
|
|
||||||
"priority": 900,
|
|
||||||
"features": "creation",
|
|
||||||
"model": {
|
|
||||||
"composition": [],
|
|
||||||
configuration: {
|
|
||||||
layout: {
|
|
||||||
panels: {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"properties": [
|
|
||||||
{
|
|
||||||
"name": "Layout Grid",
|
|
||||||
"control": "composite",
|
|
||||||
"pattern": "^(\\d*[1-9]\\d*)?$",
|
|
||||||
"items": [
|
|
||||||
{
|
|
||||||
"name": "Horizontal grid (px)",
|
|
||||||
"control": "textfield",
|
|
||||||
"cssClass": "l-input-sm l-numeric"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Vertical grid (px)",
|
|
||||||
"control": "textfield",
|
|
||||||
"cssClass": "l-input-sm l-numeric"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"key": "layoutGrid",
|
|
||||||
"conversion": "number[]"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Advanced",
|
|
||||||
"control": "textfield",
|
|
||||||
"key": "layoutAdvancedCss",
|
|
||||||
"cssClass": "l-input-lg"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
define([
|
define([
|
||||||
"./src/MCTForm",
|
"./src/MCTForm",
|
||||||
"./src/MCTToolbar",
|
|
||||||
"./src/MCTControl",
|
"./src/MCTControl",
|
||||||
"./src/MCTFileInput",
|
"./src/MCTFileInput",
|
||||||
"./src/FileInputService",
|
"./src/FileInputService",
|
||||||
@ -48,7 +47,6 @@ define([
|
|||||||
'legacyRegistry'
|
'legacyRegistry'
|
||||||
], function (
|
], function (
|
||||||
MCTForm,
|
MCTForm,
|
||||||
MCTToolbar,
|
|
||||||
MCTControl,
|
MCTControl,
|
||||||
MCTFileInput,
|
MCTFileInput,
|
||||||
FileInputService,
|
FileInputService,
|
||||||
@ -83,10 +81,6 @@ define([
|
|||||||
"key": "mctForm",
|
"key": "mctForm",
|
||||||
"implementation": MCTForm
|
"implementation": MCTForm
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"key": "mctToolbar",
|
|
||||||
"implementation": MCTToolbar
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"key": "mctControl",
|
"key": "mctControl",
|
||||||
"implementation": MCTControl,
|
"implementation": MCTControl,
|
||||||
|
@ -1,49 +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.
|
|
||||||
-->
|
|
||||||
<form novalidate>
|
|
||||||
<div class="tool-bar btn-bar contents abs">
|
|
||||||
<span ng-repeat="item in structure">
|
|
||||||
<span ng-if="item.control === 'divider'" class="l-control-group">
|
|
||||||
</span>
|
|
||||||
<ng-form ng-class="{ 'input-labeled': item.name }"
|
|
||||||
ng-hide="item.hidden"
|
|
||||||
ng-if="item.control !== 'divider'"
|
|
||||||
class="inline"
|
|
||||||
title="{{item.description}}"
|
|
||||||
name="mctFormInner">
|
|
||||||
|
|
||||||
<label ng-if="item.name">
|
|
||||||
{{item.name}}:
|
|
||||||
</label>
|
|
||||||
<mct-control key="item.control"
|
|
||||||
ng-class="{ disabled: item.disabled }"
|
|
||||||
ng-model="ngModel"
|
|
||||||
ng-required="item.required"
|
|
||||||
ng-pattern="getRegExp(item.pattern)"
|
|
||||||
options="item.options"
|
|
||||||
structure="item"
|
|
||||||
field="item.key">
|
|
||||||
</mct-control>
|
|
||||||
</ng-form>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
@ -1,69 +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.
|
|
||||||
*****************************************************************************/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Module defining MCTForm. Created by vwoeltje on 11/10/14.
|
|
||||||
*/
|
|
||||||
define(
|
|
||||||
[
|
|
||||||
"./MCTForm",
|
|
||||||
"../res/templates/toolbar.html",
|
|
||||||
"./controllers/ToolbarController"
|
|
||||||
],
|
|
||||||
function (
|
|
||||||
MCTForm,
|
|
||||||
toolbarTemplate,
|
|
||||||
ToolbarController
|
|
||||||
) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The mct-toolbar directive allows generation of displayable
|
|
||||||
* forms based on a declarative description of the form's
|
|
||||||
* structure.
|
|
||||||
*
|
|
||||||
* This directive accepts three attributes:
|
|
||||||
*
|
|
||||||
* * `ng-model`: The model for the form; where user input
|
|
||||||
* will be stored.
|
|
||||||
* * `structure`: The declarative structure of the toolbar.
|
|
||||||
* Describes what controls should be shown and where
|
|
||||||
* their values should be read/written in the model.
|
|
||||||
* * `name`: The name under which to expose the form's
|
|
||||||
* dirty/valid state. This is similar to ng-form's use
|
|
||||||
* of name, except this will be made available in the
|
|
||||||
* parent scope.
|
|
||||||
*
|
|
||||||
* @memberof platform/forms
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function MCTToolbar() {
|
|
||||||
// Use Directive Definition Object from mct-form,
|
|
||||||
// but use the toolbar's template and controller instead.
|
|
||||||
var ddo = new MCTForm();
|
|
||||||
ddo.template = toolbarTemplate;
|
|
||||||
ddo.controller = ['$scope', 'openmct', ToolbarController];
|
|
||||||
return ddo;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MCTToolbar;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,84 +0,0 @@
|
|||||||
define(
|
|
||||||
[
|
|
||||||
'../../../commonUI/edit/src/representers/EditToolbar'
|
|
||||||
],
|
|
||||||
function (EditToolbar) {
|
|
||||||
|
|
||||||
// Default ng-pattern; any non whitespace
|
|
||||||
var NON_WHITESPACE = /\S/;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Controller for mct-toolbar directive.
|
|
||||||
*
|
|
||||||
* @memberof platform/forms
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
function ToolbarController($scope, openmct) {
|
|
||||||
var regexps = [];
|
|
||||||
|
|
||||||
// ng-pattern seems to want a RegExp, and not a
|
|
||||||
// string (despite what documentation says) but
|
|
||||||
// we want toolbar structure to be JSON-expressible,
|
|
||||||
// so we make RegExp's from strings as-needed
|
|
||||||
function getRegExp(pattern) {
|
|
||||||
// If undefined, don't apply a pattern
|
|
||||||
if (!pattern) {
|
|
||||||
return NON_WHITESPACE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Just echo if it's already a regexp
|
|
||||||
if (pattern instanceof RegExp) {
|
|
||||||
return pattern;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Otherwise, assume a string
|
|
||||||
// Cache for easy lookup later (so we don't
|
|
||||||
// creat a new RegExp every digest cycle)
|
|
||||||
if (!regexps[pattern]) {
|
|
||||||
regexps[pattern] = new RegExp(pattern);
|
|
||||||
}
|
|
||||||
|
|
||||||
return regexps[pattern];
|
|
||||||
}
|
|
||||||
|
|
||||||
this.openmct = openmct;
|
|
||||||
this.$scope = $scope;
|
|
||||||
$scope.editToolbar = {};
|
|
||||||
$scope.getRegExp = getRegExp;
|
|
||||||
|
|
||||||
$scope.$on("$destroy", this.destroy.bind(this));
|
|
||||||
openmct.selection.on('change', this.handleSelection.bind(this));
|
|
||||||
}
|
|
||||||
|
|
||||||
ToolbarController.prototype.handleSelection = function (selection) {
|
|
||||||
var domainObject = selection[0].context.oldItem;
|
|
||||||
var element = selection[0].context.elementProxy;
|
|
||||||
|
|
||||||
if ((domainObject && domainObject === this.selectedObject) || (element && element === this.selectedObject)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.selectedObject = domainObject || element;
|
|
||||||
|
|
||||||
if (this.editToolbar) {
|
|
||||||
this.editToolbar.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
var structure = this.openmct.toolbars.get(selection) || [];
|
|
||||||
this.editToolbar = new EditToolbar(this.$scope, this.openmct, structure);
|
|
||||||
this.$scope.$parent.editToolbar = this.editToolbar;
|
|
||||||
this.$scope.$parent.editToolbar.structure = this.editToolbar.getStructure();
|
|
||||||
this.$scope.$parent.editToolbar.state = this.editToolbar.getState();
|
|
||||||
|
|
||||||
setTimeout(function () {
|
|
||||||
this.$scope.$apply();
|
|
||||||
}.bind(this));
|
|
||||||
};
|
|
||||||
|
|
||||||
ToolbarController.prototype.destroy = function () {
|
|
||||||
this.openmct.selection.off("change", this.handleSelection);
|
|
||||||
};
|
|
||||||
|
|
||||||
return ToolbarController;
|
|
||||||
}
|
|
||||||
);
|
|
@ -1,112 +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(
|
|
||||||
["../src/MCTToolbar"],
|
|
||||||
function (MCTToolbar) {
|
|
||||||
|
|
||||||
describe("The mct-toolbar directive", function () {
|
|
||||||
var mockScope,
|
|
||||||
mockOpenMCT,
|
|
||||||
mockSelection,
|
|
||||||
mctToolbar;
|
|
||||||
|
|
||||||
function installController() {
|
|
||||||
var Controller = mctToolbar.controller[2];
|
|
||||||
return new Controller(mockScope, mockOpenMCT);
|
|
||||||
}
|
|
||||||
|
|
||||||
beforeEach(function () {
|
|
||||||
mockScope = jasmine.createSpyObj("$scope", [
|
|
||||||
"$watch",
|
|
||||||
"$on"
|
|
||||||
]);
|
|
||||||
mockScope.$parent = {};
|
|
||||||
mockSelection = jasmine.createSpyObj("selection", [
|
|
||||||
'on',
|
|
||||||
'off'
|
|
||||||
]);
|
|
||||||
mockOpenMCT = {
|
|
||||||
selection: mockSelection
|
|
||||||
};
|
|
||||||
mctToolbar = new MCTToolbar();
|
|
||||||
});
|
|
||||||
|
|
||||||
it("is restricted to elements", function () {
|
|
||||||
expect(mctToolbar.restrict).toEqual("E");
|
|
||||||
});
|
|
||||||
|
|
||||||
it("listens for selection change event", function () {
|
|
||||||
installController();
|
|
||||||
|
|
||||||
expect(mockOpenMCT.selection.on).toHaveBeenCalledWith(
|
|
||||||
"change",
|
|
||||||
jasmine.any(Function)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("allows strings to be converted to RegExps", function () {
|
|
||||||
// This is needed to support ng-pattern in the template
|
|
||||||
installController();
|
|
||||||
|
|
||||||
// Should have added getRegExp to the scope,
|
|
||||||
// to convert strings to regular expressions
|
|
||||||
expect(mockScope.getRegExp("^\\d+$")).toEqual(/^\d+$/);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("returns the same regexp instance for the same string", function () {
|
|
||||||
// Don't want new instances each digest cycle, for performance
|
|
||||||
var strRegExp = "^[a-z]\\d+$",
|
|
||||||
regExp;
|
|
||||||
|
|
||||||
// Add getRegExp to scope
|
|
||||||
installController();
|
|
||||||
regExp = mockScope.getRegExp(strRegExp);
|
|
||||||
|
|
||||||
// Same object instance each time...
|
|
||||||
expect(mockScope.getRegExp(strRegExp)).toBe(regExp);
|
|
||||||
expect(mockScope.getRegExp(strRegExp)).toBe(regExp);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("passes RegExp objects through untouched", function () {
|
|
||||||
// Permit using forms to simply provide their own RegExp object
|
|
||||||
var regExp = /^\d+[a-d]$/;
|
|
||||||
|
|
||||||
// Add getRegExp to scope
|
|
||||||
installController();
|
|
||||||
|
|
||||||
// Should have added getRegExp to the scope,
|
|
||||||
// to convert strings to regular expressions
|
|
||||||
expect(mockScope.getRegExp(regExp)).toBe(regExp);
|
|
||||||
});
|
|
||||||
|
|
||||||
it("passes a non-whitespace regexp when no pattern is defined", function () {
|
|
||||||
// If no pattern is supplied, ng-pattern should match anything
|
|
||||||
installController();
|
|
||||||
expect(mockScope.getRegExp()).toEqual(/\S/);
|
|
||||||
expect(mockScope.getRegExp(undefined)).toEqual(/\S/);
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
});
|
|
||||||
}
|
|
||||||
);
|
|
@ -91,8 +91,8 @@
|
|||||||
background: rgba($editColor, 0.1);
|
background: rgba($editColor, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
.s-selected,
|
[s-selected],
|
||||||
.s-selected-parent {
|
[s-selected-parent] {
|
||||||
.l-layout {
|
.l-layout {
|
||||||
// Show the layout grid for the top-most child of the current selection,
|
// Show the layout grid for the top-most child of the current selection,
|
||||||
// and hide the grid for deeper nested levels.
|
// and hide the grid for deeper nested levels.
|
||||||
@ -128,7 +128,6 @@
|
|||||||
frames: [],
|
frames: [],
|
||||||
frameStyles: [],
|
frameStyles: [],
|
||||||
rawPositions: {},
|
rawPositions: {},
|
||||||
initSelect: true,
|
|
||||||
drilledIn: undefined
|
drilledIn: undefined
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -141,6 +140,7 @@
|
|||||||
this.newDomainObject = this.domainObject;
|
this.newDomainObject = this.domainObject;
|
||||||
this.gridSize = this.newDomainObject.layoutGrid || DEFAULT_GRID_SIZE;
|
this.gridSize = this.newDomainObject.layoutGrid || DEFAULT_GRID_SIZE;
|
||||||
this.composition = this.openmct.composition.get(this.newDomainObject);
|
this.composition = this.openmct.composition.get(this.newDomainObject);
|
||||||
|
this.Listeners = [];
|
||||||
let panels = (((this.newDomainObject.configuration || {}).layout || {}).panels || {});
|
let panels = (((this.newDomainObject.configuration || {}).layout || {}).panels || {});
|
||||||
|
|
||||||
if (this.composition !== undefined) {
|
if (this.composition !== undefined) {
|
||||||
@ -237,8 +237,32 @@
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let domainObject = selection[0].context.item;
|
||||||
|
if (domainObject && domainObject === this.selectedObject) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selectedObject = domainObject;
|
||||||
|
this.removeListeners();
|
||||||
|
|
||||||
|
if (selection[1]) {
|
||||||
|
this.attachSelectionListeners();
|
||||||
|
}
|
||||||
|
|
||||||
this.updateDrilledInState();
|
this.updateDrilledInState();
|
||||||
},
|
},
|
||||||
|
attachSelectionListeners() {
|
||||||
|
let id = this.openmct.objects.makeKeyString(this.selectedObject.identifier);
|
||||||
|
let path = "configuration.layout.panels[" + id + "]";
|
||||||
|
this.listeners.push(this.openmct.objects.observe(this.newDomainObject, path + ".hasFrame", function (newValue) {
|
||||||
|
this.frameItems.forEach(function (item) {
|
||||||
|
if (item.id === id) {
|
||||||
|
item.hasFrame = newValue;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this.frames[id] = newValue;
|
||||||
|
}.bind(this)));
|
||||||
|
},
|
||||||
updateDrilledInState(id) {
|
updateDrilledInState(id) {
|
||||||
this.drilledIn = id;
|
this.drilledIn = id;
|
||||||
this.frameItems.forEach(function (item) {
|
this.frameItems.forEach(function (item) {
|
||||||
@ -282,6 +306,7 @@
|
|||||||
},
|
},
|
||||||
handleDrop($event) {
|
handleDrop($event) {
|
||||||
$event.preventDefault();
|
$event.preventDefault();
|
||||||
|
$event.stopPropagation();
|
||||||
|
|
||||||
let child = JSON.parse($event.dataTransfer.getData('domainObject'));
|
let child = JSON.parse($event.dataTransfer.getData('domainObject'));
|
||||||
let duplicates = [];
|
let duplicates = [];
|
||||||
@ -311,6 +336,14 @@
|
|||||||
},
|
},
|
||||||
handleDragOver($event){
|
handleDragOver($event){
|
||||||
$event.preventDefault();
|
$event.preventDefault();
|
||||||
|
},
|
||||||
|
removeListeners() {
|
||||||
|
if (this.listeners) {
|
||||||
|
this.listeners.forEach(function (l) {
|
||||||
|
l();
|
||||||
|
})
|
||||||
|
}
|
||||||
|
this.listeners = [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
@ -321,6 +354,7 @@
|
|||||||
this.composition.off('remove', this.onRemoveComposition);
|
this.composition.off('remove', this.onRemoveComposition);
|
||||||
this.openmct.off('change', this.selection);
|
this.openmct.off('change', this.selection);
|
||||||
this.unlisten();
|
this.unlisten();
|
||||||
|
this.removeListeners();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +139,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.s-selected, // LEGACY
|
&[s-selected], // LEGACY
|
||||||
&.is-selected {
|
&.is-selected {
|
||||||
border: $browseBorderSelected;
|
border: $browseBorderSelected;
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@
|
|||||||
border: $editBorderSelectableHov;
|
border: $editBorderSelectableHov;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.s-selected,
|
&[s-selected],
|
||||||
&.is-selected {
|
&.is-selected {
|
||||||
border: $editBorderSelected;
|
border: $editBorderSelected;
|
||||||
|
|
||||||
|
@ -63,5 +63,40 @@ export default function () {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
openmct.types.addType('layout', DisplayLayoutType());
|
openmct.types.addType('layout', DisplayLayoutType());
|
||||||
|
openmct.toolbars.addProvider({
|
||||||
|
name: "Display Layout Toolbar",
|
||||||
|
key: "layout",
|
||||||
|
description: "A toolbar for objects inside a display layout.",
|
||||||
|
forSelection: function (selection) {
|
||||||
|
// Apply the layout toolbar if the selected object is inside a layout,
|
||||||
|
// and in edit mode.
|
||||||
|
return (selection &&
|
||||||
|
selection[1] &&
|
||||||
|
selection[1].context.item.type === 'layout' &&
|
||||||
|
openmct.editor.isEditing());
|
||||||
|
},
|
||||||
|
toolbar: function (selection) {
|
||||||
|
let id = openmct.objects.makeKeyString(selection[0].context.item.identifier);
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
control: "toggle-button",
|
||||||
|
domainObject: selection[1].context.item,
|
||||||
|
property: "configuration.layout.panels[" + id + "].hasFrame",
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: false,
|
||||||
|
icon: 'icon-frame-hide',
|
||||||
|
title: "Hide frame"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: true,
|
||||||
|
icon: 'icon-frame-show',
|
||||||
|
title: "Show frame"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -55,19 +55,19 @@ define(['EventEmitter'], function (EventEmitter) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.selected[0] && this.selected[0].element) {
|
if (this.selected[0] && this.selected[0].element) {
|
||||||
this.selected[0].element.classList.remove('s-selected');
|
this.selected[0].element.removeAttribute('s-selected');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.selected[1] && this.selected[1].element) {
|
if (this.selected[1] && this.selected[1].element) {
|
||||||
this.selected[1].element.classList.remove('s-selected-parent');
|
this.selected[1].element.removeAttribute('s-selected-parent');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectable[0] && selectable[0].element) {
|
if (selectable[0] && selectable[0].element) {
|
||||||
selectable[0].element.classList.add('s-selected');
|
selectable[0].element.setAttribute('s-selected', "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectable[1] && selectable[1].element) {
|
if (selectable[1] && selectable[1].element) {
|
||||||
selectable[1].element.classList.add('s-selected-parent');
|
selectable[1].element.setAttribute('s-selected-parent', "");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.selected = selectable;
|
this.selected = selectable;
|
||||||
|
@ -50,7 +50,12 @@ button {
|
|||||||
.c-click-icon {
|
.c-click-icon {
|
||||||
@include cClickIcon();
|
@include cClickIcon();
|
||||||
|
|
||||||
|
.c-click-icon__label {
|
||||||
|
margin-left: $interiorMargin;
|
||||||
|
}
|
||||||
|
|
||||||
&--menu {
|
&--menu {
|
||||||
|
|
||||||
&:after {
|
&:after {
|
||||||
content: $glyph-icon-arrow-down;
|
content: $glyph-icon-arrow-down;
|
||||||
font-family: symbolsfont;
|
font-family: symbolsfont;
|
||||||
|
@ -85,15 +85,15 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Display grid when selected or selection parent.
|
// Display grid when selected or selection parent.
|
||||||
.s-selected .l-grid-holder,
|
[s-selected] .l-grid-holder,
|
||||||
.s-selected-parent .l-grid-holder {
|
[s-selected-parent] .l-grid-holder {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display in nested frames...
|
// Display in nested frames...
|
||||||
.t-frame-outer {
|
.t-frame-outer {
|
||||||
// ...when drilled in or selection parent...
|
// ...when drilled in or selection parent...
|
||||||
&.s-drilled-in, &.s-selected-parent {
|
&.s-drilled-in, &[s-selected-parent] {
|
||||||
.l-grid-holder {
|
.l-grid-holder {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ body.desktop {
|
|||||||
border-style: dashed !important;
|
border-style: dashed !important;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.s-selected {
|
[s-selected] {
|
||||||
> .s-hover-border,
|
> .s-hover-border,
|
||||||
&.s-hover-border {
|
&.s-hover-border {
|
||||||
// Styles for a selected object. Also used by legacy Fixed Position/Panel objects.
|
// Styles for a selected object. Also used by legacy Fixed Position/Panel objects.
|
||||||
@ -71,8 +71,8 @@ body.desktop {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.s-selected > .s-hover-border,
|
[s-selected] > .s-hover-border,
|
||||||
.s-selected.s-hover-border {
|
[s-selected].s-hover-border {
|
||||||
border-color: $colorSelectableSelectedPrimary !important;
|
border-color: $colorSelectableSelectedPrimary !important;
|
||||||
//z-index: 1; // Bring selected item from beneath others. BUT, this breaks editing in Fixed Position.
|
//z-index: 1; // Bring selected item from beneath others. BUT, this breaks editing in Fixed Position.
|
||||||
}
|
}
|
||||||
|
@ -1,168 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="c-custom-checkbox">
|
|
||||||
<input type="checkbox"
|
|
||||||
:id="id"
|
|
||||||
:name="name"
|
|
||||||
:value="value"
|
|
||||||
:required="required"
|
|
||||||
:disabled="disabled"
|
|
||||||
@change="onChange"
|
|
||||||
:checked="state">
|
|
||||||
<label :for="id">
|
|
||||||
<div class="c-custom-checkbox__box"></div>
|
|
||||||
<div class="c-custom-checkbox__label-text">
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
@import "~styles/sass-base";
|
|
||||||
|
|
||||||
.c-custom-checkbox {
|
|
||||||
$d: 14px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
label {
|
|
||||||
@include userSelectNone();
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
&__box {
|
|
||||||
@include nice-input();
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
line-height: $d;
|
|
||||||
width: $d;
|
|
||||||
height: $d;
|
|
||||||
margin-right: $interiorMarginSm;
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
opacity: 0;
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
&:checked + label > .c-custom-checkbox__box {
|
|
||||||
background: $colorKey;
|
|
||||||
&:before {
|
|
||||||
color: $colorKeyFg;
|
|
||||||
content: $glyph-icon-check;
|
|
||||||
font-family: symbolsfont;
|
|
||||||
font-size: 0.6em;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(:disabled) + label {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:disabled + label {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
/*
|
|
||||||
Custom checkbox control. Use just like a checkbox in HTML, except label string is passed within tag.
|
|
||||||
Supports value, true-value, false-value, checked and disabled attributes.
|
|
||||||
Example usage:
|
|
||||||
<checkbox checked>Enable markers</checkbox>
|
|
||||||
*/
|
|
||||||
export default {
|
|
||||||
model: {
|
|
||||||
prop: 'modelValue',
|
|
||||||
event: 'input'
|
|
||||||
},
|
|
||||||
|
|
||||||
props: {
|
|
||||||
id: {
|
|
||||||
type: String,
|
|
||||||
default: function () {
|
|
||||||
return 'checkbox-id-' + this._uid;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
name: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
modelValue: {
|
|
||||||
default: undefined,
|
|
||||||
},
|
|
||||||
checked: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
required: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
model: {}
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
state() {
|
|
||||||
if (this.modelValue === undefined) {
|
|
||||||
return this.checked;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(this.modelValue)) {
|
|
||||||
return this.modelValue.indexOf(this.value) > -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return !!this.modelValue;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
onChange() {
|
|
||||||
this.toggle();
|
|
||||||
},
|
|
||||||
|
|
||||||
toggle() {
|
|
||||||
let value;
|
|
||||||
|
|
||||||
if (Array.isArray(this.modelValue)) {
|
|
||||||
value = this.modelValue.slice(0);
|
|
||||||
|
|
||||||
if (this.state) {
|
|
||||||
value.splice(value.indexOf(this.value), 1);
|
|
||||||
} else {
|
|
||||||
value.push(this.value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
value = !this.state;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$emit('input', value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
checked(newValue) {
|
|
||||||
if (newValue !== this.state) {
|
|
||||||
this.toggle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
if (this.checked && !this.state) {
|
|
||||||
this.toggle();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
@ -1,51 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="c-labeled-input"
|
|
||||||
:title="title">
|
|
||||||
<div class="c-labeled-input__label">{{ label }}</div>
|
|
||||||
<input type="number"
|
|
||||||
v-bind="$attrs"
|
|
||||||
v-bind:value="value"
|
|
||||||
v-on="inputListeners"/>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
/* Emits input and clear events */
|
|
||||||
export default {
|
|
||||||
inheritAttrs: false,
|
|
||||||
props: {
|
|
||||||
value: String,
|
|
||||||
label: String,
|
|
||||||
title: String
|
|
||||||
},
|
|
||||||
computed: {
|
|
||||||
inputListeners: function () {
|
|
||||||
let vm = this;
|
|
||||||
return Object.assign({},
|
|
||||||
this.$listeners,
|
|
||||||
{
|
|
||||||
input: function (event) {
|
|
||||||
vm.$emit('input', event.target.value);
|
|
||||||
},
|
|
||||||
change: function (event) {
|
|
||||||
vm.$emit('change', event.target.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
data: function() {
|
|
||||||
return {
|
|
||||||
// active: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
clearInput() {
|
|
||||||
// Clear the user's input and set 'active' to false
|
|
||||||
this.value = '';
|
|
||||||
this.$emit('clear','');
|
|
||||||
this.active = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
@ -1,176 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="c-togglebutton">
|
|
||||||
<input type="checkbox"
|
|
||||||
:id="id"
|
|
||||||
:name="name"
|
|
||||||
:value="value"
|
|
||||||
:required="required"
|
|
||||||
:disabled="disabled"
|
|
||||||
@change="onChange"
|
|
||||||
:checked="state">
|
|
||||||
<label :for="id">
|
|
||||||
<div class="c-togglebutton__on"
|
|
||||||
:class="innerClassOn"></div>
|
|
||||||
<div class="c-togglebutton__off"
|
|
||||||
:class="innerClassOff"></div>
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<style lang="scss">
|
|
||||||
@import "~styles/sass-base";
|
|
||||||
|
|
||||||
.c-togglebutton {
|
|
||||||
$d: 14px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
label {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
|
|
||||||
.c-togglebutton__on {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
opacity: 0;
|
|
||||||
position: absolute;
|
|
||||||
|
|
||||||
&:checked + label {
|
|
||||||
.c-togglebutton__on {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.c-togglebutton__off {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&:not(:disabled) + label {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
&:disabled + label {
|
|
||||||
opacity: 0.5;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
/*
|
|
||||||
Toggle button control, based on checkboxCustom. Use just like a checkbox in HTML.
|
|
||||||
Requires inner-class-on and -off attributes to be passed.
|
|
||||||
Supports checked and disabled attributes.
|
|
||||||
Example usage:
|
|
||||||
<toggle-button checked
|
|
||||||
class="c-click-icon"
|
|
||||||
inner-class-on="icon-grid-snap-to"
|
|
||||||
inner-class-off="icon-grid-snap-no"></toggle-button>
|
|
||||||
*/
|
|
||||||
export default {
|
|
||||||
model: {
|
|
||||||
prop: 'modelValue',
|
|
||||||
event: 'input'
|
|
||||||
},
|
|
||||||
|
|
||||||
props: {
|
|
||||||
innerClassOn: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
innerClassOff: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
id: {
|
|
||||||
type: String,
|
|
||||||
default: function () {
|
|
||||||
return 'checkbox-id-' + this._uid;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
name: {
|
|
||||||
type: String,
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
value: {
|
|
||||||
default: null,
|
|
||||||
},
|
|
||||||
modelValue: {
|
|
||||||
default: undefined,
|
|
||||||
},
|
|
||||||
checked: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
required: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
disabled: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false,
|
|
||||||
},
|
|
||||||
model: {}
|
|
||||||
},
|
|
||||||
|
|
||||||
computed: {
|
|
||||||
state() {
|
|
||||||
if (this.modelValue === undefined) {
|
|
||||||
return this.checked;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Array.isArray(this.modelValue)) {
|
|
||||||
return this.modelValue.indexOf(this.value) > -1;
|
|
||||||
}
|
|
||||||
return !!this.modelValue;
|
|
||||||
},
|
|
||||||
stateClass() {
|
|
||||||
return this.onClass;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
methods: {
|
|
||||||
onChange() {
|
|
||||||
this.toggle();
|
|
||||||
},
|
|
||||||
|
|
||||||
toggle() {
|
|
||||||
let value;
|
|
||||||
|
|
||||||
if (Array.isArray(this.modelValue)) {
|
|
||||||
value = this.modelValue.slice(0);
|
|
||||||
|
|
||||||
if (this.state) {
|
|
||||||
value.splice(value.indexOf(this.value), 1);
|
|
||||||
} else {
|
|
||||||
value.push(this.value);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
value = !this.state;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.$emit('input', value);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
watch: {
|
|
||||||
checked(newValue) {
|
|
||||||
if (newValue !== this.state) {
|
|
||||||
this.toggle();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
mounted() {
|
|
||||||
if (this.checked && !this.state) {
|
|
||||||
this.toggle();
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
</script>
|
|
@ -246,7 +246,7 @@
|
|||||||
import pane from '../controls/pane.vue';
|
import pane from '../controls/pane.vue';
|
||||||
import BrowseBar from './BrowseBar.vue';
|
import BrowseBar from './BrowseBar.vue';
|
||||||
import StatusBar from './status-bar/StatusBar.vue';
|
import StatusBar from './status-bar/StatusBar.vue';
|
||||||
import Toolbar from './Toolbar.vue';
|
import Toolbar from '../toolbar/Toolbar.vue';
|
||||||
|
|
||||||
var enterFullScreen = () => {
|
var enterFullScreen = () => {
|
||||||
var docElm = document.documentElement;
|
var docElm = document.documentElement;
|
||||||
|
@ -1,291 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="c-toolbar">
|
|
||||||
<!-- VERSION MANUALLY RESTORED FROM VUE-LAYOUT -->
|
|
||||||
<div class="c-button-set">
|
|
||||||
<div class="c-ctrl-wrapper">
|
|
||||||
<div class="c-button--menu js-add-button icon-plus"
|
|
||||||
@click="toggleMenus">
|
|
||||||
<div class="c-button__label">Add</div>
|
|
||||||
</div>
|
|
||||||
<div class="c-menu" v-if="showMenus">
|
|
||||||
<ul>
|
|
||||||
<li v-for="item in addMenuItems"
|
|
||||||
:class="item.class"
|
|
||||||
:title="item.title">
|
|
||||||
{{ item.name }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="c-button-set"
|
|
||||||
v-if="toolsItemSelected">
|
|
||||||
<div class="c-ctrl-wrapper"
|
|
||||||
v-if="toolsItemSelected">
|
|
||||||
<div class="c-click-icon c-click-icon--menu js-layers icon-layers"
|
|
||||||
@click="toggleMenus"></div>
|
|
||||||
<div class="c-menu" v-if="showMenus">
|
|
||||||
<ul>
|
|
||||||
<li v-for="item in layersMenuItems"
|
|
||||||
:class="item.class"
|
|
||||||
:title="item.title">
|
|
||||||
{{ item.name }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="c-ctrl-wrapper"
|
|
||||||
v-if="toolsColorFill">
|
|
||||||
<div class="c-click-icon c-click-icon--swatched js-color-fill icon-paint-bucket"
|
|
||||||
@click="toggleMenus">
|
|
||||||
<div class="c-swatch" style="background: #33ff00;"></div>
|
|
||||||
</div>
|
|
||||||
<div class="c-menu c-palette c-palette--color"
|
|
||||||
v-if="showMenus">
|
|
||||||
<div class="c-palette__item-none"
|
|
||||||
vif="this.palette.itemNone === true">
|
|
||||||
<div class="c-palette__item"
|
|
||||||
@click="this.setColor('no-color')"></div>
|
|
||||||
No fill
|
|
||||||
</div>
|
|
||||||
<div class="c-palette__items">
|
|
||||||
<div class="c-palette__item"
|
|
||||||
v-for="color in colorPalette"
|
|
||||||
:style="{ background: color.value }"
|
|
||||||
@click="this.setColor(color.value)"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="c-ctrl-wrapper"
|
|
||||||
v-if="toolsColorStroke">
|
|
||||||
<div class="c-click-icon c-click-icon--swatched js-color-stroke icon-pencil">
|
|
||||||
<div class="c-toolbar-button__swatch" style="background: #ffffff;"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="c-ctrl-wrapper"
|
|
||||||
v-if="toolsColorText">
|
|
||||||
<div class="c-click-icon c-click-icon--swatched js-color-text icon-font">
|
|
||||||
<div class="c-toolbar-button__swatch" style="background: #333333;"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="c-button-set"
|
|
||||||
v-if="toolsItemSelected && toolsFontSize">
|
|
||||||
<div class="c-ctrl-wrapper">
|
|
||||||
<div class="c-click-icon c-click-icon--menu js-font-size"
|
|
||||||
@click="toggleMenus">
|
|
||||||
<div class="c-button__label">11 px</div>
|
|
||||||
</div>
|
|
||||||
<div class="c-menu" v-if="showMenus">
|
|
||||||
<ul>
|
|
||||||
<li v-for="item in fontSizeMenuItems">
|
|
||||||
{{ item.name }}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="c-button-set"
|
|
||||||
v-if="toolsItemSelected && toolsEditProperties">
|
|
||||||
<div class="c-ctrl-wrapper">
|
|
||||||
<div class="c-click-icon js-image icon-gear"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="c-button-set"
|
|
||||||
v-if="toolsItemSelected">
|
|
||||||
<labeledNumberInput label="X" value=1 title="X position"></labeledNumberInput>
|
|
||||||
<labeledNumberInput label="Y" value=2 title="Y position"></labeledNumberInput>
|
|
||||||
<labeledNumberInput label="W" value=3 title="Width"></labeledNumberInput>
|
|
||||||
<labeledNumberInput label="H" value=4 title="Height"></labeledNumberInput>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="c-button-set"
|
|
||||||
v-if="toolsItemSelected">
|
|
||||||
<div class="c-click-icon c-click-icon--caution icon-trash"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="c-button-set"
|
|
||||||
v-if="toolsItemSelected">
|
|
||||||
<checkbox checked title="This is a checkbox">Checkbox</checkbox>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="c-button-set"
|
|
||||||
v-if="toolsItemSelected">
|
|
||||||
<toggle-button title="Toggle frame" checked
|
|
||||||
class="c-click-icon"
|
|
||||||
inner-class-on="icon-frame-show"
|
|
||||||
inner-class-off="icon-frame-hide"></toggle-button>
|
|
||||||
<toggle-button title="Snap to grid" checked
|
|
||||||
class="c-click-icon"
|
|
||||||
inner-class-on="icon-grid-snap-to"
|
|
||||||
inner-class-off="icon-grid-snap-no"></toggle-button>
|
|
||||||
<toggle-button title="Show label and value" checked
|
|
||||||
class="c-click-icon"
|
|
||||||
inner-class-on="icon-two-parts-both"
|
|
||||||
inner-class-off="icon-two-parts-one-only"></toggle-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import labeledNumberInput from '../controls/labeledNumberInput.vue';
|
|
||||||
import checkbox from '../controls/checkboxCustom.vue';
|
|
||||||
import toggleButton from '../controls/toggleButton.vue';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: {
|
|
||||||
labeledNumberInput,
|
|
||||||
checkbox,
|
|
||||||
toggleButton
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
toggleMenus: function () {
|
|
||||||
this.showMenus = !this.showMenus;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
props: {
|
|
||||||
toolsItemSelected: { type: Boolean, default: true },
|
|
||||||
toolsColorFill: { type: Boolean, default: true },
|
|
||||||
toolsColorStroke: { type: Boolean, default: true },
|
|
||||||
toolsColorText: { type: Boolean, default: true },
|
|
||||||
toolsFontSize: { type: Boolean, default: true },
|
|
||||||
toolsEditProperties: { type: Boolean, default: true },
|
|
||||||
toolSetBox: ['toolsColorFill', 'toolsColorStroke'],
|
|
||||||
toolSetLine: ['toolsColorStroke'],
|
|
||||||
toolSetText: ['toolsColorFill', 'toolsColorStroke', 'toolsColorText', 'toolsFontSize', 'toolsEditProperties'],
|
|
||||||
toolSetImage: ['toolsColorStroke', 'toolsEditProperties'],
|
|
||||||
toolSetTelemetry: ['toolsColorFill', 'toolsColorStroke', 'toolsColorText', 'toolsFontSize', 'toolsLabelValue']
|
|
||||||
},
|
|
||||||
data: function () {
|
|
||||||
return {
|
|
||||||
showMenus: false,
|
|
||||||
addMenuItems: [
|
|
||||||
{ name: 'Box', class: 'icon-box', title: 'Add Box' },
|
|
||||||
{ name: 'Line', class: 'icon-line-horz', title: 'Add Line' },
|
|
||||||
{ name: 'Text', class: 'icon-font', title: 'Add Text' },
|
|
||||||
{ name: 'Image', class: 'icon-image', title: 'Add Image' }
|
|
||||||
],
|
|
||||||
layersMenuItems: [
|
|
||||||
{ name: 'Move to top', class: 'icon-arrow-double-up', title: 'Move to top' },
|
|
||||||
{ name: 'Move up', class: 'icon-arrow-up', title: 'Move up' },
|
|
||||||
{ name: 'Move down', class: 'icon-arrow-down', title: 'Move down' },
|
|
||||||
{ name: 'Move to bottom', class: 'icon-arrow-double-down', title: 'Move to bottom' }
|
|
||||||
],
|
|
||||||
fontSizeMenuItems: [
|
|
||||||
{ value: '9', name: '9 px' },
|
|
||||||
{ value: '10', name: '10 px' },
|
|
||||||
{ value: '11', name: '11 px' },
|
|
||||||
{ value: '12', name: '12 px' },
|
|
||||||
{ value: '13', name: '13 px' },
|
|
||||||
{ value: '14', name: '14 px' },
|
|
||||||
{ value: '16', name: '16 px' },
|
|
||||||
{ value: '18', name: '18 px' },
|
|
||||||
{ value: '20', name: '20 px' },
|
|
||||||
{ value: '24', name: '24 px' },
|
|
||||||
{ value: '28', name: '28 px' },
|
|
||||||
{ value: '32', name: '32 px' },
|
|
||||||
{ value: '40', name: '40 px' },
|
|
||||||
{ value: '48', name: '48 px' },
|
|
||||||
{ value: '56', name: '56 px' },
|
|
||||||
{ value: '64', name: '64 px' },
|
|
||||||
{ value: '72', name: '72 px' },
|
|
||||||
{ value: '80', name: '80 px' },
|
|
||||||
{ value: '88', name: '88 px' },
|
|
||||||
{ value: '96', name: '96 px' },
|
|
||||||
{ value: '128', name: '128 px' },
|
|
||||||
{ value: '160', name: '160 px' }
|
|
||||||
],
|
|
||||||
colorPalette: [
|
|
||||||
{ value: '#000000' },
|
|
||||||
{ value: '#434343' },
|
|
||||||
{ value: '#666666' },
|
|
||||||
{ value: '#999999' },
|
|
||||||
{ value: '#b7b7b7' },
|
|
||||||
{ value: '#cccccc' },
|
|
||||||
{ value: '#d9d9d9' },
|
|
||||||
{ value: '#efefef' },
|
|
||||||
{ value: '#f3f3f3' },
|
|
||||||
{ value: '#ffffff' },
|
|
||||||
{ value: '#980000' },
|
|
||||||
{ value: '#ff0000' },
|
|
||||||
{ value: '#ff9900' },
|
|
||||||
{ value: '#ffff00' },
|
|
||||||
{ value: '#00ff00' },
|
|
||||||
{ value: '#00ffff' },
|
|
||||||
{ value: '#4a86e8' },
|
|
||||||
{ value: '#0000ff' },
|
|
||||||
{ value: '#9900ff' },
|
|
||||||
{ value: '#ff00ff' },
|
|
||||||
{ value: '#e6b8af' },
|
|
||||||
{ value: '#f4cccc' },
|
|
||||||
{ value: '#fce5cd' },
|
|
||||||
{ value: '#fff2cc' },
|
|
||||||
{ value: '#d9ead3' },
|
|
||||||
{ value: '#d0e0e3' },
|
|
||||||
{ value: '#c9daf8' },
|
|
||||||
{ value: '#cfe2f3' },
|
|
||||||
{ value: '#d9d2e9' },
|
|
||||||
{ value: '#ead1dc' },
|
|
||||||
{ value: '#dd7e6b' },
|
|
||||||
{ value: '#dd7e6b' },
|
|
||||||
{ value: '#f9cb9c' },
|
|
||||||
{ value: '#ffe599' },
|
|
||||||
{ value: '#b6d7a8' },
|
|
||||||
{ value: '#a2c4c9' },
|
|
||||||
{ value: '#a4c2f4' },
|
|
||||||
{ value: '#9fc5e8' },
|
|
||||||
{ value: '#b4a7d6' },
|
|
||||||
{ value: '#d5a6bd' },
|
|
||||||
{ value: '#cc4125' },
|
|
||||||
{ value: '#e06666' },
|
|
||||||
{ value: '#f6b26b' },
|
|
||||||
{ value: '#ffd966' },
|
|
||||||
{ value: '#93c47d' },
|
|
||||||
{ value: '#76a5af' },
|
|
||||||
{ value: '#6d9eeb' },
|
|
||||||
{ value: '#6fa8dc' },
|
|
||||||
{ value: '#8e7cc3' },
|
|
||||||
{ value: '#c27ba0' },
|
|
||||||
{ value: '#a61c00' },
|
|
||||||
{ value: '#cc0000' },
|
|
||||||
{ value: '#e69138' },
|
|
||||||
{ value: '#f1c232' },
|
|
||||||
{ value: '#6aa84f' },
|
|
||||||
{ value: '#45818e' },
|
|
||||||
{ value: '#3c78d8' },
|
|
||||||
{ value: '#3d85c6' },
|
|
||||||
{ value: '#674ea7' },
|
|
||||||
{ value: '#a64d79' },
|
|
||||||
{ value: '#85200c' },
|
|
||||||
{ value: '#990000' },
|
|
||||||
{ value: '#b45f06' },
|
|
||||||
{ value: '#bf9000' },
|
|
||||||
{ value: '#38761d' },
|
|
||||||
{ value: '#134f5c' },
|
|
||||||
{ value: '#1155cc' },
|
|
||||||
{ value: '#0b5394' },
|
|
||||||
{ value: '#351c75' },
|
|
||||||
{ value: '#741b47' },
|
|
||||||
{ value: '#5b0f00' },
|
|
||||||
{ value: '#660000' },
|
|
||||||
{ value: '#783f04' },
|
|
||||||
{ value: '#7f6000' },
|
|
||||||
{ value: '#274e13' },
|
|
||||||
{ value: '#0c343d' },
|
|
||||||
{ value: '#1c4587' },
|
|
||||||
{ value: '#073763' },
|
|
||||||
{ value: '#20124d' },
|
|
||||||
{ value: '#4c1130' }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
109
src/ui/components/toolbar/Toolbar.vue
Normal file
109
src/ui/components/toolbar/Toolbar.vue
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-toolbar">
|
||||||
|
<component v-for="item in structure"
|
||||||
|
:is="item.control"
|
||||||
|
:options="item"
|
||||||
|
@change="updateObjectValue"></component>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import toolbarButton from './components/toolbar-button.vue';
|
||||||
|
import toolbarColorPicker from './components/toolbar-color-picker.vue';
|
||||||
|
import toolbarCheckbox from './components/toolbar-checkbox.vue';
|
||||||
|
import toolbarInput from './components/toolbar-input.vue';
|
||||||
|
import toolbarMenu from './components/toolbar-menu.vue';
|
||||||
|
import toolbarSelectMenu from './components/toolbar-select-menu.vue';
|
||||||
|
import toolbarSeparator from './components/toolbar-separator.vue';
|
||||||
|
import toolbarToggleButton from './components/toolbar-toggle-button.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
inject: ['openmct', 'lodash'],
|
||||||
|
components: {
|
||||||
|
toolbarButton,
|
||||||
|
toolbarColorPicker,
|
||||||
|
toolbarCheckbox,
|
||||||
|
toolbarInput,
|
||||||
|
toolbarMenu,
|
||||||
|
toolbarSelectMenu,
|
||||||
|
toolbarSeparator,
|
||||||
|
toolbarToggleButton
|
||||||
|
},
|
||||||
|
data: function () {
|
||||||
|
return {
|
||||||
|
structure: []
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
handleSelection(selection) {
|
||||||
|
if (!selection[0]) {
|
||||||
|
this.structure = [];
|
||||||
|
this.selectedObject = undefined;
|
||||||
|
this.removeListeners();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let domainObject = selection[0].context.item;
|
||||||
|
|
||||||
|
this.selectedObject = domainObject;
|
||||||
|
this.removeListeners();
|
||||||
|
|
||||||
|
let structure = this.openmct.toolbars.get(selection) || [];
|
||||||
|
this.structure = structure.map(function (item) {
|
||||||
|
let toolbarItem = {...item};
|
||||||
|
toolbarItem.control = "toolbar-" + toolbarItem.control;
|
||||||
|
toolbarItem.value = _.get(toolbarItem.domainObject, item.property);
|
||||||
|
this.registerListener(toolbarItem.domainObject);
|
||||||
|
return toolbarItem;
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
|
registerListener(domainObject) {
|
||||||
|
let unobserveObject = this.openmct.objects.observe(domainObject, '*', function(newObject) {
|
||||||
|
let newObjectId = this.openmct.objects.makeKeyString(newObject.identifier);
|
||||||
|
this.structure = this.structure.map((item) => {
|
||||||
|
let toolbarItem = {...item};
|
||||||
|
let domainObjectId = this.openmct.objects.makeKeyString(toolbarItem.domainObject.identifier);
|
||||||
|
if (domainObjectId === newObjectId) {
|
||||||
|
toolbarItem.domainObject = JSON.parse(JSON.stringify(newObject));
|
||||||
|
}
|
||||||
|
return toolbarItem;
|
||||||
|
});
|
||||||
|
}.bind(this));
|
||||||
|
this.unObserveObjects.push(unobserveObject);
|
||||||
|
},
|
||||||
|
removeListeners() {
|
||||||
|
if (this.unObserveObjects) {
|
||||||
|
this.unObserveObjects.forEach((unObserveObject) => {
|
||||||
|
unObserveObject();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
this.unObserveObjects = [];
|
||||||
|
},
|
||||||
|
updateObjectValue(value, item) {
|
||||||
|
let changedId = this.openmct.objects.makeKeyString(item.domainObject.identifier);
|
||||||
|
this.structure = this.structure.map((s) => {
|
||||||
|
let toolbarItem = {...s};
|
||||||
|
if (changedId === this.openmct.objects.makeKeyString(toolbarItem.domainObject.identifier)) {
|
||||||
|
toolbarItem.value = value;
|
||||||
|
}
|
||||||
|
return toolbarItem;
|
||||||
|
});
|
||||||
|
this.openmct.objects.mutate(item.domainObject, item.property, value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
this.openmct.selection.on('change', this.handleSelection);
|
||||||
|
this.handleSelection(this.openmct.selection.get());
|
||||||
|
|
||||||
|
// Toolbars may change when edit mode is enabled/disabled, so listen
|
||||||
|
// for edit mode changes and update toolbars if necessary.
|
||||||
|
this.openmct.editor.on('isEditing', (isEditing) => {
|
||||||
|
this.handleSelection(this.openmct.selection.get());
|
||||||
|
});
|
||||||
|
},
|
||||||
|
detroyed() {
|
||||||
|
this.openmct.selection.off('change', this.handleSelection);
|
||||||
|
this.removeListeners();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
22
src/ui/components/toolbar/components/toggle-mixin.js
Normal file
22
src/ui/components/toolbar/components/toggle-mixin.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
open: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggle(event) {
|
||||||
|
if (this.open) {
|
||||||
|
document.removeEventListener('click', this.toggle);
|
||||||
|
this.open = false;
|
||||||
|
} else {
|
||||||
|
document.addEventListener('click', this.toggle);
|
||||||
|
event.stopPropagation();
|
||||||
|
this.open = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
destroyed() {
|
||||||
|
document.removeEventListener('click', this.toggle);
|
||||||
|
},
|
||||||
|
}
|
29
src/ui/components/toolbar/components/toolbar-button.vue
Normal file
29
src/ui/components/toolbar/components/toolbar-button.vue
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-ctrl-wrapper">
|
||||||
|
<div class="c-click-icon"
|
||||||
|
:class="{
|
||||||
|
[options.icon]: true,
|
||||||
|
'c-click-icon--caution': options.modifier === 'caution'
|
||||||
|
}"
|
||||||
|
@click="onClick">
|
||||||
|
<div class="c-click-icon__label"
|
||||||
|
v-if="options.label">
|
||||||
|
{{ options.label }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
options: Object
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onClick(event) {
|
||||||
|
this.$emit('click', this.options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
89
src/ui/components/toolbar/components/toolbar-checkbox.vue
Normal file
89
src/ui/components/toolbar/components/toolbar-checkbox.vue
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-custom-checkbox">
|
||||||
|
<input type="checkbox"
|
||||||
|
:id="uid"
|
||||||
|
:name="options.name"
|
||||||
|
:checked="options.value"
|
||||||
|
:disabled="options.disabled"
|
||||||
|
@change="onChange">
|
||||||
|
|
||||||
|
<label :for="uid">
|
||||||
|
<div class="c-custom-checkbox__box"></div>
|
||||||
|
<div class="c-custom-checkbox__label-text">
|
||||||
|
{{options.name}}
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
@import "~styles/sass-base";
|
||||||
|
|
||||||
|
.c-custom-checkbox {
|
||||||
|
$d: 14px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
label {
|
||||||
|
@include userSelectNone();
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
&__box {
|
||||||
|
@include nice-input();
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
line-height: $d;
|
||||||
|
width: $d;
|
||||||
|
height: $d;
|
||||||
|
margin-right: $interiorMarginSm;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
|
||||||
|
&:checked + label > .c-custom-checkbox__box {
|
||||||
|
background: $colorKey;
|
||||||
|
&:before {
|
||||||
|
color: $colorKeyFg;
|
||||||
|
content: $glyph-icon-check;
|
||||||
|
font-family: symbolsfont;
|
||||||
|
font-size: 0.6em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&:not(:disabled) + label {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:disabled + label {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
let uniqueId = 100;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
options: Object
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
uniqueId++;
|
||||||
|
return {
|
||||||
|
uid: `mct-checkbox-id-${uniqueId}`
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onChange(event) {
|
||||||
|
this.$emit('change', event.target.checked, {...this.options});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
132
src/ui/components/toolbar/components/toolbar-color-picker.vue
Normal file
132
src/ui/components/toolbar/components/toolbar-color-picker.vue
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-ctrl-wrapper">
|
||||||
|
<div class="c-click-icon c-click-icon--swatched"
|
||||||
|
:class="options.icon"
|
||||||
|
@click="toggle">
|
||||||
|
<div class="c-swatch" :style="{
|
||||||
|
background: options.value
|
||||||
|
}"></div>
|
||||||
|
</div>
|
||||||
|
<div class="c-menu c-palette c-palette--color"
|
||||||
|
v-if="open">
|
||||||
|
<div class="c-palette__item-none"
|
||||||
|
v-if="!this.options.preventNone"
|
||||||
|
@click="select({value: 'transparent'})">
|
||||||
|
<div class="c-palette__item"></div>
|
||||||
|
No fill
|
||||||
|
</div>
|
||||||
|
<div class="c-palette__items">
|
||||||
|
<div class="c-palette__item"
|
||||||
|
v-for="color in colorPalette"
|
||||||
|
:style="{ background: color.value }"
|
||||||
|
@click="select(color)"
|
||||||
|
></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import toggleMixin from './toggle-mixin';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [toggleMixin],
|
||||||
|
props: {
|
||||||
|
options: Object
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
select(color) {
|
||||||
|
if (color.value !== this.options.value) {
|
||||||
|
this.$emit('change', color, this.options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
colorPalette: [
|
||||||
|
{ value: '#000000' },
|
||||||
|
{ value: '#434343' },
|
||||||
|
{ value: '#666666' },
|
||||||
|
{ value: '#999999' },
|
||||||
|
{ value: '#b7b7b7' },
|
||||||
|
{ value: '#cccccc' },
|
||||||
|
{ value: '#d9d9d9' },
|
||||||
|
{ value: '#efefef' },
|
||||||
|
{ value: '#f3f3f3' },
|
||||||
|
{ value: '#ffffff' },
|
||||||
|
{ value: '#980000' },
|
||||||
|
{ value: '#ff0000' },
|
||||||
|
{ value: '#ff9900' },
|
||||||
|
{ value: '#ffff00' },
|
||||||
|
{ value: '#00ff00' },
|
||||||
|
{ value: '#00ffff' },
|
||||||
|
{ value: '#4a86e8' },
|
||||||
|
{ value: '#0000ff' },
|
||||||
|
{ value: '#9900ff' },
|
||||||
|
{ value: '#ff00ff' },
|
||||||
|
{ value: '#e6b8af' },
|
||||||
|
{ value: '#f4cccc' },
|
||||||
|
{ value: '#fce5cd' },
|
||||||
|
{ value: '#fff2cc' },
|
||||||
|
{ value: '#d9ead3' },
|
||||||
|
{ value: '#d0e0e3' },
|
||||||
|
{ value: '#c9daf8' },
|
||||||
|
{ value: '#cfe2f3' },
|
||||||
|
{ value: '#d9d2e9' },
|
||||||
|
{ value: '#ead1dc' },
|
||||||
|
{ value: '#dd7e6b' },
|
||||||
|
{ value: '#dd7e6b' },
|
||||||
|
{ value: '#f9cb9c' },
|
||||||
|
{ value: '#ffe599' },
|
||||||
|
{ value: '#b6d7a8' },
|
||||||
|
{ value: '#a2c4c9' },
|
||||||
|
{ value: '#a4c2f4' },
|
||||||
|
{ value: '#9fc5e8' },
|
||||||
|
{ value: '#b4a7d6' },
|
||||||
|
{ value: '#d5a6bd' },
|
||||||
|
{ value: '#cc4125' },
|
||||||
|
{ value: '#e06666' },
|
||||||
|
{ value: '#f6b26b' },
|
||||||
|
{ value: '#ffd966' },
|
||||||
|
{ value: '#93c47d' },
|
||||||
|
{ value: '#76a5af' },
|
||||||
|
{ value: '#6d9eeb' },
|
||||||
|
{ value: '#6fa8dc' },
|
||||||
|
{ value: '#8e7cc3' },
|
||||||
|
{ value: '#c27ba0' },
|
||||||
|
{ value: '#a61c00' },
|
||||||
|
{ value: '#cc0000' },
|
||||||
|
{ value: '#e69138' },
|
||||||
|
{ value: '#f1c232' },
|
||||||
|
{ value: '#6aa84f' },
|
||||||
|
{ value: '#45818e' },
|
||||||
|
{ value: '#3c78d8' },
|
||||||
|
{ value: '#3d85c6' },
|
||||||
|
{ value: '#674ea7' },
|
||||||
|
{ value: '#a64d79' },
|
||||||
|
{ value: '#85200c' },
|
||||||
|
{ value: '#990000' },
|
||||||
|
{ value: '#b45f06' },
|
||||||
|
{ value: '#bf9000' },
|
||||||
|
{ value: '#38761d' },
|
||||||
|
{ value: '#134f5c' },
|
||||||
|
{ value: '#1155cc' },
|
||||||
|
{ value: '#0b5394' },
|
||||||
|
{ value: '#351c75' },
|
||||||
|
{ value: '#741b47' },
|
||||||
|
{ value: '#5b0f00' },
|
||||||
|
{ value: '#660000' },
|
||||||
|
{ value: '#783f04' },
|
||||||
|
{ value: '#7f6000' },
|
||||||
|
{ value: '#274e13' },
|
||||||
|
{ value: '#0c343d' },
|
||||||
|
{ value: '#1c4587' },
|
||||||
|
{ value: '#073763' },
|
||||||
|
{ value: '#20124d' },
|
||||||
|
{ value: '#4c1130' }
|
||||||
|
]
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
40
src/ui/components/toolbar/components/toolbar-input.vue
Normal file
40
src/ui/components/toolbar/components/toolbar-input.vue
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-labeled-input"
|
||||||
|
:title="options.title">
|
||||||
|
<label :for="uid">
|
||||||
|
<div class="c-labeled-input__label">{{ options.label }}</div>
|
||||||
|
</label>
|
||||||
|
<input :id="uid"
|
||||||
|
:type="options.type"
|
||||||
|
:value="options.value"
|
||||||
|
v-bind="options.attrs"
|
||||||
|
@change="onChange"/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
let inputUniqueId = 100;
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
validator(value) {
|
||||||
|
return ['number', 'text'].indexOf(value.type) !== -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
inputUniqueId++;
|
||||||
|
return {
|
||||||
|
uid: `mct-input-id-${inputUniqueId}`
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onChange(event) {
|
||||||
|
this.$emit('change', event.target.value, this.options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
38
src/ui/components/toolbar/components/toolbar-menu.vue
Normal file
38
src/ui/components/toolbar/components/toolbar-menu.vue
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-ctrl-wrapper">
|
||||||
|
<div class="c-click-icon c-click-icon--menu"
|
||||||
|
:class="options.icon"
|
||||||
|
@click="toggle">
|
||||||
|
<div class="c-click-icon__label"
|
||||||
|
v-if="options.label">
|
||||||
|
{{ options.label }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="c-menu" v-if="open">
|
||||||
|
<ul>
|
||||||
|
<li v-for="option in options.options"
|
||||||
|
:class="option.class"
|
||||||
|
:title="option.title">
|
||||||
|
{{ option.name }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import toggle from './toggle-mixin';
|
||||||
|
export default {
|
||||||
|
mixins: [toggle],
|
||||||
|
props: {
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
validator(value) {
|
||||||
|
// must pass valid options array.
|
||||||
|
return Array.isArray(value.options) &&
|
||||||
|
value.options.every((o) => o.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
55
src/ui/components/toolbar/components/toolbar-select-menu.vue
Normal file
55
src/ui/components/toolbar/components/toolbar-select-menu.vue
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-ctrl-wrapper">
|
||||||
|
<div class="c-click-icon c-click-icon--menu"
|
||||||
|
:class="options.icon"
|
||||||
|
@click="toggle">
|
||||||
|
<div class="c-button__label">{{ selectedName }}</div>
|
||||||
|
</div>
|
||||||
|
<div class="c-menu" v-if="open">
|
||||||
|
<ul>
|
||||||
|
<li v-for="option in options.options"
|
||||||
|
:key="option.value"
|
||||||
|
@click="select(option)">
|
||||||
|
{{ option.name }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import toggleMixin from './toggle-mixin';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
mixins: [toggleMixin],
|
||||||
|
props: {
|
||||||
|
options: {
|
||||||
|
type: Object,
|
||||||
|
validator(value) {
|
||||||
|
// must pass valid options array.
|
||||||
|
return Array.isArray(value.options) &&
|
||||||
|
value.options.every((o) => o.value && o.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
select(option) {
|
||||||
|
if (this.options.value === option.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.$emit('change', option.value, this.options);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
selectedName() {
|
||||||
|
let selectedOption = this.options.options.filter((o) => o.value === this.options.value)[0];
|
||||||
|
if (selectedOption) {
|
||||||
|
return selectedOption.name
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
13
src/ui/components/toolbar/components/toolbar-separator.vue
Normal file
13
src/ui/components/toolbar/components/toolbar-separator.vue
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="c-button-set"></div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
options: Object
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -0,0 +1,34 @@
|
|||||||
|
<template>
|
||||||
|
<div class="c-ctrl-wrapper">
|
||||||
|
<div class="c-click-icon"
|
||||||
|
:title="nextValue.title"
|
||||||
|
:class="nextValue.icon"
|
||||||
|
@click="cycle">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
options: {
|
||||||
|
type: Object
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
nextValue() {
|
||||||
|
let currentValue = this.options.options.filter((v) => this.options.value === v.value)[0];
|
||||||
|
let nextIndex = this.options.options.indexOf(currentValue) + 1;
|
||||||
|
if (nextIndex >= this.options.options.length) {
|
||||||
|
nextIndex = 0;
|
||||||
|
}
|
||||||
|
return this.options.options[nextIndex];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
cycle() {
|
||||||
|
this.$emit('change', this.nextValue.value, this.options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
Loading…
x
Reference in New Issue
Block a user