ui: Optimize context menu

Signed-off-by: Jianhui Zhao <jianhuizhao329@gmail.com>
This commit is contained in:
Jianhui Zhao
2018-06-02 01:39:45 +08:00
parent ac90459c66
commit 64eb95928e
5 changed files with 139 additions and 24 deletions
Regular → Executable
+19 -22
View File
@@ -2,17 +2,9 @@
<div id="app">
<Input v-if="!terminal.show" v-model="searchString" icon="search" size="large" @on-change="handleSearch" placeholder="Please enter the filter key..." style="width: 400px" />
<Table v-if="!terminal.show" :loading="devices.loading" :height="devices.height" :columns="devlistTitle" :data="devices.filtered" style="width: 100%"></Table>
<div ref="terminal" class="terminal" v-if="terminal.show"></div>
<div ref="terminal" class="terminal" v-if="terminal.show" @contextmenu="$vuecontextmenu($event, $root)"></div>
<Spin size="large" fix v-if="terminal.loading"></Spin>
<Modal v-model="contextMenuVisible" width="21">
<Menu theme="light" @on-select="handleContextMenu">
<MenuItem name="upfile">Upload file to device</MenuItem>
<MenuItem name="downfile">Download file from device</MenuItem>
<MenuItem name="increasefontsize">Increase font size</MenuItem>
<MenuItem name="decreasefontsize">Decrease font size</MenuItem>
</Menu>
<div slot="footer"></div>
</Modal>
<vue-context-menu :contextMenuData="contextMenuData" @handleContextMenu="handleContextMenu"></vue-context-menu>
<Modal v-model="upfile.modal" width="360" :mask-closable="false" @on-cancel="cancelUpfile">
<p slot="header"><span>Upload file to device</span></p>
<Upload :before-upload="beforeUpload" action="">
@@ -48,8 +40,24 @@ Terminal.applyAddon(fit);
export default {
data() {
return {
contextMenuData: {
menulists: [
{
name: 'upfile',
caption: 'Upload file to device'
},{
name: 'downfile',
caption: 'Download file from device'
},{
name: 'increasefontsize',
caption: 'Increase font size'
},{
name: 'decreasefontsize',
caption: 'Decrease font size'
}
]
},
searchString: '',
contextMenuVisible: false,
terminal: {loading: false, show: false, term: null, recvCnt: 0},
devices: {loading: true, height: document.body.offsetHeight - 20, list: [], filtered: []},
upfile: {modal: false, file: null, step: 2048, pos: 0, canceled: false, percent: 0},
@@ -130,7 +138,6 @@ export default {
});
},
handleContextMenu(name) {
this.contextMenuVisible = false;
let changeFontSize = 0;
if (name == 'upfile') {
this.upfile = {modal: true, loading: false, file: null, step: 2048, pos: 0, canceled: false, percent: 0};
@@ -288,16 +295,6 @@ export default {
let pkt = rtty.newPacket(rtty.RTTY_PACKET_TTY, {sid: this.sid, data: Buffer.from(data)});
ws.send(pkt);
});
term.attachCustomKeyEventHandler((e) => {
if (e.type == 'keydown') {
if (e.ctrlKey && e.shiftKey) {
if (e.key == 'F') {
this.contextMenuVisible = true;
}
}
}
});
} else if (pkt.typ == rtty.RTTY_PACKET_TTY) {
this.terminal.recvCnt++;
var data = pkt.data.toString();
Regular → Executable
+3
View File
@@ -6,11 +6,14 @@ import iView from 'iview'
import 'iview/dist/styles/iview.css'
import locale from 'iview/dist/locale/en-US';
import '@zhaojh329/string.format.js'
import VueContextMenu from '../vue-contextmenu'
Vue.config.productionTip = false
Vue.use(iView, { locale });
Vue.use(VueContextMenu)
/* eslint-disable no-new */
new Vue({
el: '#app',
+89
View File
@@ -0,0 +1,89 @@
<template>
<div ref="contextmenu" class="contextmenu-content" :style="axisComputed" v-if="show" contextmenu='1'>
<a v-for="item in contextMenuData.menulists" @click.stop="menuHandler(item)">{{item.caption}}</a>
</div>
</template>
<script>
export default {
data() {
return {
show: false,
axis: {x: 0, y: 0}
}
},
props: {
contextMenuData: {
type: Object,
requred: true
},
tag: {
type: String,
requred: false
}
},
mounted() {
this.$root.$on('showVueContextMenu', (args) => {
if (args.tag == this.tag) {
this.show = true
this.axis = {x: args.x, y: args.y};
}
});
document.addEventListener('mousedown', (e) => {
if (e.target.tagName == 'A')
return;
this.show = false;
}, true);
},
updated() {
if (this.$refs.contextmenu) {
let bw = document.body.offsetWidth;
let bh = document.body.offsetHeight;
let width = this.$refs.contextmenu.offsetWidth;
let height = this.$refs.contextmenu.offsetHeight;
if (this.axis.x + width >= bw)
this.axis.x = bw - width;
if (this.axis.y + height >= bh)
this.axis.y = bh - height;
}
},
computed: {
axisComputed() {
return {
top: this.axis.y + 'px',
left: this.axis.x + 'px'
}
}
},
methods: {
menuHandler (item) {
this.show = false;
this.$emit('handleContextMenu', item.name);
}
}
}
</script>
<style scoped>
.contextmenu-content {
position: fixed;
z-index: 9999;
background-color: #f9f9f9;
min-width: 160px;
box-shadow: 0px 8px 16px 0px rgba(0, 0, 0, 0.2);
}
.contextmenu-content a {
color: black;
padding: 5px 16px;
text-decoration: none;
display: block;
}
.contextmenu-content a:hover {
background-color: #90C8F6;
}
</style>
+24
View File
@@ -0,0 +1,24 @@
import VueContextMenuComponent from './VueContextMenu.vue'
const VueContextMenu = {
install: function (Vue) {
Vue.component('VueContextMenu', VueContextMenuComponent)
Vue.prototype.$vuecontextmenu = function (e, root, id) {
e.stopPropagation();
e.preventDefault();
root.$emit('showVueContextMenu', {
id: id,
x: e.clientX,
y: e.clientY
})
}
}
}
if (typeof window !== 'undefined' && window.Vue) {
window.Vue.use(VueContextMenu)
}
export default VueContextMenu