Skip to content

Commit d76b827

Browse files
committed
fix: #205 双击时,连线上的文字支持编辑换行
1 parent 94d158a commit d76b827

File tree

8 files changed

+69
-13
lines changed

8 files changed

+69
-13
lines changed

app/src/core/render/canvas2d/basicRenderer/textRenderer.tsx

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,34 @@ export namespace TextRenderer {
100100
}
101101
}
102102

103+
export function renderMultiLineTextFromCenter(
104+
text: string,
105+
centerLocation: Vector,
106+
size: number,
107+
limitWidth: number,
108+
color: Color,
109+
lineHeight: number = 1.2,
110+
limitLines: number = Infinity,
111+
): void {
112+
text = Renderer.protectingPrivacy ? replaceTextWhenProtect(text) : text;
113+
let currentY = 0; // 顶部偏移量
114+
let textLineArray = textToTextArrayWrapCache(text, size, limitWidth);
115+
// 限制行数
116+
if (limitLines < textLineArray.length) {
117+
textLineArray = textLineArray.slice(0, limitLines);
118+
textLineArray[limitLines - 1] += "..."; // 最后一行加省略号
119+
}
120+
for (const line of textLineArray) {
121+
renderTextFromCenter(
122+
line,
123+
centerLocation.add(new Vector(0, currentY - ((textLineArray.length - 1) * size) / 2)),
124+
size,
125+
color,
126+
);
127+
currentY += size * lineHeight;
128+
}
129+
}
130+
103131
const textArrayCache: LruCache<string, string[]> = new LruCache(100);
104132

105133
/**

app/src/core/render/canvas2d/entityRenderer/edge/concrete/StraightEdgeRenderer.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,11 @@ export class StraightEdgeRenderer extends EdgeRendererClass {
8282
const midPoint = edge.bodyLine.midPoint();
8383
const startHalf = new Line(edge.bodyLine.start, midPoint);
8484
const endHalf = new Line(midPoint, edge.bodyLine.end);
85-
TextRenderer.renderTextFromCenter(
85+
TextRenderer.renderMultiLineTextFromCenter(
8686
edge.text,
8787
Renderer.transformWorld2View(midPoint),
8888
Renderer.FONT_SIZE * Camera.currentScale,
89+
Infinity,
8990
edgeColor,
9091
);
9192
const edgeTextRectangle = edge.textRectangle;

app/src/core/service/controlService/controller/concrete/ControllerEdgeEdit.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { Stage } from "../../../../stage/Stage";
22
import { StageManager } from "../../../../stage/stageManager/StageManager";
33

44
import { ControllerClass } from "../ControllerClass";
5+
import { editEdgeText } from "./utilsControl";
56

67
/**
78
* 包含编辑节点文字,编辑详细信息等功能的控制器
@@ -18,13 +19,16 @@ ControllerEdgeEdit.mouseDoubleClick = (event: MouseEvent) => {
1819
if (!firstHoverEdge) {
1920
return;
2021
}
22+
2123
// 编辑边上的文字
22-
const user_input = prompt("请输入线上的文字", firstHoverEdge.text);
23-
if (user_input) {
24-
for (const edge of Stage.mouseInteractionCore.hoverEdges) {
25-
edge.rename(user_input);
26-
}
27-
}
24+
editEdgeText(firstHoverEdge);
25+
26+
// const user_input = prompt("请输入线上的文字", firstHoverEdge.text);
27+
// if (user_input) {
28+
// for (const edge of Stage.mouseInteractionCore.hoverEdges) {
29+
// edge.rename(user_input);
30+
// }
31+
// }
2832
return;
2933
};
3034

app/src/core/service/controlService/controller/concrete/ControllerNodeConnection.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,6 @@ class ControllerNodeConnectionClass extends ControllerClass {
180180
}
181181
const releaseWorldLocation = Renderer.transformView2World(new Vector(event.clientX, event.clientY));
182182
const releaseTargetEntity = StageManager.findConnectableEntityByLocation(releaseWorldLocation);
183-
console.log("releaseTargetEntity", releaseTargetEntity);
184-
console.log("this.connectToEntity", this.connectToEntity);
185183
// 结束连线
186184
if (releaseTargetEntity !== null) {
187185
// 在目标节点上弹起

app/src/core/service/controlService/controller/concrete/ControllerNodeEdit.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ ControllerNodeEdit.mouseDoubleClick = (event: MouseEvent) => {
4848
open(clickedEntity.url);
4949
}
5050
} else if (clickedEntity instanceof PortalNode) {
51-
// TODO: 点击范围有待设计
5251
const diffNodeLeftTopLocation = pressLocation.subtract(clickedEntity.rectangle.leftTop);
5352
if (diffNodeLeftTopLocation.y < PortalNode.TITLE_LINE_Y) {
5453
// 编辑标题

app/src/core/service/controlService/controller/concrete/ControllerSectionEdit.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ ControllerSectionEdit.mousemove = (event: MouseEvent) => {
3838

3939
ControllerSectionEdit.keydown = (event: KeyboardEvent) => {
4040
if (event.key === "Enter") {
41-
// 先检测是否有选择了的边
4241
const isHaveSectionSelected = StageManager.getSections().some((section) => section.isSelected);
4342
if (!isHaveSectionSelected) {
4443
return;

app/src/core/service/controlService/controller/concrete/utilsControl.tsx

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { Stage } from "../../../../stage/Stage";
88
import { SectionMethods } from "../../../../stage/stageManager/basicMethods/SectionMethods";
99
import { StageManager } from "../../../../stage/stageManager/StageManager";
1010
import { Entity } from "../../../../stage/stageObject/abstract/StageEntity";
11+
import { LineEdge } from "../../../../stage/stageObject/association/LineEdge";
1112
import { PortalNode } from "../../../../stage/stageObject/entity/PortalNode";
1213
import { TextNode } from "../../../../stage/stageObject/entity/TextNode";
1314
import { UrlNode } from "../../../../stage/stageObject/entity/UrlNode";
@@ -51,6 +52,32 @@ export function editTextNode(clickedNode: TextNode, selectAll = true) {
5152
});
5253
}
5354

55+
export function editEdgeText(clickedLineEdge: LineEdge, selectAll = true) {
56+
Controller.isCameraLocked = true;
57+
58+
// clickedLineEdge.isEditing = true;
59+
InputElement.textarea(
60+
Renderer.transformWorld2View(clickedLineEdge.textRectangle.location).add(
61+
Vector.same(Renderer.NODE_PADDING).multiply(Camera.currentScale),
62+
),
63+
clickedLineEdge.text,
64+
(text) => {
65+
clickedLineEdge?.rename(text);
66+
},
67+
{
68+
fontSize: Renderer.FONT_SIZE * Camera.currentScale + "px",
69+
backgroundColor: StageStyleManager.currentStyle.BackgroundColor.toString(),
70+
color: StageStyleManager.currentStyle.StageObjectBorderColor.toString(),
71+
outline: "solid 1px rgba(255,255,255,0.1)",
72+
// marginTop: -8 * Camera.currentScale + "px",
73+
},
74+
selectAll,
75+
).then(() => {
76+
// clickedLineEdge!.isEditing = false;
77+
Controller.isCameraLocked = false;
78+
});
79+
}
80+
5481
export function editUrlNodeTitle(clickedUrlNode: UrlNode) {
5582
Controller.isCameraLocked = true;
5683
// 编辑节点

app/src/core/stage/stageObject/association/LineEdge.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { v4 as uuidv4 } from "uuid";
22
import { Serialized } from "../../../../types/node";
3-
import { getTextSize } from "../../../../utils/font";
3+
import { getMultiLineTextSize } from "../../../../utils/font";
44
import { Vector } from "../../../dataStruct/Vector";
55
import { Line } from "../../../dataStruct/shape/Line";
66
import { Rectangle } from "../../../dataStruct/shape/Rectangle";
@@ -90,7 +90,7 @@ export class LineEdge extends Edge {
9090

9191
get textRectangle(): Rectangle {
9292
// HACK: 这里会造成频繁渲染,频繁计算文字宽度进而可能出现性能问题
93-
const textSize = getTextSize(this.text, Renderer.FONT_SIZE);
93+
const textSize = getMultiLineTextSize(this.text, Renderer.FONT_SIZE, 1.2);
9494
if (this.isShifting) {
9595
return new Rectangle(this.shiftingMidPoint.subtract(textSize.divide(2)), textSize);
9696
} else {

0 commit comments

Comments
 (0)