securityos/components/system/Window/functions.ts

128 lines
3.4 KiB
TypeScript
Raw Normal View History

2024-09-06 15:32:35 +00:00
import {
MIN_WINDOW_HEIGHT,
MIN_WINDOW_WIDTH,
} from "components/system/Window/RndWindow/rndDefaults";
import type { Size } from "components/system/Window/RndWindow/useResizable";
import type { Processes } from "contexts/process/types";
import type { WindowState } from "contexts/session/types";
import type { Position } from "react-rnd";
import { PROCESS_DELIMITER, TASKBAR_HEIGHT } from "utils/constants";
import { pxToNum, viewHeight, viewWidth } from "utils/functions";
export const cascadePosition = (
id: string,
processes: Processes,
stackOrder: string[] = [],
offset = 0
): Position | undefined => {
const [pid] = id.split(PROCESS_DELIMITER);
const processPid = `${pid}${PROCESS_DELIMITER}`;
const parentPositionProcess =
stackOrder.find((stackPid) => stackPid.startsWith(processPid)) || "";
const { componentWindow } = processes?.[parentPositionProcess] || {};
const {
x = 0,
y = 0,
width = 0,
height = 0,
} = componentWindow?.getBoundingClientRect() || {};
const isOffscreen =
x + offset + width > viewWidth() || y + offset + height > viewHeight();
return !isOffscreen && (x || y)
? {
x: x + offset,
y: y + offset,
}
: undefined;
};
export const centerPosition = ({ height, width }: Size): Position => {
const [vh, vw] = [viewHeight(), viewWidth()];
return {
x: Math.floor(vw / 2 - pxToNum(width) / 2),
y: Math.floor((vh - TASKBAR_HEIGHT) / 2 - pxToNum(height) / 2),
};
};
export const WINDOW_OFFSCREEN_BUFFER_PX = {
BOTTOM: 15,
LEFT: 150,
RIGHT: 50,
TOP: 15,
};
export const isWindowOutsideBounds = (
windowState: WindowState,
bounds: Position,
checkOffscreen = false
): boolean => {
const { position, size } = windowState || {};
const { x = 0, y = 0 } = position || {};
const { height = 0, width = 0 } = size || {};
if (checkOffscreen) {
return (
x + WINDOW_OFFSCREEN_BUFFER_PX.RIGHT > bounds.x ||
x + pxToNum(width) - WINDOW_OFFSCREEN_BUFFER_PX.LEFT < 0 ||
y + WINDOW_OFFSCREEN_BUFFER_PX.BOTTOM > bounds.y ||
y + WINDOW_OFFSCREEN_BUFFER_PX.TOP < 0
);
}
return (
x < 0 ||
y < 0 ||
x + pxToNum(width) > bounds.x ||
y + pxToNum(height) > bounds.y
);
};
export const minMaxSize = (size: Size, lockAspectRatio: boolean): Size => {
const desiredHeight = Number(size.height);
const desiredWidth = Number(size.width);
const [vh, vw] = [viewHeight(), viewWidth()];
const vhWithoutTaskbar = vh - TASKBAR_HEIGHT;
const height = Math.max(
MIN_WINDOW_HEIGHT,
Math.min(desiredHeight, vhWithoutTaskbar)
);
const width = Math.max(MIN_WINDOW_WIDTH, Math.min(desiredWidth, vw));
if (!lockAspectRatio) return { height, width };
const isDesiredHeight = desiredHeight === height;
const isDesiredWidth = desiredWidth === width;
if (!isDesiredHeight && !isDesiredWidth) {
if (desiredHeight > desiredWidth) {
return {
height,
width: Math.round(width / (vhWithoutTaskbar / height)),
};
}
return {
height: Math.round(height / (vw / width)),
width,
};
}
if (!isDesiredHeight) {
return {
height,
width: Math.round(width / (desiredHeight / height)),
};
}
if (!isDesiredWidth) {
return {
height: Math.round(height / (desiredWidth / width)),
width,
};
}
return { height, width };
};