digital-vcd-render/src/components/sidebar/signal-context-menu.vue

230 lines
6.5 KiB
Vue

<template>
<div class="sidebar-context-menu">
<div class="menu-container">
<div
class="menu-item-container"
@click="deleteSignalByView()"
>
<span class="menu-item-icon iconfont icon-delete"></span>
<span class="menu-item-name">{{ t('context-menu.delete') }}</span>
</div>
<div
class="menu-item-container"
@click="deleteAllSelectedSignals()"
>
<span class="menu-item-icon iconfont icon-delete"></span>
<span class="menu-item-name">{{ t('context-menu.delete-all-select') }}</span>
</div>
<div
class="menu-item-container"
@click="createGroup()"
>
<span class="menu-item-icon iconfont icon-group"></span>
<span class="menu-item-name">{{ t('context-menu.create-group') }}</span>
</div>
<div
class="menu-item-container"
@mouseenter="existGroup.show()"
@mouseleave="existGroup.hide()"
>
<span class="menu-item-icon iconfont icon-join-group"></span>
<span class="menu-item-name">{{ t('context-menu.join-group') }}</span>
<transition name="collapse-from-top">
<ExistGroup v-show="existGroup.display"></ExistGroup>
</transition>
</div>
<div
class="menu-item-container"
@mouseenter="colorPicker.show()"
@mouseleave="colorPicker.hide()"
>
<span class="menu-item-icon iconfont icon-change-color"></span>
<span class="menu-item-name">{{ t('context-menu.change-color') }}</span>
<transition name="collapse-from-top">
<ColorPicker v-show="colorPicker.display"></ColorPicker>
</transition>
</div>
</div>
<hr>
<div
v-if="contextmenu.currentWire"
class="basic-info"
>
<div class="info-item">
<span class="info-item-title">{{ t('context-menu.signal.name') }}</span>
<span>
{{ contextmenu.currentWire.name }} (<code>{{contextmenu.currentWire.link}}</code>)
</span>
</div>
<div class="info-item">
<span class="info-item-title">{{ t('context-menu.signal.type') }}</span>
<span>
<span :class="makeSignalIconClass(contextmenu.currentWire)"></span>
<span>{{ contextmenu.currentWire.type }}</span>
</span>
</div>
<div class="info-item">
<span class="info-item-title">{{ t('context-menu.signal.width') }}</span>
<span>{{ contextmenu.currentWire.size }}</span>
</div>
<div class="info-item">
<span class="info-item-title">{{ t('context-menu.signal.dep') }}</span>
<span v-html="makeFullSignalNameDeps(contextmenu.currentWire)"></span>
</div>
</div>
</div>
</template>
<script setup>
import { defineComponent, reactive, ref } from 'vue';
import { globalLookup } from '@/hook/global';
import { useI18n } from 'vue-i18n';
import { colorPicker, contextmenu, deleteAllSelectedSignals, deleteSignalByView } from './handle-contextmenu';
import { makeIconClass } from '@/hook/utils';
import ColorPicker from './color-picker.vue';
import ExistGroup from './exist-group.vue';
import { existGroup } from './exist-group';
import { createGroup } from './manage-group';
const { t } = useI18n();
defineComponent({ name: 'signal-context-menu' });
const props = defineProps({
});
const emits = defineEmits([]);
const predefineColors = reactive([
'#FF0000',
'#1AD834',
'#33E633',
'#FF4D7C',
'#ff4500',
'#ff8c00',
'#ffd700',
'#90ee90',
'#00ced1',
'#1e90ff',
'#c71585',
'#801fff',
'#7ca532',
]);
function makeSignalIconClass(signal) {
return 'iconfont ' + makeIconClass(signal);
}
/**
* @param {WireItemBaseInfo} signal
*/
function makeFullSignalNameDeps(signal) {
const deps = [];
while (signal) {
if (signal.name && signal.type) {
deps.push(signal);
}
signal = signal.parent;
}
let htmlString = '';
for (let i = deps.length - 1; i >= 0; -- i) {
const mod = deps[i];
// const displayName = mod.name.length > 6 ? mod.name.substring(0, 6) + '...' : mod.name;
const iconClass = makeIconClass(mod);
const iconText = `<span class="iconfont ${iconClass}"></span>${mod.name}`;
htmlString += iconText;
if (i > 0) {
htmlString += '<div class="dep-arrow"></div>';
}
}
htmlString = '<div class="signal-info-tooltip-wrapper">' + htmlString + '</div>';
return htmlString;
}
</script>
<style>
.sidebar-context-menu {
z-index: 200;
border-radius: .5em;
padding: 10px;
position: fixed;
box-shadow: 0 0 10px 1px rgb(16, 16, 16);
background-color: var(--sidebar);
border: solid 1px var(--sidebar-border);
}
.menu-container {
display: flex;
flex-direction: column;
align-items: center;
}
.menu-item-container {
font-size: 0.9rem;
display: flex;
align-items: center;
margin: 5px;
padding: 3px;
padding-left: 10px;
border-radius: .5em;
transition: var(--animation-3s);
cursor: pointer;
width: 95%;
position: relative;
}
.menu-item-container:hover {
color: var(--sidebar);
background: linear-gradient(
90deg,
#7CA532 25%,
rgba(200, 200, 200, 1) 37%,
rgba(255, 255, 255, 0) 63%
);
background-size: 400% 100%;
animation: loading-mask 1.5s cubic-bezier(0.23,1,0.32,1);
-webkit-animation: loading-mask 1.5s cubic-bezier(0.23,1,0.32,1);
transition: var(--animation-3s);
}
.menu-item-icon {
width: 42px;
font-size: 1.0rem;
}
.basic-info {
font-size: .8rem;
padding: 7px;
}
.info-item {
display: flex;
margin-top: 12px;
}
.info-item-title {
width: 75px;
}
.info-item code {
background-color: var(--button);
border-radius: .45em;
padding: 1px 5px;
margin: 1px 3px;
}
.info-item .iconfont {
margin-right: 10px;
}
.menu-item-container .el-color-picker__panel {
box-shadow: 0 0 10px 1px rgb(16, 16, 16);
}
</style>