面板最大化和还原
This commit is contained in:
@@ -48,6 +48,11 @@
|
||||
<script setup>
|
||||
import { ref, computed, onMounted, onUnmounted, defineEmits } from 'vue'
|
||||
import Area from './Area.vue';
|
||||
import { getAreaHandler } from './handlers/AreaHandler';
|
||||
|
||||
// 获取AreaHandler实例
|
||||
const areaHandler = getAreaHandler();
|
||||
|
||||
import Panel from './Panel.vue';
|
||||
import TabPage from './TabPage.vue';
|
||||
import DockIndicator from './DockIndicator.vue';
|
||||
@@ -171,6 +176,44 @@ const onUpdatePosition = (event) => {
|
||||
}
|
||||
};
|
||||
|
||||
// 处理Area更新事件
|
||||
const onAreaUpdated = (event) => {
|
||||
const id = event.areaId;
|
||||
const updates = event.updates;
|
||||
const area = floatingAreas.value.find(a => a.id === id);
|
||||
if (area) {
|
||||
// 合并更新到Area对象
|
||||
Object.assign(area, updates);
|
||||
|
||||
// 如果是最大化状态变化,发送panel.maximize.sync事件
|
||||
if ('maximized' in updates || 'windowState' in updates) {
|
||||
// 查找该区域下的所有Panel
|
||||
const areaState = areaHandler.areaStateManager.getState(id);
|
||||
if (areaState && areaState.children) {
|
||||
const childrenArray = Array.isArray(areaState.children) ? areaState.children : [areaState.children];
|
||||
|
||||
// 查找TabPage
|
||||
childrenArray.forEach(child => {
|
||||
if (child.type === 'TabPage' && child.children) {
|
||||
const tabChildrenArray = Array.isArray(child.children) ? child.children : [child.children];
|
||||
|
||||
// 发送panel.maximize.sync事件给每个Panel
|
||||
tabChildrenArray.forEach(tabChild => {
|
||||
if (tabChild.type === 'Panel') {
|
||||
eventBus.emit(EVENT_TYPES.PANEL_MAXIMIZE_SYNC, {
|
||||
panelId: tabChild.id,
|
||||
areaId: id,
|
||||
maximized: updates.maximized !== undefined ? updates.maximized : (updates.windowState === '最大化' || updates.windowState === 'maximized')
|
||||
}, { componentId: 'dock-layout' });
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const onMaximize = (event) => {
|
||||
const panelId = event.panelId;
|
||||
const areaId = event.areaId;
|
||||
@@ -431,10 +474,10 @@ const setupEventListeners = () => {
|
||||
unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.AREA_DRAG_OVER, handleAreaDragOver, { componentId: 'dock-layout' }));
|
||||
unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.AREA_DRAG_LEAVE, handleAreaDragLeave, { componentId: 'dock-layout' }));
|
||||
unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.AREA_MERGE_REQUEST, handleAreaMergeRequest, { componentId: 'dock-layout' }));
|
||||
unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.AREA_UPDATED, onAreaUpdated, { componentId: 'dock-layout' }));
|
||||
|
||||
// 添加新的下降事件监听器
|
||||
unsubscribeFunctions.push(eventBus.on('area.position.update', onAreaPositionUpdate, { componentId: 'dock-layout' }));
|
||||
unsubscribeFunctions.push(eventBus.on('area.drag.state.update', onAreaDragStateUpdate, { componentId: 'dock-layout' }));
|
||||
unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.AREA_DRAG_STATE_UPDATE, onAreaDragStateUpdate, { componentId: 'dock-layout' }));
|
||||
|
||||
// Tab相关事件
|
||||
unsubscribeFunctions.push(eventBus.on(EVENT_TYPES.TAB_CHANGE, onTabChange, { componentId: 'dock-layout' }));
|
||||
|
||||
@@ -22,9 +22,9 @@
|
||||
<button class="button-icon p-[2px] rounded hover:opacity-100 opacity-80"
|
||||
@click.stop="onMaximize"
|
||||
@mousedown.stop
|
||||
:aria-label="maximized ? '还原' : '最大化'">
|
||||
:aria-label="isMaximized ? '还原' : '最大化'">
|
||||
<!-- 最大化图标 -->
|
||||
<template v-if="!maximized">
|
||||
<template v-if="!isMaximized">
|
||||
<!-- 最大化图标:外框 + 内部线条 -->
|
||||
<svg class="icon-square-svg" width="11" height="11" viewBox="0 0 11 11" aria-hidden="true">
|
||||
<rect x="0.5" y="0.5" width="10" height="10" fill="#cbd6ff" stroke="#8ea3d8" stroke-width="1" />
|
||||
@@ -112,7 +112,7 @@
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { defineProps, onMounted, onUnmounted } from 'vue';
|
||||
import { defineProps, onMounted, onUnmounted, ref } from 'vue';
|
||||
import {
|
||||
eventBus,
|
||||
EVENT_TYPES,
|
||||
@@ -174,6 +174,9 @@ const props = defineProps({
|
||||
const subscriptions = new Set();
|
||||
const subscriptionRegistry = new Map();
|
||||
|
||||
// 响应式的最大化状态,初始化为props.maximized
|
||||
const isMaximized = ref(props.maximized);
|
||||
|
||||
const getCurrentAreaId = () => {
|
||||
const panelElement = document.querySelector(`[data-panel-id="${props.id}"]`);
|
||||
if (panelElement) {
|
||||
@@ -212,7 +215,7 @@ const onMaximize = () => {
|
||||
emitEvent(EVENT_TYPES.PANEL_MAXIMIZE, {
|
||||
panelId: props.id,
|
||||
areaId: getCurrentAreaId(),
|
||||
currentState: props.maximized
|
||||
currentState: isMaximized.value
|
||||
}, {
|
||||
source: { component: 'Panel', panelId: props.id }
|
||||
})
|
||||
@@ -303,7 +306,7 @@ const onDragStart = (e) => {
|
||||
}
|
||||
};
|
||||
|
||||
const onDragEnd = () => {
|
||||
const onDragEnd = (e) => {
|
||||
if (isDragging) {
|
||||
isDragging = false
|
||||
// 获取所有浮动区域信息,用于单面板检测
|
||||
@@ -313,6 +316,7 @@ const onDragStart = (e) => {
|
||||
dragId: currentDragId,
|
||||
panelId: props.id,
|
||||
areaId: currentAreaId,
|
||||
position: { x: e.clientX, y: e.clientY },
|
||||
timestamp: Date.now(),
|
||||
layout: {
|
||||
areas: floatingAreas
|
||||
@@ -349,8 +353,10 @@ const setupEventListeners = () => {
|
||||
|
||||
// 监听面板最大化同步事件
|
||||
const unsubscribeMaximizeSync = onEvent(EVENT_TYPES.PANEL_MAXIMIZE_SYNC, (data) => {
|
||||
if (data.panelId === props.id) {
|
||||
console.log(`[Panel:${props.id}] 收到最大化同步事件`)
|
||||
// 同时检查panelId和areaId,确保正确匹配
|
||||
if (data.panelId === props.id || data.areaId === getCurrentAreaId()) {
|
||||
console.log(`[Panel:${props.id}] 收到最大化同步事件:`, data);
|
||||
isMaximized.value = data.maximized;
|
||||
}
|
||||
}, { componentId: `panel-${props.id}` })
|
||||
|
||||
|
||||
@@ -47,6 +47,44 @@ import { nanoid } from 'nanoid'
|
||||
*/
|
||||
|
||||
export const EVENT_TYPES = {
|
||||
// 系统级事件
|
||||
SYSTEM_INIT: 'system.init',
|
||||
SYSTEM_READY: 'system.ready',
|
||||
SYSTEM_DESTROY: 'system.destroy',
|
||||
SYSTEM_ERROR: 'system.error',
|
||||
SYSTEM_PERFORMANCE: 'system.performance',
|
||||
|
||||
// 事件路由
|
||||
EVENT_ROUTE_START: 'event.route.start',
|
||||
EVENT_ROUTE_SUCCESS: 'event.route.success',
|
||||
EVENT_ROUTE_ERROR: 'event.route.error',
|
||||
EVENT_ROUTE_FALLBACK: 'event.route.fallback',
|
||||
EVENT_RISING: 'event.rising',
|
||||
EVENT_FALLING: 'event.falling',
|
||||
|
||||
// 跨组件通信
|
||||
CROSS_COMPONENT_BROADCAST: 'cross.component.broadcast',
|
||||
CROSS_COMPONENT_REQUEST: 'cross.component.request',
|
||||
CROSS_COMPONENT_RESPONSE: 'cross.component.response',
|
||||
|
||||
// 事件链
|
||||
EVENT_CHAIN_START: 'event.chain.start',
|
||||
EVENT_CHAIN_PROGRESS: 'event.chain.progress',
|
||||
EVENT_CHAIN_COMPLETE: 'event.chain.complete',
|
||||
EVENT_CHAIN_ERROR: 'event.chain.error',
|
||||
|
||||
// 性能监控
|
||||
PERFORMANCE_MONITOR_START: 'performance.monitor.start',
|
||||
PERFORMANCE_MONITOR_END: 'performance.monitor.end',
|
||||
PERFORMANCE_THRESHOLD_EXCEEDED: 'performance.threshold.exceeded',
|
||||
|
||||
// 调试和日志
|
||||
DEBUG_EVENT_EMIT: 'debug.event.emit',
|
||||
DEBUG_EVENT_HANDLE: 'debug.event.handle',
|
||||
DEBUG_PERFORMANCE: 'debug.performance',
|
||||
DEBUG_MEMORY: 'debug.memory',
|
||||
DEBUG_TOGGLE: 'debug.toggle',
|
||||
|
||||
AREA_CLOSE: 'area.close',
|
||||
AREA_POSITION_UPDATE: 'area.position.update',
|
||||
AREA_DRAG_START: 'area.drag.start',
|
||||
@@ -102,6 +140,7 @@ export const EVENT_TYPES = {
|
||||
AREA_TABPAGE_MERGE: 'area.tabpage.merge',
|
||||
AREA_TABPAGE_SYNC: 'area.tabpage.sync',
|
||||
AREA_PANEL_SYNC: 'area.panel.sync',
|
||||
AREA_DRAG_STATE_UPDATE: 'area.drag.state.update',
|
||||
|
||||
PANEL_MAXIMIZE_SYNC: 'panel.maximize.sync',
|
||||
PANEL_MAXIMIZE: 'panel.maximize',
|
||||
|
||||
@@ -258,8 +258,11 @@ class GlobalEventManager {
|
||||
this.debugMode = false;
|
||||
this.eventListenerUnsubscribers = [];
|
||||
|
||||
// 添加拖拽状态缓存,避免在每次移动事件中重复检测
|
||||
this.dragOperationCache = new Map();
|
||||
|
||||
this._onGlobalEvent = this._onGlobalEvent.bind(this);
|
||||
this._onSystemError = this._handleSystemError.bind(this);
|
||||
this._handleSystemError = this._handleSystemError.bind(this);
|
||||
this._cleanupExpiredData = this._cleanupExpiredData.bind(this);
|
||||
|
||||
GlobalEventManager.instance = this;
|
||||
@@ -513,9 +516,15 @@ class GlobalEventManager {
|
||||
console.log('👋 处理面板拖拽开始:', data);
|
||||
}
|
||||
|
||||
// 检查是否应该操作区域而非面板
|
||||
// 检查是否应该操作区域而非面板,并缓存结果
|
||||
const shouldOperateArea = this._shouldOperateAreaInsteadOfPanel(data);
|
||||
|
||||
// 缓存检测结果,用于后续的拖拽移动和结束事件
|
||||
this.dragOperationCache.set(data.dragId, {
|
||||
shouldOperateArea,
|
||||
timestamp: Date.now()
|
||||
});
|
||||
|
||||
if (shouldOperateArea) {
|
||||
// 转换为区域拖拽事件
|
||||
const areaDragStartData = {
|
||||
@@ -544,8 +553,9 @@ class GlobalEventManager {
|
||||
console.log('✋ 处理面板拖拽移动:', data);
|
||||
}
|
||||
|
||||
// 检查是否应该操作区域而非面板
|
||||
const shouldOperateArea = this._shouldOperateAreaInsteadOfPanel(data);
|
||||
// 从缓存中获取单面板检测结果,避免重复检测
|
||||
const cache = this.dragOperationCache.get(data.dragId);
|
||||
const shouldOperateArea = cache ? cache.shouldOperateArea : this._shouldOperateAreaInsteadOfPanel(data);
|
||||
|
||||
if (shouldOperateArea) {
|
||||
// 转换为区域拖拽移动事件
|
||||
@@ -574,8 +584,9 @@ class GlobalEventManager {
|
||||
console.log('✋ 处理面板拖拽结束:', data);
|
||||
}
|
||||
|
||||
// 检查是否应该操作区域而非面板
|
||||
const shouldOperateArea = this._shouldOperateAreaInsteadOfPanel(data);
|
||||
// 从缓存中获取单面板检测结果
|
||||
const cache = this.dragOperationCache.get(data.dragId);
|
||||
const shouldOperateArea = cache ? cache.shouldOperateArea : this._shouldOperateAreaInsteadOfPanel(data);
|
||||
|
||||
if (shouldOperateArea) {
|
||||
// 转换为区域拖拽结束事件
|
||||
@@ -593,6 +604,9 @@ class GlobalEventManager {
|
||||
status: 'ended'
|
||||
});
|
||||
}
|
||||
|
||||
// 清理缓存
|
||||
this.dragOperationCache.delete(data.dragId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -609,6 +623,9 @@ class GlobalEventManager {
|
||||
...data,
|
||||
status: 'cancelled'
|
||||
});
|
||||
|
||||
// 清理缓存
|
||||
this.dragOperationCache.delete(data.dragId);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -799,10 +816,10 @@ class GlobalEventManager {
|
||||
*/
|
||||
_startDebugMode() {
|
||||
// 监听调试命令
|
||||
eventBus.on('debug.toggle', () => {
|
||||
eventBus.on(EVENT_TYPES.DEBUG_TOGGLE, () => {
|
||||
this.debugMode = !this.debugMode;
|
||||
console.log(`🔧 调试模式${this.debugMode ? '开启' : '关闭'}`);
|
||||
});
|
||||
}, { componentId: 'global-event-manager' });
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1181,7 +1198,7 @@ export const globalEventActions = {
|
||||
* 切换调试模式
|
||||
*/
|
||||
toggleDebug: () => {
|
||||
eventBus.emit('debug.toggle');
|
||||
eventBus.emit(EVENT_TYPES.DEBUG_TOGGLE, {}, { componentId: 'global-event-manager' });
|
||||
},
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user