feat: mousearea, datetime dates, dir(), renpy.image_size and style.rebuild for Ren'Py games
CI / frontend (push) Failing after 19s
CI / backend (push) Failing after 40s

Screens get an invisible mousearea that reports the pointer entering and leaving without taking
clicks. datetime.date/datetime/timedelta support construction and date arithmetic. dir() lists the
game's variables, renpy.style.rebuild() is a no-op, and renpy.image_size answers only for pictures
the browser already holds (otherwise an IOError the game can catch).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
mrleo1nidandClaude Sonnet 5.5 committed 2026-10-26 03:02:13 +03:00
1 parent 6c10d06d90
commit 4dc9836a8b
7 files changed
+119 -4

No files matched your search

+21
View File
@@ -534,6 +534,7 @@ export class ScreenManager {
case "label": return this.text(node, ctx, ["text", "label_text"], this.ev(node.args[0]), "pg-slabel");
case "add": return this.add(node, ctx);
case "null": return this.nullWidget(node, ctx);
case "mousearea": return this.mouseArea(node, ctx);
case "bar":
case "vbar": return this.bar(node, ctx);
}
@@ -686,6 +687,26 @@ export class ScreenManager {
return el;
}
/** An invisible area that reports the pointer entering and leaving it, without taking clicks from what lies below. */
private mouseArea(node: any, ctx: Ctx): HTMLElement {
const el = document.createElement("div");
const props = this.resolve(node, ctx, []);
el.className = "pg-sw pg-snull";
el.style.pointerEvents = "none";
this.layout(el, props, ctx, { fill: false });
let inside = false;
const track = (ev: MouseEvent) => {
if (!el.isConnected) { document.removeEventListener("mousemove", track); return; }
const box = el.getBoundingClientRect();
const now = ev.clientX >= box.left && ev.clientX < box.right && ev.clientY >= box.top && ev.clientY < box.bottom;
if (now === inside) return;
inside = now;
this.run(this.ev(now ? props.hovered : props.unhovered), ctx.inst);
};
document.addEventListener("mousemove", track);
return el;
}
private add(node: any, ctx: Ctx): HTMLElement | null {
const value = this.ev(node.args[0]);
if (value === null || value === undefined) return null;