Skip to content

Commit 736a2ce

Browse files
committed
feat: 增加防止backspace误删除节点的设置项、引用块能够右键跳转
1 parent 3db33d9 commit 736a2ce

File tree

10 files changed

+66
-9
lines changed

10 files changed

+66
-9
lines changed

app/src/components/context-menu-content.tsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ import {
7777
Ellipsis,
7878
SquareDashedBottomCode,
7979
RefreshCcwDot,
80+
CornerUpRight,
8081
} from "lucide-react";
8182
import { useTranslation } from "react-i18next";
8283
import { toast } from "sonner";
@@ -655,6 +656,20 @@ export default function MyContextMenuContent() {
655656
<RefreshCcwDot />
656657
刷新引用块
657658
</Item>
659+
<Item
660+
onClick={() => {
661+
p.stageManager
662+
.getSelectedEntities()
663+
.filter((it) => it instanceof ReferenceBlockNode)
664+
.filter((it) => it.isSelected)
665+
.forEach((it) => {
666+
it.goToSource();
667+
});
668+
}}
669+
>
670+
<CornerUpRight />
671+
进入该引用块所在的文件
672+
</Item>
658673
</>
659674
)}
660675
{/* 存在选中的 Edge */}

app/src/core/render/domElement/inputElement.tsx

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,16 @@ export class InputElement {
235235
} else if (event.code === "Backspace") {
236236
// event.preventDefault(); // 不能这样否则就删除不了了。
237237
if (textareaElement.value === "") {
238-
// 已经要删空了。
239-
resolve("");
240-
onChange("", textareaElement);
241-
removeElement();
242-
this.project.stageManager.deleteSelectedStageObjects();
238+
if (Settings.textNodeBackspaceDeleteWhenEmpty) {
239+
// 已经要删空了。
240+
resolve("");
241+
onChange("", textareaElement);
242+
removeElement();
243+
this.project.stageManager.deleteSelectedStageObjects();
244+
} else {
245+
// 整一个特效
246+
this.addFailEffect(false);
247+
}
243248
}
244249
} else if (event.key === "Tab") {
245250
// 防止tab切换到其他按钮
@@ -322,12 +327,14 @@ export class InputElement {
322327
}
323328
}
324329

325-
private addFailEffect() {
330+
private addFailEffect(withToast = true) {
326331
const textNodes = this.project.stageManager.getTextNodes().filter((textNode) => textNode.isEditing);
327332
for (const textNode of textNodes) {
328333
this.project.effects.addEffect(EntityShakeEffect.fromEntity(textNode));
329334
}
330-
toast("您可能记错了退出或换行的控制设置");
335+
if (withToast) {
336+
toast("您可能记错了退出或换行的控制设置");
337+
}
331338
}
332339

333340
constructor(private readonly project: Project) {}

app/src/core/service/Settings.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export const settingsSchema = z.object({
9393
.union([z.literal("trackpadIntAndWheelFloat"), z.literal("tarckpadFloatAndWheelInt")])
9494
.default("trackpadIntAndWheelFloat"),
9595
macTrackpadScaleSensitivity: z.number().min(0).max(1).multipleOf(0.001).default(0.5),
96-
macEnableControlToCut: z.boolean().default(true),
96+
macEnableControlToCut: z.boolean().default(false),
9797
allowMoveCameraByWSAD: z.boolean().default(false),
9898
allowGlobalHotKeys: z.boolean().default(true),
9999
cameraFollowsSelectedNodeOnArrowKeys: z.boolean().default(false),
@@ -124,6 +124,7 @@ export const settingsSchema = z.object({
124124
.default("enter"),
125125
textNodeSelectAllWhenStartEditByMouseClick: z.boolean().default(true),
126126
textNodeSelectAllWhenStartEditByKeyboard: z.boolean().default(false),
127+
textNodeBackspaceDeleteWhenEmpty: z.boolean().default(false),
127128
allowAddCycleEdge: z.boolean().default(false),
128129
autoLayoutWhenTreeGenerate: z.boolean().default(true),
129130
enableBackslashGenerateNodeInInput: z.boolean().default(false),

app/src/core/service/SettingsIcons.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
Columns4,
1313
Crosshair,
1414
Database,
15+
Delete,
1516
FileStack,
1617
Fullscreen,
1718
Grab,
@@ -106,6 +107,7 @@ export const settingsIcons = {
106107
textNodeExitEditMode: ListCheck,
107108
textNodeSelectAllWhenStartEditByMouseClick: TextCursorInput,
108109
textNodeSelectAllWhenStartEditByKeyboard: TextCursorInput,
110+
textNodeBackspaceDeleteWhenEmpty: Delete,
109111
allowAddCycleEdge: RotateCw,
110112
autoLayoutWhenTreeGenerate: ListTree,
111113
enableBackslashGenerateNodeInInput: Keyboard,

app/src/core/service/dataGenerateService/crossFileContentQuery.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export namespace CrossFileContentQuery {
1515
const CACHE_TIME = 10000;
1616

1717
/**
18-
* 获取指定文件中的所有Section框名称
18+
* 获取指定.prg 文件中的所有的 Section框名称
1919
* @param fileName 文件名
2020
* @returns Section框名称数组
2121
*/

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

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import { Project } from "@/core/Project";
2+
import { RecentFileManager } from "@/core/service/dataFileService/RecentFileManager";
23
import { GenerateSectionScreenshot } from "@/core/service/dataGenerateService/generateSectionScreenshot";
4+
import { onOpenFile } from "@/core/service/GlobalMenu";
35
import { ConnectableEntity } from "@/core/stage/stageObject/abstract/ConnectableEntity";
46
import { CollisionBox } from "@/core/stage/stageObject/collisionBox/collisionBox";
7+
import { PathString } from "@/utils/pathString";
58
import { Vector } from "@graphif/data-structures";
69
import { id, passExtraAtArg1, passObject, serializable } from "@graphif/serializer";
710
import { Rectangle } from "@graphif/shapes";
@@ -156,4 +159,23 @@ export class ReferenceBlockNode extends ConnectableEntity {
156159
async refresh() {
157160
await this.generateScreenshot();
158161
}
162+
163+
/**
164+
* 用户点击这个引用块,跳转到对应的跨文件的 地方
165+
*/
166+
async goToSource() {
167+
if (this.state !== "success") {
168+
return;
169+
}
170+
const recentFiles = await RecentFileManager.getRecentFiles();
171+
const file = recentFiles.find(
172+
(file) =>
173+
PathString.getFileNameFromPath(file.uri.path) === this.fileName ||
174+
PathString.getFileNameFromPath(file.uri.fsPath) === this.fileName,
175+
);
176+
if (!file) {
177+
return;
178+
}
179+
onOpenFile(file.uri, "ReferenceBlockNode跳转打开-prg文件");
180+
}
159181
}

app/src/locales/en.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,10 @@ settings:
445445
title: Select All Text When Starting Edit by Keyboard
446446
description: |
447447
When enabled, all text content will be selected when you press the key to enter text node editing mode.
448+
textNodeBackspaceDeleteWhenEmpty:
449+
title: Delete Text Node When Backspace Pressed on Empty Content
450+
description: |
451+
When enabled, pressing the Backspace key on an empty text node in edit mode will delete the entire node.
448452
enableDragAutoAlign:
449453
title: Enable Automatic Alignment When Dragging Nodes
450454
description: |

app/src/locales/zh_CN.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -550,6 +550,10 @@ settings:
550550
title: 文本节点通过键盘开始编辑时自动全选内容
551551
description: |
552552
开启后,在您按下文本节点编辑模式的按键时,会全选文本内容
553+
textNodeBackspaceDeleteWhenEmpty:
554+
title: 当在编辑模式下文本节点无内容时按Backspace键自动删除整个节点
555+
description: |
556+
开启后,在编辑文本节点且内容为空时,按下Backspace键会自动删除整个节点
553557
enableDragAutoAlign:
554558
title: 鼠标拖动自动吸附对齐节点
555559
description: |

app/src/sub/SettingsWindow/settings.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ const categories = {
269269
"textNodeExitEditMode",
270270
"textNodeSelectAllWhenStartEditByMouseClick",
271271
"textNodeSelectAllWhenStartEditByKeyboard",
272+
"textNodeBackspaceDeleteWhenEmpty",
272273
],
273274
edge: ["allowAddCycleEdge", "autoAdjustLineEndpointsByMouseTrack", "enableRightClickConnect"],
274275
generateNode: ["autoLayoutWhenTreeGenerate", "enableBackslashGenerateNodeInInput"],

app/src/utils/externalOpen.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ function splitDoubleQuote(str: string) {
7777
/**
7878
* 调用tauri框架的open方法
7979
* @param url
80+
* @param project 之所以需要project参数,是因为需要根据project的uri来转换相对路径
8081
*/
8182
function myOpen(url: string, project: Project) {
8283
const isValidURL = PathString.isValidURL(url);

0 commit comments

Comments
 (0)