update
This commit is contained in:
parent
0c21631357
commit
b120bc39b7
941
package-lock.json
generated
941
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -9,9 +9,11 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "^3.8.3",
|
||||
"element-plus": "^2.5.6",
|
||||
"mitt": "^3.0.1",
|
||||
"stream": "^0.0.2",
|
||||
"vue": "^3.2.13"
|
||||
"vue": "^3.2.13",
|
||||
"vue-i18n": "^9.9.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.12.16",
|
||||
@ -20,7 +22,9 @@
|
||||
"@vue/cli-plugin-eslint": "~5.0.0",
|
||||
"@vue/cli-service": "~5.0.0",
|
||||
"eslint": "^7.32.0",
|
||||
"eslint-plugin-vue": "^8.0.3"
|
||||
"eslint-plugin-vue": "^8.0.3",
|
||||
"unplugin-auto-import": "^0.17.5",
|
||||
"unplugin-vue-components": "^0.26.0"
|
||||
},
|
||||
"eslintConfig": {
|
||||
"root": true,
|
||||
|
@ -53,3 +53,26 @@ html, body {
|
||||
background: none;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.el-select__wrapper {
|
||||
background-color: transparent !important;
|
||||
width: 50% !important;
|
||||
min-width: 200px !important;
|
||||
padding: 13px !important;
|
||||
font-size: 16px !important;
|
||||
color: var(--sidebar-item-text) !important;
|
||||
}
|
||||
|
||||
.el-select__placeholder {
|
||||
color: var(--sidebar-item-text) !important;
|
||||
}
|
||||
|
||||
.el-select-dropdown {
|
||||
min-width: 300px !important;
|
||||
background-color: var(--sidebar);
|
||||
border: 1px solid var(--main-color);
|
||||
}
|
||||
|
||||
.el-checkbox-button__inner {
|
||||
font-size: 16px !important;
|
||||
}
|
25
src/App.vue
25
src/App.vue
@ -24,7 +24,7 @@
|
||||
<script>
|
||||
import { onMounted, reactive } from 'vue';
|
||||
import { getVcdStream, readVcdFile } from '@/hook/utils';
|
||||
import { emitter } from '@/hook/global';
|
||||
import { emitter, globalLookup } from '@/hook/global';
|
||||
|
||||
import RightNav from '@/components/right-nav.vue';
|
||||
|
||||
@ -40,6 +40,18 @@ export default {
|
||||
});
|
||||
|
||||
onMounted(async () => {
|
||||
// 改变默认颜色
|
||||
document.body.style.setProperty('--el-color-primary', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-color-primary-light-9', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-color-primary-light-3', 'var(--main-color)');
|
||||
document.body.style.setProperty('--el-text-color-secondary', 'var(--foreground)');
|
||||
document.body.style.setProperty('--el-text-color-regular', 'var(--foreground)');
|
||||
document.body.style.setProperty('--el-border-color', 'var(--vscode-focusBorder)');
|
||||
document.body.style.setProperty('--el-fill-color-blank', 'var(--sidebar)');
|
||||
document.body.style.setProperty('--el-fill-color-light', 'var(--vscode-button-hoverBackground)');
|
||||
document.body.style.setProperty('--el-switch-on-color', 'var(--main-color)');
|
||||
|
||||
|
||||
const uint8array = await readVcdFile();
|
||||
const vcdstream = await getVcdStream();
|
||||
const maxChunkLength = 1 << 17;
|
||||
@ -51,16 +63,17 @@ export default {
|
||||
VcdInfo.topModules.push(topModule);
|
||||
}
|
||||
|
||||
// timestamp when vcd is loaded
|
||||
// send wires of first module
|
||||
// 这一步时,已经加载完成
|
||||
// 默认第一个模块被选中
|
||||
if (VcdInfo.topModules.length > 0) {
|
||||
const defaultMod = VcdInfo.topModules[0];
|
||||
const wires = defaultMod.body.filter(mod => mod.link);
|
||||
emitter.emit('tree-view', wires);
|
||||
// 将顶层模块存储进全局对象,以便后续的搜索服务
|
||||
for (const mod of VcdInfo.topModules) {
|
||||
globalLookup.topModules.push(mod);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
});
|
||||
|
||||
return {
|
||||
|
@ -4,19 +4,18 @@
|
||||
<img src="../../assets/icon.png" height="200px" alt="">
|
||||
</div>
|
||||
<div class="version-caption">
|
||||
<span>当前版本   <span class="version-wrapper">0.3.3</span></span>
|
||||
<span>{{ t('current-version') }}   <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 class="copyright-caption" v-html="t('copyright')"></div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
export default {
|
||||
name: 'dide-about',
|
||||
setup() {
|
||||
@ -24,8 +23,11 @@ export default {
|
||||
window.open(url, '_blank');
|
||||
}
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
return {
|
||||
goto
|
||||
goto,
|
||||
t
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,75 @@
|
||||
<template>
|
||||
<div class="setting-wrapper">
|
||||
<div class="section">
|
||||
<div class="setting-section">
|
||||
<h2>{{ t('search-setting') }}</h2>
|
||||
<div class="setting-option">
|
||||
<span class="option-title">{{ t('case-sensitivity') }}</span>
|
||||
<el-switch v-model="globalSetting.caseSensitivity" />
|
||||
</div>
|
||||
|
||||
|
||||
<br>
|
||||
|
||||
<div class="setting-option">
|
||||
<span class="option-title">{{ t('search-scope') }}</span>
|
||||
<el-checkbox-group v-model="globalSetting.searchScope" size="default">
|
||||
<el-checkbox-button label="wire" border>wire </el-checkbox-button>
|
||||
<el-checkbox-button label="reg" border>reg </el-checkbox-button>
|
||||
<el-checkbox-button label="module" border>module</el-checkbox-button>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<hr>
|
||||
<div class="section">
|
||||
|
||||
<div class="setting-section">
|
||||
<h2>{{ t('general-setting') }}</h2>
|
||||
<div class="setting-option" style="width: 300px;">
|
||||
<span class="option-title">{{ t('language-setting') }}</span>
|
||||
|
||||
<el-select name="language-setting" class="language-setting" v-model="locale">
|
||||
<el-option
|
||||
v-for="option in languageSetting.options"
|
||||
:value="option.value"
|
||||
:label="option.text"
|
||||
:key="option.value">
|
||||
</el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { reactive } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { globalSetting } from '@/hook/global';
|
||||
|
||||
export default {
|
||||
name: 'dide-setting',
|
||||
setup() {
|
||||
const { t, locale } = useI18n();
|
||||
|
||||
const languageSetting = reactive({
|
||||
options: [
|
||||
{
|
||||
value: 'en',
|
||||
text: 'English'
|
||||
},
|
||||
{
|
||||
value: 'zh',
|
||||
text: '中文'
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
return {
|
||||
t,
|
||||
languageSetting,
|
||||
globalSetting,
|
||||
locale
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -22,12 +77,30 @@ export default {
|
||||
<style>
|
||||
.setting-wrapper {
|
||||
width: 600px;
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.setting-wrapper section {
|
||||
.setting-section {
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
border-radius: .3em;
|
||||
min-height: 50px;
|
||||
}
|
||||
|
||||
.setting-option {
|
||||
margin: 5px;
|
||||
padding: 10px 12px;
|
||||
height: 40px;
|
||||
width: fit-content;
|
||||
border-radius: .5em;
|
||||
background-color: var(--background);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
|
||||
.option-title {
|
||||
min-width: 80px;
|
||||
margin-right: 12px;
|
||||
}
|
||||
</style>
|
@ -3,17 +3,17 @@
|
||||
<div class="vcd-treeview">
|
||||
<TreeViewSearch></TreeViewSearch>
|
||||
<br>
|
||||
<div style="display: flex;">
|
||||
<div class="vcd-signal-info">
|
||||
<div>Modules</div>
|
||||
<div class="vcd-module-wrapper">
|
||||
<div class="vcd-module-info">
|
||||
<div>{{ t('module') }}</div>
|
||||
<hr>
|
||||
<Signals v-for="mod of props.topModules"
|
||||
<Modules v-for="mod of props.topModules"
|
||||
:key="mod.name"
|
||||
:signal="mod"
|
||||
></Signals>
|
||||
:module="mod"
|
||||
></Modules>
|
||||
</div>
|
||||
<div class="vcd-signal-wires">
|
||||
<Wires></Wires>
|
||||
<div class="vcd-module-wires">
|
||||
<Signals></Signals>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -21,46 +21,44 @@
|
||||
|
||||
<script>
|
||||
import { onMounted } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import TreeViewSearch from '@/components/treeview/search.vue';
|
||||
import Modules from '@/components/treeview/modules.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: {
|
||||
Modules,
|
||||
Signals,
|
||||
Wires,
|
||||
TreeViewSearch
|
||||
},
|
||||
props: {
|
||||
topModules: Array
|
||||
},
|
||||
setup(props) {
|
||||
onMounted(() => {
|
||||
|
||||
});
|
||||
const { t } = useI18n();
|
||||
|
||||
|
||||
return {
|
||||
props
|
||||
props,
|
||||
t
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.vcd-signal-info {
|
||||
.vcd-module-info {
|
||||
height: 80vh;
|
||||
width: 300px;
|
||||
padding-right: 5px;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
.vcd-signal-wires {
|
||||
.vcd-module-wires {
|
||||
height: 80vh;
|
||||
width: 300px;
|
||||
overflow-x: scroll;
|
||||
@ -68,9 +66,17 @@ export default {
|
||||
|
||||
.vcd-treeview {
|
||||
background-color: var(--sidebar);
|
||||
padding: 10px;
|
||||
height: fit-content;
|
||||
padding: 10px 10px 10px 10px;
|
||||
height: 98vh;
|
||||
border-radius: 1.0em;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.vcd-module-wrapper {
|
||||
flex: 1;
|
||||
display: flex;
|
||||
overflow: scroll;
|
||||
}
|
||||
|
||||
</style>
|
139
src/components/treeview/modules.vue
Normal file
139
src/components/treeview/modules.vue
Normal file
@ -0,0 +1,139 @@
|
||||
<template>
|
||||
<div class="module">
|
||||
<div @click="clickItem()" class="vcd-treeview-item"
|
||||
:class="module === globalLookup.currentModule ? 'vcd-treeview-selected' : ''">
|
||||
<span class="module-tag-status" @click.stop="expandManage.click">
|
||||
<div :class="expandManage.expandTagClass"></div>
|
||||
</span>
|
||||
<span class="iconfont icon-memory-chip"></span>
|
||||
 {{ module.name }}
|
||||
</div>
|
||||
|
||||
<div v-if="mods.length > 0" v-show="expandManage.expanded" class="vcd-subtree-wrapper">
|
||||
<div style="width: 20px;"></div>
|
||||
<div style="width: 100%;">
|
||||
<modules
|
||||
v-for="(child, index) in mods"
|
||||
:module="child"
|
||||
:key="index"
|
||||
></modules>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
/* eslint-disable */
|
||||
import { reactive, onMounted } from 'vue';
|
||||
import { emitter, globalLookup } from '@/hook/global';
|
||||
|
||||
export default {
|
||||
name: "modules",
|
||||
props: {
|
||||
module: Object
|
||||
},
|
||||
setup(props) {
|
||||
const module = props.module;
|
||||
globalLookup.initcurrentModule(module);
|
||||
|
||||
const signals = [];
|
||||
const mods = [];
|
||||
|
||||
for (const wire of module.body) {
|
||||
if (wire.body) {
|
||||
mods.push(wire);
|
||||
} else {
|
||||
signals.push(wire);
|
||||
}
|
||||
}
|
||||
|
||||
function clickItem() {
|
||||
emitter.emit('tree-view', signals);
|
||||
// color change into selected
|
||||
globalLookup.currentModule = module;
|
||||
|
||||
}
|
||||
|
||||
const expandManage = reactive({
|
||||
expanded: true,
|
||||
expandTagClass: mods.length === 0 ? '' : 'expand-tag',
|
||||
click() {
|
||||
this.expanded = !this.expanded;
|
||||
if (this.expandTagClass) {
|
||||
this.expandTagClass = this.expanded ? 'expand-tag' : 'collapse-tag';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
module,
|
||||
mods,
|
||||
signals,
|
||||
clickItem,
|
||||
expandManage,
|
||||
globalLookup
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.icon-memory-chip {
|
||||
color: #FF7043;
|
||||
}
|
||||
|
||||
.module {
|
||||
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;
|
||||
}
|
||||
|
||||
.module-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>
|
@ -1,17 +1,91 @@
|
||||
<template>
|
||||
<div class="tree-view-search-wrapper">
|
||||
<input type="text" class="tree-view-search" placeholder="Search Signal">
|
||||
<div>
|
||||
<el-input
|
||||
:placeholder="t('search-signal')"
|
||||
size="large"
|
||||
v-model="searchManage.content"
|
||||
input-style="font-size: 16px;"
|
||||
@input="safeSearch"
|
||||
/>
|
||||
</div>
|
||||
<div class="search-result" v-if="searchManage.content.trim().length > 0">
|
||||
<div v-if="searchManage.searchResult.length > 0">
|
||||
<div class="search-result-item"
|
||||
v-for="(searchResult, index) in searchManage.searchResult"
|
||||
:key="index"
|
||||
:class="globalLookup.currentWires.has(searchResult.module) ? 'vcd-treeview-selected' : ''"
|
||||
v-html="searchResult.htmlString"
|
||||
@click="clickItem(searchResult.module)">
|
||||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
{{ t('search-nothing') }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { reactive } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { globalSetting, globalLookup } from '@/hook/global';
|
||||
import { debounceWrapper, makeSearchResultItem } from '@/hook/utils';
|
||||
|
||||
export default {
|
||||
name: 'tree-view-search',
|
||||
setup() {
|
||||
const { t } = useI18n();
|
||||
|
||||
const searchManage = reactive({
|
||||
content: '',
|
||||
searchResult: []
|
||||
});
|
||||
|
||||
|
||||
function search() {
|
||||
const searchString = searchManage.content.trim();
|
||||
if (searchString.length === 0) {
|
||||
return;
|
||||
}
|
||||
searchManage.searchResult = [];
|
||||
|
||||
const stacks = [ { name: '', body: globalLookup.topModules } ];
|
||||
const searchRule = new Set(globalSetting.searchScope);
|
||||
const caseSensitivity = globalSetting.caseSensitivity;
|
||||
while (stacks.length > 0) {
|
||||
const p = stacks.pop();
|
||||
if (p.body && p.body.length) {
|
||||
p.body.forEach(mod => stacks.push(mod));
|
||||
}
|
||||
|
||||
const searchResultItem = makeSearchResultItem(searchString, p, searchRule, caseSensitivity);
|
||||
if (searchResultItem) {
|
||||
searchManage.searchResult.push(searchResultItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function clickItem(signal) {
|
||||
if (!signal.link) {
|
||||
return;
|
||||
}
|
||||
if (globalLookup.currentWires.has(signal)) {
|
||||
globalLookup.currentWires.delete(signal);
|
||||
} else {
|
||||
globalLookup.currentWires.add(signal);
|
||||
}
|
||||
}
|
||||
|
||||
const safeSearch = debounceWrapper(search, 500);
|
||||
|
||||
return {
|
||||
|
||||
searchManage,
|
||||
safeSearch,
|
||||
globalLookup,
|
||||
debounceWrapper,
|
||||
t,
|
||||
clickItem
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -19,33 +93,39 @@ export default {
|
||||
|
||||
<style>
|
||||
.tree-view-search-wrapper {
|
||||
height: 30px;
|
||||
min-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%;
|
||||
.search-result {
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
max-height: 40vh;
|
||||
}
|
||||
|
||||
.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;
|
||||
.search-result-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 25px;
|
||||
margin: 3px;
|
||||
padding-left: 3px;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.tree-view-search[type="text"]:hover {
|
||||
background-color: var(--input-hover);
|
||||
.search-result-item:hover {
|
||||
background-color: var(--vscode-button-hoverBackground);
|
||||
border-radius: .3em;
|
||||
}
|
||||
|
||||
.tree-view-search[type="text"]::placeholder {
|
||||
color: var(--input-placeholder);
|
||||
.dep-arrow {
|
||||
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);
|
||||
margin-right: 8px;
|
||||
margin-left: 3px;
|
||||
}
|
||||
</style>
|
@ -1,139 +1,105 @@
|
||||
<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>
|
||||
 {{ signal.name }}
|
||||
<div>
|
||||
<div>{{ t('signal') }}({{signals.content.length}})</div>
|
||||
<hr>
|
||||
<div class="vcd-signal-signals-display">
|
||||
<div v-for="(signal, index) in signals.content" :key="index"
|
||||
@click="clickItem(signal)"
|
||||
class="vcd-signal-signal-item"
|
||||
:class="globalLookup.currentWires.has(signal) ? 'vcd-treeview-selected' : ''">
|
||||
<div><span class="iconfont icon-wave-square"></span> {{ signal.name }}</div>
|
||||
<div>
|
||||
<div :class="signal.caption ? 'vcd-signal-signal-caption' : ''">
|
||||
{{ signal.caption }}
|
||||
</div>
|
||||
</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 { reactive } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
|
||||
import { emitter, globalLookup } from '@/hook/global';
|
||||
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
name: "signals",
|
||||
props: {
|
||||
signal: Object
|
||||
},
|
||||
setup(props) {
|
||||
const signal = props.signal;
|
||||
const signalChildern = signal.body;
|
||||
name: 'signals',
|
||||
props: {},
|
||||
setup() {
|
||||
const { t } = useI18n();
|
||||
|
||||
globalLookup.initCurrentSignal(signal);
|
||||
// signal : link, name, size, type
|
||||
const signals = reactive({
|
||||
content: []
|
||||
});
|
||||
|
||||
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';
|
||||
}
|
||||
emitter.on('tree-view', sendWires => {
|
||||
signals.content.length = 0;
|
||||
for (const signal of sendWires) {
|
||||
const caption = signal.size === 1 ? '' : `${signal.size - 1}:0`;
|
||||
signals.content.push({
|
||||
name: signal.name,
|
||||
caption
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function clickItem(signal) {
|
||||
if (globalLookup.currentWires.has(signal)) {
|
||||
globalLookup.currentWires.delete(signal);
|
||||
} else {
|
||||
globalLookup.currentWires.add(signal);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
signal,
|
||||
signals,
|
||||
clickItem,
|
||||
expandManage,
|
||||
globalLookup
|
||||
globalLookup,
|
||||
t
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.icon-memory-chip {
|
||||
color: #FF7043;
|
||||
.icon-wave-square {
|
||||
color: #00F600;
|
||||
}
|
||||
|
||||
.signal {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.vcd-subtree-wrapper {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.vcd-treeview-item {
|
||||
.vcd-signal-signals-display {
|
||||
color: var(--sidebar-item-text);
|
||||
cursor: pointer;
|
||||
height: 27px;
|
||||
padding: 0px 8px;
|
||||
}
|
||||
|
||||
.vcd-signal-signal-item {
|
||||
margin: 3px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 25px;
|
||||
padding-left: 3px;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.vcd-treeview-item::selection {
|
||||
|
||||
.vcd-signal-signal-item::selection {
|
||||
background: none;
|
||||
}
|
||||
|
||||
.vcd-treeview-item:hover {
|
||||
.vcd-signal-signal-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);
|
||||
.vcd-signal-signal-caption {
|
||||
color: var(--sidebar-item-text);
|
||||
border-radius: .5em;
|
||||
background-color: var(--color-deepPurple);
|
||||
padding: 3px;
|
||||
font-size: 15px;
|
||||
}
|
||||
</style>
|
@ -1,94 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<div>Signals({{wires.content.length}})</div>
|
||||
<hr>
|
||||
<div class="vcd-signal-wires-display">
|
||||
<div v-for="(wire, index) in wires.content" :key="index"
|
||||
@click="clickItem(wire)"
|
||||
class="vcd-signal-wire-item"
|
||||
:class="globalLookup.currentWires.has(wire) ? 'vcd-treeview-selected' : ''">
|
||||
<div><span class="iconfont icon-wave-square"></span> {{ wire.name }}</div>
|
||||
<div>
|
||||
<div :class="wire.caption ? 'vcd-signal-wire-caption' : ''">
|
||||
{{ wire.caption }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { reactive } from 'vue';
|
||||
import { emitter, globalLookup } from '@/hook/global';
|
||||
|
||||
/* eslint-disable */
|
||||
export default {
|
||||
name: 'wires',
|
||||
props: {},
|
||||
setup() {
|
||||
// wire : link, name, size, type
|
||||
const wires = reactive({
|
||||
content: []
|
||||
});
|
||||
|
||||
emitter.on('tree-view', sendWires => {
|
||||
wires.content.length = 0;
|
||||
for (const wire of sendWires) {
|
||||
const caption = wire.size === 1 ? '' : `${wire.size - 1}:0`;
|
||||
wires.content.push({
|
||||
name: wire.name,
|
||||
caption
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
function clickItem(wire) {
|
||||
if (globalLookup.currentWires.has(wire)) {
|
||||
globalLookup.currentWires.delete(wire);
|
||||
} else {
|
||||
globalLookup.currentWires.add(wire);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
wires,
|
||||
clickItem,
|
||||
globalLookup
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.icon-wave-square {
|
||||
color: #00F600;
|
||||
}
|
||||
|
||||
.vcd-signal-wires-display {
|
||||
color: var(--sidebar-item-text);
|
||||
padding: 0px 8px;
|
||||
}
|
||||
|
||||
.vcd-signal-wire-item {
|
||||
margin: 3px;
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
height: 25px;
|
||||
cursor: pointer;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.vcd-signal-wire-item:hover {
|
||||
background-color: var(--vscode-button-hoverBackground);
|
||||
border-radius: .3em;
|
||||
}
|
||||
|
||||
.vcd-signal-wire-caption {
|
||||
color: var(--sidebar-item-text);
|
||||
border-radius: .5em;
|
||||
background-color: var(--color-deepPurple);
|
||||
padding: 3px;
|
||||
font-size: 15px;
|
||||
}
|
||||
</style>
|
@ -5,21 +5,31 @@ const emitter = mitt();
|
||||
|
||||
// 用于记载全局的一些对象,以便在不同组件中比较 ID
|
||||
const globalLookup = reactive({
|
||||
// 所有的顶层文件
|
||||
topModules: [],
|
||||
// 当前选中的 信号,也就是 tree-view 左列的,默认是第一个。不可复选。
|
||||
currentSignal: undefined,
|
||||
currentModule: undefined,
|
||||
// 当前选中的某个 信号 的 数据。可复选。
|
||||
currentWires: new Set(),
|
||||
|
||||
initCurrentSignal(signal) {
|
||||
if (this.currentSignal === undefined && signal) {
|
||||
this.currentSignal = signal;
|
||||
initcurrentModule(module) {
|
||||
if (this.currentModule === undefined && module) {
|
||||
this.currentModule = module;
|
||||
}
|
||||
// 创造 parent
|
||||
if (module.body && module.body instanceof Array) {
|
||||
for (const childModule of module.body) {
|
||||
childModule.parent = module;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
const globalSetting = {
|
||||
caseSensitivity: false
|
||||
};
|
||||
const globalSetting = reactive({
|
||||
caseSensitivity: false,
|
||||
searchMode: 'so', // so, mo, sm
|
||||
searchScope: ['wire', 'reg']
|
||||
})
|
||||
|
||||
export {
|
||||
emitter,
|
||||
|
@ -28,7 +28,72 @@ async function readVcdFile() {
|
||||
});
|
||||
}
|
||||
|
||||
function debounceWrapper(fn, delay) {
|
||||
let timer
|
||||
return function () {
|
||||
if (timer) {
|
||||
clearTimeout(timer)
|
||||
}
|
||||
timer = setTimeout(() => {
|
||||
fn()
|
||||
}, delay)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param { string } searchString
|
||||
* @param {{
|
||||
* kind: 'var' | 'scope',
|
||||
* type: 'wire' | 'reg' | 'module',
|
||||
* name: string,
|
||||
* size?: number,
|
||||
* link?: string
|
||||
* }} module
|
||||
* @param { Set<string> } searchScope
|
||||
* @param { boolean } caseSensitivity
|
||||
* @returns { { htmlString: string, module } | null }
|
||||
*/
|
||||
function makeSearchResultItem(searchString, module, searchScope, caseSensitivity) {
|
||||
if (searchScope.has(module.type)) {
|
||||
let pattern = module.name;
|
||||
if (!caseSensitivity) {
|
||||
pattern = pattern.toLowerCase();
|
||||
searchString = searchString.toLowerCase();
|
||||
}
|
||||
if (pattern.includes(searchString)) {
|
||||
let p = module;
|
||||
const deps = [];
|
||||
while (p) {
|
||||
if (p.name && p.type) {
|
||||
deps.push(p);
|
||||
}
|
||||
p = p.parent;
|
||||
}
|
||||
let htmlString = '';
|
||||
for (let i = deps.length - 1; i >= 0; -- i) {
|
||||
const mod = deps[i];
|
||||
if (mod.type === 'module') {
|
||||
htmlString += '<span class="iconfont icon-memory-chip"></span> ' + mod.name;
|
||||
} else {
|
||||
htmlString += '<span class="iconfont icon-wave-square"></span> ' + mod.name;
|
||||
}
|
||||
if (i > 0) {
|
||||
htmlString += '<div class="dep-arrow"></div>';
|
||||
}
|
||||
}
|
||||
return {
|
||||
htmlString,
|
||||
module
|
||||
};
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
export {
|
||||
getVcdStream,
|
||||
readVcdFile
|
||||
readVcdFile,
|
||||
debounceWrapper,
|
||||
makeSearchResultItem
|
||||
};
|
17
src/i18n/en.json
Normal file
17
src/i18n/en.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"module": "Modules",
|
||||
"signal": "Signals",
|
||||
"search-signal": "Search Signal",
|
||||
"language-setting": "Language",
|
||||
"search-setting": "Search",
|
||||
"case-sensitivity": "case sensitivity",
|
||||
"search-mode": "search mode",
|
||||
"search-scope": "search scope",
|
||||
"signal-only": "Signal Only",
|
||||
"module-only": "Module Only",
|
||||
"signal-module": "Signal + Module",
|
||||
"general-setting": "General",
|
||||
"current-version": "current version",
|
||||
"search-nothing": "find nothing",
|
||||
"copyright": "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>."
|
||||
}
|
12
src/i18n/index.js
Normal file
12
src/i18n/index.js
Normal file
@ -0,0 +1,12 @@
|
||||
import { createI18n } from 'vue-i18n';
|
||||
|
||||
import en from './en.json';
|
||||
import zh from './zh.json';
|
||||
|
||||
const i18n = createI18n({
|
||||
legacy: false,
|
||||
locale: 'en',
|
||||
messages: { en, zh }
|
||||
});
|
||||
|
||||
export default i18n;
|
17
src/i18n/zh.json
Normal file
17
src/i18n/zh.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"module": "模块",
|
||||
"signal": "信号",
|
||||
"search-signal": "搜索信号",
|
||||
"language-setting": "语言",
|
||||
"search-setting": "搜索",
|
||||
"case-sensitivity": "区分大小写",
|
||||
"search-mode": "搜索模式",
|
||||
"search-scope": "搜索范围",
|
||||
"signal-only": "信号",
|
||||
"module-only": "模块",
|
||||
"signal-module": "信号 + 模块",
|
||||
"general-setting": "通用",
|
||||
"current-version": "当前版本",
|
||||
"search-nothing": "没有找到任何符号",
|
||||
"copyright": "本软件版权归 <a href=\"https://github.com/Digital-EDA\" target=\"_blank\">Digital-IDE</a> 项目组所有,欢迎 <a href=\"https://github.com/Digital-EDA/Digital-IDE\">Star</a>。"
|
||||
}
|
12
src/main.js
12
src/main.js
@ -1,4 +1,10 @@
|
||||
import { createApp } from 'vue'
|
||||
import App from './App.vue'
|
||||
import { createApp } from 'vue';
|
||||
import App from './App.vue';
|
||||
import i18n from './i18n';
|
||||
import ElementPlus from 'element-plus'
|
||||
import 'element-plus/dist/index.css'
|
||||
|
||||
createApp(App).mount('#app')
|
||||
createApp(App)
|
||||
.use(i18n)
|
||||
.use(ElementPlus)
|
||||
.mount('#app')
|
14
webpack.config.js
Normal file
14
webpack.config.js
Normal file
@ -0,0 +1,14 @@
|
||||
const AutoImport = require('unplugin-auto-import/webpack')
|
||||
const Components = require('unplugin-vue-components/webpack')
|
||||
const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
AutoImport({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
}),
|
||||
Components({
|
||||
resolvers: [ElementPlusResolver()],
|
||||
}),
|
||||
],
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user