Appearance
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 GuiButtonEventPayload of click/doubleclick/mousedown/mouseup. x/y are relative to the control's top-left.
GuiButtonEvent.button
ts
button: GuiMouseButtonGuiButtonEvent.x
ts
x: numberGuiButtonEvent.y
ts
y: numberGuiMoveEvent interface
ts
interface GuiMoveEventPayload of mousemove/mouseenter/mouseleave. x/y are relative to the control's top-left.
GuiMoveEvent.x
ts
x: numberGuiMoveEvent.y
ts
y: numberGuiWheelEvent interface
ts
interface GuiWheelEventPayload of mousewheel. delta is in wheel notches, positive = scroll up.
GuiWheelEvent.delta
ts
delta: numberGuiWheelEvent.x
ts
x: numberGuiWheelEvent.y
ts
y: numberGuiKeyEvent interface
ts
interface GuiKeyEventPayload 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: stringGuiKeyEvent.shift
ts
shift: booleanWhether either shift key is held at event time.
GuiKeyEvent.control
ts
control: booleanWhether either control key is held at event time.
GuiEventMap interface
ts
interface GuiEventMapEvents a control can emit, keyed by name, for control.on(event, handler). The handler receives the mapped event object.
GuiEventMap.click
ts
click: GuiButtonEventPress and release on this control (any button — check e.button).
GuiEventMap.doubleclick
ts
doubleclick: GuiButtonEventPress and release on this control (any button — check e.button).
GuiEventMap.mousedown
ts
mousedown: GuiButtonEventPress and release on this control (any button — check e.button).
GuiEventMap.mouseup
ts
mouseup: GuiButtonEventFires on the control(s) the press started on, even if the cursor moved off.
GuiEventMap.mousemove
ts
mousemove: GuiMoveEventFires on the control(s) the press started on, even if the cursor moved off.
GuiEventMap.mouseenter
ts
mouseenter: GuiMoveEventFires on the control(s) the press started on, even if the cursor moved off.
GuiEventMap.mouseleave
ts
mouseleave: GuiMoveEventFires on the control(s) the press started on, even if the cursor moved off.
GuiEventMap.mousewheel
ts
mousewheel: GuiWheelEventFires on the control(s) the press started on, even if the cursor moved off.
GuiEventMap.keydown
ts
keydown: GuiKeyEventFires 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: GuiKeyEventKey released while this control (or a child) has keyboard focus. See keydown.
GuiControl class
ts
declare abstract class GuiControlBase of all GUI controls. Use a concrete Gui*Ctrl subclass.
GuiControl.name
ts
readonly name: stringThe registry name the control was created with.
GuiControl.x
ts
x: numberThe registry name the control was created with.
GuiControl.y
ts
y: numberThe registry name the control was created with.
GuiControl.width
ts
width: numberThe registry name the control was created with.
GuiControl.height
ts
height: numberThe registry name the control was created with.
GuiControl.absx
ts
readonly absx: numberScreen-absolute position (live read) — for hit-testing mouse coordinates, wherever the control sits.
GuiControl.absy
ts
readonly absy: numberScreen-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: stringAccepted for GS2 compatibility; styling profiles are not implemented yet.
GuiControl.show
ts
show(): voidAccepted for GS2 compatibility; styling profiles are not implemented yet.
GuiControl.hide
ts
hide(): voidAccepted for GS2 compatibility; styling profiles are not implemented yet.
GuiControl.bringtofront
ts
bringtofront(): voidMoves 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(): voidRemoves the control (and any children added via addControl) for good.
GuiControl.addControl
ts
addControl(child: GuiControl): voidParents 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: stringServer 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): thisListens 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): voidRemoves a listener added with on(); with no listener, removes all for that event.
GuiControl.skinborder
ts
skinborder: number9-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 GuiControlA draggable window with a title bar.
GuiWindowCtrl.constructor
ts
constructor(name: string)GuiWindowCtrl.text
ts
text: stringTitle 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: booleanAccepted for GS2 compatibility; windows always drag by their title bar.
GuiWindowCtrl.canresize
ts
canresize: booleanAccepted for GS2 compatibility; windows always drag by their title bar.
GuiButtonCtrl class
ts
declare class GuiButtonCtrl extends GuiControlA clickable push button with a text caption; listen with .on('click', ...).
GuiButtonCtrl.constructor
ts
constructor(name: string)GuiButtonCtrl.text
ts
text: stringGuiButtonCtrl.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?: () => voidFired when the button is clicked. Deprecated — use on('click', ...) instead.
GuiTextCtrl class
ts
declare class GuiTextCtrl extends GuiControlA 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: stringGuiTextCtrl.font
ts
font: stringFont 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: numberText size in points (1-256); the font is re-rasterized, so it stays crisp at any size. Default 18.
GuiTextCtrl.style
ts
style: stringAny 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 GuiControlA single-line text input.
GuiTextEditCtrl.constructor
ts
constructor(name: string)GuiTextEditCtrl.text
ts
text: stringGuiTextEditCtrl.placeholder
ts
placeholder: stringHint text shown while the field is empty.
GuiTextEditCtrl.password
ts
password: booleanSet 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) => voidFired when the user edits the text.
GuiPanelCtrl class
ts
declare class GuiPanelCtrl extends GuiControlA 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: numberBorder 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: numberCorner rounding radius in pixels for the fill and border; 0 = square.
GuiImageCtrl class
ts
declare class GuiImageCtrl extends GuiControlDisplays (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: stringServer 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: number0 (invisible) .. 1 (opaque).
GuiImageCtrl.scale
ts
scale: numberZooms 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) => voidFired 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 GuiActorThe character a GuiImageCtrl draws; see GuiImageCtrl.actor.
GuiActor.ani
ts
ani: stringGani name without .gan, e.g. 'walk'. Default (and '') 'idle'.
GuiActor.head
ts
head: stringHead image, e.g. 'head0.png'. '' = the gani's default, else head0.png.
GuiActor.body
ts
body: stringBody 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 | 3Facing. Also accepts Graal's 0-3 (up, left, down, right) on write; reads are names. Default 'down'.
GuiActor.x
ts
x: numberPixel offset of the gani origin from the control's top-left. Default 0.
GuiActor.y
ts
y: numberPixel offset of the gani origin from the control's top-left. Default 0.
GuiScrollCtrl class
ts
declare class GuiScrollCtrl extends GuiControlA 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 GuiControlA 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: numberDesign (virtual) width children are laid out in. Unset = the control's own width (no scaling).
GuiStretchCtrl.virtualheight
ts
virtualheight: numberDesign (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 GuiGameScreenThe 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: numberLive viewport width in pixels (same as ScreenWidth).
GuiGameScreen.height
ts
readonly height: numberLive 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): voidParents 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(): voidNo-op — the game screen is always visible.
GuiGameScreen.hide
ts
hide(): voidNo-op — the game screen cannot be hidden.
GuiGameScreen.bringtofront
ts
bringtofront(): voidNo-op — the game screen is already the bottom-most layer.
GameControl global
ts
declare const GameControl: GuiGameScreenThe game screen pseudo-control; also returned by findobj('GameControl').
findGuiControl function
ts
declare function findGuiControl(name: 'GameControl'): GuiGameScreen
declare function findGuiControl(name: string): GuiControl | undefinedLooks 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): GuiControlGraal-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.