mirror of
https://github.com/Syngnat/GoNavi.git
synced 2026-07-21 21:01:55 +08:00
90 lines
2.9 KiB
TypeScript
90 lines
2.9 KiB
TypeScript
export type WindowRestoreBounds = {
|
|
width: number;
|
|
height: number;
|
|
x: number;
|
|
y: number;
|
|
};
|
|
|
|
type VisibleViewport = {
|
|
availWidth: number;
|
|
availHeight: number;
|
|
availLeft?: number;
|
|
availTop?: number;
|
|
};
|
|
|
|
const MIN_VISIBLE_WIDTH = 160;
|
|
const MIN_VISIBLE_HEIGHT = 120;
|
|
const MIN_RESTORED_WIDTH = 400;
|
|
const MIN_RESTORED_HEIGHT = 300;
|
|
|
|
const resolveVisibleDimension = (
|
|
rawDimension: number,
|
|
visibleDimension: number,
|
|
minimumDimension: number,
|
|
): number => {
|
|
const dimension = Math.trunc(Number(rawDimension) || 0);
|
|
if (visibleDimension <= 0 || dimension <= 0) {
|
|
return dimension;
|
|
}
|
|
const minimum = Math.min(minimumDimension, visibleDimension);
|
|
return Math.min(Math.max(dimension, minimum), visibleDimension);
|
|
};
|
|
|
|
const clampPosition = (
|
|
position: number,
|
|
dimension: number,
|
|
visibleStart: number,
|
|
visibleDimension: number,
|
|
): number => {
|
|
const maxPosition = visibleStart + Math.max(0, visibleDimension - dimension);
|
|
return Math.min(Math.max(position, visibleStart), maxPosition);
|
|
};
|
|
|
|
export const resolveVisibleStartupWindowBounds = (
|
|
bounds: WindowRestoreBounds,
|
|
viewport: VisibleViewport,
|
|
): WindowRestoreBounds => {
|
|
const visibleWidth = Math.trunc(Number(viewport.availWidth) || 0);
|
|
const visibleHeight = Math.trunc(Number(viewport.availHeight) || 0);
|
|
if (visibleWidth <= 0 || visibleHeight <= 0) {
|
|
return bounds;
|
|
}
|
|
|
|
const visibleLeft = Math.trunc(Number(viewport.availLeft) || 0);
|
|
const visibleTop = Math.trunc(Number(viewport.availTop) || 0);
|
|
const visibleRight = visibleLeft + visibleWidth;
|
|
const visibleBottom = visibleTop + visibleHeight;
|
|
const nextWidth = resolveVisibleDimension(bounds.width, visibleWidth, MIN_RESTORED_WIDTH);
|
|
const nextHeight = resolveVisibleDimension(bounds.height, visibleHeight, MIN_RESTORED_HEIGHT);
|
|
const resizedBounds: WindowRestoreBounds = {
|
|
...bounds,
|
|
width: nextWidth,
|
|
height: nextHeight,
|
|
};
|
|
|
|
const overlapWidth = Math.min(resizedBounds.x + resizedBounds.width, visibleRight) - Math.max(resizedBounds.x, visibleLeft);
|
|
const overlapHeight = Math.min(resizedBounds.y + resizedBounds.height, visibleBottom) - Math.max(resizedBounds.y, visibleTop);
|
|
const sizeChanged = resizedBounds.width !== bounds.width || resizedBounds.height !== bounds.height;
|
|
if (
|
|
!sizeChanged &&
|
|
overlapWidth >= Math.min(MIN_VISIBLE_WIDTH, bounds.width) &&
|
|
overlapHeight >= Math.min(MIN_VISIBLE_HEIGHT, bounds.height)
|
|
) {
|
|
return bounds;
|
|
}
|
|
|
|
if (sizeChanged && overlapWidth > 0 && overlapHeight > 0) {
|
|
return {
|
|
...resizedBounds,
|
|
x: clampPosition(resizedBounds.x, resizedBounds.width, visibleLeft, visibleWidth),
|
|
y: clampPosition(resizedBounds.y, resizedBounds.height, visibleTop, visibleHeight),
|
|
};
|
|
}
|
|
|
|
return {
|
|
...resizedBounds,
|
|
x: visibleLeft + Math.max(0, Math.trunc((visibleWidth - resizedBounds.width) / 2)),
|
|
y: visibleTop + Math.max(0, Math.trunc((visibleHeight - resizedBounds.height) / 2)),
|
|
};
|
|
};
|