in web/src/app/common/resizable-pane/resizing-calculator.ts [114:221]
public resizeArea(
id: string,
sizeInPx: number,
ignoreMinimumSize: boolean = false,
): void {
const areas = this.areaStates.value.map((area) => ({
spec: area.spec,
currentSize: area.currentSize,
}));
const resizeTarget = areas.find((area) => area.spec.id === id);
if (!resizeTarget) {
return;
}
if (resizeTarget.currentSize === sizeInPx) {
return;
}
let restSizeDiff = sizeInPx - resizeTarget.currentSize;
if (restSizeDiff > 0) {
resizeTarget.currentSize = sizeInPx;
// expand specified area, shrink others
for (let i = 0; i < 100; i++) {
// calculate shrink info without the expanding target
const shrinkInfo = this.calculateShrinkableAreaInfo(
areas.filter((area) => area.spec.id !== id),
);
if (shrinkInfo.nextShrinkAreaId === '') {
resizeTarget.currentSize -= restSizeDiff;
break;
}
if (
restSizeDiff <
shrinkInfo.maxShrinkableSizeBeforeReachingMinSizeOfMinShrinkableArea
) {
// Resize can be done without reaching the minSize
let restSumOfShrinkRatio = shrinkInfo.sumOfShrinkableResizeRatio;
for (const area of areas) {
if (area.spec.resizeRatio === 0) continue;
if (area.spec.id === id) continue;
if (area.spec.minSizeInPx === area.currentSize) continue;
const shrinkSize = Math.floor(
(restSizeDiff / restSumOfShrinkRatio) * area.spec.resizeRatio,
);
area.currentSize -= shrinkSize;
restSizeDiff -= shrinkSize;
restSumOfShrinkRatio -= area.spec.resizeRatio;
}
break;
} else {
const areaReachingTheLimit = areas.find(
(area) => area.spec.id === shrinkInfo.nextShrinkAreaId,
)!;
const diff =
areaReachingTheLimit.currentSize -
areaReachingTheLimit.spec.minSizeInPx;
restSizeDiff -= diff;
areaReachingTheLimit.currentSize =
areaReachingTheLimit.spec.minSizeInPx;
let restSumOfShrinkRatio =
shrinkInfo.sumOfShrinkableResizeRatio -
areaReachingTheLimit.spec.resizeRatio;
let restSizeDiffInThisLoop =
shrinkInfo.maxShrinkableSizeBeforeReachingMinSizeOfMinShrinkableArea -
diff;
for (const area of areas) {
if (area.spec.resizeRatio === 0) continue;
if (area.spec.id === id) continue;
if (area.spec.minSizeInPx === area.currentSize) continue;
const shrinkSize = Math.floor(
(restSizeDiffInThisLoop / restSumOfShrinkRatio) *
area.spec.resizeRatio,
);
area.currentSize -= shrinkSize;
restSizeDiff -= shrinkSize;
restSizeDiffInThisLoop -= shrinkSize;
restSumOfShrinkRatio -= area.spec.resizeRatio;
}
}
}
} else {
// shrink specified area, expand others
if (sizeInPx < resizeTarget.spec.minSizeInPx && !ignoreMinimumSize) {
sizeInPx = resizeTarget.spec.minSizeInPx;
restSizeDiff = resizeTarget.currentSize - sizeInPx;
}
restSizeDiff = -restSizeDiff;
let restSumOfExpandRatio = areas.reduce(
(a, b) => a + b.spec.resizeRatio,
0,
);
restSumOfExpandRatio -= resizeTarget.spec.resizeRatio;
for (const area of areas) {
if (area.spec.resizeRatio === 0) continue;
if (area.spec.id === id) continue;
const expandSize = Math.floor(
(restSizeDiff / restSumOfExpandRatio) * area.spec.resizeRatio,
);
area.currentSize += expandSize;
restSizeDiff -= expandSize;
restSumOfExpandRatio -= area.spec.resizeRatio;
}
resizeTarget.currentSize = sizeInPx;
// If the rest of areas are not expandable
if (restSizeDiff > 0) {
resizeTarget.currentSize += restSizeDiff;
}
}
this.areaStates.next(areas);
}