完成value搜索
This commit is contained in:
parent
9f50214cbb
commit
f74fc31aaf
14
package-lock.json
generated
14
package-lock.json
generated
@ -12,7 +12,7 @@
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"core-js": "^3.8.3",
|
||||
"element-plus": "^2.5.6",
|
||||
"element-plus": "^2.6.3",
|
||||
"lodash.get": "^4.4.2",
|
||||
"mitt": "^3.0.1",
|
||||
"onml": "^2.1.0",
|
||||
@ -5170,9 +5170,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/element-plus": {
|
||||
"version": "2.5.6",
|
||||
"resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.5.6.tgz",
|
||||
"integrity": "sha512-zctKTiyIDmcnMp3K5WG1hglgraW9EbiCLiIDVtaMCS5mPMl2fRKdS0vOFGnECIq9taFoxnyoDwxHD81nv0B4RA==",
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.6.3.tgz",
|
||||
"integrity": "sha512-U4L/mr+1r+EmAUYUHrs0V/8hHMdBGP07rPymSC72LZCN4jK1UwygQYICegTQ5us4mxeqBvW6wfoEfo003fwCqw==",
|
||||
"dependencies": {
|
||||
"@ctrl/tinycolor": "^3.4.1",
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
@ -14633,9 +14633,9 @@
|
||||
"dev": true
|
||||
},
|
||||
"element-plus": {
|
||||
"version": "2.5.6",
|
||||
"resolved": "https://registry.npmmirror.com/element-plus/-/element-plus-2.5.6.tgz",
|
||||
"integrity": "sha512-zctKTiyIDmcnMp3K5WG1hglgraW9EbiCLiIDVtaMCS5mPMl2fRKdS0vOFGnECIq9taFoxnyoDwxHD81nv0B4RA==",
|
||||
"version": "2.6.3",
|
||||
"resolved": "https://registry.npmjs.org/element-plus/-/element-plus-2.6.3.tgz",
|
||||
"integrity": "sha512-U4L/mr+1r+EmAUYUHrs0V/8hHMdBGP07rPymSC72LZCN4jK1UwygQYICegTQ5us4mxeqBvW6wfoEfo003fwCqw==",
|
||||
"requires": {
|
||||
"@ctrl/tinycolor": "^3.4.1",
|
||||
"@element-plus/icons-vue": "^2.3.1",
|
||||
|
@ -9,7 +9,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"core-js": "^3.8.3",
|
||||
"element-plus": "^2.5.6",
|
||||
"element-plus": "^2.6.3",
|
||||
"lodash.get": "^4.4.2",
|
||||
"mitt": "^3.0.1",
|
||||
"onml": "^2.1.0",
|
||||
|
@ -9,9 +9,11 @@ export const StaticCursor = reactive({
|
||||
left: 0,
|
||||
updateLabel(timescale) {
|
||||
this.label = formatTime(this.currentTime, timescale);
|
||||
this.show = true;
|
||||
},
|
||||
updateLeft() {
|
||||
this.left = calcCursorLeft(this.currentTime);
|
||||
this.show = true;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -87,8 +87,8 @@
|
||||
<div class="setting-option">
|
||||
<span class="option-title" style="width: 150px;">{{ t('display-signal-info-scope') }}</span>
|
||||
<el-checkbox-group v-model="globalSetting.displaySignalInfoScope" size="default">
|
||||
<el-checkbox-button label="width" border>{{ t('display-signal-info-scope.width') }}</el-checkbox-button>
|
||||
<el-checkbox-button label="parent" border>{{ t('display-signal-info-scope.parent') }}</el-checkbox-button>
|
||||
<el-checkbox-button value="width" border>{{ t('display-signal-info-scope.width') }}</el-checkbox-button>
|
||||
<el-checkbox-button value="parent" border>{{ t('display-signal-info-scope.parent') }}</el-checkbox-button>
|
||||
</el-checkbox-group>
|
||||
</div>
|
||||
|
||||
|
@ -1,5 +1,12 @@
|
||||
import { globalLookup } from "@/hook/global";
|
||||
import { reactive } from "vue";
|
||||
import { contextmenu } from "./handle-contextmenu";
|
||||
|
||||
import i18n from '@/i18n/index';
|
||||
import { ElMessage } from "element-plus";
|
||||
import { findViewIndexByLink } from "@/hook/wave-container-view";
|
||||
|
||||
const { t } = i18n.global;
|
||||
|
||||
// 从 globalLookup.currentWiresRenderView 中可以获取当前的分组情况
|
||||
export function getCurrentGroups() {
|
||||
@ -16,3 +23,64 @@ export const existGroup = reactive({
|
||||
this.display = false;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {WaveRenderSidebarItem} group
|
||||
* @param {WireItem} signal
|
||||
*/
|
||||
function inGroup(group, signal) {
|
||||
for (const child of group.children) {
|
||||
if (child.signalInfo.link === signal.link) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {WaveRenderSidebarItem} group
|
||||
*/
|
||||
export function joinGroup(group) {
|
||||
const signal = contextmenu.currentWire;
|
||||
if (signal === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 检查是否已经在里面了
|
||||
if (inGroup(group, signal)) {
|
||||
ElMessage({
|
||||
message: t('context-menu.cannot-join-repeat-group'),
|
||||
type: 'warning',
|
||||
plain: true,
|
||||
showClose: true,
|
||||
duration: 0
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 加入 group 中
|
||||
group.children.push({
|
||||
signalInfo: {
|
||||
name: signal.name,
|
||||
link: signal.link,
|
||||
size: signal.size,
|
||||
},
|
||||
groupInfo: {
|
||||
name: '',
|
||||
color: '',
|
||||
collapse: false
|
||||
},
|
||||
renderType: 0,
|
||||
children: []
|
||||
});
|
||||
|
||||
// 删除的逻辑参照 wave-container-view.js delete 函数
|
||||
const renderView = globalLookup.currentWiresRenderView;
|
||||
const i = findViewIndexByLink(signal.link);
|
||||
const tailElements = renderView.slice(i + 1);
|
||||
renderView.length = i;
|
||||
tailElements.forEach(view => renderView.push(view));
|
||||
}
|
@ -7,6 +7,7 @@
|
||||
:key="index"
|
||||
class="group-item"
|
||||
:style="getItemStyle(item)"
|
||||
@click="onClick(item)"
|
||||
>
|
||||
<span class="iconfont icon-group"></span>
|
||||
 
|
||||
@ -32,6 +33,7 @@ import { contextmenu } from './handle-contextmenu';
|
||||
import { currentGroups } from './manage-group';
|
||||
import { globalLookup } from '@/hook/global';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { joinGroup } from './exist-group';
|
||||
|
||||
const { t } = useI18n();
|
||||
|
||||
@ -61,6 +63,10 @@ function getItemName(view) {
|
||||
return name;
|
||||
}
|
||||
|
||||
function onClick(group) {
|
||||
joinGroup(group);
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
@ -192,6 +192,7 @@ function handleSidebarGlobalClick() {
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
transition: var(--animation-5s);
|
||||
}
|
||||
|
||||
.signal-color-vendor > span {
|
||||
|
@ -6,7 +6,10 @@
|
||||
}"
|
||||
>
|
||||
<div class="display-signal-item">
|
||||
<div class="signal-color-vendor">
|
||||
<div
|
||||
class="signal-color-vendor"
|
||||
:class="{ 'search-active': toolbarValueSearch.resultLinkSet.has(props.view.signalInfo.link) }"
|
||||
>
|
||||
<span :class="makeSignalIconClass(signalInfo)"></span>
|
||||
</div>
|
||||
|
||||
@ -47,6 +50,7 @@ import { defineComponent, computed } from 'vue';
|
||||
import { contextmenu } from './handle-contextmenu';
|
||||
import { sidebarSelectedWires } from '@/hook/sidebar-select-wire';
|
||||
import { FormatValueRender } from '@/hook/wave-view/toolbar/renderFormat';
|
||||
import { toolbarValueSearch } from '../toolbar/value-search';
|
||||
|
||||
defineComponent({ name: 'signal-item' });
|
||||
|
||||
@ -117,4 +121,10 @@ function makeCurrentValue(link) {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.signal-color-vendor.search-active {
|
||||
background-color: var(--main-color) !important;
|
||||
transition: var(--animation-5s);
|
||||
}
|
||||
|
||||
</style>
|
@ -1,6 +1,7 @@
|
||||
import { globalLookup } from "@/hook/global";
|
||||
import { calcCursorLeft, StaticCursor } from "../render/cursor";
|
||||
import { sidebarSelectedWires } from "@/hook/sidebar-select-wire";
|
||||
import { updateWireCurrentValue } from "@/hook/utils";
|
||||
|
||||
|
||||
/**
|
||||
@ -9,15 +10,29 @@ import { sidebarSelectedWires } from "@/hook/sidebar-select-wire";
|
||||
* @param {number} leftMargin 移动后的该时间点距离左侧多少px
|
||||
* @param {Pstate} pstate
|
||||
*/
|
||||
function moveto(time, leftMargin, pstate) {
|
||||
export function moveto(time, leftMargin, pstate) {
|
||||
StaticCursor.show = true;
|
||||
StaticCursor.currentTime = time;
|
||||
pstate.oldXOffset = pstate.xOffset;
|
||||
const { width, xOffset, xScale, tgcd, timescale } = pstate;
|
||||
pstate.xOffset = leftMargin - (time / tgcd) * xScale;
|
||||
|
||||
const { width, xOffset, xScale, tgcd, timescale } = pstate;
|
||||
let nextOffsetX = leftMargin - (time / tgcd) * xScale;
|
||||
const sidebarWidth = pstate.sidebarWidth;
|
||||
|
||||
if (nextOffsetX >= sidebarWidth) {
|
||||
nextOffsetX = sidebarWidth - 20;
|
||||
}
|
||||
|
||||
pstate.oldXOffset = pstate.xOffset;
|
||||
pstate.xOffset = nextOffsetX;
|
||||
|
||||
// 改变静态信标
|
||||
StaticCursor.updateLeft();
|
||||
StaticCursor.updateLabel(pstate.timescale);
|
||||
|
||||
// 更新所有轨道的数字
|
||||
updateWireCurrentValue(time);
|
||||
|
||||
// 更换渲染视图
|
||||
globalLookup.render();
|
||||
}
|
||||
|
||||
@ -132,7 +147,7 @@ export function makeLocation() {
|
||||
* @param {number} time
|
||||
* @return {number}
|
||||
*/
|
||||
function bisearch(wave, time) {
|
||||
export function bisearch(wave, time) {
|
||||
const times = wave.map(p => p[0]);
|
||||
|
||||
// 二分查找,并将结果存入 i
|
||||
|
@ -6,7 +6,7 @@
|
||||
@change="onSignalModalUpdate"
|
||||
>
|
||||
<!-- 数字模式 -->
|
||||
<el-radio-button :label="0">
|
||||
<el-radio-button :value="0">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="t('toolbar.modal.common-digital')"
|
||||
@ -17,7 +17,7 @@
|
||||
</el-tooltip>
|
||||
</el-radio-button>
|
||||
<!-- 阶梯模拟 -->
|
||||
<el-radio-button :label="1">
|
||||
<el-radio-button :value="1">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="t('toolbar.modal.ladder-analog')"
|
||||
@ -26,7 +26,7 @@
|
||||
><span class="iconfont icon-ladder-analog"></span></el-tooltip>
|
||||
</el-radio-button>
|
||||
<!-- 折线模拟 -->
|
||||
<el-radio-button :label="2">
|
||||
<el-radio-button :value="2">
|
||||
<el-tooltip
|
||||
effect="dark"
|
||||
:content="t('toolbar.modal.line-analog')"
|
||||
|
199
src/components/toolbar/value-search.js
Normal file
199
src/components/toolbar/value-search.js
Normal file
@ -0,0 +1,199 @@
|
||||
|
||||
/**
|
||||
* @description 搜索数值的每一个结果的数据结构
|
||||
* @typedef {Object} toolbarSearchResultItem
|
||||
* @property {string} name
|
||||
* @property {string} link
|
||||
* @property {number} width
|
||||
* @property {string} type
|
||||
* @property {number} value
|
||||
*/
|
||||
|
||||
import { globalLookup } from "@/hook/global";
|
||||
import { sidebarSelectedWires } from "@/hook/sidebar-select-wire";
|
||||
import { reactive, ref } from "vue";
|
||||
import { bisearch, moveto } from "./cursor-location";
|
||||
import { StaticCursor } from "../render/cursor";
|
||||
import { FormatValueRender, JSValueRender } from "@/hook/wave-view/toolbar/renderFormat";
|
||||
import { ElMessage } from "element-plus";
|
||||
import i18n from '@/i18n/index';
|
||||
|
||||
const { t } = i18n.global;
|
||||
|
||||
export const searchMode = ref(1);
|
||||
export const valueSearchText = ref(t('toolbar.search.value.searching'));
|
||||
|
||||
export const toolbarValueSearch = reactive({
|
||||
content: '',
|
||||
displayResult: false,
|
||||
mouseOnResult: false,
|
||||
|
||||
/**
|
||||
* @type {toolbarSearchResultItem[]}
|
||||
*/
|
||||
searchResult: [],
|
||||
|
||||
/**
|
||||
* @type {Set<string>}
|
||||
*/
|
||||
resultLinkSet: new Set(),
|
||||
|
||||
/**
|
||||
* @description 当前选择的索引
|
||||
*/
|
||||
cursorIndex: -1
|
||||
});
|
||||
|
||||
|
||||
function toPrevValue() {
|
||||
// TODO: 空间换时间,提升性能
|
||||
const prevTimes = [];
|
||||
|
||||
const currentT = StaticCursor.currentTime;
|
||||
// StaticCursor.updateLabel(currentT);
|
||||
// StaticCursor.updateLeft();
|
||||
|
||||
const searchContent = toolbarValueSearch.content.trim();
|
||||
|
||||
for (const link of globalLookup.sidebarSelectedWireLinks) {
|
||||
const chango = globalLookup.chango[link];
|
||||
const signal = globalLookup.link2CurrentWires.get(link);
|
||||
const valueRender = new FormatValueRender(link, signal.size, '');
|
||||
const { wave } = chango;
|
||||
|
||||
let i = bisearch(wave, currentT);
|
||||
console.log(i);
|
||||
|
||||
// 往前寻找
|
||||
while (i >= 0) {
|
||||
const [t, val, mask] = wave[i];
|
||||
const valString = mask === 1 ? 'x' : valueRender.render(val, -1);
|
||||
console.log(val, valString, wave[i]);
|
||||
|
||||
if (valString === searchContent && t != currentT) {
|
||||
break;
|
||||
}
|
||||
i --;
|
||||
}
|
||||
|
||||
if (i >= 0 && wave[i][0] < currentT) {
|
||||
prevTimes.push(wave[i][0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (prevTimes.length > 0) {
|
||||
const preT = Math.max(...prevTimes);
|
||||
const pstate = globalLookup.pstate;
|
||||
moveto(preT, (pstate.width + pstate.sidebarWidth) / 2, pstate);
|
||||
} else {
|
||||
valueSearchText.value = t('toolbar.search.value.already-to-head');
|
||||
}
|
||||
}
|
||||
|
||||
function toNextValue() {
|
||||
const prevTimes = [];
|
||||
|
||||
const currentT = StaticCursor.currentTime;
|
||||
// StaticCursor.updateLabel(currentT);
|
||||
// StaticCursor.updateLeft();
|
||||
|
||||
const searchContent = toolbarValueSearch.content.trim();
|
||||
|
||||
for (const link of globalLookup.sidebarSelectedWireLinks) {
|
||||
const chango = globalLookup.chango[link];
|
||||
const signal = globalLookup.link2CurrentWires.get(link);
|
||||
const valueRender = new FormatValueRender(link, signal.size, '');
|
||||
const { wave } = chango;
|
||||
|
||||
let i = bisearch(wave, currentT);
|
||||
const length = wave.length;
|
||||
// 往后寻找
|
||||
while (i < length) {
|
||||
const [t, val, mask] = wave[i];
|
||||
const valString = mask === 1 ? 'x' : valueRender.render(val, -1);
|
||||
console.log(val, mask, valString);
|
||||
|
||||
if (valString === searchContent && t != currentT) {
|
||||
break;
|
||||
}
|
||||
i ++;
|
||||
}
|
||||
|
||||
if (i < length && wave[i][0] > currentT) {
|
||||
prevTimes.push(wave[i][0]);
|
||||
}
|
||||
}
|
||||
|
||||
if (prevTimes.length > 0) {
|
||||
const preT = Math.min(...prevTimes);
|
||||
const pstate = globalLookup.pstate;
|
||||
moveto(preT, (pstate.width + pstate.sidebarWidth) / 2, pstate);
|
||||
} else {
|
||||
valueSearchText.value = t('toolbar.search.value.already-to-tail');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function toPrevName() {
|
||||
// 清空
|
||||
sidebarSelectedWires.clear();
|
||||
const currentIndex = toolbarValueSearch.cursorIndex;
|
||||
const searchResultNum = toolbarValueSearch.searchResult.length;
|
||||
const targetIndex = (currentIndex - 1 + searchResultNum) % searchResultNum;
|
||||
if (targetIndex !== currentIndex) {
|
||||
toolbarValueSearch.cursorIndex = targetIndex;
|
||||
const { link } = toolbarValueSearch.searchResult[targetIndex];
|
||||
sidebarSelectedWires.add(link);
|
||||
}
|
||||
}
|
||||
|
||||
function toNextName() {
|
||||
// 清空
|
||||
sidebarSelectedWires.clear();
|
||||
const currentIndex = toolbarValueSearch.cursorIndex;
|
||||
const searchResultNum = toolbarValueSearch.searchResult.length;
|
||||
const targetIndex = (currentIndex + 1) % searchResultNum;
|
||||
if (targetIndex !== currentIndex) {
|
||||
toolbarValueSearch.cursorIndex = targetIndex;
|
||||
const { link } = toolbarValueSearch.searchResult[targetIndex];
|
||||
sidebarSelectedWires.add(link);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
export function onClickPrev() {
|
||||
if (globalLookup.sidebarSelectedWireLinks.size === 0 || toolbarValueSearch.content.trim().length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (searchMode.value) {
|
||||
case 0:
|
||||
toPrevValue();
|
||||
break;
|
||||
case 1:
|
||||
toPrevName();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
export function onClickNext() {
|
||||
if (globalLookup.sidebarSelectedWireLinks.size === 0 || toolbarValueSearch.content.trim().length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (searchMode.value) {
|
||||
case 0:
|
||||
toNextValue();
|
||||
break;
|
||||
case 1:
|
||||
toNextName();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
@ -1,87 +1,86 @@
|
||||
<template>
|
||||
<div class="value-search">
|
||||
<div class="value-search"
|
||||
|
||||
>
|
||||
<div>
|
||||
<el-radio-group
|
||||
v-model="searchMode"
|
||||
style="border-radius: 1.2em;"
|
||||
>
|
||||
<el-radio-button :label="0">
|
||||
<el-radio-button :value="0">
|
||||
<span>{{ t('toolbar.search.value') }}</span>
|
||||
</el-radio-button>
|
||||
<el-radio-button :label="1">
|
||||
<el-radio-button :value="1">
|
||||
<span>{{ t('toolbar.search.name') }}</span>
|
||||
</el-radio-button>
|
||||
</el-radio-group>
|
||||
</div>
|
||||
<div class="value-input-wrapper">
|
||||
<div
|
||||
class="value-input-wrapper"
|
||||
:style="inputStyle"
|
||||
>
|
||||
<el-input
|
||||
v-model="searchManage.content"
|
||||
v-model="toolbarValueSearch.content"
|
||||
@input="safeSearch"
|
||||
@focus="searchManage.displayResult = true"
|
||||
@blur="searchManage.displayResult = false"
|
||||
@keydown.enter="onEnter()"
|
||||
></el-input>
|
||||
|
||||
<transition name="collapse-from-top">
|
||||
<div
|
||||
v-show="searchManage.displayResult || searchManage.mouseOnResult"
|
||||
class="toolbar-search-container"
|
||||
>
|
||||
<el-scrollbar
|
||||
height="300px"
|
||||
width="100%"
|
||||
@mouseenter="searchManage.mouseOnResult = true"
|
||||
@mouseleave="searchManage.mouseOnResult = false"
|
||||
class="search-result"
|
||||
>
|
||||
<div v-if="searchManage.searchResult.length > 0">
|
||||
<div v-for="(signal, index) in searchManage.searchResult"
|
||||
:key="index"
|
||||
@click="clickSearchItem(signal)"
|
||||
class="toolbar-search"
|
||||
>
|
||||
<span :class="makeSignalIconClass(signal)"></span>
|
||||
<span class="signal-name">{{ signal.name }}</span>
|
||||
<span
|
||||
class="signal-width"
|
||||
>
|
||||
<span :class="{ 'vec': signal.width > 1 }">{{ makeSignalCaption(signal) }}</span>
|
||||
</span>
|
||||
<span class="signal-value">{{ signal.value }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="toolbar-search-nothing">
|
||||
<span class="iconfont icon-empty"></span>
|
||||
<span>{{ t('search-nothing') }}</span>
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
</transition>
|
||||
</div>
|
||||
<div class="value-text">
|
||||
<span v-show="searchMode === 0">
|
||||
<span>{{ valueSearchText }}</span>
|
||||
</span>
|
||||
|
||||
<span v-show="searchMode === 1">
|
||||
<span v-if="toolbarValueSearch.searchResult.length === 0">{{ t('toolbar.no-result') }}</span>
|
||||
<span v-else>{{ toolbarValueSearch.cursorIndex + 1 }}
|
||||
/ {{toolbarValueSearch.searchResult.length}}</span>
|
||||
</span>
|
||||
</div>
|
||||
<div
|
||||
class="value-choose"
|
||||
:class="{ 'disabled' : toolbarValueSearch.content.trim().length === 0 ||( searchMode === 1 && toolbarValueSearch.searchResult.length === 0) }"
|
||||
>
|
||||
<span :class="getPrevIconClass()" @click="onClickPrev()"></span>
|
||||
<span :class="getNextIconClass()" @click="onClickNext()"></span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { globalLookup } from '@/hook/global';
|
||||
import { debounceWrapper, makeIconClass } from '@/hook/utils';
|
||||
import { defineComponent, reactive, ref } from 'vue';
|
||||
import { computed, defineComponent, reactive, ref } from 'vue';
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { onClickNext, onClickPrev, searchMode, toolbarValueSearch, valueSearchText } from './value-search';
|
||||
import { sidebarSelectedWires } from '@/hook/sidebar-select-wire';
|
||||
|
||||
|
||||
defineComponent({ name: 'value-search' })
|
||||
|
||||
const { t } = useI18n();
|
||||
const searchMode = ref(1);
|
||||
|
||||
const searchManage = reactive({
|
||||
content: '',
|
||||
displayResult: false,
|
||||
mouseOnResult: false,
|
||||
searchResult: [],
|
||||
});
|
||||
const inputWidth = ref(120);
|
||||
const inputStyle = computed(() => ({
|
||||
width: inputWidth.value + 'px'
|
||||
}));
|
||||
|
||||
function onFocus() {
|
||||
// inputWidth.value = 200;
|
||||
}
|
||||
|
||||
function onBlur() {
|
||||
// inputWidth.value = 120;
|
||||
}
|
||||
|
||||
function onEnter() {
|
||||
onClickNext();
|
||||
}
|
||||
|
||||
function addWire(wireItem) {
|
||||
searchManage.searchResult.push({
|
||||
toolbarValueSearch.resultLinkSet.add(wireItem.link);
|
||||
toolbarValueSearch.searchResult.push({
|
||||
name: wireItem.name,
|
||||
link: wireItem.link,
|
||||
width: wireItem.size,
|
||||
type: wireItem.type,
|
||||
value: globalLookup.currentSignalValues[wireItem.link]
|
||||
@ -89,27 +88,42 @@ function addWire(wireItem) {
|
||||
}
|
||||
|
||||
function searchByValue() {
|
||||
const value = searchManage.content.trim();
|
||||
for (const wireItem of globalLookup.currentWires) {
|
||||
const currentVal = globalLookup.currentSignalValues[wireItem.link];
|
||||
if (currentVal.toString().includes(value)) {
|
||||
addWire(wireItem);
|
||||
}
|
||||
}
|
||||
// toolbarValueSearch.searchResult.length = 0;
|
||||
// toolbarValueSearch.resultLinkSet.clear();
|
||||
// const value = toolbarValueSearch.content.trim();
|
||||
// for (const wireItem of globalLookup.currentWires) {
|
||||
// const currentVal = globalLookup.currentSignalValues[wireItem.link];
|
||||
// if (currentVal.toString().includes(value)) {
|
||||
// addWire(wireItem);
|
||||
// }
|
||||
// }
|
||||
// if (toolbarValueSearch.searchResult.length > 0) {
|
||||
// toolbarValueSearch.cursorIndex = 0;
|
||||
// const { link } = toolbarValueSearch.searchResult[0];
|
||||
// sidebarSelectedWires.add(link);
|
||||
// }
|
||||
}
|
||||
|
||||
function searchByName() {
|
||||
const name = searchManage.content.trim();
|
||||
toolbarValueSearch.searchResult.length = 0;
|
||||
toolbarValueSearch.resultLinkSet.clear();
|
||||
const name = toolbarValueSearch.content.trim();
|
||||
for (const wireItem of globalLookup.currentWires) {
|
||||
if (wireItem.name.includes(name)) {
|
||||
addWire(wireItem);
|
||||
}
|
||||
}
|
||||
if (toolbarValueSearch.searchResult.length > 0) {
|
||||
toolbarValueSearch.cursorIndex = 0;
|
||||
const { link } = toolbarValueSearch.searchResult[0];
|
||||
sidebarSelectedWires.add(link);
|
||||
}
|
||||
}
|
||||
|
||||
function search() {
|
||||
if (globalLookup.currentWires.size === 0 || searchManage.content.trim().length === 0) {
|
||||
searchManage.searchResult.length = 0;
|
||||
if (globalLookup.currentWires.size === 0 || toolbarValueSearch.content.trim().length === 0) {
|
||||
toolbarValueSearch.searchResult.length = 0;
|
||||
toolbarValueSearch.resultLinkSet.clear();
|
||||
return;
|
||||
}
|
||||
|
||||
@ -126,19 +140,30 @@ function search() {
|
||||
|
||||
const safeSearch = debounceWrapper(search, 200);
|
||||
|
||||
function clickSearchItem() {
|
||||
function getPrevIconClass() {
|
||||
switch (searchMode.value) {
|
||||
case 0:
|
||||
return 'iconfont icon-arrow-left';
|
||||
|
||||
}
|
||||
case 1:
|
||||
return 'iconfont icon-arrow-up';
|
||||
|
||||
function makeSignalCaption(signal) {
|
||||
if (signal === undefined) {
|
||||
return '';
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return signal.width === 1 ? '' : `${signal.width - 1}:0`;
|
||||
}
|
||||
|
||||
function makeSignalIconClass(signal) {
|
||||
return 'iconfont ' + makeIconClass(signal);
|
||||
function getNextIconClass() {
|
||||
switch (searchMode.value) {
|
||||
case 0:
|
||||
return 'iconfont icon-arrow-right';
|
||||
|
||||
case 1:
|
||||
return 'iconfont icon-arrow-down';
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
</script>
|
||||
@ -155,7 +180,7 @@ function makeSignalIconClass(signal) {
|
||||
.value-input-wrapper {
|
||||
position: relative;
|
||||
margin-left: 5px;
|
||||
width: 120px;
|
||||
transition: var(--animation-5s);
|
||||
}
|
||||
|
||||
.toolbar-search-container {
|
||||
@ -255,4 +280,36 @@ function makeSignalIconClass(signal) {
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.value-text {
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.value-choose > span {
|
||||
cursor: pointer;
|
||||
padding: 3px;
|
||||
border-radius: .3em;
|
||||
font-weight: 800;
|
||||
font-size: 22px;
|
||||
margin-left: 3px;
|
||||
transition: var(--animation-3s);
|
||||
}
|
||||
|
||||
.value-choose > span:hover {
|
||||
background-color: var(--main-color);
|
||||
color: var(--sidebar);
|
||||
transition: var(--animation-3s);
|
||||
}
|
||||
|
||||
.value-choose.disabled > span {
|
||||
cursor: not-allowed;
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
.value-choose.disabled > span:hover {
|
||||
background-color: unset;
|
||||
color: unset;
|
||||
}
|
||||
|
||||
|
||||
</style>
|
@ -129,7 +129,7 @@ export const globalLookup = reactive({
|
||||
/**
|
||||
*
|
||||
* @param {string} link
|
||||
* @param {'height' | 'color' | 'valueFormat' | 'renderModal'} option
|
||||
* @param {'height' | 'color' | 'valueFormat' | 'renderModal' | 'highlight'} option
|
||||
* @param {any} value
|
||||
* @returns {boolean} true 代表改变了值,否则则没有,可以用来判断是否需要重复塑造 Vertices
|
||||
*/
|
||||
|
@ -24,6 +24,9 @@ export const sidebarSelectedWires = {
|
||||
|
||||
add(link) {
|
||||
globalLookup.sidebarSelectedWireLinks.add(link);
|
||||
// 让渲染进行高亮
|
||||
globalLookup.setRenderOption(link, 'highlight', 1);
|
||||
globalLookup.render({ type: 'wave-only' });
|
||||
this.lastLink = link;
|
||||
this.togglePipe();
|
||||
},
|
||||
@ -37,6 +40,8 @@ export const sidebarSelectedWires = {
|
||||
break;
|
||||
}
|
||||
}
|
||||
globalLookup.setRenderOption(link, 'highlight', 0);
|
||||
globalLookup.render({ type: 'wave-only' });
|
||||
this.togglePipe();
|
||||
},
|
||||
|
||||
|
@ -161,9 +161,12 @@ function getSmartCurrentSignalValue(changoItem, time) {
|
||||
}
|
||||
}
|
||||
|
||||
async function updateWireCurrentValue() {
|
||||
async function updateWireCurrentValue(time) {
|
||||
const chango = globalLookup.chango;
|
||||
const time = globalLookup.currentTime;
|
||||
if (time === undefined) {
|
||||
time = globalLookup.currentTime;
|
||||
}
|
||||
|
||||
const currentSignalValues = globalLookup.currentSignalValues;
|
||||
|
||||
for (const signal of globalLookup.currentWires) {
|
||||
|
@ -37,6 +37,7 @@ out vec4 v_color;
|
||||
uniform float posYFactor;
|
||||
uniform vec2 scale;
|
||||
uniform vec2 offset;
|
||||
uniform vec3 colorOffset;
|
||||
uniform vec4 colors[${colorsLength}];
|
||||
uniform vec2 shifts[7]; // 基础八位图偏移量,为了性能,pos 只传入整数,需要的坐标负数由该值提供
|
||||
uniform vec2 widthShifts[9]; // 用于构造线宽的偏移
|
||||
@ -44,7 +45,13 @@ uniform vec2 widthShifts[9]; // 用于构造线宽的偏移
|
||||
void main() {
|
||||
vec2 shift = shifts[control.x];
|
||||
vec2 ws = widthShifts[control.y];
|
||||
v_color = colors[control.z];
|
||||
vec4 color = colors[control.z];
|
||||
v_color = vec4(
|
||||
color.x + colorOffset.x,
|
||||
color.y + colorOffset.y,
|
||||
color.z + colorOffset.z,
|
||||
color.w
|
||||
);
|
||||
|
||||
// 为了性能,传递进来进来的都是整数,pos.y 需要除以 posYFactor
|
||||
float posX = float(pos.x);
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { globalSetting, globalStyle } from '../global';
|
||||
import { globalLookup, globalSetting, globalStyle } from '../global';
|
||||
|
||||
import { gl_Colors, gl_Shifts, gl_Shifts_for_bar, gl_WidthShifts, barShift, getRatio, screenHeightPixel, maskColorIndexOffset, posYFactor, glslInputLength, prettyPrint, ladderAnalog_GL_WidthShifts, lineAnlog_GL_WidthShifts } from './render-utils.js';
|
||||
import { vertexShader, fragmentShader } from './render-shader.js';
|
||||
@ -56,6 +56,7 @@ class WebGL2WaveRender {
|
||||
* offset: WebGLUniformLocation,
|
||||
* pos: number,
|
||||
* control: number,
|
||||
* colorOffset: number,
|
||||
* widthShifts: WebGLUniformLocation,
|
||||
* gl: WebGL2RenderingContext
|
||||
* }}
|
||||
@ -73,6 +74,7 @@ class WebGL2WaveRender {
|
||||
posYFactor: gl.getUniformLocation(program, 'posYFactor'),
|
||||
scale: gl.getUniformLocation(program, 'scale'),
|
||||
offset: gl.getUniformLocation(program, 'offset'),
|
||||
colorOffset: gl.getUniformLocation(program, 'colorOffset'),
|
||||
pos: gl.getAttribLocation(program, 'pos'),
|
||||
control: gl.getAttribLocation(program, 'control'),
|
||||
widthShifts: gl.getUniformLocation(program, 'widthShifts'),
|
||||
@ -485,10 +487,19 @@ class WebGL2WaveRender {
|
||||
const lineVertices = lineVerticesMap.get(id);
|
||||
const maskVertices = maskVerticesMap.get(id);
|
||||
|
||||
const highlightCode = getHighlightCode(id);
|
||||
if (highlightCode > 0) {
|
||||
const colorIncrement = 0.3;
|
||||
gl.uniform3f(webglLocation.colorOffset, colorIncrement, colorIncrement, colorIncrement);
|
||||
} else {
|
||||
gl.uniform3f(webglLocation.colorOffset, 0, 0, 0);
|
||||
}
|
||||
|
||||
if (signal.size === 1) {
|
||||
// 如果是 bit
|
||||
gl.uniform2fv(webglLocation.widthShifts, gl_WidthShifts);
|
||||
|
||||
|
||||
gl.uniform2fv(webglLocation.shifts, gl_Shifts);
|
||||
gl.bindVertexArray(signalItem.lineVao);
|
||||
gl.drawArrays(gl.TRIANGLE_STRIP, 0, lineVertices.length / glslInputLength);
|
||||
@ -529,6 +540,9 @@ class WebGL2WaveRender {
|
||||
}
|
||||
}
|
||||
|
||||
if (renderConfig.type === 'wave-only') {
|
||||
return;
|
||||
}
|
||||
plugins.map(fn => fn(globalLookup, pstate, elements));
|
||||
}
|
||||
|
||||
@ -558,7 +572,22 @@ class WebGL2WaveRender {
|
||||
requestAnimationFrame(drawWaves);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} link
|
||||
* @returns {number}
|
||||
*/
|
||||
function getHighlightCode(link) {
|
||||
const renderOptions = globalLookup.currentSignalRenderOptions;
|
||||
if (renderOptions.has(link)) {
|
||||
const option = renderOptions.get(link);
|
||||
if (typeof option.highlight === 'number') {
|
||||
return option.highlight;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
export default WebGL2WaveRender;
|
@ -121,7 +121,7 @@ export class FormatValueRender {
|
||||
}
|
||||
|
||||
let valueString = value.toString(radix);
|
||||
if (valueString.length <= pos) {
|
||||
if (pos === -1 || valueString.length <= pos) {
|
||||
return valueString;
|
||||
}
|
||||
const valSign = (value < 0) ? '-' : '';
|
||||
@ -137,7 +137,7 @@ export class FormatValueRender {
|
||||
|
||||
// 无符号的各类进制数字
|
||||
const valueString = value.toString(radix);
|
||||
if (valueString.length <= pos) {
|
||||
if (pos === -1 || valueString.length <= pos) {
|
||||
return valueString;
|
||||
}
|
||||
if (pos === 1) {
|
||||
@ -166,7 +166,7 @@ export class FormatValueRender {
|
||||
}
|
||||
|
||||
const valueString = value.toString();
|
||||
if (valueString.length <= pos) {
|
||||
if (pos === -1 || valueString.length <= pos) {
|
||||
return valueString;
|
||||
}
|
||||
const valSign = (value < 0) ? '-' : '';
|
||||
|
@ -93,6 +93,13 @@
|
||||
"toolbar.location.to-prev-change": "Go to Previous Change Edge",
|
||||
"toolbar.location.make-location": "Create New Pivot",
|
||||
|
||||
"context-menu.cannot-join-repeat-group": "current signal is already contained in this group",
|
||||
|
||||
"toolbar.no-result": "No Result",
|
||||
"toolbar.search.value.already-to-head": "already to head",
|
||||
"toolbar.search.value.already-to-tail": "already to tail",
|
||||
"toolbar.search.value.searching": "searching",
|
||||
|
||||
"current-version": "current version",
|
||||
"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>."
|
||||
}
|
@ -91,6 +91,13 @@
|
||||
"toolbar.location.to-prev-change": "前往上一个变化的边沿",
|
||||
"toolbar.location.make-location": "创建新的信标",
|
||||
|
||||
"context-menu.cannot-join-repeat-group": "当前信号已在此分组中",
|
||||
|
||||
"toolbar.no-result": "无结果",
|
||||
"toolbar.search.value.already-to-head": "已经到开头了",
|
||||
"toolbar.search.value.already-to-tail": "已经到结尾了",
|
||||
"toolbar.search.value.searching": "搜索中",
|
||||
|
||||
"current-version": "当前版本",
|
||||
"copyright": "本软件版权归 <a href=\"https://github.com/Digital-EDA\" target=\"_blank\">Digital-IDE</a> 项目组所有,欢迎 <a href=\"https://github.com/Digital-EDA/Digital-IDE\">Star</a>。"
|
||||
}
|
@ -35,7 +35,7 @@
|
||||
* @typedef {Object} WaveRenderSidebarItem
|
||||
* @property {WireItemBaseInfo} signalInfo
|
||||
* @property {GroupBaseInfo} groupInfo
|
||||
* @property {0 | 1} renderType 0 代表单条波形,1 代表 分组
|
||||
* @property {0 | 1 | 2} renderType 0:单条波形,1:分组,2:bus聚合
|
||||
* @property {WaveRenderSidebarItem[]} children 分组内的波形,只有当 renderType 为 1 时才不为空数组
|
||||
*/
|
||||
|
||||
@ -129,7 +129,7 @@
|
||||
/**
|
||||
* @description
|
||||
* @typedef {Object} RenderConfig
|
||||
* @property {'common' | 'action' | 'value' | undefined} type
|
||||
* @property {'common' | 'action' | 'value' | 'wave-only' | undefined} type
|
||||
*/
|
||||
|
||||
/**
|
||||
@ -155,5 +155,6 @@
|
||||
* @property {number | undefined} color 波形的颜色,可以在右击菜单栏中设置
|
||||
* @property {number | undefined} valueFormat 波形数字的展示形式,可以在上侧的下拉菜单中设置,vec 类型的波形,可以设置为:0:二进制、1:八进制、2:十六进制、3:有符号整型、4:无符号整型、5:浮点数(半精度、6:单精度、7:双精度)
|
||||
* @property {number | undefined} renderModal 波形的渲染模式,默认为 bit 和 vec,vec 类型的波形,可以设置为:0:数字形式、1:折线模拟形式、2:阶梯模拟形式
|
||||
* @property {number | undefined} highlight 当前是否需要进行高亮 1 代表需要
|
||||
*/
|
||||
|
||||
|
@ -2982,10 +2982,10 @@ electron-to-chromium@^1.4.668:
|
||||
resolved "https://registry.npmmirror.com/electron-to-chromium/-/electron-to-chromium-1.4.673.tgz"
|
||||
integrity sha512-zjqzx4N7xGdl5468G+vcgzDhaHkaYgVcf9MqgexcTqsl2UHSCmOj/Bi3HAprg4BZCpC7HyD8a6nZl6QAZf72gw==
|
||||
|
||||
element-plus@^2.5.6:
|
||||
version "2.5.6"
|
||||
resolved "https://registry.npmmirror.com/element-plus/-/element-plus-2.5.6.tgz"
|
||||
integrity sha512-zctKTiyIDmcnMp3K5WG1hglgraW9EbiCLiIDVtaMCS5mPMl2fRKdS0vOFGnECIq9taFoxnyoDwxHD81nv0B4RA==
|
||||
element-plus@^2.6.3:
|
||||
version "2.6.3"
|
||||
resolved "https://registry.npmjs.org/element-plus/-/element-plus-2.6.3.tgz"
|
||||
integrity sha512-U4L/mr+1r+EmAUYUHrs0V/8hHMdBGP07rPymSC72LZCN4jK1UwygQYICegTQ5us4mxeqBvW6wfoEfo003fwCqw==
|
||||
dependencies:
|
||||
"@ctrl/tinycolor" "^3.4.1"
|
||||
"@element-plus/icons-vue" "^2.3.1"
|
||||
|
Loading…
x
Reference in New Issue
Block a user