完成信标功能
This commit is contained in:
parent
f74fc31aaf
commit
47e9e57c80
@ -1,6 +1,6 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: "iconfont"; /* Project id 4440655 */
|
font-family: "iconfont"; /* Project id 4440655 */
|
||||||
src: url('iconfont.woff2?t=1723382481292') format('woff2');
|
src: url('iconfont.woff2?t=1725033317914') format('woff2');
|
||||||
}
|
}
|
||||||
|
|
||||||
.iconfont {
|
.iconfont {
|
||||||
@ -11,6 +11,10 @@
|
|||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.icon-axis:before {
|
||||||
|
content: "\ed1f";
|
||||||
|
}
|
||||||
|
|
||||||
.icon-add-line:before {
|
.icon-add-line:before {
|
||||||
content: "\e7b0";
|
content: "\e7b0";
|
||||||
}
|
}
|
||||||
|
Binary file not shown.
@ -2,8 +2,8 @@
|
|||||||
<!-- 上方的 toolbar -->
|
<!-- 上方的 toolbar -->
|
||||||
<ToolBar></ToolBar>
|
<ToolBar></ToolBar>
|
||||||
|
|
||||||
<!-- 主渲染区 -->
|
<!-- 信标区域 -->
|
||||||
<MainRender></MainRender>
|
<Pivot></Pivot>
|
||||||
|
|
||||||
<!-- 左上角的 sidebar,用于显示 -->
|
<!-- 左上角的 sidebar,用于显示 -->
|
||||||
<Sidebar></Sidebar>
|
<Sidebar></Sidebar>
|
||||||
@ -27,7 +27,7 @@ import { getCrossOriginWorkerURL } from '@/hook/network';
|
|||||||
import ToolBar from '@/components/toolbar';
|
import ToolBar from '@/components/toolbar';
|
||||||
import Sidebar from '@/components/sidebar';
|
import Sidebar from '@/components/sidebar';
|
||||||
import RightNav from '@/components/right-nav.vue';
|
import RightNav from '@/components/right-nav.vue';
|
||||||
import MainRender from '@/components/render';
|
import Pivot from '@/components/pivot';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
@ -2,30 +2,53 @@ import { globalLookup } from '@/hook/global';
|
|||||||
import formatTime from '@/hook/wave-view/format-time';
|
import formatTime from '@/hook/wave-view/format-time';
|
||||||
import { reactive } from 'vue';
|
import { reactive } from 'vue';
|
||||||
|
|
||||||
export const StaticCursor = reactive({
|
/**
|
||||||
|
* @typedef {(event: MouseEvent) => void} MousemoveFn
|
||||||
|
*/
|
||||||
|
|
||||||
|
export const MovingPivot = reactive({
|
||||||
|
color: '#CB81DA',
|
||||||
|
label: '',
|
||||||
|
left: 0,
|
||||||
|
currentTime: 0,
|
||||||
|
show: true,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @type {import('./pivot-view').UserPivot | undefined}
|
||||||
|
*/
|
||||||
|
currentTakenPivot: undefined,
|
||||||
|
dragEnable: false
|
||||||
|
});
|
||||||
|
|
||||||
|
export const SystemPivot = reactive({
|
||||||
label: '',
|
label: '',
|
||||||
show: false,
|
show: false,
|
||||||
currentTime: 0,
|
currentTime: 0,
|
||||||
left: 0,
|
left: 0,
|
||||||
|
color: '#CB81DA',
|
||||||
updateLabel(timescale) {
|
updateLabel(timescale) {
|
||||||
this.label = formatTime(this.currentTime, timescale);
|
this.label = formatTime(this.currentTime, timescale);
|
||||||
this.show = true;
|
|
||||||
},
|
},
|
||||||
updateLeft() {
|
updateLeft() {
|
||||||
this.left = calcCursorLeft(this.currentTime);
|
this.left = calcCursorLeft(this.currentTime);
|
||||||
this.show = true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 左击改变系统信标的位置
|
||||||
|
*/
|
||||||
export function changeCursorLocation() {
|
export function changeCursorLocation() {
|
||||||
StaticCursor.show = true;
|
if (MovingPivot.dragEnable) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
SystemPivot.show = true;
|
||||||
const pstate = globalLookup.pstate;
|
const pstate = globalLookup.pstate;
|
||||||
if (pstate) {
|
if (pstate) {
|
||||||
const { xCursor, xOffset, xScale, tgcd, timescale } = pstate;
|
const { xCursor, xOffset, xScale, tgcd, timescale } = pstate;
|
||||||
const currentTime = Math.round((xCursor - xOffset) / xScale) * tgcd;
|
const currentTime = Math.round((xCursor - xOffset) / xScale) * tgcd;
|
||||||
StaticCursor.currentTime = currentTime;
|
SystemPivot.currentTime = currentTime;
|
||||||
StaticCursor.updateLabel(timescale);
|
SystemPivot.updateLabel(timescale);
|
||||||
StaticCursor.updateLeft();
|
SystemPivot.updateLeft();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,6 +67,7 @@ export function calcCursorLeft(currentTime) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const MovingCursor = reactive({
|
/**
|
||||||
|
* @type {Map<number, MousemoveFn>}
|
||||||
});
|
*/
|
||||||
|
export const mousemoveEventPipes = new Map();
|
@ -1,18 +1,47 @@
|
|||||||
<template>
|
<template>
|
||||||
<!-- <VerticalCursor></VerticalCursor> -->
|
<!-- <VerticalCursor></VerticalCursor> -->
|
||||||
<!-- <TimeScale></TimeScale> -->
|
<!-- <TimeScale></TimeScale> -->
|
||||||
<div class="vcd-render-wrapper" @click="onRenderClick()">
|
<div
|
||||||
<VerticalCursor></VerticalCursor>
|
class="vcd-render-wrapper"
|
||||||
|
@mousedown="onRenderClick()"
|
||||||
|
@mouseenter="onEnter()"
|
||||||
|
:ref="el => pivotWrapper = el"
|
||||||
|
>
|
||||||
|
<Pivot
|
||||||
|
v-show="SystemPivot.show"
|
||||||
|
:color="SystemPivot.color"
|
||||||
|
:label="SystemPivot.label"
|
||||||
|
:x="SystemPivot.left"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PivotView />
|
||||||
|
<transition name="main-fade">
|
||||||
|
<MovingPivotVue
|
||||||
|
v-show="MovingPivot.show"
|
||||||
|
/>
|
||||||
|
</transition>
|
||||||
|
|
||||||
|
<transition name="collapse-from-top">
|
||||||
|
<UserContextMenu
|
||||||
|
v-show="pivotcontextmenu.show"
|
||||||
|
/>
|
||||||
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { defineComponent, reactive, ref } from 'vue';
|
import { defineComponent, onMounted, ref } from 'vue';
|
||||||
import { emitter, globalLookup, globalSetting } from '@/hook/global';
|
|
||||||
import { updateWireCurrentValue } from '@/hook/utils';
|
import { updateWireCurrentValue } from '@/hook/utils';
|
||||||
import VerticalCursor from '@/components/render/cursor.vue';
|
import { changeCursorLocation, SystemPivot, MovingPivot, mousemoveEventPipes } from './cursor';
|
||||||
import { changeCursorLocation } from './cursor';
|
import { eventHandler, registerWheelEvent } from '@/hook/wave-view';
|
||||||
|
|
||||||
|
import PivotView from './pivot-view.vue';
|
||||||
|
import Pivot from '@/components/pivot/system-pivot.vue';
|
||||||
|
import { globalLookup } from '@/hook/global';
|
||||||
|
import MovingPivotVue from './moving-pivot.vue';
|
||||||
|
import { pivotcontextmenu } from './user-context-menu';
|
||||||
|
import UserContextMenu from './user-context-menu.vue';
|
||||||
|
|
||||||
|
|
||||||
defineComponent({ name: 'main-render' });
|
defineComponent({ name: 'main-render' });
|
||||||
|
|
||||||
@ -24,10 +53,34 @@ function onRenderClick() {
|
|||||||
changeCursorLocation();
|
changeCursorLocation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onEnter() {
|
||||||
|
MovingPivot.show = true;
|
||||||
|
MovingPivot.currentTakenPivot = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const pivotWrapper = ref(null);
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
const pivotContainer = pivotWrapper.value;
|
||||||
|
if (pivotContainer instanceof HTMLElement) {
|
||||||
|
pivotContainer.addEventListener('wheel',
|
||||||
|
registerWheelEvent(null, globalLookup.pstate, globalLookup, eventHandler)
|
||||||
|
);
|
||||||
|
|
||||||
|
pivotContainer.addEventListener('mousemove', event => {
|
||||||
|
for (const pipeId of mousemoveEventPipes.keys()) {
|
||||||
|
const fn = mousemoveEventPipes.get(pipeId);
|
||||||
|
fn(event);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
.vcd-render-wrapper {
|
.vcd-render-wrapper {
|
||||||
|
user-select: none;
|
||||||
height: 98vh;
|
height: 98vh;
|
||||||
width: 98vw;
|
width: 98vw;
|
||||||
cursor: crosshair;
|
cursor: crosshair;
|
||||||
@ -81,7 +134,7 @@ function onRenderClick() {
|
|||||||
.vcd-cursor {
|
.vcd-cursor {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
z-index: 60;
|
z-index: 80;
|
||||||
}
|
}
|
||||||
|
|
||||||
.vcd-values text {
|
.vcd-values text {
|
165
src/components/pivot/moving-pivot.vue
Normal file
165
src/components/pivot/moving-pivot.vue
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
<template>
|
||||||
|
<div :ref="el => element = el">
|
||||||
|
<div
|
||||||
|
class="vertical-cursor-wrapper"
|
||||||
|
:style="cursorStyle"
|
||||||
|
>
|
||||||
|
<div class="current-display-cursor-up">
|
||||||
|
<div class="current-time-value" :style="colorStyle">{{ MovingPivot.label }}</div>
|
||||||
|
<div class="cursor-down-arrow" :style="borderStyle"></div>
|
||||||
|
</div>
|
||||||
|
<div class="vertical-line" :style="verticalLineStyle"></div>
|
||||||
|
<div class="current-display-cursor-down">
|
||||||
|
<div class="current-time-value" :style="colorStyle">{{ MovingPivot.label }}</div>
|
||||||
|
<div class="cursor-up-arrow" :style="borderStyle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { emitter, globalLookup } from '@/hook/global';
|
||||||
|
import { eventHandler, registerWheelEvent } from '@/hook/wave-view';
|
||||||
|
import { computed, defineComponent, ref, onMounted } from 'vue';
|
||||||
|
import { calcCursorLeft, MovingPivot } from './cursor';
|
||||||
|
import formatTime from '@/hook/wave-view/format-time';
|
||||||
|
import { getNearestUserPivot } from './pivot-view';
|
||||||
|
|
||||||
|
defineComponent({ name: 'user-pivot' });
|
||||||
|
const element = ref(null);
|
||||||
|
|
||||||
|
const colorStyle = computed(() => ({
|
||||||
|
backgroundColor: MovingPivot.color
|
||||||
|
}));
|
||||||
|
|
||||||
|
const verticalLineStyle = computed(() => ({
|
||||||
|
border: '2px dashed ' + MovingPivot.color
|
||||||
|
}));
|
||||||
|
|
||||||
|
const borderStyle = computed(() => ({
|
||||||
|
borderLeft: '5px solid ' + MovingPivot.color,
|
||||||
|
borderTop: '5px solid ' + MovingPivot.color
|
||||||
|
}));
|
||||||
|
|
||||||
|
const boxShift = 30;
|
||||||
|
const cursorStyle = computed(() => ({
|
||||||
|
left: MovingPivot.left - boxShift + 'px'
|
||||||
|
}));
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {MouseEvent} event
|
||||||
|
*/
|
||||||
|
function onMousemove(event) {
|
||||||
|
const pstate = globalLookup.pstate;
|
||||||
|
const x = event.clientX || event.x;
|
||||||
|
pstate.xCursor = x;
|
||||||
|
const { xScale, xOffset, tgcd, timescale, xCursor } = pstate;
|
||||||
|
const currentT = Math.round((xCursor - xOffset) / xScale) * tgcd;
|
||||||
|
globalLookup.currentTime = currentT;
|
||||||
|
MovingPivot.currentTime = currentT;
|
||||||
|
MovingPivot.label = formatTime(currentT, timescale);
|
||||||
|
MovingPivot.left = calcCursorLeft(currentT);
|
||||||
|
|
||||||
|
if (MovingPivot.currentTakenPivot !== undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// 通过计算距离最近的用户信标,来决定是否要消失,给与用户信标空间来执行额外操作
|
||||||
|
const userPivot = getNearestUserPivot(currentT);
|
||||||
|
|
||||||
|
if (userPivot) {
|
||||||
|
const marginX = Math.abs(x - userPivot.x);
|
||||||
|
if (marginX < 25) {
|
||||||
|
// 此时距离用户信标比较近,隐藏主信标
|
||||||
|
MovingPivot.show = false;
|
||||||
|
MovingPivot.currentTakenPivot = userPivot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
emitter.on('meta-ready', () => {
|
||||||
|
const pivot = element.value;
|
||||||
|
if (pivot instanceof HTMLElement) {
|
||||||
|
document.addEventListener('mousemove', onMousemove);
|
||||||
|
|
||||||
|
// 添加光标初始位置
|
||||||
|
const validWidth = globalLookup.pstate.width || window.innerWidth;
|
||||||
|
onMousemove({ clientX: validWidth / 2 })
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.vertical-cursor-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
padding: 0;
|
||||||
|
cursor: crosshair;
|
||||||
|
z-index: 55;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center; /* 沿着横轴(水平方向)对齐 */
|
||||||
|
justify-content: center; /* 沿着纵轴(垂直方向)对齐 */
|
||||||
|
transform: translateY(var(--toolbar-height));
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-display-cursor-up {
|
||||||
|
height: var(--time-scale-height);
|
||||||
|
width: 60px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
color: var(--sidebar-item-text);
|
||||||
|
font-size: 14px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-display-cursor-down {
|
||||||
|
height: var(--time-scale-height);
|
||||||
|
width: 60px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
color: var(--sidebar-item-text);
|
||||||
|
font-size: 14px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-time-value {
|
||||||
|
border-radius: .4em;
|
||||||
|
color: var(--sidebar);
|
||||||
|
padding: 5px;
|
||||||
|
width: fit-content;
|
||||||
|
font-size: 1.05rem;
|
||||||
|
font-family: var(--vcd-value-font-family);
|
||||||
|
white-space: nowrap;
|
||||||
|
z-index: 60;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cursor-down-arrow {
|
||||||
|
transform: rotate(225deg);
|
||||||
|
position: absolute;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
/* 30px - 10 * 2 / \sqrt{2} */
|
||||||
|
left: 19.93px;
|
||||||
|
bottom: -3px;
|
||||||
|
z-index: 50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vertical-line {
|
||||||
|
height: calc(100vh - 2 * var(--time-scale-height) - 65px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cursor-up-arrow {
|
||||||
|
transform: rotate(45deg);
|
||||||
|
position: absolute;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
left: 19.93px;
|
||||||
|
top: -3px;
|
||||||
|
z-index: 50;
|
||||||
|
}
|
||||||
|
</style>
|
138
src/components/pivot/pivot-view.js
Normal file
138
src/components/pivot/pivot-view.js
Normal file
@ -0,0 +1,138 @@
|
|||||||
|
import { reactive, ref } from "vue";
|
||||||
|
import { calcCursorLeft, SystemPivot } from "./cursor";
|
||||||
|
import { globalLookup } from "@/hook/global";
|
||||||
|
import formatTime from "@/hook/wave-view/format-time";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 每一个动态信标
|
||||||
|
* @typedef {Object} UserPivot
|
||||||
|
* @property {number} id
|
||||||
|
* @property {string} label
|
||||||
|
* @property {number} x
|
||||||
|
* @property {number} time
|
||||||
|
* @property {boolean} show
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 该数据结构描述了所有通过 makePivot 创建的 用户信标
|
||||||
|
* @type {Map<number, UserPivot>}
|
||||||
|
*/
|
||||||
|
export const UserPivots = reactive(new Map());
|
||||||
|
export const orderedTimes = [];
|
||||||
|
|
||||||
|
export const UserPivotColor = ref('#1e90ff');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 创建一个信标
|
||||||
|
* @param {number} time 需要创建的轴的时间点
|
||||||
|
*/
|
||||||
|
export function createPivot(time) {
|
||||||
|
if (UserPivots.has(time)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const id = Date.now();
|
||||||
|
const x = calcCursorLeft(time);
|
||||||
|
const timescale = globalLookup.timescale;
|
||||||
|
const label = formatTime(time, timescale);
|
||||||
|
const show = true;
|
||||||
|
|
||||||
|
UserPivots.set(time, { time, x, id, label, show });
|
||||||
|
orderedTimes.push(time);
|
||||||
|
orderedTimes.sort((a, b) => a < b);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function searchOrderedTimeIndex(time) {
|
||||||
|
for (let i = 0; i < orderedTimes.length; ++ i) {
|
||||||
|
if (orderedTimes[i] === time) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function deletePivot(time) {
|
||||||
|
if (!UserPivots.has(time)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UserPivots.delete(time);
|
||||||
|
const i = searchOrderedTimeIndex(time);
|
||||||
|
if (i !== undefined) {
|
||||||
|
orderedTimes.splice(i, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateAllPivots() {
|
||||||
|
// 更新系统信标
|
||||||
|
SystemPivot.updateLeft();
|
||||||
|
|
||||||
|
// 更新所有用户信标
|
||||||
|
for (const time of UserPivots.keys()) {
|
||||||
|
const pivot = UserPivots.get(time);
|
||||||
|
pivot.x = calcCursorLeft(time);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param {number[]} times
|
||||||
|
* @param {number} target 目标时间
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
function bisearch(times, target) {
|
||||||
|
let i = 0, j = times.length - 1;
|
||||||
|
while (i < j) {
|
||||||
|
if (times[i] === target) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (times[j] <= target) {
|
||||||
|
i = j;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (j - i === 1) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const mid = (i + j) >> 1;
|
||||||
|
if (times[mid] > target) {
|
||||||
|
j = mid;
|
||||||
|
} else {
|
||||||
|
i = mid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description 高效获取距离 time 最近的时间点 t,时间复杂度 O(logn)
|
||||||
|
* @param {number} time
|
||||||
|
* @returns {UserPivot | undefined}
|
||||||
|
*/
|
||||||
|
export function getNearestUserPivot(time) {
|
||||||
|
const pivotNum = UserPivots.size;
|
||||||
|
if (pivotNum === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pivotNum === 1) {
|
||||||
|
for (const [time, pivot] of UserPivots) {
|
||||||
|
return pivot;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const i = bisearch(orderedTimes, time);
|
||||||
|
// console.log(i, orderedTimes, time);
|
||||||
|
|
||||||
|
if (i === pivotNum - 1) {
|
||||||
|
return UserPivots.get(orderedTimes[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
const prevT = orderedTimes[i];
|
||||||
|
const nextT = orderedTimes[i + 1];
|
||||||
|
if (nextT - time > time - prevT) {
|
||||||
|
return UserPivots.get(prevT);
|
||||||
|
}
|
||||||
|
return UserPivots.get(nextT);
|
||||||
|
}
|
27
src/components/pivot/pivot-view.vue
Normal file
27
src/components/pivot/pivot-view.vue
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
v-for="(pivot, index) in UserPivots"
|
||||||
|
:key="pivot[1].id"
|
||||||
|
>
|
||||||
|
<UserPivot
|
||||||
|
v-show="pivot[1].show"
|
||||||
|
:color="UserPivotColor"
|
||||||
|
:label="pivot[1].label"
|
||||||
|
:x="pivot[1].x"
|
||||||
|
:time="pivot[1].time"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
/**
|
||||||
|
* @description 该模块为创建新的信标采用的视图,可以看 makePivot 这个函数
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { defineComponent } from 'vue';
|
||||||
|
import { UserPivotColor, UserPivots } from './pivot-view';
|
||||||
|
import UserPivot from './user-pivot.vue';
|
||||||
|
|
||||||
|
defineComponent({ name: 'pivot-view' });
|
||||||
|
|
||||||
|
</script>
|
@ -1,48 +1,65 @@
|
|||||||
<template>
|
<template>
|
||||||
<div v-show="StaticCursor.show">
|
<div v-if="renderPivot">
|
||||||
<div class="vertical-cursor-wrapper"
|
<div
|
||||||
|
class="vertical-cursor-wrapper"
|
||||||
:style="cursorStyle"
|
:style="cursorStyle"
|
||||||
>
|
>
|
||||||
<div class="current-display-cursor-up">
|
<div class="current-display-cursor-up">
|
||||||
<div class="current-time-value" :style="colorStyle">{{ StaticCursor.label }}</div>
|
<div class="current-time-value" :style="colorStyle">{{ props.label }}</div>
|
||||||
<div class="cursor-down-arrow" :style="borderStyle"></div>
|
<div class="cursor-down-arrow" :style="borderStyle"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="vertical-line" :style="colorStyle"></div>
|
<div class="vertical-line" :style="colorStyle"></div>
|
||||||
<div class="current-display-cursor-down">
|
<div class="current-display-cursor-down">
|
||||||
<div class="current-time-value" :style="colorStyle">{{ StaticCursor.label }}</div>
|
<div class="current-time-value" :style="colorStyle">{{ props.label }}</div>
|
||||||
<div class="cursor-up-arrow" :style="borderStyle"></div>
|
<div class="cursor-up-arrow" :style="borderStyle"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
import { globalLookup } from '@/hook/global';
|
||||||
import { computed, defineComponent } from 'vue';
|
import { computed, defineComponent } from 'vue';
|
||||||
import { StaticCursor } from './cursor';
|
|
||||||
|
|
||||||
defineComponent({ name: 'vertical-cursor' });
|
defineComponent({ name: 'system-pivot' });
|
||||||
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
color: {
|
color: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'var(--main-color)'
|
default: 'var(--main-color)'
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
x: {
|
||||||
|
type: Number
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const colorStyle = {
|
const colorStyle = computed(() => ({
|
||||||
backgroundColor: props.color
|
backgroundColor: props.color
|
||||||
};
|
}));
|
||||||
|
|
||||||
const borderStyle = {
|
const borderStyle = computed(() => ({
|
||||||
borderLeft: '5px solid ' + props.color,
|
borderLeft: '5px solid ' + props.color,
|
||||||
borderTop: '5px solid ' + props.color
|
borderTop: '5px solid ' + props.color
|
||||||
};
|
}));
|
||||||
|
|
||||||
const boxShift = 25;
|
const boxShift = 25;
|
||||||
const cursorStyle = computed(() => ({
|
const cursorStyle = computed(() => ({
|
||||||
left: StaticCursor.left - boxShift + 'px'
|
left: props.x - boxShift + 'px'
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
const renderPivot = computed(() => {
|
||||||
|
const x = props.x - boxShift;
|
||||||
|
if (x > 0 && x < (globalLookup.pstate.width || window.innerWidth)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
@ -50,12 +67,11 @@ const cursorStyle = computed(() => ({
|
|||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
cursor: crosshair;
|
|
||||||
z-index: 55;
|
z-index: 55;
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
align-items: center; /* 沿着横轴(水平方向)对齐 */
|
align-items: center;
|
||||||
justify-content: center; /* 沿着纵轴(垂直方向)对齐 */
|
justify-content: center;
|
||||||
transform: translateY(var(--toolbar-height));
|
transform: translateY(var(--toolbar-height));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,6 +102,7 @@ const cursorStyle = computed(() => ({
|
|||||||
color: var(--sidebar-item-text);
|
color: var(--sidebar-item-text);
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
width: fit-content;
|
width: fit-content;
|
||||||
|
font-family: var(--vcd-value-font-family);
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
17
src/components/pivot/user-context-menu.js
Normal file
17
src/components/pivot/user-context-menu.js
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import { reactive } from "vue";
|
||||||
|
import { getNearestUserPivot } from "./pivot-view";
|
||||||
|
import { globalLookup } from "@/hook/global";
|
||||||
|
|
||||||
|
|
||||||
|
export const pivotcontextmenu = reactive({
|
||||||
|
show: false,
|
||||||
|
x: 0,
|
||||||
|
y: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
export function handleUserContextMenu(event) {
|
||||||
|
const x = event.x;
|
||||||
|
pivotcontextmenu.x = event.x;
|
||||||
|
pivotcontextmenu.y = event.y;
|
||||||
|
pivotcontextmenu.show = true;
|
||||||
|
}
|
76
src/components/pivot/user-context-menu.vue
Normal file
76
src/components/pivot/user-context-menu.vue
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="user-context-menu"
|
||||||
|
:style="contextStyle"
|
||||||
|
>
|
||||||
|
<div class="menu-container">
|
||||||
|
<div
|
||||||
|
class="menu-item-container"
|
||||||
|
@click="deleteUserPivot()"
|
||||||
|
>
|
||||||
|
<span class="menu-item-icon iconfont icon-delete"></span>
|
||||||
|
<span class="menu-item-name">{{ t('pivot.context.delete') }}</span>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="menu-item-container"
|
||||||
|
@click="displayRelativeAxis()"
|
||||||
|
>
|
||||||
|
<span class="menu-item-icon iconfont icon-axis"></span>
|
||||||
|
<span class="menu-item-name">{{ t('pivot.context.display-axis') }}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed, defineComponent } from 'vue';
|
||||||
|
import { MovingPivot } from './cursor';
|
||||||
|
import { useI18n } from 'vue-i18n';
|
||||||
|
import { pivotcontextmenu } from './user-context-menu';
|
||||||
|
import { globalLookup } from '@/hook/global';
|
||||||
|
import { getNearestUserPivot, orderedTimes, searchOrderedTimeIndex, UserPivots } from './pivot-view';
|
||||||
|
|
||||||
|
defineComponent({ name: 'user-context-menu' });
|
||||||
|
|
||||||
|
const { t } = useI18n();
|
||||||
|
|
||||||
|
const contextStyle = computed(() => ({
|
||||||
|
top: pivotcontextmenu.y + ' px',
|
||||||
|
left: pivotcontextmenu.x + 20 + 'px'
|
||||||
|
}));
|
||||||
|
|
||||||
|
function deleteUserPivot() {
|
||||||
|
const x = pivotcontextmenu.x;
|
||||||
|
const pstate = globalLookup.pstate;
|
||||||
|
if (pstate) {
|
||||||
|
const { xOffset, xScale, tgcd } = pstate;
|
||||||
|
const currentTime = Math.round((x - xOffset) / xScale) * tgcd;
|
||||||
|
const pivot = getNearestUserPivot(currentTime);
|
||||||
|
if (pivot) {
|
||||||
|
const i = searchOrderedTimeIndex(pivot.time);
|
||||||
|
orderedTimes.splice(i, 1);
|
||||||
|
UserPivots.delete(pivot.time);
|
||||||
|
pivotcontextmenu.show = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function displayRelativeAxis() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.user-context-menu {
|
||||||
|
z-index: 200;
|
||||||
|
border-radius: .5em;
|
||||||
|
padding: 10px;
|
||||||
|
position: fixed;
|
||||||
|
box-shadow: 0 0 10px 1px rgb(16, 16, 16);
|
||||||
|
background-color: var(--sidebar);
|
||||||
|
border: solid 1px var(--sidebar-border);
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
232
src/components/pivot/user-pivot.vue
Normal file
232
src/components/pivot/user-pivot.vue
Normal file
@ -0,0 +1,232 @@
|
|||||||
|
<template>
|
||||||
|
<div
|
||||||
|
v-if="renderPivot"
|
||||||
|
@mouseenter="onEnter()"
|
||||||
|
@mouseleave="onLeave()"
|
||||||
|
@contextmenu.prevent="handleUserContextMenu($event)"
|
||||||
|
class="user-pivot"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="vertical-cursor-wrapper"
|
||||||
|
:style="cursorStyle"
|
||||||
|
>
|
||||||
|
<div class="current-display-cursor-up">
|
||||||
|
<div class="current-time-value" :style="colorStyle">{{ props.label }}</div>
|
||||||
|
<div class="cursor-down-arrow" :style="borderStyle"></div>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="vertical-line"
|
||||||
|
:style="colorStyle"
|
||||||
|
:ref="el => vline.element = el"
|
||||||
|
@mousedown.stop="onVLineMousedown()"
|
||||||
|
@mouseup.stop="onVLineMouseup()"
|
||||||
|
></div>
|
||||||
|
<div class="current-display-cursor-down">
|
||||||
|
<div class="current-time-value" :style="colorStyle">{{ props.label }}</div>
|
||||||
|
<div class="cursor-up-arrow" :style="borderStyle"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { globalLookup } from '@/hook/global';
|
||||||
|
import { eventHandler, registerWheelEvent } from '@/hook/wave-view';
|
||||||
|
import { computed, defineComponent, ref, onMounted, reactive, nextTick } from 'vue';
|
||||||
|
import { calcCursorLeft, mousemoveEventPipes, MovingPivot } from './cursor';
|
||||||
|
import { orderedTimes, searchOrderedTimeIndex, UserPivots } from './pivot-view';
|
||||||
|
import formatTime from '@/hook/wave-view/format-time';
|
||||||
|
import { handleUserContextMenu } from './user-context-menu';
|
||||||
|
|
||||||
|
defineComponent({ name: 'user-pivot' });
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
color: {
|
||||||
|
type: String,
|
||||||
|
default: 'var(--main-color)'
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String
|
||||||
|
},
|
||||||
|
x: {
|
||||||
|
type: Number
|
||||||
|
},
|
||||||
|
time: {
|
||||||
|
type: Number
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const colorStyle = computed(() => ({
|
||||||
|
backgroundColor: props.color
|
||||||
|
}));
|
||||||
|
|
||||||
|
const borderStyle = computed(() => ({
|
||||||
|
borderLeft: '5px solid ' + props.color,
|
||||||
|
borderTop: '5px solid ' + props.color
|
||||||
|
}));
|
||||||
|
|
||||||
|
const boxShift = 25;
|
||||||
|
const cursorStyle = computed(() => ({
|
||||||
|
left: props.x - boxShift + 'px'
|
||||||
|
}));
|
||||||
|
|
||||||
|
const renderPivot = computed(() => {
|
||||||
|
const x = props.x - boxShift;
|
||||||
|
if (x > 0 && x < (globalLookup.pstate.width || window.innerWidth)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
function onEnter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
function onLeave() {
|
||||||
|
MovingPivot.show = true;
|
||||||
|
MovingPivot.currentTakenPivot = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const vline = reactive({
|
||||||
|
dragEnable: false,
|
||||||
|
element: undefined,
|
||||||
|
originTime: 0
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
function onVLineMousedown() {
|
||||||
|
const div = vline.element;
|
||||||
|
if (!(div instanceof HTMLElement)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
vline.dragEnable = true;
|
||||||
|
MovingPivot.dragEnable = true;
|
||||||
|
|
||||||
|
vline.originTime = props.time;
|
||||||
|
const pivot = UserPivots.get(vline.originTime);
|
||||||
|
if (pivot === undefined) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 先从 orderTimes 里面拿走
|
||||||
|
const i = searchOrderedTimeIndex(vline.originTime);
|
||||||
|
if (i !== undefined) {
|
||||||
|
orderedTimes.splice(i, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 开启拖拽
|
||||||
|
console.log('begin to drag');
|
||||||
|
|
||||||
|
mousemoveEventPipes.set(pivot.id, event => {
|
||||||
|
const x = event.clientX || event.x;
|
||||||
|
pivot.x = x;
|
||||||
|
const pstate = globalLookup.pstate;
|
||||||
|
if (pstate) {
|
||||||
|
const { xOffset, xScale, tgcd, timescale } = pstate;
|
||||||
|
const t = Math.round((x - xOffset) / xScale) * tgcd;
|
||||||
|
pivot.time = t;
|
||||||
|
pivot.label = formatTime(t, timescale);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onVLineMouseup() {
|
||||||
|
const div = vline.element;
|
||||||
|
if (!(div instanceof HTMLElement)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const pivot = UserPivots.get(vline.originTime);
|
||||||
|
|
||||||
|
if (pivot) {
|
||||||
|
mousemoveEventPipes.delete(pivot.id);
|
||||||
|
UserPivots.delete(vline.originTime);
|
||||||
|
UserPivots.set(pivot.time, pivot);
|
||||||
|
orderedTimes.push(pivot.time);
|
||||||
|
orderedTimes.sort((a, b) => a < b);
|
||||||
|
}
|
||||||
|
|
||||||
|
vline.originTime = 0;
|
||||||
|
vline.dragEnable = false;
|
||||||
|
MovingPivot.currentTakenPivot = pivot;
|
||||||
|
MovingPivot.show = false;
|
||||||
|
MovingPivot.dragEnable = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
|
||||||
|
.user-pivot {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vertical-cursor-wrapper {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
padding: 0;
|
||||||
|
z-index: 55;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center; /* 沿着横轴(水平方向)对齐 */
|
||||||
|
justify-content: center; /* 沿着纵轴(垂直方向)对齐 */
|
||||||
|
transform: translateY(var(--toolbar-height));
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-display-cursor-up {
|
||||||
|
height: var(--time-scale-height);
|
||||||
|
width: 50px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
color: var(--sidebar-item-text);
|
||||||
|
font-size: 14px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-display-cursor-down {
|
||||||
|
height: var(--time-scale-height);
|
||||||
|
width: 50px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-around;
|
||||||
|
color: var(--sidebar-item-text);
|
||||||
|
font-size: 14px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.current-time-value {
|
||||||
|
border-radius: .4em;
|
||||||
|
color: var(--sidebar-item-text);
|
||||||
|
padding: 5px;
|
||||||
|
width: fit-content;
|
||||||
|
font-family: var(--vcd-value-font-family);
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cursor-down-arrow {
|
||||||
|
transform: rotate(225deg);
|
||||||
|
position: absolute;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
/* 25px - 10 * 2 / \sqrt{2} */
|
||||||
|
left: 17.93px;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vertical-line {
|
||||||
|
cursor: ew-resize;
|
||||||
|
width: 2px;
|
||||||
|
height: calc(100vh - 2 * var(--time-scale-height) - 60px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.cursor-up-arrow {
|
||||||
|
transform: rotate(45deg);
|
||||||
|
position: absolute;
|
||||||
|
width: 10px;
|
||||||
|
height: 10px;
|
||||||
|
left: 17.93px;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,135 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="time-scale-up-wrapper">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="time-scale-wrapper" :style="`left: ${currentX}px; width: ${300}px;`">
|
|
||||||
<div class="current-display-cursor-up">
|
|
||||||
<div class="time-scale-value">{{ currentX }} {{ timeScaleManage.unit }}</div>
|
|
||||||
<div class="time-scale-down"></div>
|
|
||||||
</div>
|
|
||||||
<div class="time-scale-line"></div>
|
|
||||||
<div class="current-display-cursor-down">
|
|
||||||
<div class="time-scale-value">{{ currentX }} {{ timeScaleManage.unit }}</div>
|
|
||||||
<div class="time-scale-up"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="time-scale-down-wrapper">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
import { onMounted, reactive } from 'vue';
|
|
||||||
import { globalLookup, emitter } from '@/hook/global';
|
|
||||||
import { wheelScale } from '@/hook/wheel';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
name: 'time-scale',
|
|
||||||
|
|
||||||
setup() {
|
|
||||||
// see --sidebar-width
|
|
||||||
const left = 280 + 20;
|
|
||||||
|
|
||||||
// see --right-nav-width
|
|
||||||
const right = document.body.clientWidth - 60;
|
|
||||||
|
|
||||||
const timeScaleManage = reactive({
|
|
||||||
scale: 1,
|
|
||||||
unit: 'ns'
|
|
||||||
});
|
|
||||||
|
|
||||||
// 此时有关波形的元信息已经加载完毕
|
|
||||||
emitter.on('meta-ready', () => {
|
|
||||||
});
|
|
||||||
|
|
||||||
// document.addEventListener('wheel', event => {
|
|
||||||
// if ((event.wheelDelta && event.ctrlKey) || event.detail) {
|
|
||||||
// event.preventDefault();
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (event.ctrlKey) {
|
|
||||||
// // console.log(event.wheelDelta);
|
|
||||||
// wheelScale(event);
|
|
||||||
// } else if (event.shiftKey) {
|
|
||||||
// // console.log(event.wheelDelta);
|
|
||||||
// console.log('deltaX', event.deltaX);
|
|
||||||
// console.log('deltaY', event.deltaY);
|
|
||||||
// }
|
|
||||||
// }, { capture: false, passive: false });
|
|
||||||
|
|
||||||
|
|
||||||
const currentX = 300;
|
|
||||||
|
|
||||||
return {
|
|
||||||
currentX,
|
|
||||||
timeScaleManage
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.time-scale-up-wrapper {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: calc(var(--sidebar-width) + 20px);
|
|
||||||
width: calc(100vw - var(--sidebar-width) - var(--right-nav-width) - 20px);
|
|
||||||
height: var(--time-scale-height);
|
|
||||||
background-color: var(--sidebar);
|
|
||||||
z-index: 50;
|
|
||||||
cursor: crosshair;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time-scale-down-wrapper {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
left: 0;
|
|
||||||
width: calc(100vw - var(--right-nav-width));
|
|
||||||
height: var(--time-scale-height);
|
|
||||||
background-color: var(--sidebar);
|
|
||||||
z-index: 50;
|
|
||||||
cursor: crosshair;
|
|
||||||
}
|
|
||||||
|
|
||||||
.time-scale-down {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 0;
|
|
||||||
width: 1px;
|
|
||||||
height: 10px;
|
|
||||||
border: 1px solid var(--scrollbar-hover);
|
|
||||||
background-color: var(--scrollbar-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
.time-scale-up {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
width: 1px;
|
|
||||||
height: 10px;
|
|
||||||
border: 1px solid var(--scrollbar-hover);
|
|
||||||
background-color: var(--scrollbar-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
.time-scale-wrapper {
|
|
||||||
position: absolute;
|
|
||||||
height: 100vh;
|
|
||||||
padding: 0;
|
|
||||||
top: 0;
|
|
||||||
cursor: crosshair;
|
|
||||||
z-index: 55;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
/* 沿着横轴(水平方向)对齐 */
|
|
||||||
justify-content: center;
|
|
||||||
/* 沿着纵轴(垂直方向)对齐 */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.time-scale-line {
|
|
||||||
width: 1px;
|
|
||||||
background-color: var(--scrollbar-hover);
|
|
||||||
height: calc(100vh - 2 * var(--time-scale-height));
|
|
||||||
}
|
|
||||||
</style>
|
|
@ -10,6 +10,7 @@
|
|||||||
name="language-setting"
|
name="language-setting"
|
||||||
class="language-setting"
|
class="language-setting"
|
||||||
v-model="locale"
|
v-model="locale"
|
||||||
|
@change="onlanguagechange"
|
||||||
>
|
>
|
||||||
<el-option
|
<el-option
|
||||||
v-for="option in languageSetting.options"
|
v-for="option in languageSetting.options"
|
||||||
@ -19,6 +20,22 @@
|
|||||||
</el-option>
|
</el-option>
|
||||||
</el-select>
|
</el-select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<el-dialog
|
||||||
|
v-model="languageDialogShow"
|
||||||
|
class="language-dialog"
|
||||||
|
:title="t('tips')"
|
||||||
|
width="500"
|
||||||
|
>
|
||||||
|
<span>{{ t('setting.language.change-dialog') }}</span>
|
||||||
|
<template #footer>
|
||||||
|
<div class="dialog-footer">
|
||||||
|
<el-button type="primary" @click="confirmLanguageDialog()">
|
||||||
|
{{ t('confirm') }}
|
||||||
|
</el-button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
<br>
|
<br>
|
||||||
<!-- <div class="setting-option">
|
<!-- <div class="setting-option">
|
||||||
@ -115,6 +132,30 @@
|
|||||||
size="large"
|
size="large"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<br>
|
||||||
|
|
||||||
|
<div class="setting-option">
|
||||||
|
<span class="option-title" style="width: 100px;">{{ t('setting.appearance.pivot-color') }}</span>
|
||||||
|
<div style="width: 120px">
|
||||||
|
<el-select
|
||||||
|
v-model="pivotColor.currentOptionIndex"
|
||||||
|
collapse-tags
|
||||||
|
collapse-tags-tooltip
|
||||||
|
placeholder="Select"
|
||||||
|
>
|
||||||
|
<el-option v-for="option in pivotColor.options" :key="option.value"
|
||||||
|
:label="option.label" :value="option.value" />
|
||||||
|
</el-select>
|
||||||
|
</div>
|
||||||
|
<div style="height: 20px; width: 20px;"></div>
|
||||||
|
<el-color-picker
|
||||||
|
v-model="pivotColor.colors[pivotColor.currentOptionIndex]"
|
||||||
|
show-alpha
|
||||||
|
:predefine="predefinedColors"
|
||||||
|
size="large"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<hr>
|
<hr>
|
||||||
@ -159,13 +200,14 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { reactive, defineComponent, watch } from 'vue';
|
import { reactive, defineComponent, watch, ref } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { globalSetting, globalLookup } from '@/hook/global';
|
import { globalSetting, globalLookup } from '@/hook/global';
|
||||||
import { debounceWrapper, scopes, variables, predefinedColors, webglColor2rgba, rgba2WebglColor } from '@/hook/utils';
|
import { debounceWrapper, scopes, variables, predefinedColors, webglColor2rgba, rgba2WebglColor } from '@/hook/utils';
|
||||||
import { gl_Colors } from '@/hook/wave-view/render-utils';
|
import { gl_Colors } from '@/hook/wave-view/render-utils';
|
||||||
|
|
||||||
import HelpIcon from '../help-icon.vue';
|
import HelpIcon from '../help-icon.vue';
|
||||||
|
import { UserPivotColor } from '../pivot/pivot-view';
|
||||||
|
import { MovingPivot, SystemPivot } from '../pivot/cursor';
|
||||||
|
|
||||||
defineComponent({ name: "dide-setting" });
|
defineComponent({ name: "dide-setting" });
|
||||||
|
|
||||||
@ -180,6 +222,16 @@ watch(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const languageDialogShow = ref(false);
|
||||||
|
|
||||||
|
function confirmLanguageDialog() {
|
||||||
|
languageDialogShow.value = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function onlanguagechange() {
|
||||||
|
languageDialogShow.value = true;
|
||||||
|
}
|
||||||
|
|
||||||
const wavecolor = reactive({
|
const wavecolor = reactive({
|
||||||
options: [
|
options: [
|
||||||
{
|
{
|
||||||
@ -210,10 +262,31 @@ const wavecolor = reactive({
|
|||||||
reset() {}
|
reset() {}
|
||||||
});
|
});
|
||||||
|
|
||||||
watch(() => wavecolor.currentOptionIndex, () => {
|
const pivotColor = reactive({
|
||||||
console.log(wavecolor.currentOptionIndex);
|
options: [
|
||||||
|
{
|
||||||
|
value: 0,
|
||||||
|
label: t('setting.appearance.moving-pivot')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 1,
|
||||||
|
label: t('setting.appearance.user-pivot')
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 2,
|
||||||
|
label: t('setting.appearance.system-pivot')
|
||||||
|
}
|
||||||
|
],
|
||||||
|
currentOptionIndex: 0,
|
||||||
|
colors: [
|
||||||
|
MovingPivot.color,
|
||||||
|
UserPivotColor.value,
|
||||||
|
SystemPivot.color
|
||||||
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 更新默认波形颜色
|
// 更新默认波形颜色
|
||||||
watch(() => wavecolor.colors, () => {
|
watch(() => wavecolor.colors, () => {
|
||||||
const colorString = wavecolor.colors[wavecolor.currentOptionIndex];
|
const colorString = wavecolor.colors[wavecolor.currentOptionIndex];
|
||||||
@ -231,6 +304,23 @@ watch(() => wavecolor.colors, () => {
|
|||||||
}
|
}
|
||||||
}, { deep: true });
|
}, { deep: true });
|
||||||
|
|
||||||
|
// 更新信标颜色
|
||||||
|
watch(() => pivotColor.colors, () => {
|
||||||
|
const colorString = pivotColor.colors[pivotColor.currentOptionIndex];
|
||||||
|
switch (pivotColor.currentOptionIndex) {
|
||||||
|
case 0:
|
||||||
|
MovingPivot.color = colorString;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
UserPivotColor.value = colorString;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
SystemPivot.color = colorString;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}, { deep: true });
|
||||||
|
|
||||||
const languageSetting = reactive({
|
const languageSetting = reactive({
|
||||||
options: [
|
options: [
|
||||||
@ -252,6 +342,9 @@ function modifySignalTrackHeight() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const safeModifySignalTrackHeight = debounceWrapper(modifySignalTrackHeight, 200);
|
const safeModifySignalTrackHeight = debounceWrapper(modifySignalTrackHeight, 200);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style>
|
<style>
|
||||||
@ -313,4 +406,14 @@ const safeModifySignalTrackHeight = debounceWrapper(modifySignalTrackHeight, 200
|
|||||||
transition: var(--animation-3s);
|
transition: var(--animation-3s);
|
||||||
-webkit-transition: var(--animation-3s);
|
-webkit-transition: var(--animation-3s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.language-dialog {
|
||||||
|
color: var(--sidebar-item-text);
|
||||||
|
background-color: var(--sidebar) !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-dialog__title {
|
||||||
|
color: var(--sidebar-item-text) !important;
|
||||||
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
@ -220,8 +220,4 @@ function makeSignalIconClass(signal) {
|
|||||||
box-shadow: 0 0 10px 1px rgb(16, 16, 16);
|
box-shadow: 0 0 10px 1px rgb(16, 16, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-color-picker__panel button {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
</style>
|
</style>
|
@ -1,7 +1,8 @@
|
|||||||
import { globalLookup } from "@/hook/global";
|
import { globalLookup } from "@/hook/global";
|
||||||
import { calcCursorLeft, StaticCursor } from "../render/cursor";
|
import { calcCursorLeft, SystemPivot } from "../pivot/cursor";
|
||||||
import { sidebarSelectedWires } from "@/hook/sidebar-select-wire";
|
import { sidebarSelectedWires } from "@/hook/sidebar-select-wire";
|
||||||
import { updateWireCurrentValue } from "@/hook/utils";
|
import { updateWireCurrentValue } from "@/hook/utils";
|
||||||
|
import { createPivot } from "../pivot/pivot-view";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -11,8 +12,8 @@ import { updateWireCurrentValue } from "@/hook/utils";
|
|||||||
* @param {Pstate} pstate
|
* @param {Pstate} pstate
|
||||||
*/
|
*/
|
||||||
export function moveto(time, leftMargin, pstate) {
|
export function moveto(time, leftMargin, pstate) {
|
||||||
StaticCursor.show = true;
|
SystemPivot.show = true;
|
||||||
StaticCursor.currentTime = time;
|
SystemPivot.currentTime = time;
|
||||||
|
|
||||||
const { width, xOffset, xScale, tgcd, timescale } = pstate;
|
const { width, xOffset, xScale, tgcd, timescale } = pstate;
|
||||||
let nextOffsetX = leftMargin - (time / tgcd) * xScale;
|
let nextOffsetX = leftMargin - (time / tgcd) * xScale;
|
||||||
@ -26,8 +27,8 @@ export function moveto(time, leftMargin, pstate) {
|
|||||||
pstate.xOffset = nextOffsetX;
|
pstate.xOffset = nextOffsetX;
|
||||||
|
|
||||||
// 改变静态信标
|
// 改变静态信标
|
||||||
StaticCursor.updateLeft();
|
SystemPivot.updateLeft();
|
||||||
StaticCursor.updateLabel(pstate.timescale);
|
SystemPivot.updateLabel(pstate.timescale);
|
||||||
|
|
||||||
// 更新所有轨道的数字
|
// 更新所有轨道的数字
|
||||||
updateWireCurrentValue(time);
|
updateWireCurrentValue(time);
|
||||||
@ -76,7 +77,7 @@ export function toPrevChange() {
|
|||||||
if (wave.length === 1) {
|
if (wave.length === 1) {
|
||||||
toBegin();
|
toBegin();
|
||||||
} else {
|
} else {
|
||||||
const currentT = StaticCursor.currentTime;
|
const currentT = SystemPivot.currentTime;
|
||||||
let pivot = bisearch(wave, currentT);
|
let pivot = bisearch(wave, currentT);
|
||||||
|
|
||||||
const pwave = wave[pivot];
|
const pwave = wave[pivot];
|
||||||
@ -109,7 +110,7 @@ export function toNextChange() {
|
|||||||
if (wave.length === 1) {
|
if (wave.length === 1) {
|
||||||
toEnd();
|
toEnd();
|
||||||
} else {
|
} else {
|
||||||
const currentT = StaticCursor.currentTime;
|
const currentT = SystemPivot.currentTime;
|
||||||
let pivot = bisearch(wave, currentT);
|
let pivot = bisearch(wave, currentT);
|
||||||
let targetT;
|
let targetT;
|
||||||
if (pivot === wave.length - 1) {
|
if (pivot === wave.length - 1) {
|
||||||
@ -135,10 +136,10 @@ const locationManager = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
export function makeLocation() {
|
export function makePivot() {
|
||||||
const currentT = StaticCursor.currentTime;
|
const currentT = SystemPivot.currentTime;
|
||||||
// 在 currentT 创建新的信标
|
// 在 currentT 创建新的信标
|
||||||
|
createPivot(currentT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,6 +64,8 @@
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="item iconfont icon-add-line"
|
class="item iconfont icon-add-line"
|
||||||
|
:class="{ 'disable' : !SystemPivot.show }"
|
||||||
|
@click="makePivot()"
|
||||||
/>
|
/>
|
||||||
</el-tooltip>
|
</el-tooltip>
|
||||||
|
|
||||||
@ -73,8 +75,9 @@
|
|||||||
<script setup>
|
<script setup>
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { toBegin, toEnd, toNextChange, toPrevChange } from './cursor-location';
|
import { makePivot, toBegin, toEnd, toNextChange, toPrevChange } from './cursor-location';
|
||||||
import { globalLookup } from '@/hook/global';
|
import { globalLookup } from '@/hook/global';
|
||||||
|
import { SystemPivot } from '../pivot/cursor';
|
||||||
|
|
||||||
defineComponent({ name: 'cursor-location' });
|
defineComponent({ name: 'cursor-location' });
|
||||||
|
|
||||||
|
@ -1 +0,0 @@
|
|||||||
|
|
@ -13,7 +13,7 @@ import { globalLookup } from "@/hook/global";
|
|||||||
import { sidebarSelectedWires } from "@/hook/sidebar-select-wire";
|
import { sidebarSelectedWires } from "@/hook/sidebar-select-wire";
|
||||||
import { reactive, ref } from "vue";
|
import { reactive, ref } from "vue";
|
||||||
import { bisearch, moveto } from "./cursor-location";
|
import { bisearch, moveto } from "./cursor-location";
|
||||||
import { StaticCursor } from "../render/cursor";
|
import { SystemPivot } from "../pivot/cursor";
|
||||||
import { FormatValueRender, JSValueRender } from "@/hook/wave-view/toolbar/renderFormat";
|
import { FormatValueRender, JSValueRender } from "@/hook/wave-view/toolbar/renderFormat";
|
||||||
import { ElMessage } from "element-plus";
|
import { ElMessage } from "element-plus";
|
||||||
import i18n from '@/i18n/index';
|
import i18n from '@/i18n/index';
|
||||||
@ -49,9 +49,9 @@ function toPrevValue() {
|
|||||||
// TODO: 空间换时间,提升性能
|
// TODO: 空间换时间,提升性能
|
||||||
const prevTimes = [];
|
const prevTimes = [];
|
||||||
|
|
||||||
const currentT = StaticCursor.currentTime;
|
const currentT = SystemPivot.currentTime;
|
||||||
// StaticCursor.updateLabel(currentT);
|
// SystemPivot.updateLabel(currentT);
|
||||||
// StaticCursor.updateLeft();
|
// SystemPivot.updateLeft();
|
||||||
|
|
||||||
const searchContent = toolbarValueSearch.content.trim();
|
const searchContent = toolbarValueSearch.content.trim();
|
||||||
|
|
||||||
@ -93,9 +93,9 @@ function toPrevValue() {
|
|||||||
function toNextValue() {
|
function toNextValue() {
|
||||||
const prevTimes = [];
|
const prevTimes = [];
|
||||||
|
|
||||||
const currentT = StaticCursor.currentTime;
|
const currentT = SystemPivot.currentTime;
|
||||||
// StaticCursor.updateLabel(currentT);
|
// SystemPivot.updateLabel(currentT);
|
||||||
// StaticCursor.updateLeft();
|
// SystemPivot.updateLeft();
|
||||||
|
|
||||||
const searchContent = toolbarValueSearch.content.trim();
|
const searchContent = toolbarValueSearch.content.trim();
|
||||||
|
|
||||||
|
@ -47,6 +47,14 @@ export const sidebarSelectedWires = {
|
|||||||
|
|
||||||
clear() {
|
clear() {
|
||||||
this.lastLink = undefined;
|
this.lastLink = undefined;
|
||||||
|
for (const link of globalLookup.sidebarSelectedWireLinks) {
|
||||||
|
globalLookup.setRenderOption(link, 'highlight', 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (globalLookup.sidebarSelectedWireLinks.size > 0) {
|
||||||
|
globalLookup.render({ type: 'wave-only' });
|
||||||
|
}
|
||||||
|
|
||||||
globalLookup.sidebarSelectedWireLinks.clear();
|
globalLookup.sidebarSelectedWireLinks.clear();
|
||||||
this.togglePipe();
|
this.togglePipe();
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import { globalLookup } from '../global';
|
import { globalLookup } from '../global';
|
||||||
import WebGL2WaveRender from './render-wave';
|
import WebGL2WaveRender from './render-wave';
|
||||||
|
|
||||||
import renderCursor from './render-cursor';
|
|
||||||
import genResizeHandler from './gen-resize-handler';
|
import genResizeHandler from './gen-resize-handler';
|
||||||
import mTree from './mount-tree';
|
import mTree from './mount-tree';
|
||||||
|
|
||||||
@ -15,29 +14,6 @@ const setTime = (pstate, str) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const mouseMoveHandler = (cursor, content, pstate /* , render */) => {
|
|
||||||
// 这是上面展示当前 time 的圆角矩形框框的宽度
|
|
||||||
const xmargin = 160;
|
|
||||||
// 这是上面展示当前 time 的圆角矩形内的字体大小
|
|
||||||
const fontHeight = 20;
|
|
||||||
const fontWidth = fontHeight / 2;
|
|
||||||
const sidebarWidth = pstate.sidebarWidth;
|
|
||||||
|
|
||||||
const handler = event => {
|
|
||||||
const x = pstate.xCursor = event.clientX;
|
|
||||||
const left = x - xmargin;
|
|
||||||
// 不能进入左侧,也不能进入右侧
|
|
||||||
if (left > sidebarWidth - 195) {
|
|
||||||
cursor.style.left = (x - xmargin) + 'px';
|
|
||||||
cursor.innerHTML = renderCursor({ xmargin, fontWidth, fontHeight }, pstate);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
// 添加初始鼠标位置
|
|
||||||
handler({ clientX: pstate.width / 2 });
|
|
||||||
document.addEventListener('mousemove', handler);
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
const getFullView = desc => {
|
const getFullView = desc => {
|
||||||
// console.log(desc);
|
// console.log(desc);
|
||||||
if (desc.waveql) {
|
if (desc.waveql) {
|
||||||
@ -100,7 +76,6 @@ class DomContainer {
|
|||||||
const elementInfos = this.elementInfos;
|
const elementInfos = this.elementInfos;
|
||||||
for (const elName of Reflect.ownKeys(elementInfos)) {
|
for (const elName of Reflect.ownKeys(elementInfos)) {
|
||||||
const elementInfo = elementInfos[elName];
|
const elementInfo = elementInfos[elName];
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -201,7 +176,6 @@ const domContainer = (obj) => {
|
|||||||
resizeObserver.observe(document.body);
|
resizeObserver.observe(document.body);
|
||||||
|
|
||||||
resizeHandler(elo.container.clientWidth, elo.container.clientHeight);
|
resizeHandler(elo.container.clientWidth, elo.container.clientHeight);
|
||||||
mouseMoveHandler(elo.cursor, elo.container, pstate, deso.render);
|
|
||||||
deso.render();
|
deso.render();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1,59 +0,0 @@
|
|||||||
import genSVG from 'onml/gen-svg.js';
|
|
||||||
import stringify from 'onml/stringify.js';
|
|
||||||
|
|
||||||
import formatTime from './format-time';
|
|
||||||
import { globalLookup } from '../global';
|
|
||||||
|
|
||||||
const renderCursor = (cfg, pstate) => {
|
|
||||||
const { xmargin, fontWidth, fontHeight } = cfg;
|
|
||||||
const { height, xScale, xOffset, tgcd, timescale, xCursor } = pstate;
|
|
||||||
|
|
||||||
const xx = Math.round((xCursor - xOffset) / xScale) * tgcd;
|
|
||||||
globalLookup.currentTime = xx;
|
|
||||||
const label = formatTime(xx, timescale);
|
|
||||||
const lWidth = (label.length + 1) * fontWidth;
|
|
||||||
|
|
||||||
const body = [
|
|
||||||
// vertical line
|
|
||||||
['line', {
|
|
||||||
class: 'wd-cursor-line',
|
|
||||||
x1: xmargin + 0.5,
|
|
||||||
x2: xmargin + 0.5,
|
|
||||||
y1: 0,
|
|
||||||
y2: height
|
|
||||||
}],
|
|
||||||
// top time label
|
|
||||||
['rect', {
|
|
||||||
class: 'wd-cursor-time',
|
|
||||||
x: xmargin - lWidth / 2,
|
|
||||||
y: 0,
|
|
||||||
rx: 9,
|
|
||||||
ry: 9,
|
|
||||||
width: lWidth,
|
|
||||||
height: fontHeight * 1.25
|
|
||||||
}],
|
|
||||||
['text', {
|
|
||||||
class: 'wd-cursor-time',
|
|
||||||
x: xmargin,
|
|
||||||
y: fontHeight
|
|
||||||
}, label],
|
|
||||||
// bottom time label
|
|
||||||
['rect', {
|
|
||||||
class: 'wd-cursor-time',
|
|
||||||
x: xmargin - lWidth / 2,
|
|
||||||
y: height - fontHeight * 1.25,
|
|
||||||
rx: 9,
|
|
||||||
ry: 9,
|
|
||||||
width: lWidth,
|
|
||||||
height: fontHeight * 1.25
|
|
||||||
}],
|
|
||||||
['text', {
|
|
||||||
class: 'wd-cursor-time',
|
|
||||||
x: xmargin,
|
|
||||||
y: height - fontHeight * .25
|
|
||||||
}, label]
|
|
||||||
];
|
|
||||||
return stringify(genSVG(2 * xmargin, height).concat(body));
|
|
||||||
};
|
|
||||||
|
|
||||||
export default renderCursor;
|
|
@ -3,7 +3,7 @@ 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 { 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';
|
import { vertexShader, fragmentShader } from './render-shader.js';
|
||||||
import { renderAsBit, renderAsCommonDigital, renderAsLadderAnalog, renderAsLineAnalog } from './toolbar/renderModal';
|
import { renderAsBit, renderAsCommonDigital, renderAsLadderAnalog, renderAsLineAnalog } from './toolbar/renderModal';
|
||||||
import { StaticCursor } from '@/components/render/cursor';
|
import { updateAllPivots } from '@/components/pivot/pivot-view';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description
|
* @description
|
||||||
@ -404,7 +404,7 @@ class WebGL2WaveRender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 更新静态 cursor
|
// 更新静态 cursor
|
||||||
StaticCursor.updateLeft();
|
updateAllPivots();
|
||||||
|
|
||||||
function linearAnimation(delta, oldVal, newVal) {
|
function linearAnimation(delta, oldVal, newVal) {
|
||||||
return (1 - delta) * oldVal + delta * newVal;
|
return (1 - delta) * oldVal + delta * newVal;
|
||||||
|
@ -9,6 +9,9 @@
|
|||||||
* @param {WheelEvent} event
|
* @param {WheelEvent} event
|
||||||
*/
|
*/
|
||||||
function windowsWheel(element, pstate, deso, eventHandler, event) {
|
function windowsWheel(element, pstate, deso, eventHandler, event) {
|
||||||
|
if (pstate === undefined) {
|
||||||
|
pstate = deso.pstate;
|
||||||
|
}
|
||||||
const { deltaX, deltaY } = event;
|
const { deltaX, deltaY } = event;
|
||||||
if (event.ctrlKey) {
|
if (event.ctrlKey) {
|
||||||
const key = (deltaY < 0)
|
const key = (deltaY < 0)
|
||||||
@ -50,6 +53,9 @@ function windowsWheel(element, pstate, deso, eventHandler, event) {
|
|||||||
* @param {WheelEvent} event
|
* @param {WheelEvent} event
|
||||||
*/
|
*/
|
||||||
function macOsWheel(element, pstate, deso, eventHandler, event) {
|
function macOsWheel(element, pstate, deso, eventHandler, event) {
|
||||||
|
if (pstate === undefined) {
|
||||||
|
pstate = deso.pstate;
|
||||||
|
}
|
||||||
let { deltaX, deltaY } = event;
|
let { deltaX, deltaY } = event;
|
||||||
if (event.ctrlKey) {
|
if (event.ctrlKey) {
|
||||||
const key = (deltaY < 0)
|
const key = (deltaY < 0)
|
||||||
@ -90,6 +96,9 @@ function macOsWheel(element, pstate, deso, eventHandler, event) {
|
|||||||
* @param {WheelEvent} event
|
* @param {WheelEvent} event
|
||||||
*/
|
*/
|
||||||
function linuxWheel(element, pstate, deso, eventHandler, event) {
|
function linuxWheel(element, pstate, deso, eventHandler, event) {
|
||||||
|
if (pstate === undefined) {
|
||||||
|
pstate = deso.pstate;
|
||||||
|
}
|
||||||
const { deltaX, deltaY } = event;
|
const { deltaX, deltaY } = event;
|
||||||
if (event.ctrlKey) {
|
if (event.ctrlKey) {
|
||||||
const key = (deltaY < 0)
|
const key = (deltaY < 0)
|
||||||
|
@ -100,6 +100,19 @@
|
|||||||
"toolbar.search.value.already-to-tail": "already to tail",
|
"toolbar.search.value.already-to-tail": "already to tail",
|
||||||
"toolbar.search.value.searching": "searching",
|
"toolbar.search.value.searching": "searching",
|
||||||
|
|
||||||
|
"pivot.context.delete": "delete pivot",
|
||||||
|
"pivot.context.display-axis": "create relative axis",
|
||||||
|
|
||||||
|
"setting.appearance.pivot-color": "pivot color",
|
||||||
|
"setting.appearance.moving-pivot": "moving pivot",
|
||||||
|
"setting.appearance.user-pivot": "user pivot",
|
||||||
|
"setting.appearance.system-pivot": "system pivot",
|
||||||
|
|
||||||
|
"setting.language.change-dialog": "You've switched language to English, we recommend you reload Wave Viewer",
|
||||||
|
"confirm": "confirm",
|
||||||
|
"cancel": "cancel",
|
||||||
|
"tips": "Tips",
|
||||||
|
|
||||||
"current-version": "current version",
|
"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>."
|
"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>."
|
||||||
}
|
}
|
@ -98,6 +98,19 @@
|
|||||||
"toolbar.search.value.already-to-tail": "已经到结尾了",
|
"toolbar.search.value.already-to-tail": "已经到结尾了",
|
||||||
"toolbar.search.value.searching": "搜索中",
|
"toolbar.search.value.searching": "搜索中",
|
||||||
|
|
||||||
|
"pivot.context.delete": "删除信标",
|
||||||
|
"pivot.context.display-axis": "创建相对坐标轴",
|
||||||
|
|
||||||
|
"setting.appearance.pivot-color": "信标颜色",
|
||||||
|
"setting.appearance.moving-pivot": "移动信标",
|
||||||
|
"setting.appearance.user-pivot": "用户信标",
|
||||||
|
"setting.appearance.system-pivot": "系统信标",
|
||||||
|
|
||||||
|
"setting.language.change-dialog": "您已经更换语言为简体中文,我们建议您重启 Wave Viewer",
|
||||||
|
"confirm": "确定",
|
||||||
|
"cancel": "取消",
|
||||||
|
"tips": "提示",
|
||||||
|
|
||||||
"current-version": "当前版本",
|
"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>。"
|
"copyright": "本软件版权归 <a href=\"https://github.com/Digital-EDA\" target=\"_blank\">Digital-IDE</a> 项目组所有,欢迎 <a href=\"https://github.com/Digital-EDA/Digital-IDE\">Star</a>。"
|
||||||
}
|
}
|
Loading…
x
Reference in New Issue
Block a user