247 lines
5.8 KiB
JavaScript
247 lines
5.8 KiB
JavaScript
/**
|
||
* 布局管理器 - 统一管理面板布局的持久化、调整大小等功能
|
||
*/
|
||
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;
|
||
} |