table CSV and text file
[fanfix.git] / src / jexer / TWidget.java
CommitLineData
daa4106c 1/*
48e27807
KL
2 * Jexer - Java Text User Interface
3 *
e16dda65 4 * The MIT License (MIT)
48e27807 5 *
a69ed767 6 * Copyright (C) 2019 Kevin Lamonte
48e27807 7 *
e16dda65
KL
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
48e27807 14 *
e16dda65
KL
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
48e27807 17 *
e16dda65
KL
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
48e27807
KL
25 *
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
27 * @version 1
28 */
29package jexer;
30
382bc294 31import java.awt.image.BufferedImage;
0d47c546 32import java.io.IOException;
48e27807 33import java.util.List;
2ce6dab2 34import java.util.ArrayList;
48e27807 35
42873e30 36import jexer.backend.Screen;
a69ed767
KL
37import jexer.bits.Cell;
38import jexer.bits.CellAttributes;
928811d8 39import jexer.bits.ColorTheme;
48e27807
KL
40import jexer.event.TCommandEvent;
41import jexer.event.TInputEvent;
42import jexer.event.TKeypressEvent;
43import jexer.event.TMenuEvent;
44import jexer.event.TMouseEvent;
45import jexer.event.TResizeEvent;
928811d8 46import jexer.menu.TMenu;
d36057df
KL
47import jexer.ttree.TTreeItem;
48import jexer.ttree.TTreeView;
49import jexer.ttree.TTreeViewWidget;
48e27807
KL
50import static jexer.TKeypress.*;
51
52/**
53 * TWidget is the base class of all objects that can be drawn on screen or
54 * handle user input events.
55 */
2b9c27db 56public abstract class TWidget implements Comparable<TWidget> {
48e27807 57
2ce6dab2 58 // ------------------------------------------------------------------------
d36057df 59 // Variables --------------------------------------------------------------
2ce6dab2
KL
60 // ------------------------------------------------------------------------
61
48e27807
KL
62 /**
63 * Every widget has a parent widget that it may be "contained" in. For
051e2913
KL
64 * example, a TWindow might contain several TFields, or a TComboBox may
65 * contain a TList that itself contains a TVScroller.
48e27807 66 */
fca67db0
KL
67 private TWidget parent = null;
68
48e27807
KL
69 /**
70 * Child widgets that this widget contains.
71 */
72 private List<TWidget> children;
73
74 /**
75 * The currently active child widget that will receive keypress events.
76 */
77 private TWidget activeChild = null;
78
79 /**
80 * If true, this widget will receive events.
81 */
fca67db0
KL
82 private boolean active = false;
83
48e27807
KL
84 /**
85 * The window that this widget draws to.
86 */
fca67db0 87 private TWindow window = null;
48e27807
KL
88
89 /**
90 * Absolute X position of the top-left corner.
91 */
fca67db0
KL
92 private int x = 0;
93
94 /**
d36057df 95 * Absolute Y position of the top-left corner.
fca67db0 96 */
d36057df 97 private int y = 0;
fca67db0
KL
98
99 /**
d36057df 100 * Width.
fca67db0 101 */
d36057df 102 private int width = 0;
48e27807
KL
103
104 /**
d36057df 105 * Height.
48e27807 106 */
d36057df 107 private int height = 0;
fca67db0
KL
108
109 /**
d36057df 110 * My tab order inside a window or containing widget.
fca67db0 111 */
d36057df 112 private int tabOrder = 0;
fca67db0
KL
113
114 /**
d36057df 115 * If true, this widget can be tabbed to or receive events.
fca67db0 116 */
d36057df 117 private boolean enabled = true;
48e27807 118
051e2913
KL
119 /**
120 * If true, this widget will be rendered.
121 */
122 private boolean visible = true;
123
48e27807 124 /**
d36057df 125 * If true, this widget has a cursor.
48e27807 126 */
d36057df 127 private boolean cursorVisible = false;
fca67db0
KL
128
129 /**
d36057df 130 * Cursor column position in relative coordinates.
fca67db0 131 */
d36057df 132 private int cursorX = 0;
fca67db0
KL
133
134 /**
d36057df 135 * Cursor row position in relative coordinates.
fca67db0 136 */
d36057df 137 private int cursorY = 0;
48e27807 138
d36057df
KL
139 // ------------------------------------------------------------------------
140 // Constructors -----------------------------------------------------------
141 // ------------------------------------------------------------------------
fca67db0
KL
142
143 /**
d36057df 144 * Default constructor for subclasses.
fca67db0 145 */
d36057df
KL
146 protected TWidget() {
147 children = new ArrayList<TWidget>();
fca67db0
KL
148 }
149
150 /**
d36057df 151 * Protected constructor.
fca67db0 152 *
d36057df 153 * @param parent parent widget
fca67db0 154 */
d36057df
KL
155 protected TWidget(final TWidget parent) {
156 this(parent, true);
fca67db0 157 }
48e27807 158
0ee88b6d 159 /**
d36057df 160 * Protected constructor.
0ee88b6d 161 *
d36057df
KL
162 * @param parent parent widget
163 * @param x column relative to parent
164 * @param y row relative to parent
165 * @param width width of widget
166 * @param height height of widget
0ee88b6d 167 */
d36057df
KL
168 protected TWidget(final TWidget parent, final int x, final int y,
169 final int width, final int height) {
0ee88b6d 170
d36057df 171 this(parent, true, x, y, width, height);
0ee88b6d
KL
172 }
173
48e27807 174 /**
d36057df 175 * Protected constructor used by subclasses that are disabled by default.
48e27807 176 *
d36057df
KL
177 * @param parent parent widget
178 * @param enabled if true assume enabled
48e27807 179 */
d36057df
KL
180 protected TWidget(final TWidget parent, final boolean enabled) {
181 this.enabled = enabled;
182 this.parent = parent;
183 this.window = parent.window;
184 children = new ArrayList<TWidget>();
185
a69ed767 186 // Do not add TStatusBars, they are drawn by TApplication.
d36057df 187 if (this instanceof TStatusBar) {
a69ed767 188 // NOP
d36057df
KL
189 } else {
190 parent.addChild(this);
191 }
48e27807
KL
192 }
193
194 /**
d36057df 195 * Protected constructor used by subclasses that are disabled by default.
48e27807 196 *
d36057df
KL
197 * @param parent parent widget
198 * @param enabled if true assume enabled
199 * @param x column relative to parent
200 * @param y row relative to parent
201 * @param width width of widget
202 * @param height height of widget
48e27807 203 */
d36057df
KL
204 protected TWidget(final TWidget parent, final boolean enabled,
205 final int x, final int y, final int width, final int height) {
206
48e27807 207 this.enabled = enabled;
d36057df
KL
208 this.parent = parent;
209 this.window = parent.window;
210 children = new ArrayList<TWidget>();
211
a69ed767 212 // Do not add TStatusBars, they are drawn by TApplication.
d36057df 213 if (this instanceof TStatusBar) {
a69ed767 214 // NOP
d36057df
KL
215 } else {
216 parent.addChild(this);
48e27807 217 }
48e27807 218
d36057df
KL
219 this.x = x;
220 this.y = y;
221 this.width = width;
222 this.height = height;
223 }
48e27807 224
7272e49f 225 /**
d36057df 226 * Backdoor access for TWindow's constructor. ONLY TWindow USES THIS.
7272e49f 227 *
d36057df
KL
228 * @param window the top-level window
229 * @param x column relative to parent
230 * @param y row relative to parent
231 * @param width width of window
232 * @param height height of window
7272e49f 233 */
d36057df
KL
234 protected final void setupForTWindow(final TWindow window,
235 final int x, final int y, final int width, final int height) {
236
237 this.parent = window;
238 this.window = window;
239 this.x = x;
240 this.y = y;
241 this.width = width;
242 this.height = height;
7272e49f
KL
243 }
244
d36057df
KL
245 // ------------------------------------------------------------------------
246 // Event handlers ---------------------------------------------------------
247 // ------------------------------------------------------------------------
248
a69ed767
KL
249 /**
250 * Subclasses should override this method to cleanup resources. This is
251 * called by TWindow.onClose().
252 */
253 protected void close() {
254 // Default: call close() on children.
255 for (TWidget w: getChildren()) {
256 w.close();
257 }
258 }
259
a06459bd 260 /**
d36057df
KL
261 * Check if a mouse press/release event coordinate is contained in this
262 * widget.
a06459bd 263 *
d36057df
KL
264 * @param mouse a mouse-based event
265 * @return whether or not a mouse click would be sent to this widget
a06459bd 266 */
d36057df
KL
267 public final boolean mouseWouldHit(final TMouseEvent mouse) {
268
269 if (!enabled) {
24489803
KL
270 return false;
271 }
272
d36057df
KL
273 if ((this instanceof TTreeItem)
274 && ((y < 0) || (y > parent.getHeight() - 1))
24489803
KL
275 ) {
276 return false;
277 }
a06459bd 278
d36057df
KL
279 if ((mouse.getAbsoluteX() >= getAbsoluteX())
280 && (mouse.getAbsoluteX() < getAbsoluteX() + width)
281 && (mouse.getAbsoluteY() >= getAbsoluteY())
282 && (mouse.getAbsoluteY() < getAbsoluteY() + height)
283 ) {
284 return true;
285 }
286 return false;
287 }
48e27807 288
7272e49f 289 /**
d36057df 290 * Method that subclasses can override to handle keystrokes.
7272e49f 291 *
d36057df 292 * @param keypress keystroke event
7272e49f 293 */
d36057df
KL
294 public void onKeypress(final TKeypressEvent keypress) {
295
296 if ((children.size() == 0)
297 || (this instanceof TTreeView)
298 || (this instanceof TText)
a69ed767 299 || (this instanceof TComboBox)
d36057df
KL
300 ) {
301
302 // Defaults:
303 // tab / shift-tab - switch to next/previous widget
304 // left-arrow or up-arrow: same as shift-tab
305 if ((keypress.equals(kbTab))
a69ed767 306 || (keypress.equals(kbDown) && !(this instanceof TComboBox))
d36057df
KL
307 ) {
308 parent.switchWidget(true);
309 return;
310 } else if ((keypress.equals(kbShiftTab))
311 || (keypress.equals(kbBackTab))
a69ed767 312 || (keypress.equals(kbUp) && !(this instanceof TComboBox))
d36057df
KL
313 ) {
314 parent.switchWidget(false);
315 return;
316 }
317 }
318
319 if ((children.size() == 0)
320 && !(this instanceof TTreeView)
321 ) {
322
323 // Defaults:
324 // right-arrow or down-arrow: same as tab
325 if (keypress.equals(kbRight)) {
326 parent.switchWidget(true);
327 return;
328 } else if (keypress.equals(kbLeft)) {
329 parent.switchWidget(false);
330 return;
331 }
332 }
333
334 // If I have any buttons on me AND this is an Alt-key that matches
00691e80 335 // its mnemonic, send it an Enter keystroke.
d36057df
KL
336 for (TWidget widget: children) {
337 if (widget instanceof TButton) {
338 TButton button = (TButton) widget;
339 if (button.isEnabled()
340 && !keypress.getKey().isFnKey()
341 && keypress.getKey().isAlt()
342 && !keypress.getKey().isCtrl()
343 && (Character.toLowerCase(button.getMnemonic().getShortcut())
344 == Character.toLowerCase(keypress.getKey().getChar()))
345 ) {
346
347 widget.onKeypress(new TKeypressEvent(kbEnter));
348 return;
349 }
350 }
351 }
352
00691e80
KL
353 // If I have any labels on me AND this is an Alt-key that matches
354 // its mnemonic, call its action.
355 for (TWidget widget: children) {
356 if (widget instanceof TLabel) {
357 TLabel label = (TLabel) widget;
358 if (!keypress.getKey().isFnKey()
359 && keypress.getKey().isAlt()
360 && !keypress.getKey().isCtrl()
361 && (Character.toLowerCase(label.getMnemonic().getShortcut())
362 == Character.toLowerCase(keypress.getKey().getChar()))
363 ) {
364
365 label.dispatch();
366 return;
367 }
368 }
369 }
370
371 // If I have any radiobuttons on me AND this is an Alt-key that
372 // matches its mnemonic, select it and send a Space to it.
373 for (TWidget widget: children) {
374 if (widget instanceof TRadioButton) {
375 TRadioButton button = (TRadioButton) widget;
376 if (button.isEnabled()
377 && !keypress.getKey().isFnKey()
378 && keypress.getKey().isAlt()
379 && !keypress.getKey().isCtrl()
380 && (Character.toLowerCase(button.getMnemonic().getShortcut())
381 == Character.toLowerCase(keypress.getKey().getChar()))
382 ) {
383 activate(widget);
384 widget.onKeypress(new TKeypressEvent(kbSpace));
385 return;
386 }
387 }
388 if (widget instanceof TRadioGroup) {
389 for (TWidget child: widget.getChildren()) {
390 if (child instanceof TRadioButton) {
391 TRadioButton button = (TRadioButton) child;
392 if (button.isEnabled()
393 && !keypress.getKey().isFnKey()
394 && keypress.getKey().isAlt()
395 && !keypress.getKey().isCtrl()
396 && (Character.toLowerCase(button.getMnemonic().getShortcut())
397 == Character.toLowerCase(keypress.getKey().getChar()))
398 ) {
399 activate(widget);
400 widget.activate(child);
401 child.onKeypress(new TKeypressEvent(kbSpace));
402 return;
403 }
404 }
405 }
406 }
407 }
408
409 // If I have any checkboxes on me AND this is an Alt-key that matches
410 // its mnemonic, select it and set it to checked.
411 for (TWidget widget: children) {
412 if (widget instanceof TCheckBox) {
413 TCheckBox checkBox = (TCheckBox) widget;
414 if (checkBox.isEnabled()
415 && !keypress.getKey().isFnKey()
416 && keypress.getKey().isAlt()
417 && !keypress.getKey().isCtrl()
418 && (Character.toLowerCase(checkBox.getMnemonic().getShortcut())
419 == Character.toLowerCase(keypress.getKey().getChar()))
420 ) {
421 activate(checkBox);
422 checkBox.setChecked(true);
423 return;
424 }
425 }
426 }
427
d36057df
KL
428 // Dispatch the keypress to an active widget
429 for (TWidget widget: children) {
430 if (widget.active) {
431 widget.onKeypress(keypress);
432 return;
433 }
434 }
7272e49f
KL
435 }
436
437 /**
d36057df 438 * Method that subclasses can override to handle mouse button presses.
7272e49f 439 *
d36057df 440 * @param mouse mouse button event
7272e49f 441 */
d36057df
KL
442 public void onMouseDown(final TMouseEvent mouse) {
443 // Default: do nothing, pass to children instead
a69ed767
KL
444 if (activeChild != null) {
445 if (activeChild.mouseWouldHit(mouse)) {
446 // Dispatch to the active child
447
448 // Set x and y relative to the child's coordinates
449 mouse.setX(mouse.getAbsoluteX() - activeChild.getAbsoluteX());
450 mouse.setY(mouse.getAbsoluteY() - activeChild.getAbsoluteY());
451 activeChild.onMouseDown(mouse);
452 return;
453 }
454 }
d36057df
KL
455 for (int i = children.size() - 1 ; i >= 0 ; i--) {
456 TWidget widget = children.get(i);
457 if (widget.mouseWouldHit(mouse)) {
458 // Dispatch to this child, also activate it
459 activate(widget);
7272e49f 460
d36057df
KL
461 // Set x and y relative to the child's coordinates
462 mouse.setX(mouse.getAbsoluteX() - widget.getAbsoluteX());
463 mouse.setY(mouse.getAbsoluteY() - widget.getAbsoluteY());
464 widget.onMouseDown(mouse);
465 return;
466 }
467 }
468 }
48e27807 469
7272e49f 470 /**
d36057df 471 * Method that subclasses can override to handle mouse button releases.
7272e49f 472 *
d36057df 473 * @param mouse mouse button event
7272e49f 474 */
d36057df
KL
475 public void onMouseUp(final TMouseEvent mouse) {
476 // Default: do nothing, pass to children instead
a69ed767
KL
477 if (activeChild != null) {
478 if (activeChild.mouseWouldHit(mouse)) {
479 // Dispatch to the active child
480
481 // Set x and y relative to the child's coordinates
482 mouse.setX(mouse.getAbsoluteX() - activeChild.getAbsoluteX());
483 mouse.setY(mouse.getAbsoluteY() - activeChild.getAbsoluteY());
484 activeChild.onMouseUp(mouse);
485 return;
486 }
487 }
d36057df
KL
488 for (int i = children.size() - 1 ; i >= 0 ; i--) {
489 TWidget widget = children.get(i);
490 if (widget.mouseWouldHit(mouse)) {
491 // Dispatch to this child, also activate it
492 activate(widget);
493
494 // Set x and y relative to the child's coordinates
495 mouse.setX(mouse.getAbsoluteX() - widget.getAbsoluteX());
496 mouse.setY(mouse.getAbsoluteY() - widget.getAbsoluteY());
497 widget.onMouseUp(mouse);
498 return;
499 }
500 }
7272e49f
KL
501 }
502
503 /**
d36057df 504 * Method that subclasses can override to handle mouse movements.
7272e49f 505 *
d36057df 506 * @param mouse mouse motion event
7272e49f 507 */
d36057df
KL
508 public void onMouseMotion(final TMouseEvent mouse) {
509 // Default: do nothing, pass it on to ALL of my children. This way
510 // the children can see the mouse "leaving" their area.
511 for (TWidget widget: children) {
512 // Set x and y relative to the child's coordinates
513 mouse.setX(mouse.getAbsoluteX() - widget.getAbsoluteX());
514 mouse.setY(mouse.getAbsoluteY() - widget.getAbsoluteY());
515 widget.onMouseMotion(mouse);
516 }
7272e49f
KL
517 }
518
2ce6dab2 519 /**
d36057df
KL
520 * Method that subclasses can override to handle mouse button
521 * double-clicks.
2ce6dab2 522 *
d36057df 523 * @param mouse mouse button event
2ce6dab2 524 */
d36057df
KL
525 public void onMouseDoubleClick(final TMouseEvent mouse) {
526 // Default: do nothing, pass to children instead
a69ed767
KL
527 if (activeChild != null) {
528 if (activeChild.mouseWouldHit(mouse)) {
529 // Dispatch to the active child
530
531 // Set x and y relative to the child's coordinates
532 mouse.setX(mouse.getAbsoluteX() - activeChild.getAbsoluteX());
533 mouse.setY(mouse.getAbsoluteY() - activeChild.getAbsoluteY());
534 activeChild.onMouseDoubleClick(mouse);
535 return;
536 }
537 }
d36057df
KL
538 for (int i = children.size() - 1 ; i >= 0 ; i--) {
539 TWidget widget = children.get(i);
540 if (widget.mouseWouldHit(mouse)) {
541 // Dispatch to this child, also activate it
542 activate(widget);
543
544 // Set x and y relative to the child's coordinates
545 mouse.setX(mouse.getAbsoluteX() - widget.getAbsoluteX());
546 mouse.setY(mouse.getAbsoluteY() - widget.getAbsoluteY());
547 widget.onMouseDoubleClick(mouse);
548 return;
549 }
550 }
2ce6dab2
KL
551 }
552
553 /**
d36057df
KL
554 * Method that subclasses can override to handle window/screen resize
555 * events.
2ce6dab2 556 *
d36057df 557 * @param resize resize event
2ce6dab2 558 */
d36057df
KL
559 public void onResize(final TResizeEvent resize) {
560 // Default: change my width/height.
561 if (resize.getType() == TResizeEvent.Type.WIDGET) {
562 width = resize.getWidth();
563 height = resize.getHeight();
564 } else {
565 // Let children see the screen resize
566 for (TWidget widget: children) {
567 widget.onResize(resize);
568 }
569 }
2ce6dab2
KL
570 }
571
48e27807 572 /**
d36057df 573 * Method that subclasses can override to handle posted command events.
7668cb45 574 *
d36057df 575 * @param command command event
2b9c27db 576 */
d36057df
KL
577 public void onCommand(final TCommandEvent command) {
578 // Default: do nothing, pass to children instead
579 for (TWidget widget: children) {
580 widget.onCommand(command);
7668cb45 581 }
48e27807
KL
582 }
583
584 /**
d36057df
KL
585 * Method that subclasses can override to handle menu or posted menu
586 * events.
48e27807 587 *
d36057df 588 * @param menu menu event
48e27807 589 */
d36057df
KL
590 public void onMenu(final TMenuEvent menu) {
591 // Default: do nothing, pass to children instead
592 for (TWidget widget: children) {
593 widget.onMenu(menu);
48e27807 594 }
48e27807
KL
595 }
596
597 /**
d36057df
KL
598 * Method that subclasses can override to do processing when the UI is
599 * idle. Note that repainting is NOT assumed. To get a refresh after
600 * onIdle, call doRepaint().
48e27807 601 */
d36057df
KL
602 public void onIdle() {
603 // Default: do nothing, pass to children instead
604 for (TWidget widget: children) {
605 widget.onIdle();
606 }
48e27807
KL
607 }
608
609 /**
d36057df
KL
610 * Consume event. Subclasses that want to intercept all events in one go
611 * can override this method.
48e27807 612 *
d36057df 613 * @param event keyboard, mouse, resize, command, or menu event
48e27807 614 */
d36057df
KL
615 public void handleEvent(final TInputEvent event) {
616 /*
617 System.err.printf("TWidget (%s) event: %s\n", this.getClass().getName(),
618 event);
619 */
620
621 if (!enabled) {
622 // Discard event
623 // System.err.println(" -- discard --");
624 return;
625 }
626
627 if (event instanceof TKeypressEvent) {
628 onKeypress((TKeypressEvent) event);
629 } else if (event instanceof TMouseEvent) {
630
631 TMouseEvent mouse = (TMouseEvent) event;
632
633 switch (mouse.getType()) {
634
635 case MOUSE_DOWN:
636 onMouseDown(mouse);
637 break;
638
639 case MOUSE_UP:
640 onMouseUp(mouse);
641 break;
642
643 case MOUSE_MOTION:
644 onMouseMotion(mouse);
645 break;
646
647 case MOUSE_DOUBLE_CLICK:
648 onMouseDoubleClick(mouse);
649 break;
650
651 default:
652 throw new IllegalArgumentException("Invalid mouse event type: "
653 + mouse.getType());
654 }
655 } else if (event instanceof TResizeEvent) {
656 onResize((TResizeEvent) event);
657 } else if (event instanceof TCommandEvent) {
658 onCommand((TCommandEvent) event);
659 } else if (event instanceof TMenuEvent) {
660 onMenu((TMenuEvent) event);
661 }
662
663 // Do nothing else
664 return;
48e27807
KL
665 }
666
d36057df
KL
667 // ------------------------------------------------------------------------
668 // TWidget ----------------------------------------------------------------
669 // ------------------------------------------------------------------------
670
48e27807 671 /**
d36057df 672 * Get parent widget.
48e27807 673 *
d36057df 674 * @return parent widget
48e27807 675 */
d36057df
KL
676 public final TWidget getParent() {
677 return parent;
48e27807
KL
678 }
679
680 /**
d36057df 681 * Get the list of child widgets that this widget contains.
48e27807 682 *
d36057df 683 * @return the list of child widgets
48e27807 684 */
d36057df
KL
685 public List<TWidget> getChildren() {
686 return children;
48e27807
KL
687 }
688
928811d8 689 /**
d36057df 690 * Get active flag.
928811d8 691 *
d36057df 692 * @return if true, this widget will receive events
928811d8 693 */
d36057df
KL
694 public final boolean isActive() {
695 return active;
928811d8
KL
696 }
697
48e27807 698 /**
d36057df
KL
699 * Set active flag.
700 *
701 * @param active if true, this widget will receive events
48e27807 702 */
d36057df
KL
703 public final void setActive(final boolean active) {
704 this.active = active;
48e27807
KL
705 }
706
707 /**
d36057df
KL
708 * Get the window this widget is on.
709 *
710 * @return the window
48e27807 711 */
d36057df
KL
712 public final TWindow getWindow() {
713 return window;
48e27807
KL
714 }
715
be72cb5c 716 /**
d36057df
KL
717 * Get X position.
718 *
719 * @return absolute X position of the top-left corner
be72cb5c 720 */
d36057df
KL
721 public final int getX() {
722 return x;
be72cb5c
KL
723 }
724
48e27807 725 /**
d36057df
KL
726 * Set X position.
727 *
728 * @param x absolute X position of the top-left corner
48e27807 729 */
d36057df
KL
730 public final void setX(final int x) {
731 this.x = x;
48e27807
KL
732 }
733
734 /**
d36057df 735 * Get Y position.
48e27807 736 *
d36057df 737 * @return absolute Y position of the top-left corner
48e27807 738 */
d36057df
KL
739 public final int getY() {
740 return y;
30d336cc
KL
741 }
742
a83fea2b 743 /**
d36057df 744 * Set Y position.
a83fea2b 745 *
d36057df 746 * @param y absolute Y position of the top-left corner
a83fea2b 747 */
d36057df
KL
748 public final void setY(final int y) {
749 this.y = y;
a83fea2b
KL
750 }
751
30d336cc 752 /**
d36057df 753 * Get the width.
30d336cc 754 *
d36057df 755 * @return widget width
30d336cc 756 */
d36057df
KL
757 public final int getWidth() {
758 return this.width;
48e27807
KL
759 }
760
a83fea2b 761 /**
d36057df 762 * Change the width.
a83fea2b 763 *
d36057df 764 * @param width new widget width
a83fea2b 765 */
d36057df 766 public final void setWidth(final int width) {
a83fea2b 767 this.width = width;
a83fea2b
KL
768 }
769
2ce6dab2 770 /**
d36057df 771 * Get the height.
2ce6dab2 772 *
d36057df 773 * @return widget height
2ce6dab2 774 */
d36057df
KL
775 public final int getHeight() {
776 return this.height;
777 }
2ce6dab2 778
d36057df
KL
779 /**
780 * Change the height.
781 *
782 * @param height new widget height
783 */
784 public final void setHeight(final int height) {
2ce6dab2
KL
785 this.height = height;
786 }
787
48e27807 788 /**
d36057df 789 * Change the dimensions.
48e27807 790 *
d36057df
KL
791 * @param x absolute X position of the top-left corner
792 * @param y absolute Y position of the top-left corner
793 * @param width new widget width
794 * @param height new widget height
48e27807 795 */
d36057df
KL
796 public final void setDimensions(final int x, final int y, final int width,
797 final int height) {
48e27807 798
d36057df
KL
799 setX(x);
800 setY(y);
801 setWidth(width);
802 setHeight(height);
48e27807
KL
803 }
804
805 /**
d36057df 806 * Get enabled flag.
48e27807 807 *
d36057df 808 * @return if true, this widget can be tabbed to or receive events
48e27807 809 */
d36057df
KL
810 public final boolean isEnabled() {
811 return enabled;
812 }
48e27807 813
d36057df
KL
814 /**
815 * Set enabled flag.
816 *
817 * @param enabled if true, this widget can be tabbed to or receive events
818 */
819 public final void setEnabled(final boolean enabled) {
820 this.enabled = enabled;
821 if (!enabled) {
822 active = false;
823 // See if there are any active siblings to switch to
824 boolean foundSibling = false;
825 if (parent != null) {
826 for (TWidget w: parent.children) {
827 if ((w.enabled)
828 && !(this instanceof THScroller)
829 && !(this instanceof TVScroller)
830 ) {
831 parent.activate(w);
832 foundSibling = true;
833 break;
834 }
835 }
836 if (!foundSibling) {
837 parent.activeChild = null;
838 }
48e27807 839 }
48e27807
KL
840 }
841 }
842
051e2913
KL
843 /**
844 * Set visible flag.
845 *
846 * @param visible if true, this widget will be drawn
847 */
848 public final void setVisible(final boolean visible) {
849 this.visible = visible;
850 }
851
852 /**
853 * See if this widget is visible.
854 *
855 * @return if true, this widget will be drawn
856 */
857 public final boolean isVisible() {
858 return visible;
859 }
860
48e27807 861 /**
d36057df 862 * Set visible cursor flag.
48e27807 863 *
d36057df 864 * @param cursorVisible if true, this widget has a cursor
48e27807 865 */
d36057df
KL
866 public final void setCursorVisible(final boolean cursorVisible) {
867 this.cursorVisible = cursorVisible;
48e27807
KL
868 }
869
870 /**
d36057df 871 * See if this widget has a visible cursor.
48e27807 872 *
d36057df 873 * @return if true, this widget has a visible cursor
48e27807 874 */
d36057df
KL
875 public final boolean isCursorVisible() {
876 // If cursor is out of my bounds, it is not visible.
877 if ((cursorX >= width)
878 || (cursorX < 0)
879 || (cursorY >= height)
880 || (cursorY < 0)
881 ) {
882 return false;
883 }
48e27807 884
d36057df
KL
885 // If cursor is out of my window's bounds, it is not visible.
886 if ((getCursorAbsoluteX() >= window.getAbsoluteX()
887 + window.getWidth() - 1)
888 || (getCursorAbsoluteX() < 0)
889 || (getCursorAbsoluteY() >= window.getAbsoluteY()
890 + window.getHeight() - 1)
891 || (getCursorAbsoluteY() < 0)
892 ) {
893 return false;
48e27807 894 }
d36057df
KL
895 return cursorVisible;
896 }
48e27807 897
d36057df
KL
898 /**
899 * Get cursor X value.
900 *
901 * @return cursor column position in relative coordinates
902 */
903 public final int getCursorX() {
904 return cursorX;
905 }
48e27807 906
d36057df
KL
907 /**
908 * Set cursor X value.
909 *
910 * @param cursorX column position in relative coordinates
911 */
912 public final void setCursorX(final int cursorX) {
913 this.cursorX = cursorX;
914 }
48e27807 915
d36057df
KL
916 /**
917 * Get cursor Y value.
918 *
919 * @return cursor row position in relative coordinates
920 */
921 public final int getCursorY() {
922 return cursorY;
923 }
48e27807 924
d36057df
KL
925 /**
926 * Set cursor Y value.
927 *
928 * @param cursorY row position in relative coordinates
929 */
930 public final void setCursorY(final int cursorY) {
931 this.cursorY = cursorY;
932 }
48e27807 933
d36057df
KL
934 /**
935 * Get this TWidget's parent TApplication.
936 *
937 * @return the parent TApplication
938 */
939 public TApplication getApplication() {
940 return window.getApplication();
941 }
48e27807 942
d36057df
KL
943 /**
944 * Get the Screen.
945 *
946 * @return the Screen
947 */
948 public Screen getScreen() {
949 return window.getScreen();
48e27807
KL
950 }
951
952 /**
d36057df
KL
953 * Comparison operator. For various subclasses it sorts on:
954 * <ul>
955 * <li>tabOrder for TWidgets</li>
956 * <li>z for TWindows</li>
957 * <li>text for TTreeItems</li>
958 * </ul>
48e27807 959 *
d36057df
KL
960 * @param that another TWidget, TWindow, or TTreeItem instance
961 * @return difference between this.tabOrder and that.tabOrder, or
962 * difference between this.z and that.z, or String.compareTo(text)
48e27807 963 */
d36057df
KL
964 public final int compareTo(final TWidget that) {
965 if ((this instanceof TWindow)
966 && (that instanceof TWindow)
48e27807 967 ) {
d36057df
KL
968 return (((TWindow) this).getZ() - ((TWindow) that).getZ());
969 }
970 if ((this instanceof TTreeItem)
971 && (that instanceof TTreeItem)
972 ) {
973 return (((TTreeItem) this).getText().compareTo(
974 ((TTreeItem) that).getText()));
48e27807 975 }
d36057df
KL
976 return (this.tabOrder - that.tabOrder);
977 }
48e27807 978
d36057df
KL
979 /**
980 * See if this widget should render with the active color.
981 *
982 * @return true if this widget is active and all of its parents are
983 * active.
984 */
985 public final boolean isAbsoluteActive() {
986 if (parent == this) {
987 return active;
48e27807 988 }
d36057df 989 return (active && parent.isAbsoluteActive());
48e27807
KL
990 }
991
d36057df
KL
992 /**
993 * Returns the cursor X position.
994 *
995 * @return absolute screen column number for the cursor's X position
996 */
997 public final int getCursorAbsoluteX() {
998 return getAbsoluteX() + cursorX;
999 }
2ce6dab2
KL
1000
1001 /**
d36057df 1002 * Returns the cursor Y position.
2ce6dab2 1003 *
d36057df 1004 * @return absolute screen row number for the cursor's Y position
2ce6dab2 1005 */
d36057df
KL
1006 public final int getCursorAbsoluteY() {
1007 return getAbsoluteY() + cursorY;
1008 }
2ce6dab2 1009
d36057df
KL
1010 /**
1011 * Compute my absolute X position as the sum of my X plus all my parent's
1012 * X's.
1013 *
1014 * @return absolute screen column number for my X position
1015 */
1016 public final int getAbsoluteX() {
1017 assert (parent != null);
1018 if (parent == this) {
1019 return x;
2ce6dab2 1020 }
d36057df
KL
1021 if ((parent instanceof TWindow)
1022 && !(parent instanceof TMenu)
1023 && !(parent instanceof TDesktop)
1024 ) {
1025 // Widgets on a TWindow have (0,0) as their top-left, but this is
1026 // actually the TWindow's (1,1).
1027 return parent.getAbsoluteX() + x + 1;
1028 }
1029 return parent.getAbsoluteX() + x;
1030 }
2ce6dab2 1031
d36057df
KL
1032 /**
1033 * Compute my absolute Y position as the sum of my Y plus all my parent's
1034 * Y's.
1035 *
1036 * @return absolute screen row number for my Y position
1037 */
1038 public final int getAbsoluteY() {
1039 assert (parent != null);
1040 if (parent == this) {
1041 return y;
1042 }
1043 if ((parent instanceof TWindow)
1044 && !(parent instanceof TMenu)
1045 && !(parent instanceof TDesktop)
2ce6dab2 1046 ) {
d36057df
KL
1047 // Widgets on a TWindow have (0,0) as their top-left, but this is
1048 // actually the TWindow's (1,1).
1049 return parent.getAbsoluteY() + y + 1;
2ce6dab2 1050 }
d36057df 1051 return parent.getAbsoluteY() + y;
2ce6dab2
KL
1052 }
1053
48e27807 1054 /**
d36057df 1055 * Get the global color theme.
48e27807 1056 *
d36057df 1057 * @return the ColorTheme
48e27807 1058 */
a69ed767 1059 protected final ColorTheme getTheme() {
d36057df
KL
1060 return window.getApplication().getTheme();
1061 }
48e27807 1062
d36057df
KL
1063 /**
1064 * Draw my specific widget. When called, the screen rectangle I draw
1065 * into is already setup (offset and clipping).
1066 */
1067 public void draw() {
1068 // Default widget draws nothing.
1069 }
48e27807 1070
d36057df 1071 /**
a69ed767 1072 * Called by parent to render to TWindow. Note package private access.
d36057df 1073 */
a69ed767 1074 final void drawChildren() {
d36057df
KL
1075 // Set my clipping rectangle
1076 assert (window != null);
1077 assert (getScreen() != null);
1078 Screen screen = getScreen();
1079
1080 // Special case: TStatusBar is drawn by TApplication, not anything
1081 // else.
1082 if (this instanceof TStatusBar) {
1083 return;
48e27807
KL
1084 }
1085
d36057df
KL
1086 screen.setClipRight(width);
1087 screen.setClipBottom(height);
92554d64 1088
d36057df
KL
1089 int absoluteRightEdge = window.getAbsoluteX() + window.getWidth();
1090 int absoluteBottomEdge = window.getAbsoluteY() + window.getHeight();
1091 if (!(this instanceof TWindow) && !(this instanceof TVScroller)) {
1092 absoluteRightEdge -= 1;
1093 }
1094 if (!(this instanceof TWindow) && !(this instanceof THScroller)) {
1095 absoluteBottomEdge -= 1;
48e27807 1096 }
d36057df
KL
1097 int myRightEdge = getAbsoluteX() + width;
1098 int myBottomEdge = getAbsoluteY() + height;
1099 if (getAbsoluteX() > absoluteRightEdge) {
1100 // I am offscreen
1101 screen.setClipRight(0);
1102 } else if (myRightEdge > absoluteRightEdge) {
1103 screen.setClipRight(screen.getClipRight()
1104 - (myRightEdge - absoluteRightEdge));
1105 }
1106 if (getAbsoluteY() > absoluteBottomEdge) {
1107 // I am offscreen
1108 screen.setClipBottom(0);
1109 } else if (myBottomEdge > absoluteBottomEdge) {
1110 screen.setClipBottom(screen.getClipBottom()
1111 - (myBottomEdge - absoluteBottomEdge));
1112 }
1113
1114 // Set my offset
1115 screen.setOffsetX(getAbsoluteX());
1116 screen.setOffsetY(getAbsoluteY());
48e27807 1117
d36057df
KL
1118 // Draw me
1119 draw();
11cedc9a 1120 assert (visible == true);
d36057df 1121
a69ed767
KL
1122 // Continue down the chain. Draw the active child last so that it
1123 // is on top.
48e27807 1124 for (TWidget widget: children) {
a69ed767 1125 if (widget.isVisible() && (widget != activeChild)) {
051e2913
KL
1126 widget.drawChildren();
1127 }
48e27807 1128 }
a69ed767
KL
1129 if (activeChild != null) {
1130 activeChild.drawChildren();
1131 }
48e27807
KL
1132 }
1133
1134 /**
d36057df 1135 * Repaint the screen on the next update.
48e27807 1136 */
a69ed767 1137 protected final void doRepaint() {
d36057df 1138 window.getApplication().doRepaint();
48e27807
KL
1139 }
1140
1141 /**
d36057df
KL
1142 * Add a child widget to my list of children. We set its tabOrder to 0
1143 * and increment the tabOrder of all other children.
48e27807 1144 *
d36057df 1145 * @param child TWidget to add
48e27807 1146 */
d36057df
KL
1147 private void addChild(final TWidget child) {
1148 children.add(child);
48e27807 1149
d36057df
KL
1150 if ((child.enabled)
1151 && !(child instanceof THScroller)
1152 && !(child instanceof TVScroller)
1153 ) {
1154 for (TWidget widget: children) {
1155 widget.active = false;
48e27807 1156 }
d36057df
KL
1157 child.active = true;
1158 activeChild = child;
48e27807 1159 }
d36057df
KL
1160 for (int i = 0; i < children.size(); i++) {
1161 children.get(i).tabOrder = i;
48e27807
KL
1162 }
1163 }
1164
00691e80
KL
1165 /**
1166 * Reset the tab order of children to match their position in the list.
1167 * Available so that subclasses can re-order their widgets if needed.
1168 */
1169 protected void resetTabOrder() {
1170 for (int i = 0; i < children.size(); i++) {
1171 children.get(i).tabOrder = i;
1172 }
1173 }
1174
b6faeac0 1175 /**
d36057df 1176 * Switch the active child.
b6faeac0 1177 *
d36057df 1178 * @param child TWidget to activate
b6faeac0 1179 */
d36057df
KL
1180 public final void activate(final TWidget child) {
1181 assert (child.enabled);
1182 if ((child instanceof THScroller)
1183 || (child instanceof TVScroller)
1184 ) {
1185 return;
b6faeac0 1186 }
b6faeac0 1187
e23ea538
KL
1188 if (children.size() == 1) {
1189 if (children.get(0).enabled == true) {
1190 child.active = true;
1191 activeChild = child;
1192 }
1193 } else {
1194 if (child != activeChild) {
1195 if (activeChild != null) {
1196 activeChild.active = false;
1197 }
1198 child.active = true;
1199 activeChild = child;
12b55d76 1200 }
48e27807
KL
1201 }
1202 }
1203
1204 /**
d36057df 1205 * Switch the active child.
48e27807 1206 *
d36057df
KL
1207 * @param tabOrder tabOrder of the child to activate. If that child
1208 * isn't enabled, then the next enabled child will be activated.
48e27807 1209 */
d36057df 1210 public final void activate(final int tabOrder) {
e23ea538
KL
1211 if (children.size() == 1) {
1212 if (children.get(0).enabled == true) {
1213 children.get(0).active = true;
1214 activeChild = children.get(0);
1215 }
1216 return;
1217 }
1218
d36057df 1219 TWidget child = null;
48e27807 1220 for (TWidget widget: children) {
d36057df
KL
1221 if ((widget.enabled)
1222 && !(widget instanceof THScroller)
1223 && !(widget instanceof TVScroller)
1224 && (widget.tabOrder >= tabOrder)
1225 ) {
1226 child = widget;
1227 break;
1228 }
48e27807 1229 }
d36057df 1230 if ((child != null) && (child != activeChild)) {
00691e80
KL
1231 if (activeChild != null) {
1232 activeChild.active = false;
1233 }
d36057df
KL
1234 assert (child.enabled);
1235 child.active = true;
1236 activeChild = child;
48e27807
KL
1237 }
1238 }
1239
1240 /**
d36057df 1241 * Switch the active widget with the next in the tab order.
48e27807 1242 *
d36057df
KL
1243 * @param forward if true, then switch to the next enabled widget in the
1244 * list, otherwise switch to the previous enabled widget in the list
48e27807 1245 */
d36057df 1246 public final void switchWidget(final boolean forward) {
48e27807 1247
e23ea538 1248 // No children: do nothing.
00691e80 1249 if (children.size() == 0) {
e23ea538
KL
1250 return;
1251 }
1252
1253 // If there is only one child, make it active if it is enabled.
1254 if (children.size() == 1) {
1255 if (children.get(0).enabled == true) {
1256 activeChild = children.get(0);
1257 activeChild.active = true;
1258 } else {
1259 children.get(0).active = false;
1260 activeChild = null;
1261 }
48e27807
KL
1262 return;
1263 }
1264
e23ea538
KL
1265 // Two or more children: go forward or backward to the next enabled
1266 // child.
00691e80
KL
1267 int tabOrder = 0;
1268 if (activeChild != null) {
1269 tabOrder = activeChild.tabOrder;
1270 }
d36057df
KL
1271 do {
1272 if (forward) {
1273 tabOrder++;
1274 } else {
1275 tabOrder--;
1276 }
1277 if (tabOrder < 0) {
48e27807 1278
d36057df
KL
1279 // If at the end, pass the switch to my parent.
1280 if ((!forward) && (parent != this)) {
1281 parent.switchWidget(forward);
1282 return;
1283 }
48e27807 1284
d36057df
KL
1285 tabOrder = children.size() - 1;
1286 } else if (tabOrder == children.size()) {
1287 // If at the end, pass the switch to my parent.
1288 if ((forward) && (parent != this)) {
1289 parent.switchWidget(forward);
1290 return;
1291 }
48e27807 1292
d36057df
KL
1293 tabOrder = 0;
1294 }
00691e80
KL
1295 if (activeChild == null) {
1296 if (tabOrder == 0) {
1297 // We wrapped around
1298 break;
1299 }
1300 } else if (activeChild.tabOrder == tabOrder) {
d36057df 1301 // We wrapped around
48e27807 1302 break;
d36057df
KL
1303 }
1304 } while ((!children.get(tabOrder).enabled)
1305 && !(children.get(tabOrder) instanceof THScroller)
1306 && !(children.get(tabOrder) instanceof TVScroller));
48e27807 1307
00691e80
KL
1308 if (activeChild != null) {
1309 assert (children.get(tabOrder).enabled);
48e27807 1310
00691e80
KL
1311 activeChild.active = false;
1312 }
1313 if (children.get(tabOrder).enabled == true) {
1314 children.get(tabOrder).active = true;
1315 activeChild = children.get(tabOrder);
1316 }
d36057df 1317 }
48e27807 1318
d36057df
KL
1319 /**
1320 * Returns my active widget.
1321 *
1322 * @return widget that is active, or this if no children
1323 */
1324 public TWidget getActiveChild() {
1325 if ((this instanceof THScroller)
1326 || (this instanceof TVScroller)
1327 ) {
1328 return parent;
1329 }
b6faeac0 1330
d36057df
KL
1331 for (TWidget widget: children) {
1332 if (widget.active) {
1333 return widget.getActiveChild();
48e27807 1334 }
48e27807 1335 }
d36057df
KL
1336 // No active children, return me
1337 return this;
48e27807
KL
1338 }
1339
a69ed767
KL
1340 // ------------------------------------------------------------------------
1341 // Passthru for Screen functions ------------------------------------------
1342 // ------------------------------------------------------------------------
1343
1344 /**
1345 * Get the attributes at one location.
1346 *
1347 * @param x column coordinate. 0 is the left-most column.
1348 * @param y row coordinate. 0 is the top-most row.
1349 * @return attributes at (x, y)
1350 */
1351 protected final CellAttributes getAttrXY(final int x, final int y) {
1352 return getScreen().getAttrXY(x, y);
1353 }
1354
1355 /**
1356 * Set the attributes at one location.
1357 *
1358 * @param x column coordinate. 0 is the left-most column.
1359 * @param y row coordinate. 0 is the top-most row.
1360 * @param attr attributes to use (bold, foreColor, backColor)
1361 */
1362 protected final void putAttrXY(final int x, final int y,
1363 final CellAttributes attr) {
1364
1365 getScreen().putAttrXY(x, y, attr);
1366 }
1367
1368 /**
1369 * Set the attributes at one location.
1370 *
1371 * @param x column coordinate. 0 is the left-most column.
1372 * @param y row coordinate. 0 is the top-most row.
1373 * @param attr attributes to use (bold, foreColor, backColor)
1374 * @param clip if true, honor clipping/offset
1375 */
1376 protected final void putAttrXY(final int x, final int y,
1377 final CellAttributes attr, final boolean clip) {
1378
1379 getScreen().putAttrXY(x, y, attr, clip);
1380 }
1381
1382 /**
1383 * Fill the entire screen with one character with attributes.
1384 *
1385 * @param ch character to draw
1386 * @param attr attributes to use (bold, foreColor, backColor)
1387 */
1388 protected final void putAll(final char ch, final CellAttributes attr) {
1389 getScreen().putAll(ch, attr);
1390 }
1391
1392 /**
1393 * Render one character with attributes.
1394 *
1395 * @param x column coordinate. 0 is the left-most column.
1396 * @param y row coordinate. 0 is the top-most row.
1397 * @param ch character + attributes to draw
1398 */
1399 protected final void putCharXY(final int x, final int y, final Cell ch) {
1400 getScreen().putCharXY(x, y, ch);
1401 }
1402
1403 /**
1404 * Render one character with attributes.
1405 *
1406 * @param x column coordinate. 0 is the left-most column.
1407 * @param y row coordinate. 0 is the top-most row.
1408 * @param ch character to draw
1409 * @param attr attributes to use (bold, foreColor, backColor)
1410 */
1411 protected final void putCharXY(final int x, final int y, final char ch,
1412 final CellAttributes attr) {
1413
1414 getScreen().putCharXY(x, y, ch, attr);
1415 }
1416
1417 /**
1418 * Render one character without changing the underlying attributes.
1419 *
1420 * @param x column coordinate. 0 is the left-most column.
1421 * @param y row coordinate. 0 is the top-most row.
1422 * @param ch character to draw
1423 */
1424 protected final void putCharXY(final int x, final int y, final char ch) {
1425 getScreen().putCharXY(x, y, ch);
1426 }
1427
1428 /**
1429 * Render a string. Does not wrap if the string exceeds the line.
1430 *
1431 * @param x column coordinate. 0 is the left-most column.
1432 * @param y row coordinate. 0 is the top-most row.
1433 * @param str string to draw
1434 * @param attr attributes to use (bold, foreColor, backColor)
1435 */
1436 protected final void putStringXY(final int x, final int y, final String str,
1437 final CellAttributes attr) {
1438
1439 getScreen().putStringXY(x, y, str, attr);
1440 }
1441
1442 /**
1443 * Render a string without changing the underlying attribute. Does not
1444 * wrap if the string exceeds the line.
1445 *
1446 * @param x column coordinate. 0 is the left-most column.
1447 * @param y row coordinate. 0 is the top-most row.
1448 * @param str string to draw
1449 */
1450 protected final void putStringXY(final int x, final int y, final String str) {
1451 getScreen().putStringXY(x, y, str);
1452 }
1453
1454 /**
1455 * Draw a vertical line from (x, y) to (x, y + n).
1456 *
1457 * @param x column coordinate. 0 is the left-most column.
1458 * @param y row coordinate. 0 is the top-most row.
1459 * @param n number of characters to draw
1460 * @param ch character to draw
1461 * @param attr attributes to use (bold, foreColor, backColor)
1462 */
1463 protected final void vLineXY(final int x, final int y, final int n,
1464 final char ch, final CellAttributes attr) {
1465
1466 getScreen().vLineXY(x, y, n, ch, attr);
1467 }
1468
1469 /**
1470 * Draw a horizontal line from (x, y) to (x + n, y).
1471 *
1472 * @param x column coordinate. 0 is the left-most column.
1473 * @param y row coordinate. 0 is the top-most row.
1474 * @param n number of characters to draw
1475 * @param ch character to draw
1476 * @param attr attributes to use (bold, foreColor, backColor)
1477 */
1478 protected final void hLineXY(final int x, final int y, final int n,
1479 final char ch, final CellAttributes attr) {
1480
1481 getScreen().hLineXY(x, y, n, ch, attr);
1482 }
1483
1484 /**
1485 * Draw a box with a border and empty background.
1486 *
1487 * @param left left column of box. 0 is the left-most row.
1488 * @param top top row of the box. 0 is the top-most row.
1489 * @param right right column of box
1490 * @param bottom bottom row of the box
1491 * @param border attributes to use for the border
1492 * @param background attributes to use for the background
1493 */
1494 protected final void drawBox(final int left, final int top,
1495 final int right, final int bottom,
1496 final CellAttributes border, final CellAttributes background) {
1497
1498 getScreen().drawBox(left, top, right, bottom, border, background);
1499 }
1500
1501 /**
1502 * Draw a box with a border and empty background.
1503 *
1504 * @param left left column of box. 0 is the left-most row.
1505 * @param top top row of the box. 0 is the top-most row.
1506 * @param right right column of box
1507 * @param bottom bottom row of the box
1508 * @param border attributes to use for the border
1509 * @param background attributes to use for the background
1510 * @param borderType if 1, draw a single-line border; if 2, draw a
1511 * double-line border; if 3, draw double-line top/bottom edges and
1512 * single-line left/right edges (like Qmodem)
1513 * @param shadow if true, draw a "shadow" on the box
1514 */
1515 protected final void drawBox(final int left, final int top,
1516 final int right, final int bottom,
1517 final CellAttributes border, final CellAttributes background,
1518 final int borderType, final boolean shadow) {
1519
1520 getScreen().drawBox(left, top, right, bottom, border, background,
1521 borderType, shadow);
1522 }
1523
1524 /**
1525 * Draw a box shadow.
1526 *
1527 * @param left left column of box. 0 is the left-most row.
1528 * @param top top row of the box. 0 is the top-most row.
1529 * @param right right column of box
1530 * @param bottom bottom row of the box
1531 */
1532 protected final void drawBoxShadow(final int left, final int top,
1533 final int right, final int bottom) {
1534
1535 getScreen().drawBoxShadow(left, top, right, bottom);
1536 }
1537
2ce6dab2
KL
1538 // ------------------------------------------------------------------------
1539 // Other TWidget constructors ---------------------------------------------
1540 // ------------------------------------------------------------------------
48e27807 1541
30d336cc
KL
1542 /**
1543 * Convenience function to add a label to this container/window.
1544 *
1545 * @param text label
1546 * @param x column relative to parent
1547 * @param y row relative to parent
1548 * @return the new label
1549 */
1550 public final TLabel addLabel(final String text, final int x, final int y) {
1551 return addLabel(text, x, y, "tlabel");
1552 }
1553
00691e80
KL
1554 /**
1555 * Convenience function to add a label to this container/window.
1556 *
1557 * @param text label
1558 * @param x column relative to parent
1559 * @param y row relative to parent
1560 * @param action to call when shortcut is pressed
1561 * @return the new label
1562 */
1563 public final TLabel addLabel(final String text, final int x, final int y,
1564 final TAction action) {
1565
1566 return addLabel(text, x, y, "tlabel", action);
1567 }
1568
30d336cc
KL
1569 /**
1570 * Convenience function to add a label to this container/window.
1571 *
1572 * @param text label
1573 * @param x column relative to parent
1574 * @param y row relative to parent
1575 * @param colorKey ColorTheme key color to use for foreground text.
1576 * Default is "tlabel"
1577 * @return the new label
1578 */
1579 public final TLabel addLabel(final String text, final int x, final int y,
1580 final String colorKey) {
1581
1582 return new TLabel(this, text, x, y, colorKey);
1583 }
1584
00691e80
KL
1585 /**
1586 * Convenience function to add a label to this container/window.
1587 *
1588 * @param text label
1589 * @param x column relative to parent
1590 * @param y row relative to parent
1591 * @param colorKey ColorTheme key color to use for foreground text.
1592 * Default is "tlabel"
1593 * @param action to call when shortcut is pressed
1594 * @return the new label
1595 */
1596 public final TLabel addLabel(final String text, final int x, final int y,
1597 final String colorKey, final TAction action) {
1598
1599 return new TLabel(this, text, x, y, colorKey, action);
1600 }
1601
051e2913
KL
1602 /**
1603 * Convenience function to add a label to this container/window.
1604 *
1605 * @param text label
1606 * @param x column relative to parent
1607 * @param y row relative to parent
1608 * @param colorKey ColorTheme key color to use for foreground text.
1609 * Default is "tlabel"
1610 * @param useWindowBackground if true, use the window's background color
1611 * @return the new label
1612 */
1613 public final TLabel addLabel(final String text, final int x, final int y,
1614 final String colorKey, final boolean useWindowBackground) {
1615
1616 return new TLabel(this, text, x, y, colorKey, useWindowBackground);
1617 }
1618
00691e80
KL
1619 /**
1620 * Convenience function to add a label to this container/window.
1621 *
1622 * @param text label
1623 * @param x column relative to parent
1624 * @param y row relative to parent
1625 * @param colorKey ColorTheme key color to use for foreground text.
1626 * Default is "tlabel"
1627 * @param useWindowBackground if true, use the window's background color
1628 * @param action to call when shortcut is pressed
1629 * @return the new label
1630 */
1631 public final TLabel addLabel(final String text, final int x, final int y,
1632 final String colorKey, final boolean useWindowBackground,
1633 final TAction action) {
1634
1635 return new TLabel(this, text, x, y, colorKey, useWindowBackground,
1636 action);
1637 }
1638
30d336cc
KL
1639 /**
1640 * Convenience function to add a button to this container/window.
1641 *
1642 * @param text label on the button
1643 * @param x column relative to parent
1644 * @param y row relative to parent
051e2913 1645 * @param action action to call when button is pressed
30d336cc
KL
1646 * @return the new button
1647 */
1648 public final TButton addButton(final String text, final int x, final int y,
1649 final TAction action) {
1650
1651 return new TButton(this, text, x, y, action);
1652 }
1653
7272e49f
KL
1654 /**
1655 * Convenience function to add a checkbox to this container/window.
1656 *
1657 * @param x column relative to parent
1658 * @param y row relative to parent
1659 * @param label label to display next to (right of) the checkbox
1660 * @param checked initial check state
1661 * @return the new checkbox
1662 */
051e2913 1663 public final TCheckBox addCheckBox(final int x, final int y,
7272e49f
KL
1664 final String label, final boolean checked) {
1665
051e2913
KL
1666 return new TCheckBox(this, x, y, label, checked);
1667 }
1668
1669 /**
1670 * Convenience function to add a combobox to this container/window.
1671 *
1672 * @param x column relative to parent
1673 * @param y row relative to parent
1674 * @param width visible combobox width, including the down-arrow
1675 * @param values the possible values for the box, shown in the drop-down
1676 * @param valuesIndex the initial index in values, or -1 for no default
1677 * value
1678 * @param valuesHeight the height of the values drop-down when it is
1679 * visible
1680 * @param updateAction action to call when a new value is selected from
1681 * the list or enter is pressed in the edit field
1682 * @return the new combobox
1683 */
1684 public final TComboBox addComboBox(final int x, final int y,
1685 final int width, final List<String> values, final int valuesIndex,
1686 final int valuesHeight, final TAction updateAction) {
1687
1688 return new TComboBox(this, x, y, width, values, valuesIndex,
1689 valuesHeight, updateAction);
1690 }
1691
1692 /**
1693 * Convenience function to add a spinner to this container/window.
1694 *
1695 * @param x column relative to parent
1696 * @param y row relative to parent
1697 * @param upAction action to call when the up arrow is clicked or pressed
1698 * @param downAction action to call when the down arrow is clicked or
1699 * pressed
1700 * @return the new spinner
1701 */
1702 public final TSpinner addSpinner(final int x, final int y,
1703 final TAction upAction, final TAction downAction) {
1704
1705 return new TSpinner(this, x, y, upAction, downAction);
1706 }
1707
1708 /**
1709 * Convenience function to add a calendar to this container/window.
1710 *
1711 * @param x column relative to parent
1712 * @param y row relative to parent
1713 * @param updateAction action to call when the user changes the value of
1714 * the calendar
1715 * @return the new calendar
1716 */
1717 public final TCalendar addCalendar(final int x, final int y,
1718 final TAction updateAction) {
1719
1720 return new TCalendar(this, x, y, updateAction);
7272e49f 1721 }
30d336cc 1722
d502a0e9
KL
1723 /**
1724 * Convenience function to add a progress bar to this container/window.
1725 *
1726 * @param x column relative to parent
1727 * @param y row relative to parent
1728 * @param width width of progress bar
1729 * @param value initial value of percent complete
00d2622b 1730 * @return the new progress bar
d502a0e9
KL
1731 */
1732 public final TProgressBar addProgressBar(final int x, final int y,
1733 final int width, final int value) {
1734
1735 return new TProgressBar(this, x, y, width, value);
1736 }
1737
00d2622b
KL
1738 /**
1739 * Convenience function to add a radio button group to this
1740 * container/window.
1741 *
1742 * @param x column relative to parent
1743 * @param y row relative to parent
1744 * @param label label to display on the group box
1745 * @return the new radio button group
1746 */
1747 public final TRadioGroup addRadioGroup(final int x, final int y,
1748 final String label) {
1749
1750 return new TRadioGroup(this, x, y, label);
1751 }
1752
128e5be1
KL
1753 /**
1754 * Convenience function to add a text field to this container/window.
1755 *
1756 * @param x column relative to parent
1757 * @param y row relative to parent
1758 * @param width visible text width
1759 * @param fixed if true, the text cannot exceed the display width
1760 * @return the new text field
1761 */
1762 public final TField addField(final int x, final int y,
1763 final int width, final boolean fixed) {
1764
1765 return new TField(this, x, y, width, fixed);
1766 }
1767
1768 /**
1769 * Convenience function to add a text field to this container/window.
1770 *
1771 * @param x column relative to parent
1772 * @param y row relative to parent
1773 * @param width visible text width
1774 * @param fixed if true, the text cannot exceed the display width
1775 * @param text initial text, default is empty string
1776 * @return the new text field
1777 */
1778 public final TField addField(final int x, final int y,
1779 final int width, final boolean fixed, final String text) {
1780
1781 return new TField(this, x, y, width, fixed, text);
1782 }
1783
1784 /**
1785 * Convenience function to add a text field to this container/window.
1786 *
1787 * @param x column relative to parent
1788 * @param y row relative to parent
1789 * @param width visible text width
1790 * @param fixed if true, the text cannot exceed the display width
1791 * @param text initial text, default is empty string
1792 * @param enterAction function to call when enter key is pressed
1793 * @param updateAction function to call when the text is updated
1794 * @return the new text field
1795 */
1796 public final TField addField(final int x, final int y,
1797 final int width, final boolean fixed, final String text,
1798 final TAction enterAction, final TAction updateAction) {
1799
1800 return new TField(this, x, y, width, fixed, text, enterAction,
1801 updateAction);
1802 }
00d2622b 1803
cc99cba8
KL
1804 /**
1805 * Convenience function to add a scrollable text box to this
1806 * container/window.
1807 *
1808 * @param text text on the screen
1809 * @param x column relative to parent
1810 * @param y row relative to parent
1811 * @param width width of text area
1812 * @param height height of text area
1813 * @param colorKey ColorTheme key color to use for foreground text
1814 * @return the new text box
1815 */
c6940ed9 1816 public final TText addText(final String text, final int x,
cc99cba8
KL
1817 final int y, final int width, final int height, final String colorKey) {
1818
1819 return new TText(this, text, x, y, width, height, colorKey);
1820 }
1821
1822 /**
1823 * Convenience function to add a scrollable text box to this
1824 * container/window.
1825 *
1826 * @param text text on the screen
1827 * @param x column relative to parent
1828 * @param y row relative to parent
1829 * @param width width of text area
1830 * @param height height of text area
1831 * @return the new text box
1832 */
c6940ed9 1833 public final TText addText(final String text, final int x, final int y,
cc99cba8
KL
1834 final int width, final int height) {
1835
1836 return new TText(this, text, x, y, width, height, "ttext");
1837 }
1838
12b55d76
KL
1839 /**
1840 * Convenience function to add an editable text area box to this
1841 * container/window.
1842 *
1843 * @param text text on the screen
1844 * @param x column relative to parent
1845 * @param y row relative to parent
1846 * @param width width of text area
1847 * @param height height of text area
1848 * @return the new text box
1849 */
1850 public final TEditorWidget addEditor(final String text, final int x,
1851 final int y, final int width, final int height) {
1852
1853 return new TEditorWidget(this, text, x, y, width, height);
1854 }
1855
c6940ed9
KL
1856 /**
1857 * Convenience function to spawn a message box.
1858 *
1859 * @param title window title, will be centered along the top border
1860 * @param caption message to display. Use embedded newlines to get a
1861 * multi-line box.
1862 * @return the new message box
1863 */
1864 public final TMessageBox messageBox(final String title,
1865 final String caption) {
1866
1867 return getApplication().messageBox(title, caption, TMessageBox.Type.OK);
1868 }
1869
1870 /**
1871 * Convenience function to spawn a message box.
1872 *
1873 * @param title window title, will be centered along the top border
1874 * @param caption message to display. Use embedded newlines to get a
1875 * multi-line box.
1876 * @param type one of the TMessageBox.Type constants. Default is
1877 * Type.OK.
1878 * @return the new message box
1879 */
1880 public final TMessageBox messageBox(final String title,
1881 final String caption, final TMessageBox.Type type) {
1882
1883 return getApplication().messageBox(title, caption, type);
1884 }
1885
1886 /**
1887 * Convenience function to spawn an input box.
1888 *
1889 * @param title window title, will be centered along the top border
1890 * @param caption message to display. Use embedded newlines to get a
1891 * multi-line box.
1892 * @return the new input box
1893 */
1894 public final TInputBox inputBox(final String title, final String caption) {
1895
1896 return getApplication().inputBox(title, caption);
1897 }
1898
1899 /**
1900 * Convenience function to spawn an input box.
1901 *
1902 * @param title window title, will be centered along the top border
1903 * @param caption message to display. Use embedded newlines to get a
1904 * multi-line box.
1905 * @param text initial text to seed the field with
1906 * @return the new input box
1907 */
1908 public final TInputBox inputBox(final String title, final String caption,
1909 final String text) {
1910
1911 return getApplication().inputBox(title, caption, text);
1912 }
cc99cba8 1913
2b427404
KL
1914 /**
1915 * Convenience function to spawn an input box.
1916 *
1917 * @param title window title, will be centered along the top border
1918 * @param caption message to display. Use embedded newlines to get a
1919 * multi-line box.
1920 * @param text initial text to seed the field with
1921 * @param type one of the Type constants. Default is Type.OK.
1922 * @return the new input box
1923 */
1924 public final TInputBox inputBox(final String title, final String caption,
1925 final String text, final TInputBox.Type type) {
1926
1927 return getApplication().inputBox(title, caption, text, type);
1928 }
1929
87a17f3c
KL
1930 /**
1931 * Convenience function to add a password text field to this
1932 * container/window.
1933 *
1934 * @param x column relative to parent
1935 * @param y row relative to parent
1936 * @param width visible text width
1937 * @param fixed if true, the text cannot exceed the display width
1938 * @return the new text field
1939 */
1940 public final TPasswordField addPasswordField(final int x, final int y,
1941 final int width, final boolean fixed) {
1942
1943 return new TPasswordField(this, x, y, width, fixed);
1944 }
1945
1946 /**
1947 * Convenience function to add a password text field to this
1948 * container/window.
1949 *
1950 * @param x column relative to parent
1951 * @param y row relative to parent
1952 * @param width visible text width
1953 * @param fixed if true, the text cannot exceed the display width
1954 * @param text initial text, default is empty string
1955 * @return the new text field
1956 */
1957 public final TPasswordField addPasswordField(final int x, final int y,
1958 final int width, final boolean fixed, final String text) {
1959
1960 return new TPasswordField(this, x, y, width, fixed, text);
1961 }
1962
1963 /**
1964 * Convenience function to add a password text field to this
1965 * container/window.
1966 *
1967 * @param x column relative to parent
1968 * @param y row relative to parent
1969 * @param width visible text width
1970 * @param fixed if true, the text cannot exceed the display width
1971 * @param text initial text, default is empty string
1972 * @param enterAction function to call when enter key is pressed
1973 * @param updateAction function to call when the text is updated
1974 * @return the new text field
1975 */
1976 public final TPasswordField addPasswordField(final int x, final int y,
1977 final int width, final boolean fixed, final String text,
1978 final TAction enterAction, final TAction updateAction) {
1979
1980 return new TPasswordField(this, x, y, width, fixed, text, enterAction,
1981 updateAction);
1982 }
1983
7668cb45 1984 /**
d36057df
KL
1985 * Convenience function to add a scrollable tree view to this
1986 * container/window.
7668cb45
KL
1987 *
1988 * @param x column relative to parent
1989 * @param y row relative to parent
1990 * @param width width of tree view
1991 * @param height height of tree view
329fd62e 1992 * @return the new tree view
7668cb45 1993 */
d36057df 1994 public final TTreeViewWidget addTreeViewWidget(final int x, final int y,
7668cb45
KL
1995 final int width, final int height) {
1996
d36057df 1997 return new TTreeViewWidget(this, x, y, width, height);
7668cb45
KL
1998 }
1999
2000 /**
d36057df
KL
2001 * Convenience function to add a scrollable tree view to this
2002 * container/window.
7668cb45
KL
2003 *
2004 * @param x column relative to parent
2005 * @param y row relative to parent
2006 * @param width width of tree view
2007 * @param height height of tree view
2008 * @param action action to perform when an item is selected
329fd62e 2009 * @return the new tree view
7668cb45 2010 */
d36057df 2011 public final TTreeViewWidget addTreeViewWidget(final int x, final int y,
7668cb45
KL
2012 final int width, final int height, final TAction action) {
2013
d36057df 2014 return new TTreeViewWidget(this, x, y, width, height, action);
7668cb45
KL
2015 }
2016
0d47c546
KL
2017 /**
2018 * Convenience function to spawn a file open box.
2019 *
2020 * @param path path of selected file
2021 * @return the result of the new file open box
329fd62e 2022 * @throws IOException if a java.io operation throws
0d47c546
KL
2023 */
2024 public final String fileOpenBox(final String path) throws IOException {
2025 return getApplication().fileOpenBox(path);
2026 }
2027
a69ed767
KL
2028 /**
2029 * Convenience function to spawn a file save box.
2030 *
2031 * @param path path of selected file
2032 * @return the result of the new file open box
2033 * @throws IOException if a java.io operation throws
2034 */
2035 public final String fileSaveBox(final String path) throws IOException {
2036 return getApplication().fileOpenBox(path, TFileOpenBox.Type.SAVE);
2037 }
2038
0d47c546
KL
2039 /**
2040 * Convenience function to spawn a file open box.
2041 *
2042 * @param path path of selected file
2043 * @param type one of the Type constants
2044 * @return the result of the new file open box
329fd62e 2045 * @throws IOException if a java.io operation throws
0d47c546
KL
2046 */
2047 public final String fileOpenBox(final String path,
2048 final TFileOpenBox.Type type) throws IOException {
2049
2050 return getApplication().fileOpenBox(path, type);
2051 }
a69ed767
KL
2052
2053 /**
2054 * Convenience function to spawn a file open box.
2055 *
2056 * @param path path of selected file
2057 * @param type one of the Type constants
2058 * @param filter a string that files must match to be displayed
2059 * @return the result of the new file open box
2060 * @throws IOException of a java.io operation throws
2061 */
2062 public final String fileOpenBox(final String path,
2063 final TFileOpenBox.Type type, final String filter) throws IOException {
2064
2065 ArrayList<String> filters = new ArrayList<String>();
2066 filters.add(filter);
2067
2068 return getApplication().fileOpenBox(path, type, filters);
2069 }
2070
2071 /**
2072 * Convenience function to spawn a file open box.
2073 *
2074 * @param path path of selected file
2075 * @param type one of the Type constants
2076 * @param filters a list of strings that files must match to be displayed
2077 * @return the result of the new file open box
2078 * @throws IOException of a java.io operation throws
2079 */
2080 public final String fileOpenBox(final String path,
2081 final TFileOpenBox.Type type,
2082 final List<String> filters) throws IOException {
2083
2084 return getApplication().fileOpenBox(path, type, filters);
2085 }
2086
0d47c546
KL
2087 /**
2088 * Convenience function to add a directory list to this container/window.
2089 *
2090 * @param path directory path, must be a directory
2091 * @param x column relative to parent
2092 * @param y row relative to parent
2093 * @param width width of text area
2094 * @param height height of text area
329fd62e 2095 * @return the new directory list
0d47c546
KL
2096 */
2097 public final TDirectoryList addDirectoryList(final String path, final int x,
2098 final int y, final int width, final int height) {
2099
2100 return new TDirectoryList(this, path, x, y, width, height, null);
2101 }
2102
2103 /**
2104 * Convenience function to add a directory list to this container/window.
2105 *
2106 * @param path directory path, must be a directory
2107 * @param x column relative to parent
2108 * @param y row relative to parent
2109 * @param width width of text area
2110 * @param height height of text area
a69ed767
KL
2111 * @param action action to perform when an item is selected (enter or
2112 * double-click)
329fd62e 2113 * @return the new directory list
0d47c546
KL
2114 */
2115 public final TDirectoryList addDirectoryList(final String path, final int x,
2116 final int y, final int width, final int height, final TAction action) {
2117
2118 return new TDirectoryList(this, path, x, y, width, height, action);
2119 }
7668cb45 2120
3649b921
KL
2121 /**
2122 * Convenience function to add a directory list to this container/window.
2123 *
a69ed767
KL
2124 * @param path directory path, must be a directory
2125 * @param x column relative to parent
2126 * @param y row relative to parent
2127 * @param width width of text area
2128 * @param height height of text area
2129 * @param action action to perform when an item is selected (enter or
2130 * double-click)
2131 * @param singleClickAction action to perform when an item is selected
2132 * (single-click)
2133 * @return the new directory list
2134 */
2135 public final TDirectoryList addDirectoryList(final String path, final int x,
2136 final int y, final int width, final int height, final TAction action,
2137 final TAction singleClickAction) {
2138
2139 return new TDirectoryList(this, path, x, y, width, height, action,
2140 singleClickAction);
2141 }
2142
2143 /**
2144 * Convenience function to add a directory list to this container/window.
2145 *
2146 * @param path directory path, must be a directory
2147 * @param x column relative to parent
2148 * @param y row relative to parent
2149 * @param width width of text area
2150 * @param height height of text area
2151 * @param action action to perform when an item is selected (enter or
2152 * double-click)
2153 * @param singleClickAction action to perform when an item is selected
2154 * (single-click)
2155 * @param filters a list of strings that files must match to be displayed
2156 * @return the new directory list
2157 */
2158 public final TDirectoryList addDirectoryList(final String path, final int x,
2159 final int y, final int width, final int height, final TAction action,
2160 final TAction singleClickAction, final List<String> filters) {
2161
2162 return new TDirectoryList(this, path, x, y, width, height, action,
2163 singleClickAction, filters);
2164 }
2165
2166 /**
2167 * Convenience function to add a list to this container/window.
2168 *
3649b921
KL
2169 * @param strings list of strings to show
2170 * @param x column relative to parent
2171 * @param y row relative to parent
2172 * @param width width of text area
2173 * @param height height of text area
2174 * @return the new directory list
2175 */
2176 public final TList addList(final List<String> strings, final int x,
2177 final int y, final int width, final int height) {
2178
2179 return new TList(this, strings, x, y, width, height, null);
2180 }
2181
2182 /**
a69ed767 2183 * Convenience function to add a list to this container/window.
3649b921
KL
2184 *
2185 * @param strings list of strings to show
2186 * @param x column relative to parent
2187 * @param y row relative to parent
2188 * @param width width of text area
2189 * @param height height of text area
2190 * @param enterAction action to perform when an item is selected
2191 * @return the new directory list
2192 */
2193 public final TList addList(final List<String> strings, final int x,
2194 final int y, final int width, final int height,
2195 final TAction enterAction) {
2196
2197 return new TList(this, strings, x, y, width, height, enterAction);
2198 }
2199
2200 /**
a69ed767 2201 * Convenience function to add a list to this container/window.
3649b921
KL
2202 *
2203 * @param strings list of strings to show
2204 * @param x column relative to parent
2205 * @param y row relative to parent
2206 * @param width width of text area
2207 * @param height height of text area
2208 * @param enterAction action to perform when an item is selected
2209 * @param moveAction action to perform when the user navigates to a new
2210 * item with arrow/page keys
2211 * @return the new directory list
2212 */
2213 public final TList addList(final List<String> strings, final int x,
2214 final int y, final int width, final int height,
2215 final TAction enterAction, final TAction moveAction) {
2216
2217 return new TList(this, strings, x, y, width, height, enterAction,
2218 moveAction);
2219 }
2220
382bc294
KL
2221 /**
2222 * Convenience function to add an image to this container/window.
2223 *
2224 * @param x column relative to parent
2225 * @param y row relative to parent
2226 * @param width number of text cells for width of the image
2227 * @param height number of text cells for height of the image
2228 * @param image the image to display
2229 * @param left left column of the image. 0 is the left-most column.
2230 * @param top top row of the image. 0 is the top-most row.
2231 */
2232 public final TImage addImage(final int x, final int y,
2233 final int width, final int height,
2234 final BufferedImage image, final int left, final int top) {
2235
2236 return new TImage(this, x, y, width, height, image, left, top);
2237 }
2238
2239 /**
2240 * Convenience function to add an image to this container/window.
2241 *
2242 * @param x column relative to parent
2243 * @param y row relative to parent
2244 * @param width number of text cells for width of the image
2245 * @param height number of text cells for height of the image
2246 * @param image the image to display
2247 * @param left left column of the image. 0 is the left-most column.
2248 * @param top top row of the image. 0 is the top-most row.
2249 * @param clickAction function to call when mouse is pressed
2250 */
2251 public final TImage addImage(final int x, final int y,
2252 final int width, final int height,
2253 final BufferedImage image, final int left, final int top,
2254 final TAction clickAction) {
2255
2256 return new TImage(this, x, y, width, height, image, left, top,
2257 clickAction);
2258 }
2259
2260 /**
2261 * Convenience function to add an editable 2D data table to this
2262 * container/window.
2263 *
2264 * @param x column relative to parent
2265 * @param y row relative to parent
2266 * @param width width of widget
2267 * @param height height of widget
2268 */
2269 public TTableWidget addTable(final int x, final int y, final int width,
2270 final int height) {
2271
2272 return new TTableWidget(this, x, y, width, height);
2273 }
2274
656c0ddd
KL
2275 /**
2276 * Convenience function to add an editable 2D data table to this
2277 * container/window.
2278 *
2279 * @param x column relative to parent
2280 * @param y row relative to parent
2281 * @param width width of widget
2282 * @param height height of widget
2283 * @param gridColumns number of columns in grid
2284 * @param gridRows number of rows in grid
2285 */
2286 public TTableWidget addTable(final int x, final int y, final int width,
2287 final int height, final int gridColumns, final int gridRows) {
2288
2289 return new TTableWidget(this, x, y, width, height, gridColumns,
2290 gridRows);
2291 }
2292
48e27807 2293}