Your First Widget
This tutorial builds a complete interactive choice menu from scratch — engine initialization, widget creation, input handling, and result retrieval.
What You Will Build
- A scene with one Choice widget
- An input loop that reacts to arrow keys and Enter
- A clean shutdown path that frees buffers, scenes, and the input listener
Step 1: Initialize the Engine
from tuix.core import engine, builders, scenes, registry, objects, buffers, input
engine.init()
builders.register_standard()engine.init() initializes the C core and the global registry. builders.register_standard() registers the four built-in widget types: ProgressBarBuilder, ChoiceBuilder, InputBuilder, and CanvasBuilder.
Step 2: Create a Scene
scenes.init_scene(b"main")
registry.registry.current_scene_name = b"main"Scenes are containers for widgets. You must create at least one scene and set it as active before creating widgets. Scene names are byte strings.
Step 3: Start Input Listener
input.listen()This starts a background thread that captures keyboard and mouse events. Events are queued and consumed as snapshots during the main loop.
Step 4: Create a Choice Widget
uid = objects.create_object(
builders.CHOICE, # Widget type
b"main", # Scene name
0.4, # width_mod: 40% of terminal width
0.5, # height_mod: 50% of terminal height
0.25, # margin_top_mod: 25% from top
0.3 # margin_left_mod: 30% from left
)
# Get the object pointer for widget-specific operations
buf = buffers.get_buffer_by_uid(uid)
obj = buf.contents.obj.contentscreate_object returns a unique integer UID. All dimensions are proportional modifiers (0.0–1.0) of the current terminal size. To call widget-specific functions, retrieve the object pointer via get_buffer_by_uid.
Step 5: Configure Options
options = [b"Red", b"Green", b"Blue", b"Yellow", b"Cyan"]
objects.tuix_choice_set_options(obj, options)Options are passed as a list of byte strings. The C layer deep-copies the labels, so the Python list can be discarded after this call.
Step 6: Render Loop with Input
while True:
engine.main_loop()
if objects.tuix_choice_is_confirmed(obj):
breakEach iteration runs one frame. In v0.3, input handling for standard builders is automatic in the frame loop, so you only render and check confirmation state.
Step 7: Get Result and Clean Up
selected = objects.tuix_choice_get_selected(obj)
print(f"Selected index: {selected}")
print(f"Selected option: {options[selected].decode()}")
buffers.free_buffer(b"main", uid)
scenes.free_scene(b"main")
input.stop()
engine.shutdown()tuix_choice_get_selected returns the 0-based index of the confirmed option. Always free buffers and scenes before shutting down.
Complete Code
from tuix.core import engine, builders, scenes, registry, objects, buffers, input
# Initialize
engine.init()
builders.register_standard()
scenes.init_scene(b"main")
registry.registry.current_scene_name = b"main"
input.listen()
# Create choice widget
uid = objects.create_object(
builders.CHOICE, b"main",
0.4, 0.5, 0.25, 0.3
)
buf = buffers.get_buffer_by_uid(uid)
obj = buf.contents.obj.contents
# Configure options
options = [b"Red", b"Green", b"Blue", b"Yellow", b"Cyan"]
objects.tuix_choice_set_options(obj, options)
# Render loop (automatic input handling in v0.3)
while True:
engine.main_loop()
if objects.tuix_choice_is_confirmed(obj):
break
# Result
selected = objects.tuix_choice_get_selected(obj)
print(f"You chose: {options[selected].decode()}")
# Cleanup
buffers.free_buffer(b"main", uid)
scenes.free_scene(b"main")
input.stop()
engine.shutdown()Next Steps
Explore the Widgets overview to learn about all four widget types, or jump directly to the Canvas API for free-draw graphics.