Files
JoyD/AutoRobot/Windows/Robot/Web/src/components/LayoutManager.js
2025-10-20 10:59:56 +08:00

247 lines
5.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* 布局管理器 - 统一管理面板布局的持久化、调整大小等功能
*/
import { ref, onMounted, onUnmounted } from 'vue';
import { LayoutPersistence } from './LayoutPersistence';
import { ResizeHandlers } from './ResizeHandlers';
/**
* 布局管理器类
* 负责统一管理面板布局的持久化、调整大小等功能
*/
export class LayoutManager {
/**
* 构造函数
* @param {Object} store - Pinia store实例
*/
constructor(store, onLayoutApplied = null) {
this.store = store;
this.container = ref(null);
this.layoutPersistence = null;
this.resizeHandlers = null;
this.onLayoutApplied = onLayoutApplied;
}
/**
* 初始化布局管理器
*/
initialize() {
// 创建布局持久化实例
// 直接传入store对象让LayoutPersistence能够访问最新的面板数据
// 创建布局持久化实例
// 优化LayoutPersistence构造函数已简化只需要store对象和storageKey
// 传递onLayoutApplied回调以便在布局应用完成后通知调用方
this.layoutPersistence = new LayoutPersistence(
this.store,
'dockPanelLayout',
this.onLayoutApplied
);
// 创建调整大小处理器
this.resizeHandlers = new ResizeHandlers(
this.store,
this.container,
this.layoutPersistence
);
// 初始化事件监听
this.resizeHandlers.initialize();
// 初始化容器引用
this.container.value = document.querySelector('.dock-panel-container');
}
/**
* 加载保存的布局
* @returns {boolean} 是否成功加载布局
*/
loadLayout() {
if (!this.layoutPersistence) {
console.error('Layout persistence is not initialized');
return false;
}
try {
return this.layoutPersistence.loadLayout();
} catch (error) {
console.error('Failed to load layout:', error);
return false;
}
}
/**
* 保存当前布局
*/
saveLayout() {
if (!this.layoutPersistence) {
console.error('Layout persistence is not initialized');
return;
}
try {
this.layoutPersistence.saveLayout();
} catch (error) {
console.error('Failed to save layout:', error);
}
}
/**
* 导出布局为JSON文件
*/
exportLayout() {
if (!this.layoutPersistence) {
console.error('Layout persistence is not initialized');
return;
}
try {
this.layoutPersistence.exportLayout();
} catch (error) {
console.error('Failed to export layout:', error);
throw error;
}
}
/**
* 导入布局
* @param {string|Object} content - JSON字符串或解析后的对象
* @returns {boolean} 是否成功导入布局
*/
importLayout(content) {
if (!this.layoutPersistence) {
console.error('Layout persistence is not initialized');
return false;
}
try {
return this.layoutPersistence.importLayout(content);
} catch (error) {
console.error('Failed to import layout:', error);
throw error;
}
}
/**
* 清除保存的布局
*/
clearSavedLayout() {
if (!this.layoutPersistence) {
console.error('Layout persistence is not initialized');
return;
}
try {
this.layoutPersistence.clearSavedLayout();
} catch (error) {
console.error('Failed to clear saved layout:', error);
}
}
/**
* 检查是否有保存的布局
* @returns {boolean} 是否有保存的布局
*/
hasSavedLayout() {
if (!this.layoutPersistence) {
return false;
}
return this.layoutPersistence.hasSavedLayout();
}
/**
* 开始调整大小
*/
startResize(target, event) {
if (!this.resizeHandlers) {
console.error('Resize handlers is not initialized');
return;
}
this.resizeHandlers.startResize(target, event);
}
/**
* 开始面板调整大小
*/
startPanelResize(position, panelId, panelIndex, event) {
if (!this.resizeHandlers) {
console.error('Resize handlers is not initialized');
return;
}
this.resizeHandlers.startPanelResize(position, panelId, panelIndex, event);
}
/**
* 处理鼠标移动
*/
handleMouseMove(event, minSizes, leftPanelArea, rightPanelArea, topPanelArea, bottomPanelArea, centerPanelArea) {
if (!this.resizeHandlers) {
console.error('Resize handlers is not initialized');
return;
}
this.resizeHandlers.handleMouseMove(event, minSizes, leftPanelArea, rightPanelArea, topPanelArea, bottomPanelArea, centerPanelArea);
}
/**
* 处理鼠标松开
*/
handleMouseUp(event, hideContextMenuCallback, checkDockZoneCallback = null) {
if (!this.resizeHandlers) {
console.error('Resize handlers is not initialized');
if (hideContextMenuCallback) {
hideContextMenuCallback();
}
return;
}
this.resizeHandlers.handleMouseUp(event, hideContextMenuCallback, checkDockZoneCallback);
}
/**
* 清理资源
*/
cleanup() {
if (this.resizeHandlers) {
this.resizeHandlers.cleanup();
}
}
/**
* 设置容器引用
* @param {HTMLElement} container - 容器元素
*/
setContainer(container) {
this.container.value = container;
}
/**
* 获取容器引用
* @returns {HTMLElement|null} 容器元素
*/
getContainer() {
return this.container.value;
}
}
/**
* 创建LayoutManager的Vue组合式函数
* @param {Object} store - Pinia store实例
* @param {Function} onLayoutApplied - 布局应用完成后的回调函数
* @returns {Object} LayoutManager实例及相关方法
*/
export function useLayoutManager(store, onLayoutApplied = null) {
const layoutManager = new LayoutManager(store, onLayoutApplied);
onMounted(() => {
layoutManager.initialize();
});
onUnmounted(() => {
layoutManager.cleanup();
});
return layoutManager;
}