Repository navigation
User interface
proleak.ui builds game UI from Python widgets, drawn with the game's own components. UI works
on every server kind. Everything a plugin shows goes away when the plugin unloads, and an open
page closes as if the player pressed Back.
Contents
from proleak import ui
ui.main_menu.add("Overlay", page="settings")
ui.game_menu.add("Say hi", on_click=lambda: ui.toast("hi"))main_menu is the launcher list and game_menu the in-game menu.
add(label, page=None, on_click=None, after=None, before=None, huge=False, badge=None) takes
either a page name of the plugin or a callback, and returns an item with remove().
Without after or before the item goes at the end of the list, above the game's own last
entries (Quit and Return to game in a match). after="<name>" and before="<name>" place it
next to the game item with that name, or at the end when there is none.
from proleak import camera, ui
ui.unit_menu.add("First person", lambda unit: camera.pov(unit))
ui.unit_menu.add("Follow", lambda unit: camera.third_person(unit),
when=lambda unit: unit.owner is not None and unit.owner.is_local)ui.unit_menu.add(label, on_click, when=None, alt=False) adds an entry to a menu that opens on
a right-click on a unit. on_click(unit) gets the world Unit clicked, and
when(unit) decides whether the entry shows for it. With alt=True the entry shows on
Alt + right-click only. The call returns an item with remove().
When at least one entry shows, the menu replaces the game's ping wheel for that click. A right-click on the ground still opens the wheel.
mode = ui.state("fast")
@ui.page("settings", title="Overlay settings")
def build(p):
p.add(
ui.heading("Display"),
ui.toggle("Show names", bind=ui.setting("enabled")),
ui.slider("Size", 1, 5, bind=ui.setting("size")),
ui.choice("Mode", ["fast", "full"], bind=mode),
ui.button("Close", on_click=lambda: ui.close("settings")),
)A page opens in the game's own menu frame, with its title at the top left. Back returns to the
menu it was opened from. The builder runs each time the page opens. ui.open(name) and
ui.close(name) show and hide a page of the calling plugin, and ui.refresh(name) runs the
builder again when the page is open. Registering a page name again replaces its builder.
p.add(*widgets) appends widgets, p.tabs(*tabs) adds a tab bar, and p.redraw() runs the
builder again.
| Widget | Arguments | Callback |
|---|---|---|
text(s) |
||
heading(s) |
||
button(label, on_click=None, style="standard", tone=None) |
style: standard, emphasized or text (menu buttons), small (for lists); a small button's tone is primary (gold, the main action), quiet (dimmed) or danger (red, removes something) |
on_click() |
toggle(label, bind=None, on_change=None) |
an On/Off button like the game options | on_change(value) |
slider(label, min, max, step=1, bind=None, on_change=None) |
the game's slider; the value is sent on release | on_change(value) |
choice(label, options, bind=None, on_change=None) |
options: list of strings, in the game's drop-down |
on_change(value) |
multi(label, options, bind=None, on_change=None) |
a drop-down where any number of options are ticked; the value is the ticked list, in option order |
on_change(value) |
key(label, bind=None, on_change=None) |
a hotkey button: click it, then press a key (Escape cancels); the value is the Unity key name | on_change(value) |
color(label, bind=None, on_change=None) |
a #rrggbb color with a color picker |
on_change(value) |
input(label, bind=None, on_change=None) |
reports on Enter or on losing focus | on_change(value) |
image(src) |
a path in the game's UI files, such as hud/img/icons/Gold.png
|
|
row(*widgets, align="start"), column(*widgets)
|
side by side (align="end" against the right, align="split" with the last one against the right), stacked |
|
group(*widgets) |
stacked in a framed box, one entry of a list | |
entry(title, *lines, buttons=(), badge=None, tone="neutral", author=None, version=None) |
a group with a heading, lines of text and small buttons, as the Mods menu lists plugins; buttons holds (label, on_click) pairs; badge is a short status beside the title, colored by tone (neutral, good, bad or busy) |
|
table(headers, rows) |
lists of strings | |
tab(label, *widgets) |
one tab for p.tabs
|
ui.settings_form() returns the widgets for every setting the plugin declares (with
settings.add or in plugin.yml), the same form the Mods menu shows, ready to add to a page.
A plugin needs no page for its settings: the Mods menu gives every plugin with settings a
Settings button.
bind connects an input widget to a value:
-
ui.state(value)holds a value in memory. Settingstate.valueredraws the widgets bound to it. - A
Settingfromsettings.add, orui.setting(key), binds to one of the plugin's settings; changes are validated and saved likesettings.set.
A callback that raises counts against the plugin like a failing handler; the page keeps working.
ui.popup("Reset?", "Clear all names?", buttons=("Yes", "No"),
on_result=lambda label: label == "Yes" and names.clear())
ui.toast("Names loaded", header="Overlay", seconds=4)on_result receives the label of the clicked button. A toast appears with the launcher's
notifications in the menus and in the game's message feed during a match.
ui.nameplate(unit, "alice", color="#33ff33")
ui.world_text(x, z, "rally here")ui.nameplate(unit, text) shows a text label above a unit's health bar until the unit dies or
is sold, and ui.world_text(x, z, text) places one at a map point. The User interface
reference lists their options.
Panels and scripts reach the game's page directly. They can change anything on screen, including what the cosmetic rule protects, so the approved plugin list reviews them.
hud = ui.panel("score", '<button data-proleak-evt="reset">Reset</button>',
css="button { color: gold; }", anchor="top-left")
@ui.on_js("reset")
def reset(data):
...
hud.send("score", 42)ui.panel(name, html, css="", anchor="top-right") shows raw HTML in a corner: top-left,
top-right, bottom-left, bottom-right or center. Clicking an element with
data-proleak-evt calls the plugin's on_js handler for that event, with the element's
data-value as data. panel.send(evt, data) delivers to the plugin's scripts and fires a
proleak DOM event on the panel (event.detail holds evt and data).
ui.script(path) loads a .js file from the plugin folder into the game page. The script
runs with one variable, api:
| Member | Use |
|---|---|
api.send(evt, data) |
Call the plugin's on_js(evt) handler. |
api.on(evt, fn) |
Receive panel.send(evt, data) from Python. |
api.onUnload(fn) |
Clean up when the script or plugin unloads. |
api.React, api.globalState
|
The game's React and state. |
Previous: Plugin settings | Next: Players, units and game data
Using ProLeak
Features
Tutorial
- Your first plugin
- Plugin basics
- Handling events
- Plugin settings
- User interface
- Players, units and game data
- Purchases, signals and pings
- Chat, camera, input and more
- Cosmetics
- Game modes
- Game updates
- Publishing plugins
Reference