增加重算列表

This commit is contained in:
JoyD
2025-10-27 22:03:58 +08:00
parent 88c90a3afc
commit ba9a9e99b7
4 changed files with 2654 additions and 19 deletions

View File

@@ -131,6 +131,8 @@ export const useDockPanelStore = defineStore('dockPanel', () => {
center: ref([])
}
}
// 全局:待重算的区域队列(去重)
const pendingRecompute = new Set();
// 根据面板ID获取面板位置
function getPanelPositionById(panelId) {
@@ -193,57 +195,102 @@ export const useDockPanelStore = defineStore('dockPanel', () => {
// 获取全局容器元素只查询一次DOM
const container = document.querySelector('.dock-panel-container');
// 辅助:获取区域对象
function getAreaByPos(pos) {
return pos === 'left' ? leftPanelArea.value
: pos === 'right' ? rightPanelArea.value
: pos === 'top' ? topPanelArea.value
: pos === 'bottom' ? bottomPanelArea.value
: pos === 'center' ? centerPanelArea.value
: null;
}
// 辅助:获取受影响的区域列表
function impactedBy(position) {
const map = panelSizeInfluence.value?.influencedBy || {};
return Object.keys(map).filter(pos => {
const arr = map[pos] || [];
return arr.some(item => item.influence && item.position === position);
});
}
// 队列入列
function enqueueRecompute(...positions) {
positions.filter(Boolean).forEach(p => pendingRecompute.add(p));
}
// 处理队列
function processRecomputeQueue(externalContainer, sizes = minSizes) {
if (!externalContainer) return;
let guard = 0;
while (pendingRecompute.size > 0 && guard < 20) {
guard++;
const iterator = pendingRecompute.values();
const current = iterator.next().value;
pendingRecompute.delete(current);
// 先整体更新边界
handlePanelSizeInfluence(current, externalContainer);
// 更新当前区域的子面板尺寸
const currentArea = getAreaByPos(current);
if (currentArea) {
updatePanelsSize(current, currentArea, externalContainer, sizes);
}
// 将受影响区域入队并更新其子面板尺寸
const impacted = impactedBy(current);
impacted.forEach(pos => {
const area = getAreaByPos(pos);
if (area) {
updatePanelsSize(pos, area, externalContainer, sizes);
pendingRecompute.add(pos);
}
});
}
}
switch (panel.position) {
case 'left':
const isLeftFirst = leftPanels.value.length === 0
leftPanelArea.value.panels.push(panelData)
resetPanelsSizeRatios('left')
// 使用全局容器元素更新面板尺寸和绝对位置
if (container) {
updatePanelsSize('left', leftPanelArea.value, container, minSizes);
}
if (isLeftFirst) {
// 触发左侧面板的尺寸影响处理,传入容器引用避免重复查询
handlePanelSizeInfluence('left', container)
enqueueRecompute('left');
processRecomputeQueue(container, minSizes);
}
break
case 'right':
const isRightFirst = rightPanels.value.length === 0
rightPanelArea.value.panels.push(panelData)
resetPanelsSizeRatios('right')
// 使用全局容器元素更新面板尺寸和绝对位置
if (container) {
updatePanelsSize('right', rightPanelArea.value, container, minSizes);
}
if (isRightFirst) {
// 触发右侧面板的尺寸影响处理,传入容器引用避免重复查询
handlePanelSizeInfluence('right', container)
enqueueRecompute('right');
processRecomputeQueue(container, minSizes);
}
break
case 'top':
const isTopFirst = topPanels.value.length === 0
topPanelArea.value.panels.push(panelData)
resetPanelsSizeRatios('top')
// 使用全局容器元素更新面板尺寸和绝对位置
if (container) {
updatePanelsSize('top', topPanelArea.value, container, minSizes);
}
if (isTopFirst) {
// 触发顶部面板的尺寸影响处理,传入容器引用避免重复查询
handlePanelSizeInfluence('top', container)
enqueueRecompute('top');
processRecomputeQueue(container, minSizes);
}
break
case 'bottom':
const isBottomFirst = bottomPanels.value.length === 0
bottomPanelArea.value.panels.push(panelData)
resetPanelsSizeRatios('bottom')
// 使用全局容器元素更新面板尺寸和绝对位置
if (container) {
updatePanelsSize('bottom', bottomPanelArea.value, container, minSizes);
}
if (isBottomFirst) {
// 触发底部面板的尺寸影响处理,传入容器引用避免重复查询
handlePanelSizeInfluence('bottom', container)
enqueueRecompute('bottom');
processRecomputeQueue(container, minSizes);
}
break
case 'center':
@@ -363,7 +410,9 @@ export const useDockPanelStore = defineStore('dockPanel', () => {
}
// 如果面板区域变为空,触发尺寸影响处理以更新其他区域
if (panels.length === 0) {
handlePanelSizeInfluence(position, container);
// 入队并批量重算,直到队列为空
enqueueRecompute(position);
processRecomputeQueue(container, { panelWidth: 150, panelHeight: 100 });
}
// 处理中心面板的特殊逻辑