Files
esengine/packages/editor-app/src/presentation/hooks/useCommandHistory.ts
YHH adfc7e91b3 Refactor/clean architecture phase1 (#215)
* refactor(editor): 建立Clean Architecture领域模型层

* refactor(editor): 实现应用层架构 - 命令模式、用例和状态管理

* refactor(editor): 实现展示层核心Hooks

* refactor(editor): 实现基础设施层和展示层组件

* refactor(editor): 迁移画布和连接渲染到 Clean Architecture 组件

* feat(editor): 集成应用层架构和命令模式,实现撤销/重做功能

* refactor(editor): UI组件拆分

* refactor(editor): 提取快速创建菜单逻辑

* refactor(editor): 重构BehaviorTreeEditor,提取组件和Hook

* refactor(editor): 提取端口连接和键盘事件Hook

* refactor(editor): 提取拖放处理Hook

* refactor(editor): 提取画布交互Hook和工具函数

* refactor(editor): 完成核心重构

* fix(editor): 修复节点无法创建和连接

* refactor(behavior-tree,editor): 重构节点子节点约束系统,实现元数据驱动的架构
2025-11-03 21:22:16 +08:00

81 lines
2.3 KiB
TypeScript

import { useRef, useCallback, useMemo, useEffect } from 'react';
import { CommandManager } from '../../application/commands/CommandManager';
/**
* 撤销/重做功能 Hook
*/
export function useCommandHistory() {
const commandManagerRef = useRef<CommandManager>(new CommandManager({
maxHistorySize: 100,
autoMerge: true
}));
const commandManager = commandManagerRef.current;
const canUndo = useCallback(() => {
return commandManager.canUndo();
}, [commandManager]);
const canRedo = useCallback(() => {
return commandManager.canRedo();
}, [commandManager]);
const undo = useCallback(() => {
if (commandManager.canUndo()) {
commandManager.undo();
}
}, [commandManager]);
const redo = useCallback(() => {
if (commandManager.canRedo()) {
commandManager.redo();
}
}, [commandManager]);
const getUndoHistory = useCallback(() => {
return commandManager.getUndoHistory();
}, [commandManager]);
const getRedoHistory = useCallback(() => {
return commandManager.getRedoHistory();
}, [commandManager]);
const clear = useCallback(() => {
commandManager.clear();
}, [commandManager]);
// 键盘快捷键
useEffect(() => {
const handleKeyDown = (e: KeyboardEvent) => {
const isMac = navigator.platform.toUpperCase().indexOf('MAC') >= 0;
const isCtrlOrCmd = isMac ? e.metaKey : e.ctrlKey;
if (isCtrlOrCmd && e.key === 'z') {
e.preventDefault();
if (e.shiftKey) {
redo();
} else {
undo();
}
} else if (isCtrlOrCmd && e.key === 'y') {
e.preventDefault();
redo();
}
};
window.addEventListener('keydown', handleKeyDown);
return () => window.removeEventListener('keydown', handleKeyDown);
}, [undo, redo]);
return useMemo(() => ({
commandManager,
canUndo: canUndo(),
canRedo: canRedo(),
undo,
redo,
getUndoHistory,
getRedoHistory,
clear
}), [commandManager, canUndo, canRedo, undo, redo, getUndoHistory, getRedoHistory, clear]);
}