91 lines
2.5 KiB
TypeScript
91 lines
2.5 KiB
TypeScript
import { AlignX, AlignY, Point, Rect, Size } from "./engine/datatypes.ts";
|
|
import { D } from "./engine/public.ts";
|
|
import { getHud } from "./hud.ts";
|
|
import { getHotbar } from "./hotbar.ts";
|
|
|
|
// general
|
|
let margin = 8;
|
|
export function getLayoutRect(
|
|
size: Size,
|
|
options?: { alignX?: AlignX; alignY?: AlignY },
|
|
): Rect {
|
|
let { w: screenW, h: screenH } = D.size;
|
|
|
|
// first of all: place the _internal_ screen inside the real screen
|
|
let marginalScreenW = screenW - margin * 2;
|
|
let marginalScreenH = screenH - margin * 2;
|
|
let marginalScreenX = margin;
|
|
let marginalScreenY = margin;
|
|
|
|
// NOTE: If the screen is too small, remainingSpace will be negative
|
|
// This is fine -- it actually results in reasonable outcomes except
|
|
// that the size of the box is exceeded in the opposite of the align direction.
|
|
let { w: innerW, h: innerH } = size;
|
|
let remainingSpaceX = marginalScreenW - innerW;
|
|
let remainingSpaceY = marginalScreenH - innerH;
|
|
|
|
let alignXCoef =
|
|
options?.alignX == AlignX.Left
|
|
? 0.0
|
|
: options?.alignX == AlignX.Center
|
|
? 0.5
|
|
: options?.alignX == AlignX.Right
|
|
? 1.0
|
|
: 0.5;
|
|
let alignYCoef =
|
|
options?.alignY == AlignY.Top
|
|
? 0.0
|
|
: options?.alignY == AlignY.Middle
|
|
? 0.5
|
|
: options?.alignY == AlignY.Bottom
|
|
? 1.0
|
|
: 0.5;
|
|
|
|
let x = marginalScreenX + alignXCoef * remainingSpaceX;
|
|
let y = marginalScreenY + alignYCoef * remainingSpaceY;
|
|
|
|
return new Rect(new Point(Math.floor(x), Math.floor(y)), size);
|
|
}
|
|
|
|
export function withCamera(part: UIPart, cb: () => void) {
|
|
let region = getPartLocation(part);
|
|
|
|
D.withCamera(D.camera.offset(region.top.negate()), cb);
|
|
}
|
|
|
|
// specific
|
|
export type UIPart =
|
|
| "BottomModal"
|
|
| "FullscreenPopover"
|
|
| "Hotbar"
|
|
| "HUD"
|
|
| "Gameplay"
|
|
| "Thralls";
|
|
|
|
|
|
export function getPartLocation(part: UIPart) {
|
|
switch (part) {
|
|
case "BottomModal":
|
|
return getLayoutRect(new Size(384, 128), {
|
|
alignX: AlignX.Center,
|
|
alignY: AlignY.Bottom,
|
|
});
|
|
case "FullscreenPopover":
|
|
return getLayoutRect(new Size(384, 384));
|
|
case "Gameplay":
|
|
case "Thralls":
|
|
return getLayoutRect(new Size(384, 384));
|
|
case "Hotbar":
|
|
return getLayoutRect(getHotbar().size, {
|
|
alignX: AlignX.Center,
|
|
alignY: AlignY.Bottom,
|
|
});
|
|
case "HUD":
|
|
return getLayoutRect(getHud().size, {
|
|
alignX: AlignX.Left,
|
|
alignY: AlignY.Top,
|
|
});
|
|
}
|
|
throw `not sure what layout rect to use ${part}`;
|
|
}
|