This commit is contained in:
锦恢 2024-02-24 23:13:16 +08:00
parent 7ba166ea59
commit 0c21631357
16 changed files with 583 additions and 156 deletions

View File

@ -1,8 +1,8 @@
@font-face { @font-face {
font-family: "iconfont"; /* Project id 4440655 */ font-family: "iconfont"; /* Project id 4440655 */
src: url('iconfont.woff2?t=1708523702559') format('woff2'), src: url('iconfont.woff2?t=1708609094813') format('woff2'),
url('iconfont.woff?t=1708523702559') format('woff'), url('iconfont.woff?t=1708609094813') format('woff'),
url('iconfont.ttf?t=1708523702559') format('truetype'); url('iconfont.ttf?t=1708609094813') format('truetype');
} }
.iconfont { .iconfont {
@ -13,6 +13,18 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-about:before {
content: "\e601";
}
.icon-setting:before {
content: "\e657";
}
.icon-Collections:before {
content: "\e689";
}
.icon-memory-chip:before { .icon-memory-chip:before {
content: "\e600"; content: "\e600";
} }

Binary file not shown.

View File

@ -24,30 +24,11 @@ html, body {
} }
.vcd-treeview { * hr {
position: absolute; border: none;
bottom: 0; background-color: var(--vscode-focusBorder);
left: 10px; height: 2px;
height: 500px; width: 95%;
background-color: var(--sidebar);
padding: 10px;
height: fit-content;
display: flex;
box-shadow: 0 0 15px 1px rgb(16, 16, 16);
border-radius: 1.0em;
}
.vcd-signal-info {
height: 500px;
width: 300px;
padding-right: 5px;
overflow-x: scroll;
}
.vcd-signal-wires {
height: 500px;
width: 300px;
overflow-x: scroll;
} }
::-webkit-scrollbar { ::-webkit-scrollbar {

View File

@ -15,32 +15,22 @@
</div> </div>
<!-- 显示当前信号树形关系 --> <!-- 显示当前信号树形关系 -->
<div class="vcd-treeview"> <!-- 右侧工具合集 -->
<div class="vcd-signal-info"> <RightNav :topModules="VcdInfo.topModules"></RightNav>
<Signals v-for="mod of VcdInfo.topModules"
:key="mod.name"
:signal="mod"
></Signals>
</div>
<div class="vcd-signal-wires">
<Wires></Wires>
</div>
</div>
</div> </div>
</template> </template>
<script> <script>
import { onMounted, reactive } from 'vue'; import { onMounted, reactive } from 'vue';
import { getVcdStream, readVcdFile } from '@/hook/utils'; import { getVcdStream, readVcdFile } from '@/hook/utils';
import { emitter } from '@/hook/event'; import { emitter } from '@/hook/global';
import Signals from '@/components/signals.vue'; import RightNav from '@/components/right-nav.vue';
import Wires from '@/components/wires.vue';
export default { export default {
components: { components: {
Signals, RightNav
Wires
}, },
setup() { setup() {
@ -61,12 +51,16 @@ export default {
VcdInfo.topModules.push(topModule); VcdInfo.topModules.push(topModule);
} }
// timestamp when vcd is loaded
// send wires of first module // send wires of first module
if (VcdInfo.topModules.length > 0) { if (VcdInfo.topModules.length > 0) {
const defaultMod = VcdInfo.topModules[0]; const defaultMod = VcdInfo.topModules[0];
const wires = defaultMod.body.filter(mod => mod.link); const wires = defaultMod.body.filter(mod => mod.link);
emitter.emit('tree-view', wires); emitter.emit('tree-view', wires);
} }
}); });
return { return {
@ -83,8 +77,5 @@ export default {
font-family: Avenir, Helvetica, Arial, sans-serif; font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
} }
</style> </style>

BIN
src/assets/icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

BIN
src/assets/images/dide.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,74 @@
<template>
<div class="about-wrapper">
<div class="icon-caption" @click="goto('https://github.com/Digital-EDA')">
<img src="../../assets/icon.png" height="200px" alt="">
</div>
<div class="version-caption">
<span>当前版本 &ensp; <span class="version-wrapper">0.3.3</span></span>
</div>
<hr>
<div style="display: flex;justify-content: space-around;">
<div class="copyright-caption">本软件版权归
<a href="https://github.com/Digital-EDA" target="_blank">Digital-IDE</a> 项目组所有欢迎 <a href="https://github.com/Digital-EDA/Digital-IDE">Star</a></div>
<div class="copyright-caption">The copyright of this software belongs to
<a href="https://github.com/Digital-EDA" target="_blank">Digital-IDE</a> project team. Welcome to <a href="https://github.com/Digital-EDA/Digital-IDE">Star</a>.</div>
</div>
</div>
</template>
<script>
export default {
name: 'dide-about',
setup() {
function goto(url) {
window.open(url, '_blank');
}
return {
goto
}
}
}
</script>
<style>
.about-wrapper {
margin-top: 20px;
padding: 10px;
width: 600px;
}
.version-caption {
display: flex;
width: 100% !important;
font-size: 20px;
padding: 10px;
margin: 10px;
align-items: center;
justify-content: space-evenly;
}
.copyright-caption {
width: 50% !important;
line-height: 30px;
font-size: 20px;
padding: 10px;
margin: 10px;
align-items: center;
}
.icon-caption {
display: flex;
align-items: center;
justify-content: space-around;
cursor: pointer;
}
.version-wrapper {
border-radius: .5em;
color: white;
background-color: var(--color-deepPurple);
padding: 5px;
}
</style>

View File

@ -0,0 +1,126 @@
<template>
<div class="vcd-right-nav">
<div class="vcd-function-panel">
<TreeView :topModules="props.topModules"
v-show="controlPanel.currentIndex === 0"></TreeView>
<Setting
v-show="controlPanel.currentIndex === 1"></Setting>
<About
v-show="controlPanel.currentIndex === 2"></About>
</div>
<div class="vcd-function-option">
<div class="vcd-control-panel-wrapper">
<img class="vcd-control-panel-icon" src="../assets/icon.png" alt="">
</div>
<hr>
<div class="vcd-control-panel-wrapper"
v-for="(section, index) of controlPanel.sections" :key="index"
@click="controlPanel.click(index)"
>
<div :class="controlPanel.currentIndex === index ? 'vcd-control-panel-active': ''"><span
class="vcd-control-panel-icon"
:class="section.iconClass"
></span></div>
</div>
</div>
</div>
</template>
<script>
import { reactive } from 'vue';
import TreeView from '@/components/treeview';
import Setting from '@/components/setting';
import About from '@/components/about';
export default {
name: 'right-nav',
components: {
TreeView,
Setting,
About
},
props: {
topModules: Array
},
setup(props) {
const controlPanel = reactive({
sections: [
{
iconClass: 'iconfont icon-Collections'
},
{
iconClass: 'iconfont icon-setting'
},
{
iconClass: 'iconfont icon-about'
}
],
currentIndex: -1,
click(index) {
if (this.currentIndex === index) {
this.currentIndex = -1;
} else {
this.currentIndex = index;
}
console.log(this.currentIndex);
}
});
return {
props,
controlPanel
};
}
}
</script>
<style>
.vcd-right-nav {
display: flex;
position: absolute;
top: 0;
right: 0;
}
.vcd-function-panel {
display: flex;
background-color: var(--sidebar);
height: 100vh;
box-shadow: 0 0 15px 1px rgb(16, 16, 16);
}
.vcd-function-option {
width: fit-content;
height: 100vh;
box-shadow: 0 0 15px 1px rgb(16, 16, 16);
}
.vcd-control-panel-wrapper {
width: 60px;
height: 60px;
display: flex;
align-items: center;
justify-content: space-around;
cursor: pointer;
margin-top: 10px;
}
.vcd-control-panel-wrapper:hover {
color: var(--vscode-icon-foreground);
}
.vcd-control-panel-icon {
width: 50px;
height: 50px;
font-size: 35px;
}
.vcd-control-panel-active {
color: var(--main-color);
}
</style>

View File

@ -0,0 +1,33 @@
<template>
<div class="setting-wrapper">
<div class="section">
</div>
<hr>
<div class="section">
</div>
</div>
</template>
<script>
export default {
name: 'dide-setting',
setup() {
}
}
</script>
<style>
.setting-wrapper {
width: 600px;
}
.setting-wrapper section {
padding: 10px;
margin: 10px;
border-radius: .3em;
min-height: 50px;
}
</style>

View File

@ -1,92 +0,0 @@
<template>
<div class="signal">
<div v-on:click="clickItem()" class="vcd-treeview-item">
<span class="iconfont icon-memory-chip"></span>&ensp;{{ signal.name }}
</div>
<div v-if="signal.body" v-show="expanded" class="vcd-subtree-wrapper">
<div style="width: 20px;"></div>
<div style="width: 100%;">
<signals
v-for="(child, index) in signal.body"
:signal="child"
:key="index"
></signals>
</div>
</div>
</div>
</template>
<script>
/* eslint-disable */
import { ref } from 'vue';
import { emitter } from '@/hook/event';
export default {
name: "signals",
props: {
signal: Object
},
setup(props) {
const signal = props.signal;
const signalChildern = signal.body;
const wires = [];
signal.body = [];
for (const wire of signalChildern) {
if (wire.body) {
signal.body.push(wire);
} else {
wires.push(wire);
}
}
const expanded = ref(true);
function clickItem() {
emitter.emit('tree-view', wires);
if (signal.body === undefined) {
return;
}
expanded.value = !expanded.value;
}
return {
signal,
expanded,
clickItem
}
}
};
</script>
<style>
.icon-memory-chip {
color: #FF7043;
}
.signal {
text-align: left;
}
.vcd-subtree-wrapper {
display: flex;
width: 100%;
}
.vcd-treeview-item {
color: var(--sidebar-item-text);
cursor: pointer;
height: 27px;
display: flex;
align-items: center;
}
.vcd-treeview-item::selection {
background: none;
}
.vcd-treeview-item:hover {
background-color: #3D4450;
border-radius: .3em;
}
</style>

View File

@ -0,0 +1,76 @@
<template>
<!-- treeview -->
<div class="vcd-treeview">
<TreeViewSearch></TreeViewSearch>
<br>
<div style="display: flex;">
<div class="vcd-signal-info">
<div>Modules</div>
<hr>
<Signals v-for="mod of props.topModules"
:key="mod.name"
:signal="mod"
></Signals>
</div>
<div class="vcd-signal-wires">
<Wires></Wires>
</div>
</div>
</div>
</template>
<script>
import { onMounted } from 'vue';
import TreeViewSearch from '@/components/treeview/search.vue';
import Signals from '@/components/treeview/signals.vue';
import Wires from '@/components/treeview/wires.vue';
import { emitter } from '@/hook/global';
export default {
name: 'tree-view',
components: {
Signals,
Wires,
TreeViewSearch
},
props: {
topModules: Array
},
setup(props) {
onMounted(() => {
});
return {
props
}
}
}
</script>
<style>
.vcd-signal-info {
height: 80vh;
width: 300px;
padding-right: 5px;
overflow-x: scroll;
}
.vcd-signal-wires {
height: 80vh;
width: 300px;
overflow-x: scroll;
}
.vcd-treeview {
background-color: var(--sidebar);
padding: 10px;
height: fit-content;
border-radius: 1.0em;
}
</style>

View File

@ -0,0 +1,51 @@
<template>
<div class="tree-view-search-wrapper">
<input type="text" class="tree-view-search" placeholder="Search Signal">
</div>
</template>
<script>
export default {
name: 'tree-view-search',
setup() {
return {
}
}
}
</script>
<style>
.tree-view-search-wrapper {
height: 30px;
padding: 10px;
margin-bottom: 10px;
}
.tree-view-search[type="text"] {
color: var(--input-foreground);
background-color: var(--input-background);
border-radius: var(--input-radius);
border: .5px solid var(--input-border);
font-size: 18px;
padding: 6px;
width: 98%;
}
.tree-view-search[type="text"]:focus {
color: var(--input-active-foreground);
background-color: var(--input-active-background);
border: .5px solid var(--input-active-border);
outline: none;
}
.tree-view-search[type="text"]:hover {
background-color: var(--input-hover);
}
.tree-view-search[type="text"]::placeholder {
color: var(--input-placeholder);
}
</style>

View File

@ -0,0 +1,139 @@
<template>
<div class="signal">
<div @click="clickItem()" class="vcd-treeview-item"
:class="signal === globalLookup.currentSignal ? 'vcd-treeview-selected' : ''">
<span class="signal-tag-status" @click.stop="expandManage.click">
<div :class="expandManage.expandTagClass"></div>
</span>
<span class="iconfont icon-memory-chip"></span>
&ensp;{{ signal.name }}
</div>
<div v-if="signal.body" v-show="expandManage.expanded" class="vcd-subtree-wrapper">
<div style="width: 20px;"></div>
<div style="width: 100%;">
<signals
v-for="(child, index) in signal.body"
:signal="child"
:key="index"
></signals>
</div>
</div>
</div>
</template>
<script>
/* eslint-disable */
import { reactive, onMounted } from 'vue';
import { emitter, globalLookup } from '@/hook/global';
export default {
name: "signals",
props: {
signal: Object
},
setup(props) {
const signal = props.signal;
const signalChildern = signal.body;
globalLookup.initCurrentSignal(signal);
const wires = [];
signal.body = [];
for (const wire of signalChildern) {
if (wire.body) {
signal.body.push(wire);
} else {
wires.push(wire);
}
}
function clickItem() {
emitter.emit('tree-view', wires);
// color change into selected
globalLookup.currentSignal = signal;
}
const expandManage = reactive({
expanded: true,
expandTagClass: signal.body.length === 0 ? '' : 'expand-tag',
click() {
this.expanded = !this.expanded;
if (this.expandTagClass) {
this.expandTagClass = this.expanded ? 'expand-tag' : 'collapse-tag';
}
}
});
return {
signal,
clickItem,
expandManage,
globalLookup
}
}
};
</script>
<style>
.icon-memory-chip {
color: #FF7043;
}
.signal {
text-align: left;
}
.vcd-subtree-wrapper {
display: flex;
width: 100%;
}
.vcd-treeview-item {
color: var(--sidebar-item-text);
cursor: pointer;
height: 27px;
display: flex;
align-items: center;
}
.vcd-treeview-item::selection {
background: none;
}
.vcd-treeview-item:hover {
background-color: var(--vscode-button-hoverBackground);
border-radius: .3em;
}
.vcd-treeview-selected {
background-color: var(--vscode-button-hoverBackground);
border-radius: .3em;
}
.signal-tag-status {
width: 25px;
height: 25px;
align-items: center;
justify-content: space-around;
display: flex;
}
.expand-tag {
height: 7px;
width: 7px;
border-top: solid 1.7px var(--sidebar-item-text);
border-left: solid 1.7px var(--sidebar-item-text);
transform: rotate(225deg);
}
.collapse-tag {
height: 7px;
width: 7px;
border-top: solid 1.7px var(--sidebar-item-text);
border-left: solid 1.7px var(--sidebar-item-text);
transform: rotate(135deg);
}
</style>

View File

@ -1,12 +1,17 @@
<template> <template>
<div class="vcd-signal-wires-display"> <div>
<div v-for="(wire, index) in wires.content" :key="index" <div>Signals({{wires.content.length}})</div>
class="vcd-signal-wire-item"> <hr>
<div class="vcd-signal-wires-display">
<div><span class="iconfont icon-wave-square"></span>&ensp;{{ wire.name }}</div> <div v-for="(wire, index) in wires.content" :key="index"
<div> @click="clickItem(wire)"
<div :class="wire.caption ? 'vcd-signal-wire-caption' : ''"> class="vcd-signal-wire-item"
{{ wire.caption }} :class="globalLookup.currentWires.has(wire) ? 'vcd-treeview-selected' : ''">
<div><span class="iconfont icon-wave-square"></span>&ensp;{{ wire.name }}</div>
<div>
<div :class="wire.caption ? 'vcd-signal-wire-caption' : ''">
{{ wire.caption }}
</div>
</div> </div>
</div> </div>
</div> </div>
@ -15,7 +20,7 @@
<script> <script>
import { reactive } from 'vue'; import { reactive } from 'vue';
import { emitter } from '@/hook/event'; import { emitter, globalLookup } from '@/hook/global';
/* eslint-disable */ /* eslint-disable */
export default { export default {
@ -30,7 +35,6 @@ export default {
emitter.on('tree-view', sendWires => { emitter.on('tree-view', sendWires => {
wires.content.length = 0; wires.content.length = 0;
for (const wire of sendWires) { for (const wire of sendWires) {
console.log(wire);
const caption = wire.size === 1 ? '' : `${wire.size - 1}:0`; const caption = wire.size === 1 ? '' : `${wire.size - 1}:0`;
wires.content.push({ wires.content.push({
name: wire.name, name: wire.name,
@ -39,8 +43,18 @@ export default {
} }
}); });
function clickItem(wire) {
if (globalLookup.currentWires.has(wire)) {
globalLookup.currentWires.delete(wire);
} else {
globalLookup.currentWires.add(wire);
}
}
return { return {
wires wires,
clickItem,
globalLookup
} }
} }
} }
@ -66,7 +80,7 @@ export default {
} }
.vcd-signal-wire-item:hover { .vcd-signal-wire-item:hover {
background-color: #3D4450; background-color: var(--vscode-button-hoverBackground);
border-radius: .3em; border-radius: .3em;
} }

View File

@ -1,6 +0,0 @@
import mitt from 'mitt';
const emitter = mitt();
export {
emitter
};

28
src/hook/global.js Normal file
View File

@ -0,0 +1,28 @@
import mitt from 'mitt';
import { reactive } from 'vue';
const emitter = mitt();
// 用于记载全局的一些对象,以便在不同组件中比较 ID
const globalLookup = reactive({
// 当前选中的 信号,也就是 tree-view 左列的,默认是第一个。不可复选。
currentSignal: undefined,
// 当前选中的某个 信号 的 数据。可复选。
currentWires: new Set(),
initCurrentSignal(signal) {
if (this.currentSignal === undefined && signal) {
this.currentSignal = signal;
}
}
});
const globalSetting = {
caseSensitivity: false
};
export {
emitter,
globalLookup,
globalSetting
};