Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perform: graphical editor display #357

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/origine2/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"@lingui/macro": "^4.8.0",
"@lingui/react": "^4.8.0",
"@monaco-editor/react": "^4.4.5",
"@tanstack/react-virtual": "^3.11.2",
"@uiw/react-json-view": "^2.0.0-alpha.12",
"axios": "^1.6.0",
"classnames": "^2.5.1",
Expand Down
8 changes: 4 additions & 4 deletions packages/origine2/src/locales/en.po
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ msgstr "Delete"
msgid "删除属性"
msgstr "Delete Property"

#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:205
#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:215
#: src/pages/editor/GraphicalEditor/SentenceEditor/Choose.tsx:28
msgid "删除本句"
msgstr "Delete this sentence"
Expand Down Expand Up @@ -858,7 +858,7 @@ msgstr "Open effect editor"
msgid "打开文件夹"
msgstr "Open folder"

#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:213
#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:223
msgid "执行到此句"
msgstr "Execute to this sentence"

Expand Down Expand Up @@ -1157,7 +1157,7 @@ msgstr "Unrecognized"
msgid "未识别的指令"
msgstr "Unrecognized command"

#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:176
#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:186
msgid "本句前插入句子"
msgstr "Insert sentence before this"

Expand Down Expand Up @@ -1298,7 +1298,7 @@ msgstr "Add new line"
msgid "添加自定义属性"
msgstr "Add Custom Property"

#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:229
#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:285
#: src/pages/editor/GraphicalEditor/SentenceEditor/Choose.tsx:63
#: src/pages/editor/Topbar/Topbar.tsx:108
msgid "添加语句"
Expand Down
8 changes: 4 additions & 4 deletions packages/origine2/src/locales/ja.po
Original file line number Diff line number Diff line change
Expand Up @@ -481,7 +481,7 @@ msgstr "削除"
msgid "删除属性"
msgstr "属性を削除"

#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:205
#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:215
#: src/pages/editor/GraphicalEditor/SentenceEditor/Choose.tsx:28
msgid "删除本句"
msgstr "この文を削除"
Expand Down Expand Up @@ -858,7 +858,7 @@ msgstr "エフェクトエディタを開く"
msgid "打开文件夹"
msgstr "フォルダーを開く"

#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:213
#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:223
msgid "执行到此句"
msgstr "この文まで実行"

Expand Down Expand Up @@ -1157,7 +1157,7 @@ msgstr "認識されないコマンド"
msgid "未识别的指令"
msgstr "認識されないコマンド"

#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:176
#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:186
msgid "本句前插入句子"
msgstr "選択した文の前に追加"

Expand Down Expand Up @@ -1298,7 +1298,7 @@ msgstr "新しい行を追加"
msgid "添加自定义属性"
msgstr "カスタム属性を追加"

#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:229
#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:285
#: src/pages/editor/GraphicalEditor/SentenceEditor/Choose.tsx:63
#: src/pages/editor/Topbar/Topbar.tsx:108
msgid "添加语句"
Expand Down
8 changes: 4 additions & 4 deletions packages/origine2/src/locales/zhCn.po
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,7 @@ msgstr "删除"
msgid "删除属性"
msgstr "删除属性"

#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:205
#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:215
#: src/pages/editor/GraphicalEditor/SentenceEditor/Choose.tsx:28
msgid "删除本句"
msgstr "删除本句"
Expand Down Expand Up @@ -878,7 +878,7 @@ msgstr "打开效果编辑器"
msgid "打开文件夹"
msgstr "打开文件夹"

#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:213
#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:223
msgid "执行到此句"
msgstr "执行到此句"

Expand Down Expand Up @@ -1177,7 +1177,7 @@ msgstr "未识别"
msgid "未识别的指令"
msgstr "未识别的指令"

#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:176
#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:186
msgid "本句前插入句子"
msgstr "本句前插入句子"

Expand Down Expand Up @@ -1318,7 +1318,7 @@ msgstr "添加新行"
msgid "添加自定义属性"
msgstr "添加自定义属性"

#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:229
#: src/pages/editor/GraphicalEditor/GraphicalEditor.tsx:285
#: src/pages/editor/GraphicalEditor/SentenceEditor/Choose.tsx:63
#: src/pages/editor/Topbar/Topbar.tsx:108
msgid "添加语句"
Expand Down
202 changes: 129 additions & 73 deletions packages/origine2/src/pages/editor/GraphicalEditor/GraphicalEditor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {useValue} from "../../../hooks/useValue";
import {parseScene} from "./parser";
import axios from "axios";
import {useEffect} from "react";
import {useCallback, useEffect, useRef} from "react";
import {WsUtil} from "../../../utils/wsUtil";
import {mergeToString, splitToArray} from "./utils/sceneTextProcessor";
import styles from "./graphicalEditor.module.scss";
Expand All @@ -14,6 +14,7 @@ import {eventBus} from "@/utils/eventBus";
import useEditorStore from "@/store/useEditorStore";
import { t } from "@lingui/macro";
import { api } from "@/api";
import { useVirtualizer } from '@tanstack/react-virtual';

interface IGraphicalEditorProps {
targetPath: string;
Expand All @@ -24,6 +25,10 @@ export default function GraphicalEditor(props: IGraphicalEditorProps) {
const sceneText = useValue("");
const gameName = useEditorStore.use.subPage();
const showSentence = useValue<Array<boolean>>([]);
const parentRef = useRef<HTMLDivElement>(null);
const parsedScene = (sceneText.value === "" ? {sentenceList: []} : parseScene(sceneText.value));
const containerRef = useRef<HTMLDivElement>(null);
const containerHeight = useValue(1000);

function updateScene() {
const path = props.targetPath;
Expand Down Expand Up @@ -143,8 +148,97 @@ export default function GraphicalEditor(props: IGraphicalEditorProps) {
};
}, [sceneText.value]);

const parsedScene = (sceneText.value === "" ? {sentenceList: []} : parseScene(sceneText.value));
return <div className={styles.main} id="graphical-editor-main">
useEffect(() => {
const handleResize = () => {
containerHeight.set(containerRef.current?.clientHeight ?? 1000);
console.debug("resize", containerRef.current?.clientHeight);
};
setTimeout(handleResize, 500);
window.addEventListener('resize', handleResize);
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);

const rowVirtualRef = useVirtualizer({
count: parsedScene.sentenceList.length,
getScrollElement: () => parentRef.current,
estimateSize: () => 35,
});

const sentenceItem = useCallback(() => (
parsedScene.sentenceList.map((sentence, i) => {
const index = i + 1;
// console.log(sentence.command);
const sentenceConfig = sentenceEditorConfig.find((e) => e.type === sentence.command) ?? sentenceEditorDefault;
const SentenceEditor = sentenceConfig.component;
return <Draggable key={JSON.stringify(sentence) + i}
draggableId={sentence.content + sentence.commandRaw + i} index={i}>
{(provided, snapshot) => (
<div className={`${styles.sentenceEditorWrapper} sentence-block-${index}`}
key={sentence.commandRaw + JSON.stringify(sentence.sentenceAssets) + i + 'inner'}
ref={provided.innerRef}
{...provided.draggableProps}
>
<div className={styles.addForwardArea}>
<div className={styles.addForwardAreaButtonGroup}>
<div className={styles.addForwardAreaButton}>
<AddSentence titleText={t`本句前插入句子`} type={addSentenceType.forward}
onChoose={(newSentence) => addOneSentence(newSentence, i)}/>
</div>
</div>
</div>
<div className={styles.sentenceEditorContent}>
<div className={styles.lineNumber}><span style={{padding: "0 6px 0 0"}}>{index}</span>
<Sort {...provided.dragHandleProps} style={{padding: "5px 0 0 0"}} theme="outline" size="22"
strokeWidth={3}/>
</div>
<div className={styles.seArea}>
<div className={styles.head}>
<div className={styles.title}>
{sentenceConfig.title()}
</div>
<div className={styles.optionButton}
onClick={() => changeShowSentence(i)}>
{showSentence.value[i] ?
<DownOne strokeWidth={3} theme="outline" size="18"
fill="#005CAF"/> :
<RightOne strokeWidth={3} theme="outline" size="18"
fill="#005CAF"/>}
</div>
<div className={styles.optionButtonContainer}>
<div className={styles.optionButton}
onClick={() => deleteOneSentence(i)}>
<DeleteFive strokeWidth={3} style={{padding: "2px 4px 0 0"}} theme="outline" size="14"
fill="#333"/>
<div>
{t`删除本句`}
</div>
</div>
<div className={styles.optionButton}
onClick={() => syncToIndex(i)}>
<Play strokeWidth={3} style={{padding: "2px 4px 0 0"}} theme="outline" size="14"
fill="#333"/>
<div>
{t`执行到此句`}
</div>
</div>
</div>
</div>
{showSentence.value[i] && <SentenceEditor sentence={sentence} index={index} onSubmit={(newSentence) => {
updateSentenceByIndex(newSentence, i);
}}/>}
</div>
</div>
</div>
)}
</Draggable>;
})
), [sceneText.value]);

const items = rowVirtualRef.getVirtualItems();

return <div className={styles.main} id="graphical-editor-main" ref={containerRef}>
<div style={{flex: 1, padding: '14px 4px 0 4px'}}>
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="droppable">
Expand All @@ -156,78 +250,40 @@ export default function GraphicalEditor(props: IGraphicalEditorProps) {
// 为了使 droppable 能够正常工作必须 绑定到最高可能的DOM节点中provided.innerRef.
ref={provided.innerRef}
>
{parsedScene.sentenceList.map((sentence, i) => {
// 实际显示的行数
const index = i + 1;
// console.log(sentence.command);
const sentenceConfig = sentenceEditorConfig.find((e) => e.type === sentence.command) ?? sentenceEditorDefault;
const SentenceEditor = sentenceConfig.component;
return <Draggable key={JSON.stringify(sentence) + i}
draggableId={sentence.content + sentence.commandRaw + i} index={i}>
{(provided, snapshot) => (
<div className={`${styles.sentenceEditorWrapper} sentence-block-${index}`}
key={sentence.commandRaw + JSON.stringify(sentence.sentenceAssets) + i + 'inner'}
ref={provided.innerRef}
{...provided.draggableProps}
>
<div className={styles.addForwardArea}>
<div className={styles.addForwardAreaButtonGroup}>
<div className={styles.addForwardAreaButton}>
<AddSentence titleText={t`本句前插入句子`} type={addSentenceType.forward}
onChoose={(newSentence) => addOneSentence(newSentence, i)}/>
</div>
</div>
</div>
<div className={styles.sentenceEditorContent}>
<div className={styles.lineNumber}><span style={{padding: "0 6px 0 0"}}>{index}</span>
<Sort {...provided.dragHandleProps} style={{padding: "5px 0 0 0"}} theme="outline" size="22"
strokeWidth={3}/>
</div>
<div className={styles.seArea}>
<div className={styles.head}>
<div className={styles.title}>
{sentenceConfig.title()}
</div>
<div className={styles.optionButton}
onClick={() => changeShowSentence(i)}>
{showSentence.value[i] ?
<DownOne strokeWidth={3} theme="outline" size="18"
fill="#005CAF"/> :
<RightOne strokeWidth={3} theme="outline" size="18"
fill="#005CAF"/>}
</div>
<div className={styles.optionButtonContainer}>
<div className={styles.optionButton}
onClick={() => deleteOneSentence(i)}>
<DeleteFive strokeWidth={3} style={{padding: "2px 4px 0 0"}} theme="outline" size="14"
fill="#333"/>
<div>
{t`删除本句`}
</div>
</div>
<div className={styles.optionButton}
onClick={() => syncToIndex(i)}>
<Play strokeWidth={3} style={{padding: "2px 4px 0 0"}} theme="outline" size="14"
fill="#333"/>
<div>
{t`执行到此句`}
</div>
</div>
</div>
</div>
{showSentence.value[i] && <SentenceEditor sentence={sentence} index={index} onSubmit={(newSentence) => {
updateSentenceByIndex(newSentence, i);
}}/>}
</div>
<div ref={parentRef} style={{
height: containerHeight.value - 14,
width: "100%",
overflowY: 'auto',
contain: "strict"
}}>
<div style={{
height: rowVirtualRef.getTotalSize(),
width: "100%",
position: "relative"
}}>
<div style={{
position: 'absolute',
top: 0,
left: 0,
width: '100%',
transform: `translateY(${items[0]?.start ?? 0}px)`,
}}>
{items.map((virtualRow, i) => (
<div
key={virtualRow.key}
data-index={virtualRow.index}
ref={rowVirtualRef.measureElement}
>
{sentenceItem()[virtualRow.index]}
</div>
))}
{provided.placeholder}
<div className={styles.addWrapper}>
<AddSentence titleText={t`添加语句`} type={addSentenceType.backward}
onChoose={(newSentence) => addOneSentence(newSentence, splitToArray(sceneText.value).length)}/>
</div>
)}
</Draggable>;
})}
{provided.placeholder}
<div className={styles.addWrapper}>
<AddSentence titleText={t`添加语句`} type={addSentenceType.backward}
onChoose={(newSentence) => addOneSentence(newSentence, splitToArray(sceneText.value).length)}/>
</div>
</div>
</div>
</div>
)}
Expand Down
Loading
Loading