From eef490641169a9c0ce56cc3450c672a8dcbc1624 Mon Sep 17 00:00:00 2001 From: Sam Wray Date: Mon, 13 Nov 2017 14:01:33 +0000 Subject: [PATCH] Adds context menu to Layers --- package-lock.json | 44 ++++++-- src/components/Layer/index.vue | 138 ++++++++++++++++++++++--- src/components/LayerControls.vue | 22 ++-- src/extra/context-menu/Menu.vue | 2 +- src/extra/context-menu/MenuHandler.vue | 4 +- src/extra/context-menu/index.js | 6 ++ src/main.js | 4 + src/vuePlugins/capitalize-filter.js | 14 +++ 8 files changed, 195 insertions(+), 39 deletions(-) create mode 100644 src/vuePlugins/capitalize-filter.js diff --git a/package-lock.json b/package-lock.json index a191f3857..27bc2116a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -150,7 +150,7 @@ "string-width": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha1-q5Pyeo3BPSjKyBXEYhQ6bZASrp4=", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", "requires": { "is-fullwidth-code-point": "2.0.0", "strip-ansi": "4.0.0" @@ -1733,6 +1733,16 @@ "electron-to-chromium": "1.3.26" } }, + "buefy": { + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/buefy/-/buefy-0.5.4.tgz", + "integrity": "sha512-E1gCh98+qrltr1tTULUpyPFcqK4I9QEIpCh7gEJFagAO0AhEDaqpKkbpKp25CBx81LfYfpKrq/NIWH4tSCsBjw==", + "dev": true, + "requires": { + "bulma": "0.5.3", + "vue": "2.4.4" + } + }, "buffer": { "version": "4.9.1", "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", @@ -1775,6 +1785,12 @@ "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", "dev": true }, + "bulma": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/bulma/-/bulma-0.5.3.tgz", + "integrity": "sha1-vpOvtiRhklBcMN8/nBwpqX0xmhM=", + "dev": true + }, "bytes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", @@ -1876,7 +1892,7 @@ "ccapture.js": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/ccapture.js/-/ccapture.js-1.0.7.tgz", - "integrity": "sha1-hDfrFFRZJfKJamk7bSLNoYdqjTY=", + "integrity": "sha512-RuIOv/DDUR9PF9QU/NdkxjYQ/0zXi8jHfPc6ua6ljVZgq281iale5LBUNvv/5SDc5mW7i4KEIH5qTRmhKnPZjw==", "dev": true }, "center-align": { @@ -2180,7 +2196,7 @@ "complex.js": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/complex.js/-/complex.js-2.0.4.tgz", - "integrity": "sha1-2OfPuWUtHoU+cjOGQhwaDKekg3M=" + "integrity": "sha512-Syl95HpxUTS0QjwNxencZsKukgh1zdS9uXeXX2Us0pHaqBR6kiZZi0AkZ9VpZFwHJyVIUVzI4EumjWdXP3fy6w==" }, "component-bind": { "version": "1.0.0", @@ -2831,7 +2847,7 @@ "decimal.js": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-7.2.3.tgz", - "integrity": "sha1-ZDTDuKjDdXgAYvxjPQ0rvbJkzHg=" + "integrity": "sha512-AoFI37QS0S87Ft0r3Bdz4q9xSpm1Paa9lSeKLXgMPk/u/+QPIM5Gy4DHcZQS1seqPJH4gHLauPGn347z0HbsrA==" }, "deep-eql": { "version": "0.1.3", @@ -4546,7 +4562,7 @@ "fraction.js": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.0.2.tgz", - "integrity": "sha1-Dq6JZibzNLG952M3E0eoO1V11/A=" + "integrity": "sha512-OswcigOSil3vYXgrPSx4NCaSyPikXqVNYN/4CyhS0ucVOJ4GVYr6KQQLLcAudvS/4bBOzxqJ3XIsFaaMjl98ZQ==" }, "frame-debounce": { "version": "0.0.0", @@ -5498,7 +5514,7 @@ "glob": { "version": "7.1.2", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", "requires": { "fs.realpath": "1.0.0", "inflight": "1.0.6", @@ -6897,7 +6913,7 @@ "istanbul-lib-coverage": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz", - "integrity": "sha1-c7+5mIhSmUFck9OKPprfeEp3qdo=", + "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==", "dev": true }, "istanbul-lib-instrument": { @@ -8075,7 +8091,7 @@ "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", "requires": { "brace-expansion": "1.1.8" } @@ -11682,7 +11698,7 @@ "nw-builder": { "version": "3.4.1", "resolved": "https://registry.npmjs.org/nw-builder/-/nw-builder-3.4.1.tgz", - "integrity": "sha1-e+TzKX2DaBci6sBm5xuu1S+QxeE=", + "integrity": "sha512-lW5sJnHkWRhofYAzaw2tGtEtXilENZrKOwpnFJn+hpn4pEpAfl1Krbcbt+mL/L/qMe1M1+SFp1IukU4WlJXkMw==", "requires": { "archiver": "1.3.0", "boxen": "1.2.1", @@ -15171,7 +15187,7 @@ "test-exclude": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.1.1.tgz", - "integrity": "sha1-TYSWSwlmsAh+zDNKLOAC09k0HiY=", + "integrity": "sha512-35+Asrsk3XHJDBgf/VRFexPgh3UyETv8IAn/LRTiZjVy6rjPVqdEk8dJcJYBzl1w0XCJM48lvTy8SfEsCWS4nA==", "dev": true, "requires": { "arrify": "1.0.1", @@ -15831,6 +15847,12 @@ "vue": "2.4.4" } }, + "vuebar": { + "version": "0.0.17", + "resolved": "https://registry.npmjs.org/vuebar/-/vuebar-0.0.17.tgz", + "integrity": "sha512-UbGfCc8sriQzqanrLIfT9QZVwvfPyyTYVaiv+mj1QE6OhqeKC4vDw4wsAU0okkVS5JBxALYzNBvDY8HA0eCBZQ==", + "dev": true + }, "vuedraggable": { "version": "git+https://github.com/SortableJS/Vue.Draggable.git#d108f3ca2ae9acf6a203ae68e0c2135c42187bb3", "requires": { @@ -16156,7 +16178,7 @@ "wide-align": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz", - "integrity": "sha1-Vx4PGwYEY268DfwhsDObvjE0FxA=", + "integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==", "dev": true, "requires": { "string-width": "1.0.2" diff --git a/src/components/Layer/index.vue b/src/components/Layer/index.vue index 6dad01b81..f9d91cf47 100644 --- a/src/components/Layer/index.vue +++ b/src/components/Layer/index.vue @@ -7,6 +7,7 @@ collapsed: collapsed }" @click="focusLayer" + v-context-menu="menuOptions" >
@@ -61,6 +62,16 @@ import { mapActions, mapGetters, mapMutations } from 'vuex'; import ActiveModule from '@/components/ActiveModule'; import draggable from 'vuedraggable'; + import { Menu, MenuItem } from 'nwjs-menu-browser'; + + if (!window.nw) { + window.nw = { + Menu, + MenuItem, + }; + } + + const nw = window.nw; export default { name: 'layer', @@ -68,6 +79,19 @@ 'Layer', 'LayerIndex', ], + data() { + return { + menuOptions: { + match: ['layerItem'], + menuItems: [], + createMenus: this.createMenus, + }, + clearingChecked: false, + inheritChecked: false, + pipelineChecked: false, + drawToOutputChecked: false, + }; + }, computed: { modules: { get() { @@ -93,6 +117,26 @@ ]), }, methods: { + ...mapActions('layers', [ + 'addLayer', + 'toggleLocked', + 'toggleCollapsed', + 'addModuleToLayer', + 'updateModuleOrder', + 'moveModuleInstance', + ]), + ...mapActions('modVModules', [ + 'createActiveModule', + ]), + ...mapMutations('layers', [ + 'setLayerName', + 'setLayerFocus', + 'setClearing', + 'setInherit', + 'setInheritFrom', + 'setPipeline', + 'setDrawToOutput', + ]), drop(e) { e.preventDefault(); const moduleName = e.item.dataset.moduleName; @@ -122,21 +166,6 @@ e.item.classList.remove('deletable'); } }, - ...mapActions('layers', [ - 'addLayer', - 'toggleLocked', - 'toggleCollapsed', - 'addModuleToLayer', - 'updateModuleOrder', - 'moveModuleInstance', - ]), - ...mapActions('modVModules', [ - 'createActiveModule', - ]), - ...mapMutations('layers', [ - 'setLayerName', - 'setLayerFocus', - ]), startNameEdit() { const node = this.$el.querySelector('.layer-title'); if (node.classList.contains('editable')) return; @@ -187,6 +216,85 @@ clickToggleCollapse() { this.toggleCollapsed({ layerIndex: this.LayerIndex }); }, + updateChecked() { + const Layer = this.Layer; + + this.clearingChecked = Layer.clearing; + this.inheritChecked = Layer.inherit; + this.inheritanceIndex = Layer.inheritFrom; + this.pipelineChecked = Layer.pipeline; + this.drawToOutputChecked = Layer.drawToOutput; + }, + createMenus() { + const that = this; + + this.menuOptions.menuItems.splice(0, this.menuOptions.menuItems.length); + + this.menuOptions.menuItems.push( + new nw.MenuItem({ + label: this.name, + enabled: false, + }), + new nw.MenuItem({ + type: 'separator', + }), + new nw.MenuItem({ + type: 'checkbox', + label: 'Clearing', + checked: this.clearingChecked, + click: function click() { + that.setClearing({ + layerIndex: that.LayerIndex, + clearing: this.checked, + }); + }, + }), + new nw.MenuItem({ + type: 'checkbox', + label: 'Inherit', + checked: this.inheritChecked, + click: function click() { + that.setInherit({ + layerIndex: that.LayerIndex, + inherit: this.checked, + }); + }, + }), + new nw.MenuItem({ + type: 'checkbox', + label: 'Pipeline', + checked: this.pipelineChecked, + click: function click() { + that.setPipeline({ + layerIndex: that.LayerIndex, + pipeline: this.checked, + }); + }, + }), + new nw.MenuItem({ + type: 'checkbox', + label: 'Draw To Output', + checked: this.drawToOutputChecked, + click: function click() { + that.setDrawToOutput({ + layerIndex: that.LayerIndex, + drawToOutput: this.checked, + }); + }, + }), + ); + }, + }, + beforeMount() { + this.updateChecked(); + }, + watch: { + Layer: { + handler() { + this.updateChecked(); + }, + deep: true, + }, }, components: { ActiveModule, diff --git a/src/components/LayerControls.vue b/src/components/LayerControls.vue index 1d30d7542..42da2a5d3 100644 --- a/src/components/LayerControls.vue +++ b/src/components/LayerControls.vue @@ -83,10 +83,7 @@ 'setPipeline', 'setDrawToOutput', ]), - }, - watch: { - name() { - if (!this.Layer) return; + updateChecked() { const Layer = this.Layer; this.clearingChecked = Layer.clearing; @@ -95,6 +92,15 @@ this.pipelineChecked = Layer.pipeline; this.drawToOutputChecked = Layer.drawToOutput; }, + }, + watch: { + Layer: { + handler() { + if (!this.Layer) return; + this.updateChecked(); + }, + deep: true, + }, clearingChecked() { this.setClearing({ layerIndex: this.layerIndex, @@ -116,12 +122,8 @@ }, mounted() { if (!this.Layer) return; - const Layer = this.Layer; - this.clearingChecked = Layer.clearing; - this.inheritChecked = Layer.inherit; - this.inheritanceIndex = Layer.inheritFrom; - this.pipelineChecked = Layer.pipeline; - this.drawToOutputChecked = Layer.drawToOutput; + + this.updateChecked(); }, }; diff --git a/src/extra/context-menu/Menu.vue b/src/extra/context-menu/Menu.vue index 0a36a77da..390e76e5c 100644 --- a/src/extra/context-menu/Menu.vue +++ b/src/extra/context-menu/Menu.vue @@ -5,7 +5,7 @@
diff --git a/src/extra/context-menu/index.js b/src/extra/context-menu/index.js index b7a782bd3..c4eb38e94 100644 --- a/src/extra/context-menu/index.js +++ b/src/extra/context-menu/index.js @@ -25,6 +25,12 @@ function buildMenu(e, id, options, vnode, store) { menu.$id = id; menu.isSubmenu = false; + if ('createMenus' in options) { + if (typeof options.createMenus === 'function') { + options.createMenus(); + } + } + options.menuItems.forEach((item, idx) => menu.insert(item, idx)); const moduleName = vnode.context.moduleName; diff --git a/src/main.js b/src/main.js index 05b1e7e3f..c87ec9712 100644 --- a/src/main.js +++ b/src/main.js @@ -8,6 +8,8 @@ import VueThrottleEvent from 'vue-throttle-event'; import Buefy from 'buefy'; import Vuebar from 'vuebar'; +import Capitalize from '@/vuePlugins/capitalize-filter'; + import stats from '@/extra/stats'; import { ModuleISF, modV } from './modv'; import App from './App'; @@ -34,6 +36,8 @@ stats.dom.style.left = null; stats.dom.style.right = 0; stats.dom.classList.add('hidden'); +Vue.use(Capitalize); + Vue.use(Vuebar); Vue.use(Buefy, { defaultIconPack: 'fa', diff --git a/src/vuePlugins/capitalize-filter.js b/src/vuePlugins/capitalize-filter.js new file mode 100644 index 000000000..51fee856a --- /dev/null +++ b/src/vuePlugins/capitalize-filter.js @@ -0,0 +1,14 @@ +const CapitalizeFilter = {}; + +export default CapitalizeFilter.install = (Vue) => { + Vue.mixin({ + filters: { + capitalize(valueIn) { + let value = valueIn; + if (!value) return ''; + value = value.toString(); + return value.charAt(0).toUpperCase() + value.slice(1); + }, + }, + }); +};