Skip to content

GUI controls clientside ​

Graal-style GUI controls: windows, buttons, text, images, scroll views and events (weapons/gui.client.d.ts).

Source

Generated from templates/server/data/scripts/weapons/gui.client.d.ts. To change this page, edit the JSDoc in that file.

Overview ​

Graal-style GUI controls, backed by Gum on the client.

Creation and property writes batch through the command dispatcher: each control costs one guicreate plus at most one guiset per flush window, no matter how many properties are assigned. Reads of text/x/y/width/height/ visible are live from the host once the control exists (end of the creating tick); before that, reads return what you wrote.

Every control is also published as a global under its name, so Login_Window.hide() works like classic GS2 — prefix control names with your weapon's name to avoid collisions with other weapons.

Controls are destroyed automatically when the weapon that created them is unloaded or reloaded. The exception: controls created from setTimeout / setInterval callbacks are only swept on disconnect, so prefer building UI in onCreated or event handlers.

New controls attach to the screen root by default (no window needed). findobj('GameControl') returns a pseudo-control for the game screen itself: GameControl.addControl(ctrl) makes root parenting explicit and also moves a control back out of a window.

Declarations ​

GuiMouseButton type ​

ts
type GuiMouseButton = 'left' | 'right' | 'middle'

Which physical mouse button an event came from.

GuiButtonEvent interface ​

ts
interface GuiButtonEvent

Payload of click/doubleclick/mousedown/mouseup. x/y are relative to the control's top-left.

GuiButtonEvent.button ​

ts
button: GuiMouseButton

GuiButtonEvent.x ​

ts
x: number

GuiButtonEvent.y ​

ts
y: number

GuiMoveEvent interface ​

ts
interface GuiMoveEvent

Payload of mousemove/mouseenter/mouseleave. x/y are relative to the control's top-left.

GuiMoveEvent.x ​

ts
x: number

GuiMoveEvent.y ​

ts
y: number

GuiWheelEvent interface ​

ts
interface GuiWheelEvent

Payload of mousewheel. delta is in wheel notches, positive = scroll up.

GuiWheelEvent.delta ​

ts
delta: number

GuiWheelEvent.x ​

ts
x: number

GuiWheelEvent.y ​

ts
y: number

GuiKeyEvent interface ​

ts
interface GuiKeyEvent

Payload of keydown/keyup. key uses the same names as the global keydown() helper: lowercase MonoGame Keys names ("a", "enter", "space", "escape", "leftshift"), digits as "0".."9".

GuiKeyEvent.key ​

ts
key: string

GuiKeyEvent.shift ​

ts
shift: boolean

Whether either shift key is held at event time.

GuiKeyEvent.control ​

ts
control: boolean

Whether either control key is held at event time.

GuiEventMap interface ​

ts
interface GuiEventMap

Events a control can emit, keyed by name, for control.on(event, handler). The handler receives the mapped event object.

GuiEventMap.click ​

ts
click: GuiButtonEvent

Press and release on this control (any button — check e.button).

GuiEventMap.doubleclick ​

ts
doubleclick: GuiButtonEvent

Press and release on this control (any button — check e.button).

GuiEventMap.mousedown ​

ts
mousedown: GuiButtonEvent

Press and release on this control (any button — check e.button).

GuiEventMap.mouseup ​

ts
mouseup: GuiButtonEvent

Fires on the control(s) the press started on, even if the cursor moved off.

GuiEventMap.mousemove ​

ts
mousemove: GuiMoveEvent

Fires on the control(s) the press started on, even if the cursor moved off.

GuiEventMap.mouseenter ​

ts
mouseenter: GuiMoveEvent

Fires on the control(s) the press started on, even if the cursor moved off.

GuiEventMap.mouseleave ​

ts
mouseleave: GuiMoveEvent

Fires on the control(s) the press started on, even if the cursor moved off.

GuiEventMap.mousewheel ​

ts
mousewheel: GuiWheelEvent

Fires on the control(s) the press started on, even if the cursor moved off.

GuiEventMap.keydown ​

ts
keydown: GuiKeyEvent

Fires while this control (or a child of it, e.g. a textedit inside a listening panel) has keyboard focus — click a textedit to focus it. Edge-triggered per key press, no auto-repeat. Keys still reach the control itself (Enter won't insert into a textedit, but letters do).

GuiEventMap.keyup ​

ts
keyup: GuiKeyEvent

Key released while this control (or a child) has keyboard focus. See keydown.

GuiControl class ​

ts
declare abstract class GuiControl

Base of all GUI controls. Use a concrete Gui*Ctrl subclass.

GuiControl.name ​

ts
readonly name: string

The registry name the control was created with.

GuiControl.x ​

ts
x: number

The registry name the control was created with.

GuiControl.y ​

ts
y: number

The registry name the control was created with.

GuiControl.width ​

ts
width: number

The registry name the control was created with.

GuiControl.height ​

ts
height: number

The registry name the control was created with.

GuiControl.absx ​

ts
readonly absx: number

Screen-absolute position (live read) — for hit-testing mouse coordinates, wherever the control sits.

GuiControl.absy ​

ts
readonly absy: number

Screen-absolute position (live read) — for hit-testing mouse coordinates, wherever the control sits.

GuiControl.position ​

ts
position: string

"x,y" — write-only convenience that sets x and y.

GuiControl.extent ​

ts
extent: string

"w,h" — write-only convenience that sets width and height.

GuiControl.visible ​

ts
visible: boolean

"w,h" — write-only convenience that sets width and height.

GuiControl.profile ​

ts
profile: string

Accepted for GS2 compatibility; styling profiles are not implemented yet.

GuiControl.show ​

ts
show(): void

Accepted for GS2 compatibility; styling profiles are not implemented yet.

GuiControl.hide ​

ts
hide(): void

Accepted for GS2 compatibility; styling profiles are not implemented yet.

GuiControl.bringtofront ​

ts
bringtofront(): void

Moves the control above its siblings (the last one drawn wins): a screen-level control goes on top of every other screen-level control, a child on top of the other children of its parent. Its own children come along with it.

GuiControl.destroy ​

ts
destroy(): void

Removes the control (and any children added via addControl) for good.

GuiControl.addControl ​

ts
addControl(child: GuiControl): void

Parents child inside this control. Children are positioned relative to the parent's top-left corner — for windows that includes the title bar (GS2-style), so start content at y ≈ 40 to clear it.

GuiControl.skin ​

ts
skin: string

Server image asset used as a 9-slice skin (e.g. "gui/fancywindow.png"), replacing the default themed look: corners render 1:1, edges and the center stretch. Fetched through the asset cache; the first use may pop in a moment later, later uses of a loaded image apply instantly. Set '' to return to the default look. Windows: the skin covers the whole frame including the title-bar area. Labels and image controls ignore skins.

GuiControl.skinrect ​

ts
skinrect: string

"left,top,width,height" in pixels — sub-region of the skin texture to use (atlas support). Defaults to the whole image.

GuiControl.on ​

ts
on<K extends keyof GuiEventMap>(event: K, listener: (e: GuiEventMap[K]) => void): this

Listens for a mouse event on this control. Works on every control kind. Events bubble: a click on a child (e.g. an image inside a panel) also fires on its parents, deepest control first. Multiple listeners per event are called in registration order. Returns the control for chaining.

GuiControl.off ​

ts
off<K extends keyof GuiEventMap>(event: K, listener?: (e: GuiEventMap[K]) => void): void

Removes a listener added with on(); with no listener, removes all for that event.

GuiControl.skinborder ​

ts
skinborder: number

9-slice border thickness in source-image pixels. Unset = one third of the region per border; 0 = stretch the whole region (no borders).

GuiWindowCtrl class ​

ts
declare class GuiWindowCtrl extends GuiControl

A draggable window with a title bar.

GuiWindowCtrl.constructor ​

ts
constructor(name: string)

GuiWindowCtrl.text ​

ts
text: string

Title bar text.

GuiWindowCtrl.color ​

ts
color: string

"r,g,b" or "r,g,b,a" (0-255) tint multiplied into the window's frame, preserving the 9-slice: a white skin renders in exactly this color; without a skin it tints the default themed look. Survives setting or clearing the skin. Set '' to remove the tint again.

GuiWindowCtrl.clientextent ​

ts
clientextent: string

"w,h" — alias of extent, for GS2 compatibility.

GuiWindowCtrl.canmove ​

ts
canmove: boolean

Accepted for GS2 compatibility; windows always drag by their title bar.

GuiWindowCtrl.canresize ​

ts
canresize: boolean

Accepted for GS2 compatibility; windows always drag by their title bar.

GuiButtonCtrl class ​

ts
declare class GuiButtonCtrl extends GuiControl

A clickable push button with a text caption; listen with .on('click', ...).

GuiButtonCtrl.constructor ​

ts
constructor(name: string)

GuiButtonCtrl.text ​

ts
text: string

GuiButtonCtrl.skinrecthover ​

ts
skinrecthover: string

"left,top,width,height" skin region shown while the mouse hovers. With a skin but no per-state rects, hover/press auto-lighten/darken the skin instead; setting either state rect switches to untinted rect-swapping (unset states fall back: pressed -> hover -> skinrect).

GuiButtonCtrl.skinrectpressed ​

ts
skinrectpressed: string

"left,top,width,height" skin region shown while pressed. See skinrecthover.

GuiButtonCtrl.onAction ​

ts
onAction?: () => void

Fired when the button is clicked. Deprecated — use on('click', ...) instead.

GuiTextCtrl class ​

ts
declare class GuiTextCtrl extends GuiControl

A static text label. Auto-sizes to its text until width/height are set explicitly; set width when using the 'c' style so there is a box to center within.

GuiTextCtrl.constructor ​

ts
constructor(name: string)

GuiTextCtrl.text ​

ts
text: string

GuiTextCtrl.font ​

ts
font: string

Font family. Defaults to 'opensans', which ships with the client; other names try the system's fonts and degrade to Gum's embedded font when not found. Set '' to return to the opensans default.

GuiTextCtrl.fontsize ​

ts
fontsize: number

Text size in points (1-256); the font is re-rasterized, so it stays crisp at any size. Default 18.

GuiTextCtrl.style ​

ts
style: string

Any combination of 'b'old, 'i'talic, 'c'entered, in any order — same grammar as findimg's style. 'c' centers the text within the control's width; '' resets to plain left-aligned.

GuiTextCtrl.color ​

ts
color: string

"r,g,b" or "r,g,b,a" (0-255) text color; white until set.

GuiTextEditCtrl class ​

ts
declare class GuiTextEditCtrl extends GuiControl

A single-line text input.

GuiTextEditCtrl.constructor ​

ts
constructor(name: string)

GuiTextEditCtrl.text ​

ts
text: string

GuiTextEditCtrl.placeholder ​

ts
placeholder: string

Hint text shown while the field is empty.

GuiTextEditCtrl.password ​

ts
password: boolean

Set true in the creating tick to make this a masked password field; it has no effect once the control exists.

GuiTextEditCtrl.onTextChanged ​

ts
onTextChanged?: (text: string) => void

Fired when the user edits the text.

GuiPanelCtrl class ​

ts
declare class GuiPanelCtrl extends GuiControl

A grouping container. Invisible by default; give it a color and/or a border to draw it. The border straddles the panel's edge and is drawn over the fill; borderradius rounds both. Children are not clipped to the rounded shape.

GuiPanelCtrl.constructor ​

ts
constructor(name: string)

GuiPanelCtrl.color ​

ts
color: string

"r,g,b" or "r,g,b,a" (0-255) background fill. Set '' to remove the fill again.

GuiPanelCtrl.bordersize ​

ts
bordersize: number

Border thickness in pixels; 0 (the default) means no border.

GuiPanelCtrl.bordercolor ​

ts
bordercolor: string

"r,g,b" or "r,g,b,a" (0-255) border color; black until set.

GuiPanelCtrl.borderradius ​

ts
borderradius: number

Corner rounding radius in pixels for the fill and border; 0 = square.

GuiImageCtrl class ​

ts
declare class GuiImageCtrl extends GuiControl

Displays (a region of) a server image asset, e.g. a tileset. The region selected by imagerect stretches to the control's extent: extent == region size shows it 1:1, double extent shows it at 2x zoom.

Live reads of absx/absy (screen-absolute position, e.g. TE_Palette.absx) exist on every control for hit-testing mouse coordinates, which matters once the control sits inside a draggable window.

GuiImageCtrl.constructor ​

ts
constructor(name: string)

GuiImageCtrl.image ​

ts
image: string

Server asset name, e.g. "images/pics1.png". Fetched through the asset cache; the first use may pop in a moment later, later uses of a loaded image apply instantly. Set '' for a solid rectangle in the tint color (e.g. a highlight overlay).

GuiImageCtrl.imagerect ​

ts
imagerect: string

"left,top,width,height" in pixels — the source region of the image to show. Defaults to the whole image.

GuiImageCtrl.tint ​

ts
tint: string

"r,g,b" (0-255) color multiplier; "255,255,255" is unchanged.

GuiImageCtrl.alpha ​

ts
alpha: number

0 (invisible) .. 1 (opaque).

GuiImageCtrl.scale ​

ts
scale: number

Zooms the whole control, image or actor included: on screen it is width * scale by height * scale. width/height, actor.x/y and mouse event x/y all stay in the unscaled units, so extent = '32,48' with scale = 2 shows 64x96 while clicks still report 0..32, 0..48. Default 1.

GuiImageCtrl.onClick ​

ts
onClick?: (pos: string) => void

Fired on mouse press over the control; pos is "x,y" relative to its top-left. Deprecated — use on('mousedown', ...) instead.

GuiImageCtrl.actor ​

ts
get actor(): GuiActor
set actor(value: Partial<GuiActor> | null)

Draws a gani character instead of image. Setting any field turns the actor on (unset fields keep their defaults); actor = null turns it off and brings the image back. Assigning an object sets the whole actor at once: pic.actor = { ani: 'walk', dir: 'left' }.

The gani's origin sits at the control's top-left, zoomed by scale, shifted by actor.x/actor.y; anything outside the extent is cut off (a stock idle character (head drawn 14px above the origin) fits in '32,48' with actor.y = 16). tint/alpha still apply. Gani sounds don't play.

GuiActor interface ​

ts
interface GuiActor

The character a GuiImageCtrl draws; see GuiImageCtrl.actor.

GuiActor.ani ​

ts
ani: string

Gani name without .gan, e.g. 'walk'. Default (and '') 'idle'.

GuiActor.head ​

ts
head: string

Head image, e.g. 'head0.png'. '' = the gani's default, else head0.png.

GuiActor.body ​

ts
body: string

Body image, e.g. 'body.png'. '' = the gani's default, else body.png.

GuiActor.colors ​

ts
colors: string[]

Body colors as 'r,g,b' (same slots as player.colors: skin, coat, sleeves, shoes, belt). Default: the player defaults. Assign an array (e.g. pic.actor.colors = player.colors) or one index (pic.actor.colors[1] = '255,0,0'); invalid values throw.

GuiActor.dir ​

ts
dir: 'up' | 'left' | 'down' | 'right' | 0 | 1 | 2 | 3

Facing. Also accepts Graal's 0-3 (up, left, down, right) on write; reads are names. Default 'down'.

GuiActor.x ​

ts
x: number

Pixel offset of the gani origin from the control's top-left. Default 0.

GuiActor.y ​

ts
y: number

Pixel offset of the gani origin from the control's top-left. Default 0.

GuiScrollCtrl class ​

ts
declare class GuiScrollCtrl extends GuiControl

A scrollable viewport. Children added via addControl land in the inner content area and may be larger than the viewport; scrollbars appear as needed and the mouse wheel scrolls when the cursor is over it. Children's absx/absy shift as the content scrolls, so hit-testing against a scrolled child keeps working unchanged.

GuiScrollCtrl.constructor ​

ts
constructor(name: string)

GuiStretchCtrl class ​

ts
declare class GuiStretchCtrl extends GuiControl

A container designed at a fixed virtual resolution that scales everything inside it to its real extent — build a screen once (say 720x480) and let it fill any window size. Children are positioned and sized in the VIRTUAL units: their x/y/width/height reads, and the x/y of their mouse events, stay in those design units. absx/absy stay real screen pixels, so they compare directly with mousex()/mousey(). Stretch controls nest (factors multiply).

What scales: position, extent, image scale, gani actors, label fontsize and panel bordersize/borderradius. Text and borders scale by the SMALLER axis factor, so they never distort or overflow their box; label fonts are re-rasterized at the new size, so they stay crisp. Themed chrome keeps its native pixel metrics even though it resizes: window title bars, the default button height, scrollbar thickness, and the text of buttons/text edits. 9-slice skin corners stay 1:1.

There are no anchors, so a full-screen stretch control re-asserts its extent when the window resizes:

ts
const ui = new GuiStretchCtrl('Battle_Root')
ui.virtualextent = '720,480'
ui.extent = `${ScreenWidth},${ScreenHeight}`
// onUpdate: if the size changed, ui.extent = `${ScreenWidth},${ScreenHeight}`

GuiStretchCtrl.constructor ​

ts
constructor(name: string)

GuiStretchCtrl.virtualwidth ​

ts
virtualwidth: number

Design (virtual) width children are laid out in. Unset = the control's own width (no scaling).

GuiStretchCtrl.virtualheight ​

ts
virtualheight: number

Design (virtual) height children are laid out in. Unset = the control's own height (no scaling).

GuiStretchCtrl.virtualextent ​

ts
virtualextent: string

"w,h" — write-only convenience that sets virtualwidth and virtualheight.

GuiStretchCtrl.stretchmode ​

ts
stretchmode: 'stretch' | 'fit' | 'fill'

How the virtual area maps onto the real extent:

  • 'stretch' (default): each axis scales independently to fill the
ts
extent exactly (distorts when the aspect ratios differ).
  • 'fit': uniform scale to the largest size that fits, centered —
ts
leaves empty bars on mismatched aspect ratios (letterboxing).
  • 'fill': uniform scale to cover the whole extent, centered; the
ts
overflow is cropped.

GuiGameScreen interface ​

ts
interface GuiGameScreen

The game screen itself — a pseudo-control for parenting GUI directly onto the game view (custom chatbars, HUDs) without any window chrome. It cannot be created, destroyed, styled, or listened to; 'GameControl' is a reserved control name.

GuiGameScreen.name ​

ts
readonly name: 'GameControl'

GuiGameScreen.width ​

ts
readonly width: number

Live viewport width in pixels (same as ScreenWidth).

GuiGameScreen.height ​

ts
readonly height: number

Live viewport height in pixels (same as ScreenHeight). Position bottom-anchored UI as y = GameControl.height - barHeight; there is no anchor API, so reposition in onUpdate if the window can be resized.

GuiGameScreen.extent ​

ts
readonly extent: string

"w,h" — the viewport size as a pair string.

GuiGameScreen.addControl ​

ts
addControl(child: GuiControl): void

Parents child directly onto the game screen (positions from the canvas top-left). Also moves a control back out of a window.

GuiGameScreen.show ​

ts
show(): void

No-op — the game screen is always visible.

GuiGameScreen.hide ​

ts
hide(): void

No-op — the game screen cannot be hidden.

GuiGameScreen.bringtofront ​

ts
bringtofront(): void

No-op — the game screen is already the bottom-most layer.

GameControl global ​

ts
declare const GameControl: GuiGameScreen

The game screen pseudo-control; also returned by findobj('GameControl').

findGuiControl function ​

ts
declare function findGuiControl(name: 'GameControl'): GuiGameScreen
declare function findGuiControl(name: string): GuiControl | undefined

Looks up a live control by name; undefined if it doesn't exist.

findobj function ​

ts
declare function findobj(name: 'GameControl'): GuiGameScreen
declare function findobj(name: string): GuiControl

Graal-style alias of findGuiControl, typed non-optional so property chaining stays terse (findobj('My_Window').visible = true). It still returns undefined at runtime when no control has that name — use findGuiControl when existence is in doubt.

findobj('GameControl') returns the game-screen pseudo-control, e.g. findobj('GameControl').addControl(myChatEdit) for a custom chatbar.