Skip to main content

Window Management

This guide covers everything about creating and managing windows on the client side. If you want to build UI for your plugin, this is where you start.

UI Groups

Windows belong to different groups depending on where the player is in the game:

UI_GROUP_SERVER = 0  -- Server selection screen
UI_GROUP_SELECT = 1 -- Character selection
UI_GROUP_INGAME = 2 -- In game (most common)

Most of your plugins will use UI_GROUP_INGAME since that's where players actually play.

Getting a Window Index

Every window needs a unique ID. Get one like this:

local MyPlugin = {
index = GetWindowIndex(), -- Gets a unique ID
group = UI_GROUP_INGAME -- Where the window appears
}

Screen Dimensions

Need to know how big the screen is?

-- GetWindowW()
-- Returns the screen width in pixels
local screenWidth = GetWindowW()
LogPrint("Screen width: " .. screenWidth)

-- GetWindowH()
-- Returns the screen height in pixels
local screenHeight = GetWindowH()
LogPrint("Screen height: " .. screenHeight)

Centering Windows

Want to center your window? Use these helpers:

-- GetWindowCenterX(width)
-- Calculates the X position to center an element horizontally
local windowWidth = 300
local centerX = GetWindowCenterX(windowWidth)
-- If screen is 1920px, centerX will be 810 (1920-300)/2

-- GetWindowCenterY(height)
-- Calculates the Y position to center an element vertically
local windowHeight = 200
local centerY = GetWindowCenterY(windowHeight)

Creating Windows

Here's the main function to create a window:

UIWindowAdd(group, index, state, depth, x, y, w, h, scale, render, update)

Parameters:

  • group - UI group (SERVER/SELECT/INGAME)
  • index - Unique window ID
  • state - Initial state (0=hidden, 1=visible)
  • depth - Render depth (higher = in front)
  • x, y - Position on screen
  • w, h - Width and height
  • scale - Render scale (normally 1)
  • render - Render function (optional)
  • update - Update function (optional)

Returns: Window object or nil if it failed

Complete Example

BridgeFunction:push("OnLoad", function()
local width = 300
local height = 200

local window = UIWindowAdd(
UI_GROUP_INGAME, -- Show in game
MyPlugin.index, -- Unique ID
0, -- Start hidden
2, -- Depth 2
GetWindowCenterX(width), -- Centered X
GetWindowCenterY(height), -- Centered Y
width, -- Width
height, -- Height
1, -- Normal scale
MyPlugin.renderWindow, -- Render function
MyPlugin.updateWindow -- Update function
)

if window then
LogPrint("Window created successfully!")
end
end)

Getting and Removing Windows

-- UIWindowGet(group, index)
-- Gets a reference to an existing window
local window = UIWindowGet(UI_GROUP_INGAME, MyPlugin.index)
if window then
LogPrint("Window found!")
end

-- UIWindowDel(group, index)
-- Removes a window from the interface
local success = UIWindowDel(UI_GROUP_INGAME, MyPlugin.index)
if success then
LogPrint("Window removed!")
end

Window Properties

When you create a window, it has these properties:

window.index     -- Window ID
window.state -- State (0=hidden, 1=visible)
window.hover -- Mouse over? (0=no, 1=yes)
window.click -- Click state (0=none, 1=clicked, 2=holding, 3=released)
window.wheel -- Mouse wheel value
window.x -- Current X position
window.y -- Current Y position
window.w -- Width
window.h -- Height
window.ox -- Original X position
window.oy -- Original Y position
window.ow -- Original width
window.oh -- Original height
window.scale -- Render scale
window.depth -- Render depth

Window Methods

Basic Methods

-- Change visibility
window:setState(1) -- Show window
window:setState(0) -- Hide window

-- Move window
window:setSpot(100, 50) -- Move to x=100, y=50

-- Resize window
window:setSize(400, 300) -- Resize to 400x300

-- Change render depth
window:setDepth(5) -- Bring to front

Making Windows Draggable

-- setDragArea(x, y, w, h)
-- Defines the area that can be clicked to drag the window
-- Coordinates are relative to the window (0,0 = top-left corner)

-- Allow dragging by the top bar (30 pixels tall)
window:setDragArea(0, 0, window.w, 30)

-- setDragZone(x, y, w, h)
-- Defines the boundaries where the window can be moved
-- Useful for restricting movement to a specific area

-- Restrict movement to an 800x600 area starting at 100,100
window:setDragZone(100, 100, 800, 600)

Storing Custom Data

You can attach any data to a window:

-- setAttach(value)
-- Attach custom data to the window
window:setAttach({
playerName = "John",
score = 100,
items = {1, 2, 3}
})

-- getAttach()
-- Retrieve the attached data
local data = window:getAttach()
if data then
LogPrint("Name: " .. data.playerName)
LogPrint("Score: " .. data.score)
end

This is super useful for storing plugin state without using global variables.

Complete Example - Basic Window

Here's a full working example:

-- Plugin setup
MyBasicWindow = {
index = GetWindowIndex(),
group = UI_GROUP_INGAME,
}

-- Render function
function MyBasicWindow.renderWindow(window)
-- Render window border
UIRenderWindow(window, 0, 0, window.w, window.h, 0)

-- Render text at the top
window:renderText(
"My Window", -- Text
0, 10, -- Position X, Y
window.w, 20, -- Width, Height
4, -- Alignment (4=center)
RGBA(255,255,255,255), -- White color
FontL -- Font
)
end

-- Update function
function MyBasicWindow.updateWindow(window)
-- Return true to consume input (block clicks through window)
-- Return false to allow clicks through window
return window.state == 1
end

-- Initialization
BridgeFunction:push("OnLoad", function()
local w = 300
local h = 200

local window = UIWindowAdd(
MyBasicWindow.group,
MyBasicWindow.index,
0, -- Start hidden
2, -- Depth
GetWindowCenterX(w),
GetWindowCenterY(h),
w, h, 1,
MyBasicWindow.renderWindow,
MyBasicWindow.updateWindow
)

if window then
-- Allow dragging by the top bar (30px)
window:setDragArea(0, 0, w, 30)

LogPrint("Basic window created!")
end
end)

-- Function to toggle the window open/closed
function MyBasicWindow:toggle()
local window = UIWindowGet(self.group, self.index)
if window then
if window.state == 0 then
window:setState(1) -- Open
else
window:setState(0) -- Close
end
end
end

Quick Tips

  1. Always check if window creation succeeded - UIWindowAdd returns nil on failure
  2. Use depth wisely - Higher values render on top
  3. State 0 = hidden doesn't mean deleted - The window still exists
  4. Drag areas make windows feel professional - Players expect to drag windows by the title bar
  5. Store plugin data in window.attach - Keeps things organized

That's the basics of window management! Next up, you'll want to learn about rendering content inside your windows.