Skip to main content
Version: Dev

Widgets

Every scene creates a GUI root at scene.root. Add widgets to that tree to build interfaces.

class MyScene(bf.Scene):
def do_when_added(self):
button = bf.gui.Button("Click me", callback=lambda: print("hi"))
self.root.add(button)

Core concepts​

Widget tree​

Widgets form a parent/child tree under Root. Common operations:

  • add(*children) / remove(*children)
  • visit(func) — walk the subtree
  • top_at(x, y) — pick the topmost widget at a point
  • get_root() — climb to the scene root

Layouts​

Containers arrange children with a layout:

LayoutBehavior
Column(gap=0)Vertical stack
Row(gap=0)Horizontal stack
Grid(rows, cols, gap=0)Grid
ColumnFill / RowFill / GridFillStretch children to fill
FreeLayoutNo automatic arrangement
panel = bf.gui.Container(bf.gui.Column(gap=8))
panel.add(
bf.gui.Label("Settings"),
bf.gui.Button("Apply"),
)
self.root.add(panel)

Constraints​

Widgets can declare sizing and positioning constraints:

from batFramework.gui.constraints import constraints as c

widget.add_constraints(
c.Width(200),
c.Height(40),
c.Center(),
)

Common constraints include Width, Height, Fill, FillX, FillY, Center, CenterX, CenterY, margins, percentage sizes, and grow weights (GrowH, GrowV) used by layouts.

Focus and layers​

Root manages hover, focus, tab navigation, and tooltips.

Transient UI (dropdowns, dialogs, tooltips) can be attached to a GuiLayer above the normal tree:

self.root.attach_to_layer(overlay_widget, bf.GuiLayer.OVERLAY)
# NORMAL, OVERLAY, MODAL, TOOLTIP, DEBUG

Common widgets​

WidgetRole
LabelText display
ButtonClickable label with callback
Toggle / RadioButtonOn/off and exclusive choices
SliderNumeric value with handle and meter
DropdownOption list (opens on GuiLayer.OVERLAY)
SelectorCycle through options
TextInputEditable text field
AnimatedLabelTypewriter-style text
ImageDisplays a surface/image
ContainerLayout host for children
ScrollingContainerContainer with scrollbars
CollapseContainerExpand/collapse content
BarMeter / metersProgress-style displays
SyncedVarReactive value shared by widgets

Slider example​

volume = bf.gui.SyncedVar(0.8)
slider = (
bf.gui.Slider("Volume", default_value=0.8, synced_var=volume)
.set_range(0, 1)
.set_step(0.05)
)
self.root.add(slider)
menu = bf.gui.Dropdown(
options=["Easy", "Normal", "Hard"],
default_value_index=1,
)
self.root.add(menu)
Draw order

GUI widgets inherit render order from their parent (parent.render_order + 1). Raise render_order on world drawables or widgets if something draws in the wrong order — there is no separate HUD camera.