Text Input Demo

validates character input, focus routing, and scissor clipping.

▶ Run in browser

Tags: ui

  • Two TextEdit fields with working keyboard input

  • A clipped scroll area showing labels that extend beyond bounds

  • Tab to switch focus between fields

Run: uv run python examples/features/ui/text_input.py

Source

  1"""Text Input Demo: validates character input, focus routing, and scissor clipping.
  2
  3- Two TextEdit fields with working keyboard input
  4- A clipped scroll area showing labels that extend beyond bounds
  5- Tab to switch focus between fields
  6
  7Run: uv run python examples/features/ui/text_input.py
  8"""
  9
 10from simvx.core import (
 11    AnchorPreset,
 12    Colour,
 13    Label,
 14    Node,
 15    Panel,
 16    ScrollContainer,
 17    TextEdit,
 18    VBoxContainer,
 19    Vec2,
 20)
 21from simvx.graphics import App
 22
 23
 24class TextInputDemo(Node):
 25    """Root node for text input demo."""
 26
 27    def on_ready(self):
 28        panel = Panel(name="MainPanel")
 29        # Fill the viewport with a 30px gutter so the panel grows with the window.
 30        panel.set_anchor_preset(AnchorPreset.FULL_RECT)
 31        panel.margin_left = 30
 32        panel.margin_top = 30
 33        panel.margin_right = 30
 34        panel.margin_bottom = 30
 35        panel.bg_colour = Colour.hex("#12121A")
 36        self.add_child(panel)
 37
 38        vbox = VBoxContainer(name="Layout")
 39        vbox.set_anchor_preset(AnchorPreset.FULL_RECT)
 40        vbox.margin_left = 20
 41        vbox.margin_top = 20
 42        vbox.margin_right = 20
 43        vbox.margin_bottom = 20
 44        vbox.separation = 15
 45        panel.add_child(vbox)
 46
 47        # Title: multi-line centred (regression sample for
 48        # bug-label-center-multiline).
 49        title = Label("Text Input\n& Clipping Demo")
 50        title.text_colour = Colour.hex("#4FC3F7")
 51        title.font_size = 16.0
 52        title.size = Vec2(460, 50)
 53        title.alignment = "center"
 54        vbox.add_child(title)
 55
 56        # Field 1
 57        label1 = Label("Username:")
 58        label1.size = Vec2(460, 18)
 59        vbox.add_child(label1)
 60
 61        edit1 = TextEdit(placeholder="Enter username...")
 62        edit1.size = Vec2(460, 30)
 63        edit1.bg_colour = Colour.hex("#1A1A2E")
 64        edit1.focus_colour = Colour.hex("#4FC3F7")
 65        vbox.add_child(edit1)
 66
 67        # Field 2
 68        label2 = Label("Message:")
 69        label2.size = Vec2(460, 18)
 70        vbox.add_child(label2)
 71
 72        edit2 = TextEdit(placeholder="Type a message...")
 73        edit2.size = Vec2(460, 30)
 74        edit2.bg_colour = Colour.hex("#1A1A2E")
 75        edit2.focus_colour = Colour.hex("#E94560")
 76        vbox.add_child(edit2)
 77
 78        # Echo
 79        echo = Label("")
 80        echo.text_colour = Colour.GREEN
 81        echo.size = Vec2(460, 20)
 82
 83        def on_submit(txt):
 84            echo.text = f"Sent: {txt}"
 85
 86        edit2.text_submitted.connect(on_submit)
 87        vbox.add_child(echo)
 88
 89        # Clipped scroll area: overflowing content exercises the scrollbar.
 90        clip_label = Label("Scrollable Area (Up/Down to scroll, mouse wheel, drag bar):")
 91        clip_label.size = Vec2(460, 18)
 92        vbox.add_child(clip_label)
 93
 94        scroll_area = ScrollContainer(name="ScrollArea")
 95        scroll_area.size = Vec2(460, 160)
 96        scroll_area.separation = 4
 97        vbox.add_child(scroll_area)
 98
 99        for i in range(1, 11):
100            line = Label(f"Line {i}: scrollable content row {i}")
101            line.size = Vec2(440, 18)
102            line.text_colour = Colour.WHITE
103            scroll_area.add_child(line)
104
105        # Instructions
106        help_text = Label("Click fields to focus / Enter to submit / Up/Down to scroll")
107        help_text.text_colour = Colour.GRAY
108        help_text.size = Vec2(460, 18)
109        help_text.alignment = "center"
110        vbox.add_child(help_text)
111
112
113if __name__ == "__main__":
114    app = App(title="SimVX Text Input Demo", width=800, height=600)
115    app.run(TextInputDemo())