完成缩放和平移
This commit is contained in:
parent
2d27298b29
commit
45619460cf
@ -1,14 +1,26 @@
|
||||
<template>
|
||||
<div>
|
||||
<div id="netlist"></div>
|
||||
<div id="netlist" :ref="el => netlist = el">
|
||||
<svg></svg>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineComponent } from 'vue';
|
||||
import { registerWheelEvent } from '@/hook/wheel-event';
|
||||
import { defineComponent, onMounted, ref, computed } from 'vue';
|
||||
|
||||
defineComponent({ name: 'netlist-render' });
|
||||
|
||||
const netlist = ref(null);
|
||||
|
||||
onMounted(async () => {
|
||||
const netlistElement = netlist.value;
|
||||
const wheelHandler = registerWheelEvent(netlistElement);
|
||||
netlistElement.addEventListener('wheel', event => {
|
||||
wheelHandler(event);
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
@ -20,5 +32,6 @@ defineComponent({ name: 'netlist-render' });
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
transition: var(--animation-5s);
|
||||
}
|
||||
</style>
|
@ -40,6 +40,20 @@
|
||||
</el-dialog>
|
||||
</div>
|
||||
<br>
|
||||
|
||||
|
||||
<div class="setting-option">
|
||||
<span class="option-title">
|
||||
{{ t('render-animation') }}
|
||||
</span>
|
||||
<el-switch
|
||||
v-model="globalSetting.renderAnimation"
|
||||
size="large"
|
||||
active-text="ON"
|
||||
inactive-text="OFF"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</el-scrollbar>
|
||||
</div>
|
||||
|
@ -19,6 +19,7 @@ export function setDefaultCss() {
|
||||
document.body.style.setProperty('--el-color-info-light-9', 'var(--vscode-focusBorder)');
|
||||
document.body.style.setProperty('--el-color-info', 'var(--foreground)');
|
||||
document.body.style.setProperty('--el-color-info-light-8', 'var(--vscode-focusBorder)');
|
||||
|
||||
// document.body.style.setProperty('--el-color-white', 'var(--background)');
|
||||
|
||||
// 设置全局宏
|
||||
|
@ -7,7 +7,8 @@ import { NetlistRender } from './render';
|
||||
export const emitter = mitt();
|
||||
|
||||
export const globalSetting = reactive({
|
||||
language: 'zh'
|
||||
language: 'zh',
|
||||
renderAnimation: true
|
||||
});
|
||||
|
||||
export const globalLookup = {
|
||||
@ -19,7 +20,22 @@ export const globalLookup = {
|
||||
/**
|
||||
* @type {NetlistRender}
|
||||
*/
|
||||
netlistRender: new NetlistRender()
|
||||
netlistRender: new NetlistRender(),
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
svgScale: 1,
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
svgTranslateX: 0,
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
svgTranslateY: 0
|
||||
};
|
||||
|
||||
function loadSetting() {
|
||||
|
14
src/hook/render/drag.js
Normal file
14
src/hook/render/drag.js
Normal file
@ -0,0 +1,14 @@
|
||||
import * as d3 from 'd3';
|
||||
import ELK from 'elkjs';
|
||||
|
||||
/**
|
||||
* @description 注册关于 器件 的拖动事件
|
||||
*
|
||||
* 需要提取最小拓扑子图,然后重新调整各个区域的尺寸
|
||||
* @param {d3.Transition} renderSvg
|
||||
*/
|
||||
export function registerCellDragEvent(renderSvg) {
|
||||
// renderSvg.call(d3.drag().on('drag', (event, g) => {
|
||||
// console.log(event);
|
||||
// }));
|
||||
}
|
@ -3,7 +3,8 @@ import ELK from 'elkjs';
|
||||
|
||||
|
||||
import { Module } from './layout';
|
||||
import { globalLookup } from '../global';
|
||||
import { globalLookup, globalSetting } from '../global';
|
||||
import { registerCellDragEvent } from './drag';
|
||||
|
||||
export class NetlistRender {
|
||||
/**
|
||||
@ -77,7 +78,6 @@ export class NetlistRender {
|
||||
'org.eclipse.elk.layered.layering.strategy': 'LONGEST_PATH'
|
||||
}
|
||||
});
|
||||
console.log(layoutGraph);
|
||||
|
||||
return layoutGraph;
|
||||
}
|
||||
@ -96,12 +96,15 @@ export class NetlistRender {
|
||||
const ratio = this.renderHeight / virtualHeight;
|
||||
|
||||
// 遍历计算布局进行创建
|
||||
const svg = d3.select(container).append('svg')
|
||||
const svg = d3.select(container)
|
||||
.selectAll('svg')
|
||||
.attr('width', virtualWidth)
|
||||
.attr('height', virtualHeight);
|
||||
|
||||
await this.renderEntity(svg, computedLayout, ratio);
|
||||
await this.renderLine(svg, computedLayout, ratio);
|
||||
await this.renderEntity(svg, computedLayout, ratio);
|
||||
|
||||
this.selection = svg;
|
||||
|
||||
return svg;
|
||||
}
|
||||
@ -121,12 +124,15 @@ export class NetlistRender {
|
||||
// 生成用于绘制的 d3 数据结构
|
||||
// 默认需要渲染成矩形的(缺失样式的器件、例化模块等等)
|
||||
const squares = [];
|
||||
|
||||
const connections = [];
|
||||
const svgElements = [];
|
||||
const skinManager = globalLookup.skinManager;
|
||||
|
||||
for (const node of computedLayout.children) {
|
||||
const skin = skinManager.querySkin(node.renderName);
|
||||
if (skin) {
|
||||
// 具有 skin 的器件
|
||||
svgElements.push({
|
||||
element: skin.meta.svgDoc.documentElement,
|
||||
x: node.x,
|
||||
@ -136,6 +142,7 @@ export class NetlistRender {
|
||||
fill: 'var(--main-dark-color)',
|
||||
});
|
||||
} else {
|
||||
// 没有 skin 的器件
|
||||
squares.push({
|
||||
x: node.x,
|
||||
y: node.y,
|
||||
@ -150,54 +157,126 @@ export class NetlistRender {
|
||||
|
||||
// 如果存在 port,绘制 port
|
||||
for (const cellPort of node.ports || []) {
|
||||
squares.push({
|
||||
connections.push({
|
||||
x: cellPort.x + node.x,
|
||||
y: cellPort.y + node.y,
|
||||
y: cellPort.y + node.y + 0.5, // 0.5 是为了线宽
|
||||
width: cellPort.width,
|
||||
height: cellPort.height,
|
||||
fill: 'var(--main-color)',
|
||||
text: '',
|
||||
rx: 0,
|
||||
ry: 0
|
||||
r: 3.5
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
svg.selectAll('rect')
|
||||
.data(squares)
|
||||
.enter()
|
||||
.append('rect')
|
||||
.attr('x', data => data.x)
|
||||
.attr('y', data => data.y)
|
||||
.attr('width', data => data.width)
|
||||
.attr('height', data => data.height)
|
||||
.attr('fill', d => d.fill)
|
||||
.attr('stroke', 'var(--main-color)')
|
||||
.attr('stroke-width', 2)
|
||||
.attr('rx', d => d.rx)
|
||||
.attr('ry', d => d.ry);
|
||||
if (globalSetting.renderAnimation) {
|
||||
svg.selectAll('rect')
|
||||
.data(squares)
|
||||
.enter()
|
||||
.append('rect')
|
||||
.attr('x', data => data.x)
|
||||
.attr('y', data => data.y)
|
||||
.attr('width', data => data.width)
|
||||
.attr('height', data => data.height)
|
||||
.attr('fill', d => d.fill)
|
||||
.transition()
|
||||
.duration(1000)
|
||||
.attr('stroke', 'var(--main-color)')
|
||||
.attr('stroke-width', 2)
|
||||
.attr('rx', d => d.rx)
|
||||
.attr('ry', d => d.ry);
|
||||
|
||||
svg.selectAll('g')
|
||||
.data(svgElements)
|
||||
.enter()
|
||||
.append(data => {
|
||||
const element = data.element;
|
||||
element.setAttribute('x', data.x);
|
||||
element.setAttribute('y', data.y);
|
||||
return element;
|
||||
});
|
||||
const renderSvg = svg.selectAll('g')
|
||||
.data(svgElements)
|
||||
.enter()
|
||||
.append(data => {
|
||||
const element = data.element;
|
||||
element.setAttribute('x', data.x);
|
||||
element.setAttribute('y', data.y);
|
||||
element.setAttribute('stroke-opacity', 0);
|
||||
return element;
|
||||
})
|
||||
.transition()
|
||||
.duration(1000)
|
||||
.attr('stroke-opacity', 1);
|
||||
|
||||
svg.selectAll('text')
|
||||
.data(squares)
|
||||
.enter()
|
||||
.append('text')
|
||||
.attr('x', data => data.x + data.width / 2) // 文本的 x 坐标(居中)
|
||||
.attr('y', data => data.y + data.height / 2) // 文本的 y 坐标(居中)
|
||||
.attr('dominant-baseline', 'middle') // 文本垂直居中
|
||||
.attr('text-anchor', 'middle') // 文本水平居中
|
||||
.attr('fill', 'white') // 文本颜色
|
||||
.attr('font-size', '12px')
|
||||
.text(data => data.text); // 设置文本内容
|
||||
registerCellDragEvent(renderSvg);
|
||||
|
||||
svg.selectAll('circle')
|
||||
.data(connections)
|
||||
.enter()
|
||||
.append('circle')
|
||||
.attr('cx', data => data.x)
|
||||
.attr('cy', data => data.y)
|
||||
.attr('width', data => data.width)
|
||||
.attr('height', data => data.height)
|
||||
.transition()
|
||||
.duration(1000)
|
||||
.attr('fill', d => d.fill)
|
||||
.attr('r', d => d.r);
|
||||
|
||||
svg.selectAll('text')
|
||||
.data(squares)
|
||||
.enter()
|
||||
.append('text')
|
||||
.attr('x', data => data.x + data.width / 2) // 文本的 x 坐标(居中)
|
||||
.attr('y', data => data.y + data.height / 2) // 文本的 y 坐标(居中)
|
||||
.attr('dominant-baseline', 'middle') // 文本垂直居中
|
||||
.attr('text-anchor', 'middle') // 文本水平居中
|
||||
.attr('fill', 'white') // 文本颜色
|
||||
.attr('font-size', '0')
|
||||
.transition()
|
||||
.duration(1000)
|
||||
.attr('font-size', '12px')
|
||||
.text(data => data.text); // 设置文本内容
|
||||
} else {
|
||||
svg.selectAll('rect')
|
||||
.data(squares)
|
||||
.enter()
|
||||
.append('rect')
|
||||
.attr('x', data => data.x)
|
||||
.attr('y', data => data.y)
|
||||
.attr('width', data => data.width)
|
||||
.attr('height', data => data.height)
|
||||
.attr('fill', d => d.fill)
|
||||
.attr('stroke', 'var(--main-color)')
|
||||
.attr('stroke-width', 2)
|
||||
.attr('rx', d => d.rx)
|
||||
.attr('ry', d => d.ry);
|
||||
|
||||
svg.selectAll('g')
|
||||
.data(svgElements)
|
||||
.enter()
|
||||
.append(data => {
|
||||
const element = data.element;
|
||||
element.setAttribute('x', data.x);
|
||||
element.setAttribute('y', data.y);
|
||||
return element;
|
||||
});
|
||||
|
||||
svg.selectAll('circle')
|
||||
.data(connections)
|
||||
.enter()
|
||||
.append('circle')
|
||||
.attr('cx', data => data.x)
|
||||
.attr('cy', data => data.y)
|
||||
.attr('width', data => data.width)
|
||||
.attr('height', data => data.height)
|
||||
.attr('fill', d => d.fill)
|
||||
.attr('r', d => d.r);
|
||||
|
||||
svg.selectAll('text')
|
||||
.data(squares)
|
||||
.enter()
|
||||
.append('text')
|
||||
.attr('x', data => data.x + data.width / 2) // 文本的 x 坐标(居中)
|
||||
.attr('y', data => data.y + data.height / 2) // 文本的 y 坐标(居中)
|
||||
.attr('dominant-baseline', 'middle') // 文本垂直居中
|
||||
.attr('text-anchor', 'middle') // 文本水平居中
|
||||
.attr('fill', 'white') // 文本颜色
|
||||
.attr('font-size', '12px')
|
||||
.text(data => data.text); // 设置文本内容
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -230,7 +309,7 @@ export class NetlistRender {
|
||||
}
|
||||
}
|
||||
|
||||
svg.selectAll('line')
|
||||
let lineSelection = svg.selectAll('line')
|
||||
.data(lines)
|
||||
.enter()
|
||||
.append('line')
|
||||
@ -238,7 +317,24 @@ export class NetlistRender {
|
||||
.attr('y1', data => data.y1)
|
||||
.attr('x2', data => data.x2)
|
||||
.attr('y2', data => data.y2)
|
||||
.attr('stroke-width', data => data.strokeWidth)
|
||||
.attr('stroke', data => data.color);
|
||||
|
||||
if (globalSetting.renderAnimation) {
|
||||
lineSelection = lineSelection.transition().duration(1000);
|
||||
}
|
||||
|
||||
lineSelection.attr('stroke-width', data => data.strokeWidth);
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 从 globalLookup 中更新 svg 的方位
|
||||
*/
|
||||
updateLocationFromGlobal() {
|
||||
const svg = globalLookup.netlistRender.selection;
|
||||
if (!svg) {
|
||||
return;
|
||||
}
|
||||
|
||||
svg.attr('transform', `translate(${globalLookup.svgTranslateX}, ${globalLookup.svgTranslateY}) scale(${globalLookup.svgScale})`);
|
||||
}
|
||||
}
|
@ -134,16 +134,6 @@ export class Module {
|
||||
for (let i = 0; i < leftSideConnections.length; ++ i) {
|
||||
const connection = leftSideConnections[i];
|
||||
const yOffset = meta.getPortYOffset(connection.name) * SKIN_SCALE;
|
||||
const targetY = yOffset;
|
||||
|
||||
// 默认采用 JUSTIFIED,均分一侧的 height
|
||||
// 我们绘制的 svg 的 port offset y 未必和 elk 分配得到的一样,因此需要进行修正
|
||||
const layoutY = height / (leftSideConnections.length + 1) * (i + 1);
|
||||
const extraOffset = LINE_WIDTH * leftSideConnections.length;
|
||||
const anchorY = layoutY - targetY;
|
||||
|
||||
console.log(yOffset);
|
||||
|
||||
|
||||
ports.push({
|
||||
id: connection.id,
|
||||
@ -162,16 +152,6 @@ export class Module {
|
||||
for (let i = 0; i < rightSideConnections.length; ++ i) {
|
||||
const connection = rightSideConnections[i];
|
||||
const yOffset = meta.getPortYOffset(connection.name) * SKIN_SCALE;
|
||||
const targetY = yOffset;
|
||||
|
||||
// 默认采用 JUSTIFIED,均分一侧的 height
|
||||
// 我们绘制的 svg 的 port offset y 未必和 elk 分配得到的一样,因此需要进行修正
|
||||
const layoutY = height / (rightSideConnections.length + 1) * (i + 1);
|
||||
const extraOffset = LINE_WIDTH * rightSideConnections.length / 2;
|
||||
const anchorY = targetY - layoutY + extraOffset;
|
||||
|
||||
console.log(yOffset);
|
||||
|
||||
|
||||
ports.push({
|
||||
id: connection.id,
|
||||
|
104
src/hook/wheel-event.js
Normal file
104
src/hook/wheel-event.js
Normal file
@ -0,0 +1,104 @@
|
||||
import { globalLookup } from "./global";
|
||||
|
||||
const MAX_SCALE = 10.0;
|
||||
const MIN_SCALE = 0.0;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @param {WheelEvent} event
|
||||
*/
|
||||
function windowsKeydown(element, event) {
|
||||
const svg = globalLookup.netlistRender.selection;
|
||||
if (!svg) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { deltaX, deltaY } = event;
|
||||
if (event.ctrlKey) {
|
||||
if (deltaY < 0) {
|
||||
// scale up
|
||||
const nextScale = globalLookup.svgScale + 0.1;
|
||||
if (nextScale <= MAX_SCALE) {
|
||||
globalLookup.svgScale = nextScale;
|
||||
globalLookup.netlistRender.updateLocationFromGlobal();
|
||||
}
|
||||
|
||||
} else if (deltaY > 0) {
|
||||
// scale down
|
||||
const nextScale = globalLookup.svgScale - 0.1;
|
||||
if (nextScale >= MIN_SCALE) {
|
||||
globalLookup.svgScale = nextScale;
|
||||
globalLookup.netlistRender.updateLocationFromGlobal();
|
||||
}
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
} else if (event.shiftKey) {
|
||||
event.preventDefault();
|
||||
} else if (deltaX !== 0 && deltaY === 0) {
|
||||
if (deltaX > 0) {
|
||||
// scroll left
|
||||
const translateX = globalLookup.svgTranslateX - 50;
|
||||
globalLookup.svgTranslateX = translateX;
|
||||
globalLookup.netlistRender.updateLocationFromGlobal();
|
||||
} else {
|
||||
// scroll right
|
||||
const translateX = globalLookup.svgTranslateX + 50;
|
||||
globalLookup.svgTranslateX = translateX;
|
||||
globalLookup.netlistRender.updateLocationFromGlobal();
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
} else if (deltaX === 0 && deltaY !== 0) {
|
||||
if (deltaY > 0) {
|
||||
// scroll up
|
||||
const translateY = globalLookup.svgTranslateY - 50;
|
||||
globalLookup.svgTranslateY = translateY;
|
||||
globalLookup.netlistRender.updateLocationFromGlobal();
|
||||
} else {
|
||||
// scroll down
|
||||
const translateY = globalLookup.svgTranslateY + 50;
|
||||
globalLookup.svgTranslateY = translateY;
|
||||
globalLookup.netlistRender.updateLocationFromGlobal();
|
||||
}
|
||||
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @param {WheelEvent} event
|
||||
*/
|
||||
function linuxKeydown(element, event) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {HTMLElement} element
|
||||
* @param {WheelEvent} event
|
||||
*/
|
||||
function macOsKeydown(element, event) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @description 注册滚轮事件
|
||||
* @param {HTMLElement} element
|
||||
* @returns {(event: WheelEvent) => void}
|
||||
*/
|
||||
export function registerWheelEvent(element) {
|
||||
const platform = navigator.platform;
|
||||
if (platform.startsWith('Win')) {
|
||||
return event => windowsKeydown(element, event);
|
||||
} else if (platform.startsWith('Linux')) {
|
||||
return event => linuxKeydown(element, event);
|
||||
} else if (platform.startsWith('Mac')) {
|
||||
return event => macOsKeydown(element, event);
|
||||
} else {
|
||||
throw Error('不支持的操作系统!');
|
||||
}
|
||||
}
|
@ -8,5 +8,6 @@
|
||||
"cancel": "إلغاء",
|
||||
"tips": "نصائح",
|
||||
"language-setting": "اللغة",
|
||||
"setting.language.change-dialog": "لقد قمت بتغيير اللغة إلى {0} ، ونوصي بإعادة تشغيل Netlist Viewer"
|
||||
"setting.language.change-dialog": "لقد قمت بتغيير اللغة إلى {0} ، ونوصي بإعادة تشغيل Netlist Viewer",
|
||||
"render-animation": "تفعيل الرسوم المتحركة للعرض"
|
||||
}
|
@ -8,5 +8,6 @@
|
||||
"cancel": "Abbrechen",
|
||||
"tips": "Tipps",
|
||||
"language-setting": "Sprache",
|
||||
"setting.language.change-dialog": "Sie haben die Sprache auf {0} geändert. Wir empfehlen Ihnen, Netlist Viewer neu zu starten."
|
||||
"setting.language.change-dialog": "Sie haben die Sprache auf {0} geändert. Wir empfehlen Ihnen, Netlist Viewer neu zu starten.",
|
||||
"render-animation": "Rendering-Animation aktivieren"
|
||||
}
|
@ -3,10 +3,11 @@
|
||||
"general-setting": "General",
|
||||
"appearance-setting": "Appearance",
|
||||
"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>.",
|
||||
"confirm": "confirm",
|
||||
"cancel": "cancel",
|
||||
"tips": "Tips",
|
||||
"language-setting": "Language",
|
||||
"setting.language.change-dialog": "You have changed the language to {0}, we recommend restarting Netlist Viewer."
|
||||
"setting.language.change-dialog": "You have changed the language to {0}, we recommend restarting Netlist Viewer.",
|
||||
"render-animation": "enable rendering animation"
|
||||
}
|
@ -8,5 +8,6 @@
|
||||
"cancel": "Annuler",
|
||||
"tips": "Conseils",
|
||||
"language-setting": "Langue",
|
||||
"setting.language.change-dialog": "Vous avez changé la langue en {0}, nous vous recommandons de redémarrer Netlist Viewer."
|
||||
"setting.language.change-dialog": "Vous avez changé la langue en {0}, nous vous recommandons de redémarrer Netlist Viewer.",
|
||||
"render-animation": "Activer l'animation de rendu"
|
||||
}
|
@ -8,5 +8,6 @@
|
||||
"cancel": "キャンセル",
|
||||
"tips": "ヒント",
|
||||
"language-setting": "言語",
|
||||
"setting.language.change-dialog": "言語を {0} に変更しました。Netlist Viewer を再起動することをお勧めします。"
|
||||
"setting.language.change-dialog": "言語を {0} に変更しました。Netlist Viewer を再起動することをお勧めします。",
|
||||
"render-animation": "レンダリングアニメーションを有効にする"
|
||||
}
|
@ -8,5 +8,6 @@
|
||||
"cancel": "취소",
|
||||
"tips": "팁",
|
||||
"language-setting": "언어",
|
||||
"setting.language.change-dialog": "언어를 {0} 으로 변경했습니다. Netlist Viewer 를 다시 시작하는 것을 권장합니다."
|
||||
"setting.language.change-dialog": "언어를 {0} 으로 변경했습니다. Netlist Viewer 를 다시 시작하는 것을 권장합니다.",
|
||||
"render-animation": "렌더링 애니메이션 활성화"
|
||||
}
|
@ -8,5 +8,6 @@
|
||||
"cancel": "Отменить",
|
||||
"tips": "Советы",
|
||||
"language-setting": "Язык",
|
||||
"setting.language.change-dialog": "Вы изменили язык на {0}, мы рекомендуем перезапустить Netlist Viewer."
|
||||
"setting.language.change-dialog": "Вы изменили язык на {0}, мы рекомендуем перезапустить Netlist Viewer.",
|
||||
"render-animation": "Включить анимацию рендеринга"
|
||||
}
|
@ -8,5 +8,6 @@
|
||||
"cancel": "取消",
|
||||
"tips": "提示",
|
||||
"language-setting": "语言",
|
||||
"setting.language.change-dialog": "您已经更换语言为 {0} ,我们建议您重启 Netlist Viewer"
|
||||
"setting.language.change-dialog": "您已经更换语言为 {0} ,我们建议您重启 Netlist Viewer",
|
||||
"render-animation": "开启渲染动画"
|
||||
}
|
@ -8,5 +8,6 @@
|
||||
"cancel": "取消",
|
||||
"tips": "提示",
|
||||
"language-setting": "語言",
|
||||
"setting.language.change-dialog": "您已將語言更改為 {0} ,我們建議您重新啟動 Netlist Viewer。"
|
||||
"setting.language.change-dialog": "您已將語言更改為 {0} ,我們建議您重新啟動 Netlist Viewer。",
|
||||
"render-animation": "開啟渲染動畫"
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user