Skip to content

Commit e95b60a

Browse files
committed
🚧 完善传送门节点的标题编辑和渲染
1 parent 901299e commit e95b60a

File tree

4 files changed

+172
-5
lines changed

4 files changed

+172
-5
lines changed

app/src/core/render/canvas2d/entityRenderer/portalNode/portalNodeRenderer.tsx

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,71 @@
11
import { Rectangle } from "../../../../dataStruct/shape/Rectangle";
2+
import { Vector } from "../../../../dataStruct/Vector";
3+
import { MouseLocation } from "../../../../service/controlService/MouseLocation";
24
import { StageStyleManager } from "../../../../service/feedbackService/stageStyle/StageStyleManager";
35
import { Camera } from "../../../../stage/Camera";
46
import { PortalNode } from "../../../../stage/stageObject/entity/PortalNode";
7+
import { CurveRenderer } from "../../basicRenderer/curveRenderer";
58
import { ShapeRenderer } from "../../basicRenderer/shapeRenderer";
69
import { TextRenderer } from "../../basicRenderer/textRenderer";
710
import { Renderer } from "../../renderer";
811
import { CollisionBoxRenderer } from "../CollisionBoxRenderer";
912
import { EntityRenderer } from "../EntityRenderer";
1013

1114
export namespace PortalNodeRenderer {
15+
/**
16+
* 主渲染
17+
* @param portalNode
18+
*/
1219
export function render(portalNode: PortalNode) {
1320
const leftTopLocation = portalNode.location;
21+
const rightTopLocation = portalNode.collisionBox.getRectangle().rightTop;
22+
// 绘制矩形
1423
ShapeRenderer.renderRect(
1524
new Rectangle(leftTopLocation, portalNode.size).transformWorld2View(),
1625
portalNode.color,
1726
StageStyleManager.currentStyle.StageObjectBorderColor,
1827
2 * Camera.currentScale,
1928
Renderer.NODE_ROUNDED_RADIUS * Camera.currentScale,
2029
);
30+
// 虚线 1
31+
CurveRenderer.renderDashedLine(
32+
Renderer.transformWorld2View(leftTopLocation.add(new Vector(0, PortalNode.TITLE_LINE_Y))),
33+
Renderer.transformWorld2View(rightTopLocation.add(new Vector(0, PortalNode.TITLE_LINE_Y))),
34+
StageStyleManager.currentStyle.StageObjectBorderColor,
35+
1 * Camera.currentScale,
36+
10 * Camera.currentScale,
37+
);
38+
// 绘制标题,和节点文字大小保持一致
39+
TextRenderer.renderText(
40+
portalNode.title,
41+
Renderer.transformWorld2View(leftTopLocation.add(Vector.same(Renderer.NODE_PADDING))),
42+
Renderer.FONT_SIZE * Camera.currentScale,
43+
StageStyleManager.currentStyle.StageObjectBorderColor,
44+
);
45+
// 虚线 2
46+
CurveRenderer.renderDashedLine(
47+
Renderer.transformWorld2View(leftTopLocation.add(new Vector(0, PortalNode.PATH_LINE_Y))),
48+
Renderer.transformWorld2View(rightTopLocation.add(new Vector(0, PortalNode.PATH_LINE_Y))),
49+
StageStyleManager.currentStyle.StageObjectBorderColor,
50+
1 * Camera.currentScale,
51+
5 * Camera.currentScale,
52+
);
53+
// 绘制文件路径文字
54+
TextRenderer.renderText(
55+
`path: "${portalNode.portalFilePath}"`,
56+
Renderer.transformWorld2View(
57+
leftTopLocation.add(new Vector(0, PortalNode.TITLE_LINE_Y)).add(Vector.same(Renderer.NODE_PADDING)),
58+
),
59+
Renderer.FONT_SIZE_DETAILS * Camera.currentScale,
60+
StageStyleManager.currentStyle.StageObjectBorderColor,
61+
);
62+
63+
// 选中状态
2164
if (portalNode.isSelected) {
2265
// 在外面增加一个框
2366
CollisionBoxRenderer.render(portalNode.collisionBox, StageStyleManager.currentStyle.CollideBoxSelectedColor);
2467
}
68+
// 绘制实体详情
2569
EntityRenderer.renderEntityDetails(portalNode);
2670

2771
// 绘制debug信息
@@ -34,5 +78,75 @@ export namespace PortalNodeRenderer {
3478
StageStyleManager.currentStyle.DetailsDebugTextColor,
3579
);
3680
}
81+
// 提示施工中
82+
TextRenderer.renderTextFromCenter(
83+
"预览功能还在开发中",
84+
Renderer.transformWorld2View(portalNode.rectangle.center),
85+
Renderer.FONT_SIZE_DETAILS * Camera.currentScale,
86+
StageStyleManager.currentStyle.DetailsDebugTextColor,
87+
);
88+
89+
renderHoverState(portalNode);
90+
}
91+
92+
function renderHoverState(portalNode: PortalNode) {
93+
const mouseLocation = Renderer.transformView2World(MouseLocation.vector());
94+
const bodyRectangle = portalNode.collisionBox.getRectangle();
95+
if (bodyRectangle.isPointIn(mouseLocation)) {
96+
const titleRectangle = portalNode.titleRectangleArea();
97+
const pathRectangle = portalNode.pathRectangleArea();
98+
if (titleRectangle.isPointIn(mouseLocation)) {
99+
// 鼠标在标题区域
100+
// 绘制矩形
101+
ShapeRenderer.renderRect(
102+
titleRectangle.transformWorld2View(),
103+
StageStyleManager.currentStyle.CollideBoxPreSelectedColor,
104+
StageStyleManager.currentStyle.CollideBoxSelectedColor,
105+
2 * Camera.currentScale,
106+
Renderer.NODE_ROUNDED_RADIUS * Camera.currentScale,
107+
);
108+
// 绘制悬浮提示文字
109+
TextRenderer.renderText(
110+
"双击编辑标题",
111+
Renderer.transformWorld2View(bodyRectangle.leftBottom.add(Vector.same(Renderer.NODE_PADDING))),
112+
Renderer.FONT_SIZE_DETAILS * Camera.currentScale,
113+
StageStyleManager.currentStyle.DetailsDebugTextColor,
114+
);
115+
} else if (pathRectangle.isPointIn(mouseLocation)) {
116+
// 鼠标在路径区域
117+
// 绘制矩形
118+
ShapeRenderer.renderRect(
119+
pathRectangle.transformWorld2View(),
120+
StageStyleManager.currentStyle.CollideBoxPreSelectedColor,
121+
StageStyleManager.currentStyle.CollideBoxSelectedColor,
122+
2 * Camera.currentScale,
123+
Renderer.NODE_ROUNDED_RADIUS * Camera.currentScale,
124+
);
125+
// 绘制悬浮提示文字
126+
TextRenderer.renderText(
127+
"双击编辑相对路径",
128+
Renderer.transformWorld2View(bodyRectangle.leftBottom.add(Vector.same(Renderer.NODE_PADDING))),
129+
Renderer.FONT_SIZE_DETAILS * Camera.currentScale,
130+
StageStyleManager.currentStyle.DetailsDebugTextColor,
131+
);
132+
} else {
133+
// 鼠标在节点区域
134+
// 绘制矩形
135+
ShapeRenderer.renderRect(
136+
bodyRectangle.transformWorld2View(),
137+
StageStyleManager.currentStyle.CollideBoxPreSelectedColor,
138+
StageStyleManager.currentStyle.CollideBoxSelectedColor,
139+
2 * Camera.currentScale,
140+
Renderer.NODE_ROUNDED_RADIUS * Camera.currentScale,
141+
);
142+
// 绘制悬浮提示文字
143+
TextRenderer.renderText(
144+
"双击传送",
145+
Renderer.transformWorld2View(bodyRectangle.leftBottom.add(Vector.same(Renderer.NODE_PADDING))),
146+
Renderer.FONT_SIZE_DETAILS * Camera.currentScale,
147+
StageStyleManager.currentStyle.DetailsDebugTextColor,
148+
);
149+
}
150+
}
37151
}
38152
}

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

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@ import { isWeb } from "../../../../../utils/platform";
55
import { Vector } from "../../../../dataStruct/Vector";
66
import { Renderer } from "../../../../render/canvas2d/renderer";
77
import { Stage } from "../../../../stage/Stage";
8+
import { StageDumper } from "../../../../stage/StageDumper";
89
import { StageManager } from "../../../../stage/stageManager/StageManager";
910
import { PortalNode } from "../../../../stage/stageObject/entity/PortalNode";
1011
import { TextNode } from "../../../../stage/stageObject/entity/TextNode";
1112
import { UrlNode } from "../../../../stage/stageObject/entity/UrlNode";
1213
import { RecentFileManager } from "../../../dataFileService/RecentFileManager";
14+
import { StageSaveManager } from "../../../dataFileService/StageSaveManager";
1315
import { Controller } from "../Controller";
1416
import { ControllerClass } from "../ControllerClass";
15-
import { editNodeDetails, editTextNode, editUrlNodeTitle } from "./utilsControl";
16-
import { StageSaveManager } from "../../../dataFileService/StageSaveManager";
17-
import { StageDumper } from "../../../../stage/StageDumper";
17+
import { editNodeDetails, editPortalNodeTitle, editTextNode, editUrlNodeTitle } from "./utilsControl";
1818
/**
1919
* 包含编辑节点文字,编辑详细信息等功能的控制器
2020
*
@@ -50,7 +50,10 @@ ControllerNodeEdit.mouseDoubleClick = (event: MouseEvent) => {
5050
} else if (clickedEntity instanceof PortalNode) {
5151
// TODO: 点击范围有待设计
5252
const diffNodeLeftTopLocation = pressLocation.subtract(clickedEntity.rectangle.leftTop);
53-
if (diffNodeLeftTopLocation.y < PortalNode.TITLE_HEIGHT) {
53+
if (diffNodeLeftTopLocation.y < PortalNode.TITLE_LINE_Y) {
54+
// 编辑标题
55+
editPortalNodeTitle(clickedEntity);
56+
} else if (diffNodeLeftTopLocation.y < PortalNode.PATH_LINE_Y) {
5457
// 更改路径
5558
const newPortalFilePath = prompt("请输入新的路径", clickedEntity.portalFilePath);
5659
if (newPortalFilePath) {

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { Stage } from "../../../../stage/Stage";
77
import { SectionMethods } from "../../../../stage/stageManager/basicMethods/SectionMethods";
88
import { StageManager } from "../../../../stage/stageManager/StageManager";
99
import { Entity } from "../../../../stage/stageObject/abstract/StageEntity";
10+
import { PortalNode } from "../../../../stage/stageObject/entity/PortalNode";
1011
import { TextNode } from "../../../../stage/stageObject/entity/TextNode";
1112
import { UrlNode } from "../../../../stage/stageObject/entity/UrlNode";
1213
import { EntityCreateLineEffect } from "../../../feedbackService/effectEngine/concrete/EntityCreateLineEffect";
@@ -75,6 +76,32 @@ export function editUrlNodeTitle(clickedUrlNode: UrlNode) {
7576
});
7677
}
7778

79+
export function editPortalNodeTitle(clickedPortalNode: PortalNode) {
80+
Controller.isCameraLocked = true;
81+
// 编辑节点
82+
clickedPortalNode.isEditingTitle = true;
83+
InputElement.input(
84+
Renderer.transformWorld2View(clickedPortalNode.rectangle.location).add(
85+
Vector.same(Renderer.NODE_PADDING).multiply(Camera.currentScale),
86+
),
87+
clickedPortalNode.title,
88+
(text) => {
89+
clickedPortalNode?.rename(text);
90+
},
91+
{
92+
fontSize: Renderer.FONT_SIZE * Camera.currentScale + "px",
93+
backgroundColor: "transparent",
94+
color: StageStyleManager.currentStyle.StageObjectBorderColor.toString(),
95+
outline: "none",
96+
marginTop: -8 * Camera.currentScale + "px",
97+
width: "100vw",
98+
},
99+
).then(() => {
100+
clickedPortalNode!.isEditingTitle = false;
101+
Controller.isCameraLocked = false;
102+
});
103+
}
104+
78105
/**
79106
* 一个全局对象,用于编辑节点的钩子函数
80107
*/

app/src/core/stage/stageObject/entity/PortalNode.tsx

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,30 @@ import { ConnectableEntity } from "../abstract/ConnectableEntity";
99
import { CollisionBox } from "../collisionBox/collisionBox";
1010

1111
export class PortalNode extends ConnectableEntity {
12-
static TITLE_HEIGHT = 100;
12+
/**
13+
* 标题标记线
14+
*/
15+
static TITLE_LINE_Y = 60;
16+
/**
17+
* 路径标记线
18+
*/
19+
static PATH_LINE_Y = 120;
20+
public isEditingTitle: boolean = false;
21+
public rename(newTitle: string): void {
22+
this.title = newTitle;
23+
this.updateFatherSectionByMove();
24+
}
25+
26+
public titleRectangleArea(): Rectangle {
27+
return new Rectangle(this.location, new Vector(this.size.x, PortalNode.TITLE_LINE_Y));
28+
}
29+
public pathRectangleArea(): Rectangle {
30+
return new Rectangle(
31+
this.location.add(new Vector(0, PortalNode.TITLE_LINE_Y)),
32+
new Vector(this.size.x, PortalNode.PATH_LINE_Y - PortalNode.TITLE_LINE_Y),
33+
);
34+
}
35+
1336
isHiddenBySectionCollapse: boolean = false;
1437
public uuid: string;
1538
public collisionBox: CollisionBox;

0 commit comments

Comments
 (0)