chore: replace all cn comments of fe to en version by volc api (#320)
This commit is contained in:
@@ -35,11 +35,11 @@ const PADDING = 12;
|
||||
export interface BezierLineProps {
|
||||
fromColor?: string;
|
||||
toColor?: string;
|
||||
color?: string; // 高亮颜色,优先级最高
|
||||
color?: string; // Highlight color, highest priority
|
||||
selected?: boolean;
|
||||
showControlPoints?: boolean;
|
||||
line: WorkflowLineEntity;
|
||||
version: string; // 用于控制 memo 刷新
|
||||
version: string; // Used to control memo refresh
|
||||
}
|
||||
|
||||
export const BezierLineRender = React.memo(
|
||||
@@ -48,14 +48,14 @@ export const BezierLineRender = React.memo(
|
||||
const renderData = line.getData(WorkflowLineRenderData);
|
||||
const { bounds: bbox } = renderData;
|
||||
const { position } = line;
|
||||
// 相对位置
|
||||
// relative position
|
||||
const toRelative = (p: IPoint) => ({
|
||||
x: p.x - bbox.x + PADDING,
|
||||
y: p.y - bbox.y + PADDING,
|
||||
});
|
||||
const fromPos = toRelative(position.from);
|
||||
const toPos = toRelative(position.to);
|
||||
// 真正连接线需要到的点的位置
|
||||
// The location of the point that the real connection line needs to go to
|
||||
const arrowToPos = {
|
||||
x: toPos.x - POINT_RADIUS,
|
||||
y: toPos.y,
|
||||
|
||||
@@ -28,14 +28,14 @@ import ArrowRenderer from '../arrow';
|
||||
import { STROKE_WIDTH, STROKE_WIDTH_SLECTED } from '../../../constants/points';
|
||||
|
||||
/**
|
||||
* 折叠线
|
||||
* fold line
|
||||
*/
|
||||
export const FoldLineRender = React.memo(
|
||||
WithPopover((props: BezierLineProps) => {
|
||||
const { selected, color, line } = props;
|
||||
const { to } = line.position;
|
||||
const strokeWidth = selected ? STROKE_WIDTH_SLECTED : STROKE_WIDTH;
|
||||
// 真正连接线需要到的点的位置
|
||||
// The location of the point that the real connection line needs to go to
|
||||
const arrowToPos = {
|
||||
x: to.x - POINT_RADIUS,
|
||||
y: to.y,
|
||||
|
||||
@@ -25,7 +25,7 @@ import { getSelectionBounds } from '../../utils/selection-utils';
|
||||
import styles from './index.module.less';
|
||||
|
||||
/**
|
||||
* 选择框
|
||||
* select box
|
||||
* @param props
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
@@ -18,7 +18,7 @@ import React from 'react';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
// demo 环境自绘 cross-hair,正式环境使用 IconAdd
|
||||
// The demo environment self-draws cross-hair, and the formal environment uses IconAdd.
|
||||
export default function CrossHair(): JSX.Element {
|
||||
return (
|
||||
<div className={styles.symbol}>
|
||||
|
||||
@@ -73,11 +73,11 @@ export const WorkflowPortRender: React.FC<WorkflowPortRenderProps> =
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// useEffect 时序问题可能导致 port.hasError 非最新,需重新触发一次 validate
|
||||
// useEffect timing issue may cause port.hasError to be not up-to-date, and validate needs to be triggered again
|
||||
props.entity.validate();
|
||||
setHasError(props.entity.hasError);
|
||||
const dispose = props.entity.onEntityChange(() => {
|
||||
// 如果有挂载的节点,不需要更新位置信息
|
||||
// If there are mounted nodes, there is no need to update the location information
|
||||
if (entity.targetElement) {
|
||||
if (entity.targetElement !== targetElement) {
|
||||
setTargetElement(entity.targetElement);
|
||||
@@ -85,7 +85,7 @@ export const WorkflowPortRender: React.FC<WorkflowPortRenderProps> =
|
||||
return;
|
||||
}
|
||||
const newPos = props.entity.relativePosition;
|
||||
// 加上 round 避免点位抖动
|
||||
// Add round to avoid point jitter
|
||||
updatePosX(Math.round(newPos.x));
|
||||
updatePosY(Math.round(newPos.y));
|
||||
});
|
||||
@@ -108,11 +108,11 @@ export const WorkflowPortRender: React.FC<WorkflowPortRenderProps> =
|
||||
};
|
||||
}, [props.entity, hoverService, entity, targetElement, linesManager]);
|
||||
|
||||
// 监听变化
|
||||
// Monitor changes
|
||||
const className = classNames(styles.workflowPoint, {
|
||||
[styles.hovered]:
|
||||
!readonly && hovered && !disabled && portType !== 'input',
|
||||
// 有线条链接的时候深蓝色小圆点
|
||||
// Dark blue dots when there are line links.
|
||||
[styles.linked]: linked,
|
||||
});
|
||||
|
||||
|
||||
@@ -14,5 +14,5 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// 箭头宽度
|
||||
// Arrow width
|
||||
export const LINE_OFFSET = 6;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// 连接点半径
|
||||
// Connection point radius
|
||||
|
||||
export const STROKE_WIDTH_SLECTED = 3;
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ const RENDER_SIZE = 20;
|
||||
const DOT_SIZE = 1;
|
||||
|
||||
/**
|
||||
* dot 网格背景
|
||||
* Dot grid background
|
||||
*/
|
||||
export class BackgroundLayer extends Layer {
|
||||
static type = 'WorkflowBackgroundLayer';
|
||||
@@ -46,7 +46,7 @@ export class BackgroundLayer extends Layer {
|
||||
grid: HTMLElement = document.createElement('div');
|
||||
|
||||
/**
|
||||
* 当前缩放比
|
||||
* current zoom ratio
|
||||
*/
|
||||
get zoom(): number {
|
||||
return this.config.finalScale;
|
||||
@@ -54,14 +54,14 @@ export class BackgroundLayer extends Layer {
|
||||
|
||||
onReady() {
|
||||
const { firstChild } = this.pipelineNode;
|
||||
// 背景插入到最下边
|
||||
// Insert the background to the bottom
|
||||
this.pipelineNode.insertBefore(this.node, firstChild);
|
||||
// 初始化设置最大 200% 最小 10% 缩放
|
||||
// Initialization settings Maximum 200% Minimum 10% Zoom
|
||||
this.playgroundConfigEntity.updateConfig({
|
||||
minZoom: 0.1,
|
||||
maxZoom: 2,
|
||||
});
|
||||
// 确保点的位置在线条的下方
|
||||
// Make sure the dot is located below the line
|
||||
this.grid.style.zIndex = '-1';
|
||||
this.grid.style.position = 'relative';
|
||||
this.node.appendChild(this.grid);
|
||||
@@ -69,19 +69,19 @@ export class BackgroundLayer extends Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* 最小单元格大小
|
||||
* Minimum cell size
|
||||
*/
|
||||
getScaleUnit(): BackgroundScaleUnit {
|
||||
const { zoom } = this;
|
||||
|
||||
return {
|
||||
realSize: RENDER_SIZE, // 一个单元格代表的真实大小
|
||||
renderSize: Math.round(RENDER_SIZE * zoom * 100) / 100, // 一个单元格渲染的大小值
|
||||
zoom, // 缩放比
|
||||
realSize: RENDER_SIZE, // The actual size represented by a cell
|
||||
renderSize: Math.round(RENDER_SIZE * zoom * 100) / 100, // The size value of a cell rendering
|
||||
zoom, // zoom ratio
|
||||
};
|
||||
}
|
||||
/**
|
||||
* 绘制
|
||||
* draw
|
||||
*/
|
||||
autorun(): void {
|
||||
const playgroundConfig = this.playgroundConfigEntity.config;
|
||||
@@ -98,7 +98,7 @@ export class BackgroundLayer extends Layer {
|
||||
top: scrollY - SCALE_WIDTH,
|
||||
});
|
||||
this.drawGrid(scaleUnit);
|
||||
// 设置网格
|
||||
// Set Grid
|
||||
this.setSVGStyle(this.grid, {
|
||||
width: viewBoxWidth,
|
||||
height: viewBoxHeight,
|
||||
@@ -108,7 +108,7 @@ export class BackgroundLayer extends Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* 绘制网格
|
||||
* Draw mesh
|
||||
*/
|
||||
protected drawGrid(unit: BackgroundScaleUnit): void {
|
||||
const minor = unit.renderSize;
|
||||
@@ -147,12 +147,12 @@ export class BackgroundLayer extends Layer {
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取相对滚动距离
|
||||
* Get the relative scroll distance
|
||||
* @param realScroll
|
||||
* @param mod
|
||||
*/
|
||||
protected getScrollDelta(realScroll: number, mod: number): number {
|
||||
// 正向滚动不用补差
|
||||
// There is no need to make up for the difference in forward scrolling.
|
||||
if (realScroll >= 0) {
|
||||
return realScroll % mod;
|
||||
}
|
||||
|
||||
@@ -72,12 +72,12 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
|
||||
protected selectorBoxConfigEntity: SelectorBoxConfigEntity;
|
||||
@inject(PlaygroundConfigEntity) configEntity: PlaygroundConfigEntity;
|
||||
/**
|
||||
* 监听节点 transform
|
||||
* Listen node transform
|
||||
*/
|
||||
@observeEntityDatas(WorkflowNodeEntity, FlowNodeTransformData)
|
||||
protected readonly nodeTransforms: FlowNodeTransformData[];
|
||||
/**
|
||||
* 按选中排序
|
||||
* Sort by Selected
|
||||
* @private
|
||||
*/
|
||||
protected nodeTransformsWithSort: FlowNodeTransformData[] = [];
|
||||
@@ -85,16 +85,16 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
|
||||
const { activatedNode } = this.selectionService;
|
||||
this.nodeTransformsWithSort = this.nodeTransforms
|
||||
.filter(n => n.entity.id !== 'root')
|
||||
.reverse() // 后创建的排在前面
|
||||
.reverse() // The post-created one comes first
|
||||
.sort(n1 => (n1.entity === activatedNode ? -1 : 0));
|
||||
}
|
||||
/**
|
||||
* 监听线条
|
||||
* monitor line
|
||||
*/
|
||||
@observeEntities(WorkflowLineEntity)
|
||||
protected readonly lines: WorkflowLineEntity[];
|
||||
/**
|
||||
* 是否正在调整线条
|
||||
* Is the line being adjusted?
|
||||
* @protected
|
||||
*/
|
||||
get isDrawing(): boolean {
|
||||
@@ -106,7 +106,7 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
|
||||
...this.options,
|
||||
};
|
||||
this.toDispose.pushAll([
|
||||
// 监听画布鼠标移动事件
|
||||
// Monitor canvas mouse movement events
|
||||
this.listenPlaygroundEvent('mousemove', (e: MouseEvent) => {
|
||||
this.hoverService.hoveredPos = this.config.getPosFromMouseEvent(e);
|
||||
if (!this.isEnabled()) {
|
||||
@@ -117,11 +117,11 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
|
||||
return;
|
||||
}
|
||||
const mousePos = this.config.getPosFromMouseEvent(e);
|
||||
// 更新 hover 状态
|
||||
// Update hover status
|
||||
this.updateHoveredState(mousePos, e?.target as HTMLElement);
|
||||
}),
|
||||
this.selectionService.onSelectionChanged(() => this.autorun()),
|
||||
// 控制选中逻辑
|
||||
// Control selection logic
|
||||
this.listenPlaygroundEvent(
|
||||
'mousedown',
|
||||
(e: MouseEvent): boolean | undefined => {
|
||||
@@ -129,7 +129,7 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
|
||||
return undefined;
|
||||
}
|
||||
const { hoveredNode } = this.hoverService;
|
||||
// 重置线条
|
||||
// Reset line
|
||||
if (hoveredNode && hoveredNode instanceof WorkflowLineEntity) {
|
||||
this.dragService.resetLine(hoveredNode, e);
|
||||
return true;
|
||||
@@ -150,7 +150,7 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
|
||||
const mousePos = this.config.getPosFromMouseEvent(e);
|
||||
const selectionBounds = getSelectionBounds(
|
||||
this.selectionService,
|
||||
// 这里只考虑多选模式,单选模式已经下沉到 use-node-render 中
|
||||
// Only multi-select mode is considered here, and radio mode has sunk into use-node-render
|
||||
true,
|
||||
);
|
||||
if (
|
||||
@@ -158,11 +158,11 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
|
||||
selectionBounds.contains(mousePos.x, mousePos.y)
|
||||
) {
|
||||
/**
|
||||
* 拖拽选择框
|
||||
* Drag select box
|
||||
*/
|
||||
this.dragService.startDragSelectedNodes(e).then(dragSuccess => {
|
||||
if (!dragSuccess) {
|
||||
// 拖拽没有成功触发了点击
|
||||
// The drag failed to trigger the click successfully.
|
||||
if (hoveredNode && hoveredNode instanceof WorkflowNodeEntity) {
|
||||
if (e.metaKey || e.shiftKey || e.ctrlKey) {
|
||||
this.selectionService.toggleSelect(hoveredNode);
|
||||
@@ -174,7 +174,7 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
|
||||
}
|
||||
}
|
||||
});
|
||||
// 这里会组织触发 selector box
|
||||
// The trigger selector box will be organized here.
|
||||
return true;
|
||||
} else {
|
||||
if (!hoveredNode) {
|
||||
@@ -188,28 +188,28 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新 hoverd
|
||||
* Update hoverd
|
||||
* @param mousePos
|
||||
*/
|
||||
updateHoveredState(mousePos: IPoint, target?: HTMLElement): void {
|
||||
const nodeTransforms = this.nodeTransformsWithSort;
|
||||
// // 判断连接点是否 hover
|
||||
// //Determine whether the connection point is hover
|
||||
const portHovered = this.linesManager.getPortFromMousePos(mousePos);
|
||||
|
||||
const lineDomNodes = this.playgroundNode.querySelectorAll(LINE_CLASS_NAME);
|
||||
const checkTargetFromLine = [...lineDomNodes].some(lineDom =>
|
||||
lineDom.contains(target as HTMLElement),
|
||||
);
|
||||
// 默认 只有 output 点位可以 hover
|
||||
// By default, only output points can be hover
|
||||
if (portHovered) {
|
||||
// 输出点可以直接选中
|
||||
// The output point can be directly selected.
|
||||
if (portHovered.portType === 'output') {
|
||||
this.updateHoveredKey(portHovered.id);
|
||||
} else if (
|
||||
checkTargetFromLine ||
|
||||
target?.className?.includes?.(PORT_BG_CLASS_NAME)
|
||||
) {
|
||||
// 输入点采用获取最接近的线条
|
||||
// The input point uses to get the closest line
|
||||
const lineHovered =
|
||||
this.linesManager.getCloseInLineFromMousePos(mousePos);
|
||||
if (lineHovered) {
|
||||
@@ -219,7 +219,7 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
|
||||
return;
|
||||
}
|
||||
|
||||
// Drawing 情况,不能选中节点和线条
|
||||
// Drawing situation, nodes and lines cannot be selected
|
||||
if (this.isDrawing) {
|
||||
return;
|
||||
}
|
||||
@@ -228,7 +228,7 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
|
||||
trans.bounds.contains(mousePos.x, mousePos.y),
|
||||
)?.entity as WorkflowNodeEntity;
|
||||
|
||||
// 判断当前鼠标位置所在元素是否在节点内部
|
||||
// Determine whether the element where the current mouse position is located is inside the node
|
||||
const nodeDomNodes = this.playgroundNode.querySelectorAll(NODE_CLASS_NAME);
|
||||
const checkTargetFromNode = [...nodeDomNodes].some(nodeDom =>
|
||||
nodeDom.contains(target as HTMLElement),
|
||||
@@ -244,61 +244,61 @@ export class HoverLayer extends Layer<HoverLayerOptions> {
|
||||
nodeHovered?.parent && nodeHovered.parent.flowNodeType !== 'root'
|
||||
);
|
||||
|
||||
// 获取最接近的线条
|
||||
// 线条会相交需要获取最接近点位的线条,不能删除的线条不能被选中
|
||||
// Get the closest line
|
||||
// Lines will intersect. You need to get the line closest to the point. Lines that cannot be deleted cannot be selected.
|
||||
const lineHovered = checkTargetFromLine
|
||||
? this.linesManager.getCloseInLineFromMousePos(mousePos)
|
||||
: undefined;
|
||||
const lineInContainer = !!lineHovered?.inContainer;
|
||||
|
||||
// 判断容器内节点是否 hover
|
||||
// Determine whether the node in the container is hover
|
||||
if (nodeHovered && nodeInContainer) {
|
||||
this.updateHoveredKey(nodeHovered.id);
|
||||
return;
|
||||
}
|
||||
// 判断容器内线条是否 hover
|
||||
// Determine whether the lines in the container are hovered
|
||||
if (lineHovered && lineInContainer) {
|
||||
this.updateHoveredKey(lineHovered.id);
|
||||
return;
|
||||
}
|
||||
|
||||
// 判断节点是否 hover
|
||||
// Determine whether the node is hovering
|
||||
if (nodeHovered) {
|
||||
this.updateHoveredKey(nodeHovered.id);
|
||||
return;
|
||||
}
|
||||
// 判断线条是否 hover
|
||||
// Determine if the line is hovering
|
||||
if (lineHovered) {
|
||||
this.hoverService.updateHoveredKey(lineHovered.id);
|
||||
return;
|
||||
}
|
||||
|
||||
// 上述逻辑都未命中 则清空 hoverd
|
||||
// None of the above logic hits, then clear the hoverd.
|
||||
this.hoverService.clearHovered();
|
||||
|
||||
const currentState = this.editorStateConfig.getCurrentState();
|
||||
const isMouseFriendly =
|
||||
currentState === EditorState.STATE_MOUSE_FRIENDLY_SELECT;
|
||||
|
||||
// 鼠标优先,并且不是按住 shift 键,更新为小手
|
||||
// The mouse is given priority, and instead of holding down the shift button, it is updated to small hands.
|
||||
if (isMouseFriendly && !this.editorStateConfig.isPressingShift) {
|
||||
this.configEntity.updateCursor('grab');
|
||||
}
|
||||
}
|
||||
|
||||
updateHoveredKey(key: string): void {
|
||||
// 鼠标优先交互模式,如果是 hover,需要将鼠标的小手去掉,还原鼠标原有样式
|
||||
// Mouse priority interaction mode, if it is hover, you need to remove the small hand of the mouse and restore the original style of the mouse
|
||||
this.configEntity.updateCursor('default');
|
||||
this.hoverService.updateHoveredKey(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断是否能够 hover
|
||||
* @returns 是否能 hover
|
||||
* Determine if it can be hover
|
||||
* Can @returns hover?
|
||||
*/
|
||||
isEnabled(): boolean {
|
||||
const currentState = this.editorStateConfig.getCurrentState();
|
||||
// 选择框情况禁止 hover
|
||||
// Select box condition disable hover
|
||||
return (
|
||||
(currentState === EditorState.STATE_SELECT ||
|
||||
currentState === EditorState.STATE_MOUSE_FRIENDLY_SELECT) &&
|
||||
|
||||
@@ -61,13 +61,13 @@ export class LinesLayer extends Layer {
|
||||
private _backLineEntities: WorkflowLineEntity[] = [];
|
||||
private _version = 0;
|
||||
/**
|
||||
* 节点下边的线条
|
||||
* The line under the node
|
||||
*/
|
||||
protected backLines = domUtils.createDivWithClass(
|
||||
'gedit-playground-layer gedit-flow-lines-layer back',
|
||||
);
|
||||
/**
|
||||
* 节点前面的线条
|
||||
* The line in front of the node
|
||||
*/
|
||||
protected frontLines = domUtils.createDivWithClass(
|
||||
'gedit-playground-layer gedit-flow-lines-layer front',
|
||||
@@ -78,7 +78,7 @@ export class LinesLayer extends Layer {
|
||||
this.frontLines.style.transform = `scale(${scale})`;
|
||||
}
|
||||
|
||||
// 用来绕过 memo
|
||||
// To bypass the memo
|
||||
private bumpVersion() {
|
||||
this._version = this._version + 1;
|
||||
if (this._version === Number.MAX_SAFE_INTEGER) {
|
||||
@@ -100,7 +100,7 @@ export class LinesLayer extends Layer {
|
||||
]);
|
||||
}
|
||||
getLineColor(line: WorkflowLineEntity): string {
|
||||
// 隐藏的优先级比 hasError 高
|
||||
// Hidden priority is higher than hasError
|
||||
if (line.isHidden) {
|
||||
return line.highlightColor;
|
||||
}
|
||||
@@ -144,7 +144,7 @@ export class LinesLayer extends Layer {
|
||||
: this.selectService.isSelected(line.id);
|
||||
const renderData = line.getData(WorkflowLineRenderData);
|
||||
const version = `${this._version}:${line.version}:${renderData.renderVersion}`;
|
||||
// 正在绘制中的线条使用贝塞尔曲线
|
||||
// The line being drawn uses a Bézier curve
|
||||
if (lineType === LineType.LINE_CHART) {
|
||||
return (
|
||||
<FoldLineRender
|
||||
@@ -179,7 +179,7 @@ export class LinesLayer extends Layer {
|
||||
return true;
|
||||
}
|
||||
// const { activatedNode } = this.selectService
|
||||
// // 将选中的节点的连接线放置到前面
|
||||
// //Place the cable of the selected node to the front
|
||||
// if (activatedNode) {
|
||||
// const { inputLines, outputLines } = activatedNode.getData<WorkflowNodeLinesData>(WorkflowNodeLinesData)!
|
||||
// if (inputLines.includes(line) || outputLines.includes(line)) {
|
||||
@@ -205,7 +205,7 @@ export class LinesLayer extends Layer {
|
||||
// this.render();
|
||||
// }, 100);
|
||||
/**
|
||||
* 对线条进行分组
|
||||
* Group lines
|
||||
*/
|
||||
groupLines(): void {
|
||||
this._backLineEntities = [];
|
||||
@@ -221,7 +221,7 @@ export class LinesLayer extends Layer {
|
||||
|
||||
render(): JSX.Element {
|
||||
// const isViewportVisible = this.config.isViewportVisible.bind(this.config);
|
||||
// 对线条进行分组
|
||||
// Group lines
|
||||
this.groupLines();
|
||||
return (
|
||||
<>
|
||||
|
||||
@@ -40,7 +40,7 @@ export class ShortcutsLayer extends Layer<object> {
|
||||
onReady(): void {
|
||||
this.shortcuts.addHandlersIfNotFound(
|
||||
/**
|
||||
* 删除
|
||||
* delete
|
||||
*/
|
||||
{
|
||||
commandId: WorkflowCommands.DELETE_NODES,
|
||||
@@ -75,7 +75,7 @@ export class ShortcutsLayer extends Layer<object> {
|
||||
},
|
||||
},
|
||||
/**
|
||||
* 放大
|
||||
* enlarge
|
||||
*/
|
||||
{
|
||||
commandId: WorkflowCommands.ZOOM_IN,
|
||||
@@ -85,7 +85,7 @@ export class ShortcutsLayer extends Layer<object> {
|
||||
},
|
||||
},
|
||||
/**
|
||||
* 缩小
|
||||
* zoom out
|
||||
*/
|
||||
{
|
||||
commandId: WorkflowCommands.ZOOM_OUT,
|
||||
@@ -96,7 +96,7 @@ export class ShortcutsLayer extends Layer<object> {
|
||||
},
|
||||
);
|
||||
this.toDispose.pushAll([
|
||||
// 监听画布鼠标移动事件
|
||||
// Monitor canvas mouse movement events
|
||||
this.listenPlaygroundEvent('keydown', (e: KeyboardEvent) => {
|
||||
if (!this.isFocused || e.target !== this.playgroundNode) {
|
||||
return;
|
||||
|
||||
@@ -25,13 +25,13 @@ import { Rectangle } from '@flowgram-adapter/common';
|
||||
const BOUNDS_PADDING = 2;
|
||||
export function getSelectionBounds(
|
||||
selectionService: SelectionService | WorkflowSelectService,
|
||||
ignoreOneSelect?: boolean, // 忽略单选
|
||||
ignoreOneSelect?: boolean, // Ignore radio
|
||||
): Rectangle {
|
||||
const selectedNodes = selectionService.selection.filter(
|
||||
node => node instanceof WorkflowNodeEntity,
|
||||
);
|
||||
|
||||
// 选中单个的时候不显示
|
||||
// It is not displayed when a single is selected.
|
||||
return selectedNodes.length > (ignoreOneSelect ? 1 : 0)
|
||||
? Rectangle.enlarge(
|
||||
selectedNodes.map(n => n.getData(FlowNodeTransformData)!.bounds),
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
const isAppleDevice = /(mac|iphone|ipod|ipad)/i.test(
|
||||
typeof navigator !== 'undefined' ? navigator?.platform : '',
|
||||
);
|
||||
// 键盘事件 keyCode 别名
|
||||
// Keyboard Event keyCode Alias
|
||||
const aliasKeyCodeMap = {
|
||||
'0': 48,
|
||||
'1': 49,
|
||||
@@ -135,7 +135,7 @@ const modifierKey = {
|
||||
},
|
||||
};
|
||||
|
||||
// 根据 event 计算激活键数量
|
||||
// Number of activation keys based on event
|
||||
function countKeyByEvent(event: KeyboardEvent): number {
|
||||
const countOfModifier = Object.keys(modifierKey).reduce((total, key) => {
|
||||
if (modifierKey[key](event)) {
|
||||
@@ -145,7 +145,7 @@ function countKeyByEvent(event: KeyboardEvent): number {
|
||||
return total;
|
||||
}, 0);
|
||||
|
||||
// 16 17 18 91 92 是修饰键的 keyCode,如果 keyCode 是修饰键,那么激活数量就是修饰键的数量,如果不是,那么就需要 +1
|
||||
// 16 17 18 91 92 is the keyCode of the modifier key. If keyCode is a modifier key, then the number of activations is the number of modifier keys. If not, then + 1 is required.
|
||||
return [16, 17, 18, 91, 92].includes(event.keyCode)
|
||||
? countOfModifier
|
||||
: countOfModifier + 1;
|
||||
@@ -162,18 +162,18 @@ function isKeyStringMatch(
|
||||
keyString: string,
|
||||
exactMatch = true,
|
||||
): boolean {
|
||||
// 浏览器自动补全 input 的时候,会触发 keyDown、keyUp 事件,但此时 event.key 等为空
|
||||
// When the browser automatically completes the input, keyDown and keyUp events will be triggered, but at this time event.key, etc. are empty
|
||||
if (!event.key || !keyString) {
|
||||
return false;
|
||||
}
|
||||
// 字符串依次判断是否有组合键
|
||||
// String in turn determines whether there is a key combination
|
||||
const genArr = keyString.split(/\s+/);
|
||||
let genLen = 0;
|
||||
|
||||
for (const key of genArr) {
|
||||
// 组合键
|
||||
// key combination
|
||||
const genModifier = modifierKey[key];
|
||||
// keyCode 别名
|
||||
// keyCode alias
|
||||
const aliasKeyCode: number | number[] = aliasKeyCodeMap[key.toLowerCase()];
|
||||
|
||||
if (
|
||||
@@ -185,10 +185,10 @@ function isKeyStringMatch(
|
||||
}
|
||||
|
||||
/**
|
||||
* 需要判断触发的键位和监听的键位完全一致,判断方法就是触发的键位里有且等于监听的键位
|
||||
* genLen === genArr.length 能判断出来触发的键位里有监听的键位
|
||||
* countKeyByEvent(event) === genArr.length 判断出来触发的键位数量里有且等于监听的键位数量
|
||||
* 主要用来防止按组合键其子集也会触发的情况,例如监听 ctrl+a 会触发监听 ctrl 和 a 两个键的事件。
|
||||
* It is necessary to determine that the triggered key is exactly the same as the monitored key. The judgment method is that the triggered key is equal to the monitored key.
|
||||
* genLen == genArr.length can determine that there is a listening key among the triggered keys
|
||||
* countKeyByEvent (event) === genArr.length The number of keys triggered by the judgment is equal to the number of keys listened to
|
||||
* It is mainly used to prevent the situation that pressing a subset of the key combination will also trigger, such as listening to the event that ctrl + a will trigger listening to the two keys ctrl and a.
|
||||
*/
|
||||
if (exactMatch) {
|
||||
return genLen === genArr.length && countKeyByEvent(event) === genArr.length;
|
||||
@@ -197,7 +197,7 @@ function isKeyStringMatch(
|
||||
}
|
||||
|
||||
/**
|
||||
* 匹配指定的快捷键
|
||||
* Matches the specified shortcut
|
||||
* @param event
|
||||
* @param shortcuts
|
||||
*/
|
||||
|
||||
@@ -29,16 +29,16 @@ export const WorkflowLoader: React.FC = () => {
|
||||
const loggerService = useService<LoggerService>(LoggerService);
|
||||
useMemo(() => renderRegistry.init(), [renderRegistry]);
|
||||
useLayoutEffect(() => {
|
||||
// 加载数据
|
||||
// load data
|
||||
doc.load();
|
||||
// 销毁数据
|
||||
// Destroy data
|
||||
return () => doc.dispose();
|
||||
}, [doc]);
|
||||
|
||||
useEffect(() => {
|
||||
const disposable = loggerService.onLogger(({ event }) => {
|
||||
if (event === LoggerEvent.CANVAS_TTI) {
|
||||
// 上报到 coze
|
||||
// Report to coze
|
||||
reportTti();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -55,22 +55,22 @@ export class WorkflowRenderContribution
|
||||
protected linesManager: WorkflowLinesManager;
|
||||
|
||||
registerRenderer(registry: FlowRendererRegistry): void {
|
||||
// 画布基础层,提供缩放、手势等能力
|
||||
// Canvas base layer, providing zoom, gesture, and more
|
||||
registry.registerLayer(PlaygroundLayer, {
|
||||
hoverService: this.hoverService,
|
||||
});
|
||||
registry.registerLayers(
|
||||
FlowNodesContentLayer,
|
||||
// FlowScrollLimitLayer, // 控制滚动范围
|
||||
FlowScrollBarLayer, // 滚动条
|
||||
HoverLayer, // 控制hover
|
||||
ShortcutsLayer, // 快捷键配置
|
||||
// FlowScrollLimitLayer,//control scrolling range
|
||||
FlowScrollBarLayer, // scroll bar
|
||||
HoverLayer, // Control hover
|
||||
ShortcutsLayer, // Shortcut configuration
|
||||
);
|
||||
// 线条
|
||||
// line
|
||||
registry.registerLayer(WorkflowLinesLayer, {
|
||||
renderElement: () => this.stackingContext.node,
|
||||
});
|
||||
// 节点位置
|
||||
// Node location
|
||||
registry.registerLayer(FlowNodesTransformLayer, {
|
||||
renderElement: () => this.stackingContext.node,
|
||||
});
|
||||
@@ -81,17 +81,17 @@ export class WorkflowRenderContribution
|
||||
});
|
||||
registry.registerLayer<FlowSelectorBoxLayer>(FlowSelectorBoxLayer, {
|
||||
canSelect: (event, entity) => {
|
||||
// 需满足以下条件:
|
||||
// 1. 非左键不能触发框选
|
||||
// The following conditions must be met:
|
||||
// 1. Non-left button cannot trigger box selection
|
||||
if (event.button !== 0) {
|
||||
return false;
|
||||
}
|
||||
const element = event.target as Element;
|
||||
// 2. 没有元素不能触发框选
|
||||
// 2. No element can trigger the box selection
|
||||
if (!element) {
|
||||
return false;
|
||||
}
|
||||
// 3. 如存在自定义配置,以配置为准
|
||||
// 3. If there is a custom configuration, the configuration shall prevail.
|
||||
if (element) {
|
||||
if (element.closest('[data-flow-editor-selectable="true"]')) {
|
||||
return true;
|
||||
@@ -100,15 +100,15 @@ export class WorkflowRenderContribution
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// 4. hover 到节点或者线条不能触发框选
|
||||
// 4. Hovering to nodes or lines cannot trigger box selection
|
||||
if (this.hoverService.isSomeHovered()) {
|
||||
return false;
|
||||
}
|
||||
// 5. 未处于画布内不能触发框选
|
||||
// 5. Cannot trigger box selection without being in the canvas
|
||||
if (
|
||||
!element.classList.contains('gedit-playground-layer') &&
|
||||
!element.classList.contains('gedit-flow-background-layer') &&
|
||||
// 连线的空白区域
|
||||
// Blank space for connection
|
||||
!element.closest('.gedit-flow-activity-edge')
|
||||
) {
|
||||
return false;
|
||||
@@ -116,16 +116,16 @@ export class WorkflowRenderContribution
|
||||
return true;
|
||||
},
|
||||
});
|
||||
// 调试画布
|
||||
// Debug Canvas
|
||||
if (location.search.match('playground_debug')) {
|
||||
registry.registerLayers(FlowDebugLayer);
|
||||
}
|
||||
// 背景最后插入,因为里边会调整位置
|
||||
// The background is inserted at the end, because the position will be adjusted inside.
|
||||
registry.registerLayer(BackgroundLayer);
|
||||
}
|
||||
|
||||
/**
|
||||
* 这个用于阻止 document.body 的手势缩放
|
||||
* This is used to prevent gesture scaling of document.body
|
||||
* @private
|
||||
*/
|
||||
private _gestureForStopDefault = new Gesture(document.body, {
|
||||
|
||||
@@ -39,16 +39,16 @@ export interface WorkflowRenderProviderProps {
|
||||
}
|
||||
|
||||
/**
|
||||
* 画布引擎渲染
|
||||
* Canvas Engine Rendering
|
||||
*/
|
||||
export const WorkflowRenderProvider = (props: WorkflowRenderProviderProps) => {
|
||||
const modules = useMemo(
|
||||
() => [
|
||||
FlowDocumentContainerModule, // 默认文档
|
||||
FlowRendererContainerModule, // 默认渲染
|
||||
// FlowActivitiesContainerModule, // 这是固定画布的 module,目前不需要依赖
|
||||
WorkflowDocumentContainerModule, // 扩展文档
|
||||
WorkflowRenderContainerModule, // 扩展渲染
|
||||
FlowDocumentContainerModule, // default document
|
||||
FlowRendererContainerModule, // default rendering
|
||||
// FlowActivitiesContainerModule,//This is a module to fix the canvas, no dependency is currently required
|
||||
WorkflowDocumentContainerModule, // extended document
|
||||
WorkflowRenderContainerModule, // extended rendering
|
||||
...(props.containerModules || []),
|
||||
],
|
||||
[],
|
||||
@@ -57,7 +57,7 @@ export const WorkflowRenderProvider = (props: WorkflowRenderProviderProps) => {
|
||||
const preset = useCallback(
|
||||
() => [
|
||||
createFreeAutoLayoutPlugin({}),
|
||||
createFreeStackPlugin({}), // 渲染层级管理
|
||||
createFreeStackPlugin({}), // rendering hierarchy management
|
||||
createNodeCorePlugin({}),
|
||||
...(props.preset?.() || []),
|
||||
],
|
||||
|
||||
@@ -48,7 +48,7 @@ export class WorkflowShortcutsRegistry {
|
||||
@inject(CommandRegistry) protected commandRegistry: CommandRegistry;
|
||||
readonly shortcutsHandlers: ShorcutsHandler[] = [];
|
||||
addHandlers(...handlers: ShorcutsHandler[]): void {
|
||||
// 注册 command
|
||||
// Registration command
|
||||
handlers.forEach(handler => {
|
||||
this.commandRegistry.registerCommand(
|
||||
{ id: handler.commandId },
|
||||
|
||||
Reference in New Issue
Block a user