or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

colors-styling.mdindex.mdkey-bindings.mdmain-interface.mdpopups.mdwidgets.md

widgets.mddocs/

0

# Widget Creation and Management

1

2

Methods for creating and managing all widget types including scroll menus, text boxes, buttons, labels, and custom widgets. Includes widget positioning, removal, and focus management.

3

4

## Capabilities

5

6

### Scroll Menu Widgets

7

8

Scrollable menu widgets for displaying selectable lists of items.

9

10

```python { .api }

11

def add_scroll_menu(title: str, row: int, column: int, row_span: int = 1,

12

column_span: int = 1, padx: int = 1, pady: int = 0) -> ScrollMenu:

13

"""

14

Add a scrollable menu widget to the grid.

15

16

Parameters:

17

- title: Widget title displayed in border

18

- row: Grid row position (0-indexed)

19

- column: Grid column position (0-indexed)

20

- row_span: Number of rows to span (default: 1)

21

- column_span: Number of columns to span (default: 1)

22

- padx: Horizontal padding in characters (default: 1)

23

- pady: Vertical padding in characters (default: 0)

24

25

Returns:

26

ScrollMenu widget instance

27

"""

28

29

class ScrollMenu:

30

def add_item(item: Any) -> None: ...

31

def add_item_list(item_list: List[Any]) -> None: ...

32

def remove_selected_item() -> None: ...

33

def remove_item(item: Any) -> None: ...

34

def get_item_list() -> List[Any]: ...

35

def get() -> Optional[Any]: ...

36

def get_selected_item() -> Optional[Any]: ...

37

def is_empty() -> bool: ...

38

def set_selected_item(selected_item: Any) -> None: ...

39

def get_selected_item_index() -> int: ...

40

def set_selected_item_index(selected_item_index: int) -> None: ...

41

def clear() -> None: ...

42

def set_on_selection_change_event(callback: Callable[[Any], Any]) -> None: ...

43

```

44

45

Usage example:

46

```python

47

root = py_cui.PyCUI(3, 3)

48

menu = root.add_scroll_menu('Options', 0, 0, row_span=2)

49

50

menu.add_item('Option 1')

51

menu.add_item('Option 2')

52

menu.add_item_list(['Option 3', 'Option 4', 'Option 5'])

53

54

def handle_selection():

55

selected = menu.get_selected_item()

56

print(f'Selected: {selected}')

57

58

menu.add_key_command(py_cui.keys.KEY_ENTER, handle_selection)

59

```

60

61

### Checkbox Menu Widgets

62

63

Menu widgets with checkboxes for multiple selections.

64

65

```python { .api }

66

def add_checkbox_menu(title: str, row: int, column: int, row_span: int = 1,

67

column_span: int = 1, padx: int = 1, pady: int = 0,

68

checked_char: str = "X") -> CheckBoxMenu:

69

"""

70

Add a checkbox menu widget to the grid.

71

72

Parameters:

73

- title: Widget title displayed in border

74

- row: Grid row position (0-indexed)

75

- column: Grid column position (0-indexed)

76

- row_span: Number of rows to span (default: 1)

77

- column_span: Number of columns to span (default: 1)

78

- padx: Horizontal padding in characters (default: 1)

79

- pady: Vertical padding in characters (default: 0)

80

- checked_char: Character to display for checked items (default: "X")

81

82

Returns:

83

CheckBoxMenu widget instance

84

"""

85

86

class CheckBoxMenu:

87

def add_item(text: str, checked: bool = False) -> None: ...

88

def add_item_list(item_list: List[str]) -> None: ...

89

def get_checked_items() -> List[str]: ...

90

def mark_item_as_checked(item_index: int) -> None: ...

91

def mark_item_as_unchecked(item_index: int) -> None: ...

92

def toggle_item_checked(item_index: int) -> None: ...

93

```

94

95

Usage example:

96

```python

97

root = py_cui.PyCUI(3, 3)

98

checkbox_menu = root.add_checkbox_menu('Features', 0, 1, checked_char='✓')

99

100

checkbox_menu.add_item('Feature A', True) # Initially checked

101

checkbox_menu.add_item('Feature B', False)

102

checkbox_menu.add_item_list(['Feature C', 'Feature D'])

103

104

def show_checked():

105

checked = checkbox_menu.get_checked_items()

106

print(f'Checked items: {checked}')

107

108

def toggle_current():

109

current_index = checkbox_menu.get_selected_item_index()

110

checkbox_menu.toggle_item_checked(current_index)

111

112

checkbox_menu.add_key_command(py_cui.keys.KEY_SPACE, toggle_current)

113

```

114

115

### Text Input Widgets

116

117

Single-line text input widgets for user text entry.

118

119

```python { .api }

120

def add_text_box(title: str, row: int, column: int, row_span: int = 1,

121

column_span: int = 1, padx: int = 1, pady: int = 0,

122

initial_text: str = "", password: bool = False) -> TextBox:

123

"""

124

Add a text input box widget to the grid.

125

126

Parameters:

127

- title: Widget title displayed in border

128

- row: Grid row position (0-indexed)

129

- column: Grid column position (0-indexed)

130

- row_span: Number of rows to span (default: 1)

131

- column_span: Number of columns to span (default: 1)

132

- padx: Horizontal padding in characters (default: 1)

133

- pady: Vertical padding in characters (default: 0)

134

- initial_text: Initial text content (default: "")

135

- password: If True, display '*' instead of characters (default: False)

136

137

Returns:

138

TextBox widget instance

139

"""

140

141

class TextBox:

142

def get() -> str: ...

143

def set_text(text: str) -> None: ...

144

def clear() -> None: ...

145

def write(text: str) -> None: ...

146

```

147

148

Usage example:

149

```python

150

root = py_cui.PyCUI(3, 3)

151

name_box = root.add_text_box('Name', 0, 0, initial_text='Enter name...')

152

password_box = root.add_text_box('Password', 1, 0, password=True)

153

154

def submit_form():

155

name = name_box.get()

156

password = password_box.get()

157

print(f'Name: {name}, Password: {"*" * len(password)}')

158

159

submit_btn = root.add_button('Submit', 2, 0, command=submit_form)

160

```

161

162

### Multi-line Text Display

163

164

Scrollable text block widgets for displaying multi-line text content.

165

166

```python { .api }

167

def add_text_block(title: str, row: int, column: int, row_span: int = 1,

168

column_span: int = 1, padx: int = 1, pady: int = 0,

169

initial_text: str = "") -> ScrollTextBlock:

170

"""

171

Add a scrollable text block widget to the grid.

172

173

Parameters:

174

- title: Widget title displayed in border

175

- row: Grid row position (0-indexed)

176

- column: Grid column position (0-indexed)

177

- row_span: Number of rows to span (default: 1)

178

- column_span: Number of columns to span (default: 1)

179

- padx: Horizontal padding in characters (default: 1)

180

- pady: Vertical padding in characters (default: 0)

181

- initial_text: Initial text content (default: "")

182

183

Returns:

184

ScrollTextBlock widget instance

185

"""

186

187

class ScrollTextBlock:

188

def set_text(text: str) -> None: ...

189

def get_text() -> str: ...

190

def write(text: str) -> None: ...

191

def clear() -> None: ...

192

def scroll_up() -> None: ...

193

def scroll_down() -> None: ...

194

```

195

196

Usage example:

197

```python

198

root = py_cui.PyCUI(3, 3)

199

log_block = root.add_text_block('Log Output', 0, 0, row_span=3, column_span=2)

200

201

log_block.set_text('Application started...\nInitializing components...')

202

log_block.write('\nReady for input.')

203

204

# Add scroll controls

205

log_block.add_key_command(py_cui.keys.KEY_UP_ARROW, log_block.scroll_up)

206

log_block.add_key_command(py_cui.keys.KEY_DOWN_ARROW, log_block.scroll_down)

207

```

208

209

### Label Widgets

210

211

Simple text labels for displaying static text.

212

213

```python { .api }

214

def add_label(title: str, row: int, column: int, row_span: int = 1,

215

column_span: int = 1, padx: int = 1, pady: int = 0) -> Label:

216

"""

217

Add a simple label widget to the grid.

218

219

Parameters:

220

- title: Widget title and text content

221

- row: Grid row position (0-indexed)

222

- column: Grid column position (0-indexed)

223

- row_span: Number of rows to span (default: 1)

224

- column_span: Number of columns to span (default: 1)

225

- padx: Horizontal padding in characters (default: 1)

226

- pady: Vertical padding in characters (default: 0)

227

228

Returns:

229

Label widget instance

230

"""

231

232

def add_block_label(title: str, row: int, column: int, row_span: int = 1,

233

column_span: int = 1, padx: int = 1, pady: int = 0,

234

center: bool = True) -> BlockLabel:

235

"""

236

Add a block-style label widget to the grid.

237

238

Parameters:

239

- title: Widget title and text content

240

- row: Grid row position (0-indexed)

241

- column: Grid column position (0-indexed)

242

- row_span: Number of rows to span (default: 1)

243

- column_span: Number of columns to span (default: 1)

244

- padx: Horizontal padding in characters (default: 1)

245

- pady: Vertical padding in characters (default: 0)

246

- center: Whether to center the text (default: True)

247

248

Returns:

249

BlockLabel widget instance

250

"""

251

252

class Label:

253

def set_title(title: str) -> None: ...

254

def get_title() -> str: ...

255

256

class BlockLabel(Label):

257

def set_text(text: str) -> None: ...

258

def get_text() -> str: ...

259

```

260

261

Usage example:

262

```python

263

root = py_cui.PyCUI(3, 3)

264

header = root.add_block_label('Welcome to My App', 0, 0, column_span=3, center=True)

265

status = root.add_label('Status: Ready', 2, 0)

266

267

status.set_title('Status: Processing...')

268

```

269

270

### Button Widgets

271

272

Clickable button widgets that execute commands when activated.

273

274

```python { .api }

275

def add_button(title: str, row: int, column: int, row_span: int = 1,

276

column_span: int = 1, padx: int = 1, pady: int = 0,

277

command: Callable[[], Any] = None) -> Button:

278

"""

279

Add a button widget to the grid.

280

281

Parameters:

282

- title: Button text

283

- row: Grid row position (0-indexed)

284

- column: Grid column position (0-indexed)

285

- row_span: Number of rows to span (default: 1)

286

- column_span: Number of columns to span (default: 1)

287

- padx: Horizontal padding in characters (default: 1)

288

- pady: Vertical padding in characters (default: 0)

289

- command: Function to execute when button is pressed (optional)

290

291

Returns:

292

Button widget instance

293

"""

294

295

class Button:

296

def set_command(command: Callable[[], Any]) -> None: ...

297

def get_command() -> Callable[[], Any]: ...

298

```

299

300

Usage example:

301

```python

302

def save_data():

303

print('Saving data...')

304

305

def load_data():

306

print('Loading data...')

307

308

root = py_cui.PyCUI(3, 3)

309

save_btn = root.add_button('Save', 0, 0, command=save_data)

310

load_btn = root.add_button('Load', 0, 1, command=load_data)

311

312

# Change button command later

313

save_btn.set_command(lambda: print('Save with new logic'))

314

```

315

316

### Slider Widgets

317

318

Slider controls for numeric value selection.

319

320

```python { .api }

321

def add_slider(title: str, row: int, column: int, row_span: int = 1,

322

column_span: int = 1, padx: int = 1, pady: int = 0,

323

min_val: int = 0, max_val: int = 100, step: int = 1,

324

init_val: int = 0) -> SliderWidget:

325

"""

326

Add a slider widget to the grid.

327

328

Parameters:

329

- title: Widget title displayed in border

330

- row: Grid row position (0-indexed)

331

- column: Grid column position (0-indexed)

332

- row_span: Number of rows to span (default: 1)

333

- column_span: Number of columns to span (default: 1)

334

- padx: Horizontal padding in characters (default: 1)

335

- pady: Vertical padding in characters (default: 0)

336

- min_val: Minimum slider value (default: 0)

337

- max_val: Maximum slider value (default: 100)

338

- step: Step size for value changes (default: 1)

339

- init_val: Initial slider value (default: 0)

340

341

Returns:

342

SliderWidget instance

343

"""

344

345

class SliderWidget:

346

def get_slider_value() -> float: ...

347

def update_slider_value(offset: int) -> float: ...

348

def set_slider_step(step: int) -> None: ...

349

def set_bar_char(char: str) -> None: ...

350

def toggle_title() -> None: ...

351

def toggle_border() -> None: ...

352

def toggle_value() -> None: ...

353

def align_to_top() -> None: ...

354

```

355

356

Usage example:

357

```python

358

root = py_cui.PyCUI(3, 3)

359

volume_slider = root.add_slider('Volume', 0, 0, min_val=0, max_val=100, init_val=50)

360

361

def update_volume():

362

volume = volume_slider.get_slider_value()

363

print(f'Volume set to: {volume}%')

364

365

volume_slider.add_key_command(py_cui.keys.KEY_ENTER, update_volume)

366

```

367

368

### Custom Widget Support

369

370

System for adding custom widget types not included with py_cui by default.

371

372

```python { .api }

373

def add_custom_widget(widget_class: type, title: str, row: int, column: int,

374

row_span: int, column_span: int, padx: int, pady: int,

375

*args, **kwargs) -> Widget:

376

"""

377

Add a custom widget type to the grid.

378

379

Parameters:

380

- widget_class: Custom widget class (must inherit from Widget)

381

- title: Widget title displayed in border

382

- row: Grid row position (0-indexed)

383

- column: Grid column position (0-indexed)

384

- row_span: Number of rows to span

385

- column_span: Number of columns to span

386

- padx: Horizontal padding in characters

387

- pady: Vertical padding in characters

388

- *args, **kwargs: Additional arguments passed to widget constructor

389

390

Returns:

391

Custom widget instance

392

393

Raises:

394

TypeError: If widget_class is not a subclass of Widget

395

"""

396

```

397

398

Usage example:

399

```python

400

import py_cui

401

402

class CustomProgressBar(py_cui.widgets.Widget):

403

def __init__(self, id, title, grid, row, col, row_span, col_span, padx, pady, logger, max_val=100):

404

super().__init__(id, title, grid, row, col, row_span, col_span, padx, pady, logger)

405

self.max_val = max_val

406

self.current_val = 0

407

408

def set_progress(self, value):

409

self.current_val = min(value, self.max_val)

410

411

root = py_cui.PyCUI(3, 3)

412

progress = root.add_custom_widget(CustomProgressBar, 'Progress', 0, 0, 1, 2, 1, 0, max_val=200)

413

progress.set_progress(75)

414

```

415

416

### Widget Management

417

418

Functions for managing widgets after creation including selection, focus, and removal.

419

420

```python { .api }

421

def get_widgets() -> Dict[int, Optional[Widget]]:

422

"""

423

Get current set of widgets.

424

425

Returns:

426

Dictionary mapping widget IDs to widget instances

427

"""

428

429

def get_selected_widget() -> Optional[Widget]:

430

"""

431

Get currently selected widget.

432

433

Returns:

434

Currently selected widget instance or None

435

"""

436

437

def set_selected_widget(widget_id: int) -> None:

438

"""

439

Set the selected widget.

440

441

Parameters:

442

- widget_id: ID of widget to select

443

"""

444

445

def move_focus(widget: Widget, auto_press_buttons: bool = True) -> None:

446

"""

447

Move focus to specified widget.

448

449

Parameters:

450

- widget: Widget to focus on

451

- auto_press_buttons: Whether to auto-execute button commands (default: True)

452

"""

453

454

def lose_focus() -> None:

455

"""Exit focus mode and return to overview mode."""

456

457

def forget_widget(widget: Widget) -> None:

458

"""

459

Remove widget from the UI.

460

461

Parameters:

462

- widget: Widget to remove

463

464

Raises:

465

TypeError: If widget is not a Widget instance

466

KeyError: If widget does not exist in current UI

467

"""

468

```

469

470

Usage example:

471

```python

472

root = py_cui.PyCUI(3, 3)

473

menu = root.add_scroll_menu('Menu', 0, 0)

474

button = root.add_button('Focus Menu', 1, 0, command=lambda: root.move_focus(menu))

475

476

# Get all widgets

477

widgets = root.get_widgets()

478

print(f'Total widgets: {len([w for w in widgets.values() if w is not None])}')

479

480

# Remove widget

481

root.forget_widget(button)

482

```