UI

Sprites, text, and touch areas.

Interface is ordinary scene content: sprites, text, and touch. Put HUD and menus in a scene with no camera so they draw over the whole screen and do not scroll. Types below are in WillEngine.Core.Components unless noted.

Touch

Only touch areas receive pointers. A sprite by itself does not. The areas are TouchBox and TouchImage. A pointer hits areas front to back, scenes by draw order. The first area under the point takes it, unless that area has PassThrough, in which case areas behind it are tested too. An area covered by a MaskArea on an ancestor is hit only when the point is inside every mask — a button scrolled out of a scroll view receives nothing. A scene at opacity 0 receives nothing.

Once pressed, an area keeps that pointer until release, so drag and click still arrive after the pointer leaves. Phases, in order: Enter or Exit, Down, DragStart after the drag threshold (3 canvas pixels unless game.json says otherwise), Drag, then on release Up plus either Click or DragEnd. Cancel means a surrounding ScrollView took the press.

TouchData carries the phase, the pointer id (0 is the mouse), screen position, and world position. Delivery is the area’s Inspector bindings, then code listeners, then any UiControl on the same object.

Controls

Button, Toggle, ToggleGroup, Slider, ProgressBar, and ScrollView derive from UiControl. They listen to the touch area on their own object. On Initialize, a control adds a TouchBox fitted to the picture when the object has none.

Button and Toggle are selectables. Looks are UiLook values — a sprite GUID and an optional palette — for Hover, Pressed, and Disabled. Interactable = false shows the disabled look and ignores clicks. Children (a label, an icon) nudge by PressOffset, default (0, 1), while held.

Owner.GetComponent<Button>().Clicked += button => StartGame();

Click() fires the same path from code when the button is interactable. A Toggle has IsOn, an optional check mark, and an on-look. A ToggleGroup on a parent makes the toggles under it a radio set.

A ProgressBar shows Value between Min and Max by masking a Fill object. A Slider is a progress bar you drag: the touch area is the track, and an optional Handle moves with the value. A ScrollView moves its Content under a mask. A drag that starts on a button inside it cancels that press (no click) and scrolls; a tap still clicks.

Masks and drawing from code

A MaskArea clips what is drawn under it and what can be touched. Use it for a scroll window or a portrait frame. For pixels that are not a sprite, add a PixelRenderer and draw in OnDraw during the render pass. Keep that work free of per-pixel allocation; the frame is already an indexed buffer.