ui/phase-13: planet inspector — read-only

Plumbs the map → inspector pathway: a click on a planet selects it
through the new SelectionStore, the sidebar Inspector tab swaps
its empty-state copy for a per-kind read-only field set, and a
mobile-only bottom-sheet mirrors the same content over the map.
Field projection in api/game-state.ts now surfaces every documented
planet field.
This commit is contained in:
Ilia Denisov
2026-05-09 08:29:03 +02:00
parent a3fdcfe9c5
commit 6364bba6fd
19 changed files with 1440 additions and 75 deletions
+21
View File
@@ -58,6 +58,18 @@ export interface RendererHandle {
getViewport(): Viewport;
getBackend(): "webgl" | "webgpu" | "canvas";
hitAt(cursorPx: { x: number; y: number }): Hit | null;
/**
* onClick subscribes `cb` to a click on the map (a pointer-down /
* pointer-up pair without enough drag to trigger pan). The cursor
* is reported in canvas pixel coordinates so callers can hand it
* straight to `hitAt`. Returns a function that detaches the
* listener; the returned disposer is idempotent.
*
* Built on `pixi-viewport`'s `clicked` event, which already
* applies the same drag threshold the pan plugin uses, so a
* click here will not race a pan gesture.
*/
onClick(cb: (cursorPx: { x: number; y: number }) => void): () => void;
resize(widthPx: number, heightPx: number): void;
dispose(): void;
}
@@ -222,6 +234,15 @@ export async function createRenderer(opts: RendererOptions): Promise<RendererHan
getBackend: () => rendererBackendName(app.renderer),
hitAt: (cursorPx) =>
hitTest(opts.world, handle.getCamera(), handle.getViewport(), cursorPx, mode),
onClick: (cb) => {
const handler = (e: { screen: { x: number; y: number } }): void => {
cb({ x: e.screen.x, y: e.screen.y });
};
viewport.on("clicked", handler);
return () => {
viewport.off("clicked", handler);
};
},
resize: (w, h) => {
app.renderer.resize(w, h);
viewport.resize(w, h, opts.world.width, opts.world.height);