166 lines
3.8 KiB
Vue
166 lines
3.8 KiB
Vue
<template>
|
|
<div class="module">
|
|
<div @click="clickItem()" class="netlist-treeview-item">
|
|
<span class="module-tag-status" @click.stop="expandManage.click">
|
|
<div :class="expandManage.expandTagClass"></div>
|
|
</span>
|
|
<span :class="`iconfont ${makeIconClass(module)}`"></span>
|
|
 {{ module.name }}
|
|
</div>
|
|
|
|
<!-- 渲染这个 module scope 有的组件 -->
|
|
<div v-if="ports.length > 0 || cells.length > 0" class="netlist-subtree-wrapper">
|
|
<div style="width: 20px;"></div>
|
|
<div style="width: 100%;">
|
|
<!-- ports -->
|
|
<div v-for="port in ports" :key="port.name" class="netlist-treeview-item">
|
|
<span class="module-tag-status">
|
|
</span>
|
|
<span class="iconfont icon-wave-square"></span>
|
|
 {{ port.name }}
|
|
</div>
|
|
|
|
<!-- 例化模块 -->
|
|
<modules
|
|
v-for="(cell, index) in cells"
|
|
:module="cell.view"
|
|
:key="index"
|
|
></modules>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script setup>
|
|
/* eslint-disable */
|
|
import { ModuleView } from '@/hook/render/yosys';
|
|
import { defineComponent, reactive } from 'vue';
|
|
|
|
defineComponent({ name: 'modules' });
|
|
|
|
const props = defineProps({
|
|
module: {
|
|
type: ModuleView,
|
|
required: true
|
|
}
|
|
});
|
|
|
|
const module = props.module;
|
|
|
|
// 当前 scope 的例化模块下的
|
|
const ports = [];
|
|
const cells = [];
|
|
|
|
// 初始化渲染的子视图 ports & modules
|
|
for (const portName of module.nameToPort.keys()) {
|
|
ports.push({
|
|
name: portName
|
|
});
|
|
}
|
|
|
|
for (const cellName of module.nameToCell.keys()) {
|
|
const cell = module.nameToCell.get(cellName);
|
|
if (cell.view === module) {
|
|
// 防止递归
|
|
continue;
|
|
}
|
|
if (cell.isInstantiation) {
|
|
cells.push({
|
|
name: cellName,
|
|
view: cell.belongModuleView
|
|
});
|
|
}
|
|
}
|
|
|
|
function clickItem() {
|
|
|
|
}
|
|
|
|
function getExpandStatus() {
|
|
if (ports.length === 0 && cells.length === 0) {
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
const expandManage = reactive({
|
|
expanded: getExpandStatus(),
|
|
expandTagClass: ports.length === 0 && cells.length === 0 ? '' : 'collapse-tag',
|
|
click() {
|
|
this.expanded = !this.expanded;
|
|
if (this.expandTagClass) {
|
|
this.expandTagClass = this.expanded ? 'expand-tag' : 'collapse-tag';
|
|
}
|
|
}
|
|
});
|
|
|
|
function makeIconClass() {
|
|
return 'icon-memory-chip';
|
|
}
|
|
|
|
</script>
|
|
|
|
<style>
|
|
.icon-memory-chip {
|
|
color: #FF7043;
|
|
}
|
|
|
|
.module {
|
|
text-align: left;
|
|
}
|
|
|
|
.netlist-subtree-wrapper {
|
|
display: flex;
|
|
width: 100%;
|
|
}
|
|
|
|
.netlist-treeview-item {
|
|
color: var(--vscode-foreground);
|
|
cursor: pointer;
|
|
display: flex;
|
|
align-items: center;
|
|
white-space: nowrap;
|
|
text-overflow: ellipsis;
|
|
font-size: 0.75rem;
|
|
}
|
|
|
|
.netlist-treeview-item::selection {
|
|
background: none;
|
|
}
|
|
|
|
.netlist-treeview-item:hover {
|
|
background-color: var(--sidebar-item-selected);
|
|
border-radius: .3em;
|
|
}
|
|
|
|
.netlist-treeview-selected {
|
|
color: #ddd;
|
|
background-color: var(--button-active) !important;
|
|
border-radius: .3em;
|
|
}
|
|
|
|
.module-tag-status {
|
|
width: 23px;
|
|
height: 23px;
|
|
align-items: center;
|
|
justify-content: space-around;
|
|
display: flex;
|
|
}
|
|
|
|
.expand-tag {
|
|
height: 5px;
|
|
width: 5px;
|
|
border-top: solid 1.7px var(--vscode-foreground);
|
|
border-left: solid 1.7px var(--vscode-foreground);
|
|
transform: rotate(225deg);
|
|
}
|
|
|
|
.collapse-tag {
|
|
height: 5px;
|
|
width: 5px;
|
|
border-top: solid 1.7px var(--vscode-foreground);
|
|
border-left: solid 1.7px var(--vscode-foreground);
|
|
transform: rotate(135deg);
|
|
}
|
|
</style> |