or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application.mdaudio.mdfiles.mdgraphics.mdindex.mdinput.mdnetworking.mdpreloader.mdwebaudio.mdwidgets.md

widgets.mddocs/

0

# UI Widgets

1

2

The GWT backend provides web-specific UI components designed for browser integration and responsive behavior. These widgets handle common web deployment needs like progress indication, text input dialogs, and responsive layout management.

3

4

## Core Widget Interfaces

5

6

### ResizableWidget { .api }

7

8

```java

9

public interface ResizableWidget {

10

void resize(int width, int height);

11

}

12

```

13

14

### ResizableWidgetCollection { .api }

15

16

```java

17

public class ResizableWidgetCollection implements ResizeHandler, Iterable<ResizableWidget> {

18

// Widget management

19

public void add(ResizableWidget widget);

20

public boolean remove(ResizableWidget widget);

21

public void clear();

22

public int size();

23

24

// Resize handling

25

public void onResize(ResizeEvent event);

26

27

// Iteration support

28

public Iterator<ResizableWidget> iterator();

29

30

// Manual resize trigger

31

public void resize(int width, int height);

32

}

33

```

34

35

## Progress Display Widgets

36

37

### ProgressBar { .api }

38

39

```java

40

public class ProgressBar extends Widget implements ResizableWidget {

41

// Progress control

42

public void setValue(float value); // 0.0 to 1.0

43

public float getValue();

44

45

// Appearance

46

public void setVisible(boolean visible);

47

public boolean isVisible();

48

public void setAnimated(boolean animated);

49

public boolean isAnimated();

50

51

// Styling

52

public void setProgressColor(String color);

53

public void setBackgroundColor(String color);

54

public void setBorderColor(String color);

55

public void setHeight(int height);

56

57

// Text display

58

public void setShowText(boolean showText);

59

public boolean isShowText();

60

public void setTextFormat(String format); // e.g., "{0}%" for percentage

61

62

// ResizableWidget implementation

63

public void resize(int width, int height);

64

65

// Widget positioning

66

public void setPosition(int x, int y);

67

public void setSize(int width, int height);

68

69

// Constructors

70

public ProgressBar();

71

public ProgressBar(int width, int height);

72

}

73

```

74

75

## Text Input Widgets

76

77

### TextInputDialogBox { .api }

78

79

```java

80

public class TextInputDialogBox extends DialogBox {

81

// Dialog display

82

public void show(String title, String text, TextInputListener listener);

83

public void show(String title, String text, String hint, TextInputListener listener);

84

public void hide();

85

86

// Dialog configuration

87

public void setModal(boolean modal);

88

public boolean isModal();

89

public void setAnimationEnabled(boolean enabled);

90

public boolean isAnimationEnabled();

91

92

// Input validation

93

public void setValidator(InputValidator validator);

94

public InputValidator getValidator();

95

public void setMaxLength(int maxLength);

96

public int getMaxLength();

97

98

// Styling

99

public void setDialogStyle(String styleName);

100

public void setButtonText(String okText, String cancelText);

101

102

// Event handling

103

public interface TextInputListener {

104

void input(String text);

105

void canceled();

106

}

107

108

public interface InputValidator {

109

boolean isValid(String input);

110

String getErrorMessage();

111

}

112

113

// Constructors

114

public TextInputDialogBox();

115

public TextInputDialogBox(boolean autoHide);

116

}

117

```

118

119

### PlaceholderTextBox { .api }

120

121

```java

122

public class PlaceholderTextBox extends TextBox {

123

// Placeholder functionality

124

public void setPlaceholder(String placeholder);

125

public String getPlaceholder();

126

127

// Enhanced text input

128

public void selectAll();

129

public void setSelectionRange(int start, int length);

130

public String getSelectedText();

131

132

// Input filtering

133

public void setInputFilter(InputFilter filter);

134

public InputFilter getInputFilter();

135

136

// Event handling

137

public void addValueChangeHandler(ValueChangeHandler<String> handler);

138

public void addKeyUpHandler(KeyUpHandler handler);

139

public void addFocusHandler(FocusHandler handler);

140

public void addBlurHandler(BlurHandler handler);

141

142

// Styling enhancements

143

public void setErrorStyle(boolean error);

144

public boolean hasErrorStyle();

145

146

public interface InputFilter {

147

boolean accept(char character);

148

String filter(String input);

149

}

150

151

// Constructors

152

public PlaceholderTextBox();

153

public PlaceholderTextBox(String placeholder);

154

}

155

```

156

157

## Usage Examples

158

159

### Loading Screen with Progress Bar

160

161

```java

162

public class LoadingScreen implements Screen {

163

private ProgressBar progressBar;

164

private ResizableWidgetCollection widgets;

165

private Stage stage;

166

private Label statusLabel;

167

168

public LoadingScreen() {

169

stage = new Stage();

170

widgets = new ResizableWidgetCollection();

171

172

// Create progress bar

173

progressBar = new ProgressBar(400, 30);

174

progressBar.setProgressColor("#00ff00");

175

progressBar.setBackgroundColor("#333333");

176

progressBar.setBorderColor("#666666");

177

progressBar.setShowText(true);

178

progressBar.setTextFormat("{0}%");

179

progressBar.setAnimated(true);

180

181

// Add to widget collection for automatic resizing

182

widgets.add(progressBar);

183

184

// Create status label

185

statusLabel = new Label("Loading...", new Label.LabelStyle());

186

187

// Position widgets

188

layoutWidgets();

189

190

// Handle window resize

191

Gdx.graphics.setResizeCallback(new Graphics.ResizeCallback() {

192

@Override

193

public void onResize(int width, int height) {

194

widgets.resize(width, height);

195

layoutWidgets();

196

}

197

});

198

}

199

200

@Override

201

public void show() {

202

Gdx.input.setInputProcessor(stage);

203

}

204

205

@Override

206

public void render(float delta) {

207

// Update progress (example: based on asset loading)

208

updateProgress();

209

210

// Clear screen

211

Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);

212

Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

213

214

// Render UI

215

stage.act(delta);

216

stage.draw();

217

}

218

219

private void updateProgress() {

220

// Example: Update based on preloader state

221

if (MyGame.getPreloader() != null) {

222

Preloader.PreloaderState state = MyGame.getPreloader().update();

223

float progress = state.getProgress();

224

225

progressBar.setValue(progress);

226

227

// Update status text

228

if (progress < 0.3f) {

229

statusLabel.setText("Loading graphics...");

230

} else if (progress < 0.6f) {

231

statusLabel.setText("Loading audio...");

232

} else if (progress < 0.9f) {

233

statusLabel.setText("Loading data...");

234

} else if (progress < 1.0f) {

235

statusLabel.setText("Finalizing...");

236

} else {

237

statusLabel.setText("Complete!");

238

}

239

}

240

}

241

242

private void layoutWidgets() {

243

int screenWidth = Gdx.graphics.getWidth();

244

int screenHeight = Gdx.graphics.getHeight();

245

246

// Center progress bar

247

int barX = (screenWidth - 400) / 2;

248

int barY = (screenHeight - 30) / 2;

249

progressBar.setPosition(barX, barY);

250

251

// Position status label above progress bar

252

statusLabel.setPosition(barX, barY + 50);

253

}

254

255

// ... other Screen methods

256

}

257

```

258

259

### Text Input Dialog System

260

261

```java

262

public class TextInputManager {

263

private TextInputDialogBox currentDialog;

264

265

public void showNameInput(TextInputListener listener) {

266

if (currentDialog != null) {

267

currentDialog.hide();

268

}

269

270

currentDialog = new TextInputDialogBox();

271

currentDialog.setModal(true);

272

currentDialog.setAnimationEnabled(true);

273

currentDialog.setButtonText("OK", "Cancel");

274

275

// Set up validation

276

currentDialog.setValidator(new TextInputDialogBox.InputValidator() {

277

@Override

278

public boolean isValid(String input) {

279

return input != null && input.trim().length() >= 2 && input.length() <= 20;

280

}

281

282

@Override

283

public String getErrorMessage() {

284

return "Name must be 2-20 characters long";

285

}

286

});

287

288

currentDialog.show("Enter Your Name", "", "Your name here", new TextInputDialogBox.TextInputListener() {

289

@Override

290

public void input(String text) {

291

currentDialog = null;

292

if (listener != null) {

293

listener.input(text.trim());

294

}

295

}

296

297

@Override

298

public void canceled() {

299

currentDialog = null;

300

if (listener != null) {

301

listener.canceled();

302

}

303

}

304

});

305

}

306

307

public void showScoreInput(int currentHighScore, TextInputListener listener) {

308

if (currentDialog != null) {

309

currentDialog.hide();

310

}

311

312

currentDialog = new TextInputDialogBox();

313

currentDialog.setMaxLength(10);

314

315

// Numeric validation

316

currentDialog.setValidator(new TextInputDialogBox.InputValidator() {

317

@Override

318

public boolean isValid(String input) {

319

try {

320

int score = Integer.parseInt(input);

321

return score > currentHighScore;

322

} catch (NumberFormatException e) {

323

return false;

324

}

325

}

326

327

@Override

328

public String getErrorMessage() {

329

return "Enter a score higher than " + currentHighScore;

330

}

331

});

332

333

currentDialog.show("New High Score!", "", "Enter score", listener);

334

}

335

336

public void showCustomDialog(String title, String defaultText, String hint,

337

TextInputDialogBox.InputValidator validator,

338

TextInputListener listener) {

339

if (currentDialog != null) {

340

currentDialog.hide();

341

}

342

343

currentDialog = new TextInputDialogBox();

344

if (validator != null) {

345

currentDialog.setValidator(validator);

346

}

347

348

currentDialog.show(title, defaultText, hint, listener);

349

}

350

351

public void hideCurrentDialog() {

352

if (currentDialog != null) {

353

currentDialog.hide();

354

currentDialog = null;

355

}

356

}

357

358

public boolean isDialogShowing() {

359

return currentDialog != null;

360

}

361

}

362

```

363

364

### Enhanced Text Input with Filtering

365

366

```java

367

public class GameTextInput extends PlaceholderTextBox {

368

private InputType inputType;

369

370

public enum InputType {

371

ALPHA_ONLY,

372

NUMERIC_ONLY,

373

ALPHANUMERIC,

374

EMAIL,

375

PASSWORD,

376

CUSTOM

377

}

378

379

public GameTextInput(InputType type) {

380

super();

381

this.inputType = type;

382

setupInputFilter();

383

setupStyling();

384

}

385

386

public GameTextInput(String placeholder, InputType type) {

387

super(placeholder);

388

this.inputType = type;

389

setupInputFilter();

390

setupStyling();

391

}

392

393

private void setupInputFilter() {

394

switch (inputType) {

395

case ALPHA_ONLY:

396

setInputFilter(new InputFilter() {

397

@Override

398

public boolean accept(char c) {

399

return Character.isLetter(c) || Character.isWhitespace(c);

400

}

401

402

@Override

403

public String filter(String input) {

404

return input.replaceAll("[^a-zA-Z\\s]", "");

405

}

406

});

407

break;

408

409

case NUMERIC_ONLY:

410

setInputFilter(new InputFilter() {

411

@Override

412

public boolean accept(char c) {

413

return Character.isDigit(c) || c == '.' || c == '-';

414

}

415

416

@Override

417

public String filter(String input) {

418

return input.replaceAll("[^0-9.-]", "");

419

}

420

});

421

break;

422

423

case ALPHANUMERIC:

424

setInputFilter(new InputFilter() {

425

@Override

426

public boolean accept(char c) {

427

return Character.isLetterOrDigit(c) || Character.isWhitespace(c);

428

}

429

430

@Override

431

public String filter(String input) {

432

return input.replaceAll("[^a-zA-Z0-9\\s]", "");

433

}

434

});

435

break;

436

437

case EMAIL:

438

setInputFilter(new InputFilter() {

439

@Override

440

public boolean accept(char c) {

441

return Character.isLetterOrDigit(c) || c == '@' || c == '.' || c == '_' || c == '-';

442

}

443

444

@Override

445

public String filter(String input) {

446

return input.replaceAll("[^a-zA-Z0-9@._-]", "").toLowerCase();

447

}

448

});

449

break;

450

}

451

}

452

453

private void setupStyling() {

454

// Add focus/blur styling

455

addFocusHandler(new FocusHandler() {

456

@Override

457

public void onFocus(FocusEvent event) {

458

getElement().getStyle().setBorderColor("#4CAF50");

459

getElement().getStyle().setProperty("boxShadow", "0 0 5px rgba(76, 175, 80, 0.5)");

460

}

461

});

462

463

addBlurHandler(new BlurHandler() {

464

@Override

465

public void onBlur(BlurEvent event) {

466

getElement().getStyle().setBorderColor("#ccc");

467

getElement().getStyle().setProperty("boxShadow", "none");

468

469

// Validate input on blur

470

validateInput();

471

}

472

});

473

474

// Real-time validation

475

addValueChangeHandler(new ValueChangeHandler<String>() {

476

@Override

477

public void onValueChange(ValueChangeEvent<String> event) {

478

validateInput();

479

}

480

});

481

}

482

483

private void validateInput() {

484

String value = getText();

485

boolean isValid = true;

486

487

switch (inputType) {

488

case EMAIL:

489

isValid = value.matches("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$");

490

break;

491

case NUMERIC_ONLY:

492

try {

493

Double.parseDouble(value);

494

} catch (NumberFormatException e) {

495

isValid = !value.isEmpty();

496

}

497

break;

498

}

499

500

setErrorStyle(!isValid);

501

}

502

503

public boolean isValidInput() {

504

validateInput();

505

return !hasErrorStyle();

506

}

507

508

public String getValidatedText() {

509

if (isValidInput()) {

510

return getText();

511

}

512

return null;

513

}

514

}

515

```

516

517

### Responsive Widget Layout Manager

518

519

```java

520

public class ResponsiveLayoutManager {

521

private ResizableWidgetCollection widgets;

522

private Map<ResizableWidget, LayoutConstraints> constraints;

523

524

public static class LayoutConstraints {

525

public float percentX, percentY; // Position as percentage of screen

526

public float percentWidth, percentHeight; // Size as percentage of screen

527

public int minWidth, minHeight; // Minimum pixel sizes

528

public int maxWidth, maxHeight; // Maximum pixel sizes

529

public Anchor anchor; // Anchor point for positioning

530

531

public enum Anchor {

532

TOP_LEFT, TOP_CENTER, TOP_RIGHT,

533

MIDDLE_LEFT, MIDDLE_CENTER, MIDDLE_RIGHT,

534

BOTTOM_LEFT, BOTTOM_CENTER, BOTTOM_RIGHT

535

}

536

}

537

538

public ResponsiveLayoutManager() {

539

widgets = new ResizableWidgetCollection();

540

constraints = new HashMap<>();

541

542

// Listen for window resize events

543

Window.addResizeHandler(new ResizeHandler() {

544

@Override

545

public void onResize(ResizeEvent event) {

546

layoutAllWidgets();

547

}

548

});

549

}

550

551

public void addWidget(ResizableWidget widget, LayoutConstraints layoutConstraints) {

552

widgets.add(widget);

553

constraints.put(widget, layoutConstraints);

554

layoutWidget(widget, layoutConstraints);

555

}

556

557

public void removeWidget(ResizableWidget widget) {

558

widgets.remove(widget);

559

constraints.remove(widget);

560

}

561

562

public void layoutAllWidgets() {

563

for (ResizableWidget widget : widgets) {

564

LayoutConstraints constraint = constraints.get(widget);

565

if (constraint != null) {

566

layoutWidget(widget, constraint);

567

}

568

}

569

}

570

571

private void layoutWidget(ResizableWidget widget, LayoutConstraints constraint) {

572

int screenWidth = Gdx.graphics.getWidth();

573

int screenHeight = Gdx.graphics.getHeight();

574

575

// Calculate size

576

int width = (int)(screenWidth * constraint.percentWidth);

577

int height = (int)(screenHeight * constraint.percentHeight);

578

579

// Apply size constraints

580

width = Math.max(constraint.minWidth, Math.min(constraint.maxWidth, width));

581

height = Math.max(constraint.minHeight, Math.min(constraint.maxHeight, height));

582

583

// Calculate position based on anchor

584

int x = calculateAnchoredX(screenWidth, width, constraint);

585

int y = calculateAnchoredY(screenHeight, height, constraint);

586

587

// Apply layout

588

widget.resize(width, height);

589

590

// Set position if widget supports it

591

if (widget instanceof Widget) {

592

((Widget) widget).setPixelSize(width, height);

593

// Position setting depends on widget implementation

594

}

595

}

596

597

private int calculateAnchoredX(int screenWidth, int widgetWidth, LayoutConstraints constraint) {

598

int baseX = (int)(screenWidth * constraint.percentX);

599

600

switch (constraint.anchor) {

601

case TOP_LEFT:

602

case MIDDLE_LEFT:

603

case BOTTOM_LEFT:

604

return baseX;

605

case TOP_CENTER:

606

case MIDDLE_CENTER:

607

case BOTTOM_CENTER:

608

return baseX - widgetWidth / 2;

609

case TOP_RIGHT:

610

case MIDDLE_RIGHT:

611

case BOTTOM_RIGHT:

612

return baseX - widgetWidth;

613

default:

614

return baseX;

615

}

616

}

617

618

private int calculateAnchoredY(int screenHeight, int widgetHeight, LayoutConstraints constraint) {

619

int baseY = (int)(screenHeight * constraint.percentY);

620

621

switch (constraint.anchor) {

622

case TOP_LEFT:

623

case TOP_CENTER:

624

case TOP_RIGHT:

625

return baseY;

626

case MIDDLE_LEFT:

627

case MIDDLE_CENTER:

628

case MIDDLE_RIGHT:

629

return baseY - widgetHeight / 2;

630

case BOTTOM_LEFT:

631

case BOTTOM_CENTER:

632

case BOTTOM_RIGHT:

633

return baseY - widgetHeight;

634

default:

635

return baseY;

636

}

637

}

638

639

// Predefined constraint builders

640

public static LayoutConstraints centerScreen(float percentWidth, float percentHeight) {

641

LayoutConstraints constraints = new LayoutConstraints();

642

constraints.percentX = 0.5f;

643

constraints.percentY = 0.5f;

644

constraints.percentWidth = percentWidth;

645

constraints.percentHeight = percentHeight;

646

constraints.anchor = LayoutConstraints.Anchor.MIDDLE_CENTER;

647

constraints.minWidth = 100;

648

constraints.minHeight = 50;

649

constraints.maxWidth = Integer.MAX_VALUE;

650

constraints.maxHeight = Integer.MAX_VALUE;

651

return constraints;

652

}

653

654

public static LayoutConstraints bottomCenter(float percentWidth, float height) {

655

LayoutConstraints constraints = new LayoutConstraints();

656

constraints.percentX = 0.5f;

657

constraints.percentY = 0.1f;

658

constraints.percentWidth = percentWidth;

659

constraints.percentHeight = 0; // Fixed height

660

constraints.anchor = LayoutConstraints.Anchor.BOTTOM_CENTER;

661

constraints.minWidth = 200;

662

constraints.minHeight = (int)height;

663

constraints.maxWidth = Integer.MAX_VALUE;

664

constraints.maxHeight = (int)height;

665

return constraints;

666

}

667

}

668

```

669

670

## Web-Specific Widget Considerations

671

672

### Browser Integration

673

674

```java

675

// Widgets are designed for web browser environments

676

public class BrowserIntegrationHelper {

677

678

public static void configureForMobile() {

679

// Optimize widgets for mobile browsers

680

ProgressBar.setDefaultHeight(40); // Larger for touch

681

TextInputDialogBox.setDefaultAnimationDuration(200); // Faster for mobile

682

683

// Handle virtual keyboard

684

PlaceholderTextBox.addGlobalFocusHandler(new FocusHandler() {

685

@Override

686

public void onFocus(FocusEvent event) {

687

// Scroll input into view when virtual keyboard appears

688

Element element = event.getSource().getElement();

689

element.scrollIntoView();

690

}

691

});

692

}

693

694

public static void configureForDesktop() {

695

// Optimize for desktop browsers

696

ProgressBar.setDefaultHeight(24); // Standard height

697

TextInputDialogBox.setDefaultAnimationDuration(300); // Smooth animations

698

699

// Enable advanced keyboard shortcuts

700

configureKeyboardShortcuts();

701

}

702

703

private static void configureKeyboardShortcuts() {

704

// Add Ctrl+A, Ctrl+C, Ctrl+V support for text inputs

705

// This is handled automatically by PlaceholderTextBox

706

}

707

}