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>
&ensp;{{ 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>
&ensp;{{ 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>