responsive desktop: shrink icons on cramped viewports so they never collide; clamp windows to the viewport
This commit is contained in:
parent
9695452974
commit
194501e467
4 changed files with 136 additions and 9 deletions
|
|
@ -149,11 +149,15 @@ export default function WindowsDesktop() {
|
|||
const id = idRef.current++;
|
||||
const vw = window.innerWidth;
|
||||
const vh = window.innerHeight - TASKBAR_HEIGHT;
|
||||
// Fit the window to the viewport so it never opens off-screen or under the
|
||||
// panel on a narrow/short monitor.
|
||||
const w = Math.min(app.width, Math.max(260, vw - 20));
|
||||
const h = Math.min(app.height, Math.max(150, vh - 20));
|
||||
const cascade = Math.min(wins.length, 8) * 30;
|
||||
let x = Math.round((vw - app.width) / 2) + cascade;
|
||||
let y = Math.round((vh - app.height) / 2) + cascade;
|
||||
x = Math.max(10, Math.min(x, vw - app.width - 10));
|
||||
y = Math.max(10, Math.min(y, vh - app.height - 10));
|
||||
let x = Math.round((vw - w) / 2) + cascade;
|
||||
let y = Math.round((vh - h) / 2) + cascade;
|
||||
x = Math.max(10, Math.min(x, vw - w - 10));
|
||||
y = Math.max(10, Math.min(y, vh - h - 10));
|
||||
setWins((prev) => [
|
||||
...prev,
|
||||
{
|
||||
|
|
@ -161,8 +165,8 @@ export default function WindowsDesktop() {
|
|||
appId: app.id,
|
||||
x,
|
||||
y,
|
||||
w: app.width,
|
||||
h: app.height,
|
||||
w,
|
||||
h,
|
||||
z: ++zRef.current,
|
||||
minimized: false,
|
||||
maximized: false,
|
||||
|
|
@ -252,11 +256,43 @@ export default function WindowsDesktop() {
|
|||
);
|
||||
};
|
||||
const resizeWin = (id: number, x: number, y: number, w: number, h: number) => {
|
||||
const vw = typeof window !== "undefined" ? window.innerWidth : 1280;
|
||||
const vh = (typeof window !== "undefined" ? window.innerHeight : 800) - TASKBAR_HEIGHT;
|
||||
const nw = Math.min(w, Math.max(260, vw - 20));
|
||||
const nh = Math.min(h, Math.max(150, vh - 20));
|
||||
setWins((prev) =>
|
||||
prev.map((win) => (win.id === id ? { ...win, centered: false, x, y, w, h } : win))
|
||||
prev.map((win) =>
|
||||
win.id === id ? { ...win, centered: false, x, y, w: nw, h: nh } : win
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
// Keep windows on-screen when the viewport shrinks (narrow monitor, or the
|
||||
// user resizing the browser): clamp size to the viewport and pull anything
|
||||
// that would fall off the edge back into view.
|
||||
useEffect(() => {
|
||||
const clampToViewport = () => {
|
||||
const vw = window.innerWidth;
|
||||
const vh = window.innerHeight - TASKBAR_HEIGHT;
|
||||
setWins((prev) =>
|
||||
prev.map((w) => {
|
||||
if (w.maximized) return w;
|
||||
const nw = Math.min(w.w, Math.max(260, vw - 20));
|
||||
const nh = Math.min(w.h, Math.max(150, vh - 20));
|
||||
if (w.centered) {
|
||||
return nw === w.w && nh === w.h ? w : { ...w, w: nw, h: nh };
|
||||
}
|
||||
const nx = Math.max(10, Math.min(w.x, vw - nw - 10));
|
||||
const ny = Math.max(10, Math.min(w.y, vh - nh - 10));
|
||||
if (nw === w.w && nh === w.h && nx === w.x && ny === w.y) return w;
|
||||
return { ...w, x: nx, y: ny, w: nw, h: nh };
|
||||
})
|
||||
);
|
||||
};
|
||||
window.addEventListener("resize", clampToViewport);
|
||||
return () => window.removeEventListener("resize", clampToViewport);
|
||||
}, []);
|
||||
|
||||
const taskbarClick = (w: WinState) => {
|
||||
if (w.minimized) {
|
||||
setWins((prev) =>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue