build_tools.tui_common.controls.inputs
======================================
.. py:module:: build_tools.tui_common.controls.inputs
.. autoapi-nested-parse::
Seed input and radio option widgets.
This module provides input widgets for seed/random value entry and
radio-button style option selection.
**Widgets:**
- :class:`SeedInput` - Two-box seed input with random mode support
- :class:`RadioOption` - Checkbox-style radio button for option groups
**Example Usage:**
.. code-block:: python
from build_tools.tui_common.controls import SeedInput, RadioOption
from textual import on
class MyApp(App):
def compose(self) -> ComposeResult:
# Seed input with random default
yield SeedInput(id="seed-input")
# Radio options for mode selection
yield RadioOption("fast", "Quick processing", is_selected=True, id="opt-fast")
yield RadioOption("thorough", "Deep analysis", id="opt-thorough")
@on(SeedInput.Changed)
def on_seed_changed(self, event: SeedInput.Changed) -> None:
print(f"Using seed: {event.value}")
@on(RadioOption.Selected)
def on_option_selected(self, event: RadioOption.Selected) -> None:
# Update other options to deselect them
for opt in self.query(RadioOption):
opt.set_selected(opt.option_name == event.option_name)
Classes
-------
.. autoapisummary::
build_tools.tui_common.controls.inputs.SeedInput
build_tools.tui_common.controls.inputs.RadioOption
Module Contents
---------------
.. py:class:: SeedInput(value = None, *args, **kwargs)
Bases: :py:obj:`textual.widgets.Static`
Seed input widget with two-box design.
Displays an input field for entering a seed value and a display
showing the actual seed being used. Supports random mode when
input is empty or "-1".
**Layout:**
``[Seed:] [Input Field] [->] [Actual Seed Used]``
**Modes:**
- **Manual mode**: Enter a specific integer seed value
- **Random mode**: Enter "-1" or leave empty to auto-generate
.. attribute:: value
Current seed value being used (always a valid integer)
.. attribute:: user_input
User's raw input (-1 means random mode)
Keybindings:
- ``r``: Set to random mode (-1)
Messages:
- :class:`Changed`: Posted when seed changes, includes actual seed value
CSS Classes:
- ``.seed-label``: "Seed:" label (width: 15)
- ``Input``: Text input field (width: 13)
- ``.arrow``: Arrow indicator "->" (width: 3)
- ``.seed-used-value``: Actual seed display (width: 12, muted)
Initialize seed input with two-box design.
:param value: Initial seed value. If None, generates a random seed
using SystemRandom for cryptographic randomness.
:param \*args: Additional positional arguments passed to Static
:param \*\*kwargs: Additional keyword arguments passed to Static
.. py:attribute:: BINDINGS
:value: [('r', 'random', 'Random')]
A list of key bindings.
.. py:class:: Changed(value, widget_id)
Bases: :py:obj:`textual.message.Message`
Message posted when the seed value changes.
.. attribute:: value
The actual seed value being used (always valid integer)
.. attribute:: widget_id
The ID of the widget that posted this message, or None
Initialize the Changed message.
:param value: The actual seed value
:param widget_id: ID of the seed input widget that changed
.. py:attribute:: value
.. py:attribute:: widget_id
.. py:attribute:: DEFAULT_CSS
:value: Multiline-String
.. raw:: html
Show Value
.. code-block:: python
"""
SeedInput {
layout: horizontal;
height: 3;
width: 100%;
}
SeedInput .seed-label {
width: 15;
text-align: right;
padding-right: 1;
height: 3;
content-align: center middle;
}
SeedInput Input {
width: 13;
height: 3;
border: solid $primary;
}
SeedInput .arrow {
width: 3;
text-align: center;
height: 3;
content-align: center middle;
}
SeedInput .seed-used-value {
width: 12;
height: 3;
text-align: left;
content-align: center middle;
color: $text-muted;
background: $boost;
padding-left: 1;
}
"""
.. raw:: html
Default TCSS.
.. py:attribute:: user_input
:value: -1
.. py:method:: compose()
Create two-box seed input in single horizontal row.
Layout: [Label] [Input] [Arrow] [Actual Value]
:Yields: Label and Input widgets for the two-box design
.. py:method:: action_random()
Set input to random mode (-1).
Bound to 'r' key. Generates a new random seed.
.. py:method:: on_input_changed(event)
Handle user typing in the seed input.
:param event: Input change event from Textual
.. py:class:: RadioOption(option_name, description, is_selected = False, *args, **kwargs)
Bases: :py:obj:`textual.widgets.Static`
Radio button style option widget.
Displays as a checkbox-style option that can be selected with
keyboard or mouse. Used in groups where only one option should
be selected at a time (managed by parent).
**Display Format:**
- Selected: ``[x] Label: Description`` (green, bold)
- Unselected: ``[ ] Label: Description`` (muted)
.. attribute:: option_name
Internal name for this option (e.g., "fast", "thorough")
.. attribute:: description
Brief description shown after the label
.. attribute:: is_selected
Whether this option is currently selected
Keybindings:
- ``Enter`` or ``Space``: Select this option
Messages:
- :class:`Selected`: Posted when this option is selected (only if not already selected)
CSS Classes:
- Default styles handle hover and focus states
- ``.profile-selected`` / ``.profile-unselected``: Selection state classes
.. note::
This widget only posts a message when selected. The parent
is responsible for deselecting other options in the group
by calling :meth:`set_selected` on each.
Initialize radio option.
:param option_name: Internal name for this option (e.g., "fast")
:param description: Brief description to show after the label
:param is_selected: Whether this option starts selected
:param \*args: Additional positional arguments passed to Static
:param \*\*kwargs: Additional keyword arguments passed to Static
.. py:attribute:: BINDINGS
:value: [('enter', 'select', 'Select Option'), ('space', 'select', 'Select Option')]
A list of key bindings.
.. py:class:: Selected(option_name, widget_id)
Bases: :py:obj:`textual.message.Message`
Message posted when this option is selected.
Only posted if the option was not already selected.
.. attribute:: option_name
The name of the selected option
.. attribute:: widget_id
The ID of the widget that posted this message, or None
.. attribute:: profile_name
Alias for option_name (backward compatibility)
Initialize the Selected message.
:param option_name: Name of the option that was selected
:param widget_id: ID of the radio option widget
.. py:attribute:: option_name
.. py:attribute:: widget_id
.. py:property:: profile_name
:type: str
Alias for option_name (backward compatibility with ProfileOption).
.. py:attribute:: DEFAULT_CSS
:value: Multiline-String
.. raw:: html
Show Value
.. code-block:: python
"""
RadioOption {
height: 1;
width: 100%;
}
RadioOption:hover {
background: $boost;
}
RadioOption:focus {
background: $accent;
}
.profile-selected {
color: $success;
text-style: bold;
}
.profile-unselected {
color: $text-muted;
}
"""
.. raw:: html
Default TCSS.
.. py:attribute:: option_name
.. py:attribute:: description
.. py:attribute:: is_selected
:value: False
.. py:method:: on_mount()
Configure widget after mounting.
Makes the widget focusable for keyboard navigation.
.. py:method:: render()
Render the option as text with Rich markup.
:returns: Rich Text object with checkbox, label, and description
.. py:method:: action_select()
Select this option (Enter/Space).
Only posts Selected message if not already selected.
Does not blur focus - keeps focus on selected option
like standard radio button behavior.
.. py:method:: on_click()
Handle click on this option.
Same behavior as action_select - posts message if not selected.
.. py:method:: set_selected(selected)
Update selection state and refresh display.
Called by parent to manage radio group state.
Does not post any message.
:param selected: Whether this option should be selected