Not dead note
[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 *
a2018e99 6 * Copyright (C) 2017 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
0d47c546 31import java.io.IOException;
48e27807 32import java.util.List;
2ce6dab2 33import java.util.ArrayList;
48e27807 34
42873e30 35import jexer.backend.Screen;
928811d8 36import jexer.bits.ColorTheme;
48e27807
KL
37import jexer.event.TCommandEvent;
38import jexer.event.TInputEvent;
39import jexer.event.TKeypressEvent;
40import jexer.event.TMenuEvent;
41import jexer.event.TMouseEvent;
42import jexer.event.TResizeEvent;
928811d8 43import jexer.menu.TMenu;
d36057df
KL
44import jexer.ttree.TTreeItem;
45import jexer.ttree.TTreeView;
46import jexer.ttree.TTreeViewWidget;
48e27807
KL
47import static jexer.TKeypress.*;
48
49/**
50 * TWidget is the base class of all objects that can be drawn on screen or
51 * handle user input events.
52 */
2b9c27db 53public abstract class TWidget implements Comparable<TWidget> {
48e27807 54
2ce6dab2 55 // ------------------------------------------------------------------------
d36057df 56 // Variables --------------------------------------------------------------
2ce6dab2
KL
57 // ------------------------------------------------------------------------
58
48e27807
KL
59 /**
60 * Every widget has a parent widget that it may be "contained" in. For
051e2913
KL
61 * example, a TWindow might contain several TFields, or a TComboBox may
62 * contain a TList that itself contains a TVScroller.
48e27807 63 */
fca67db0
KL
64 private TWidget parent = null;
65
48e27807
KL
66 /**
67 * Child widgets that this widget contains.
68 */
69 private List<TWidget> children;
70
71 /**
72 * The currently active child widget that will receive keypress events.
73 */
74 private TWidget activeChild = null;
75
76 /**
77 * If true, this widget will receive events.
78 */
fca67db0
KL
79 private boolean active = false;
80
48e27807
KL
81 /**
82 * The window that this widget draws to.
83 */
fca67db0 84 private TWindow window = null;
48e27807
KL
85
86 /**
87 * Absolute X position of the top-left corner.
88 */
fca67db0
KL
89 private int x = 0;
90
91 /**
d36057df 92 * Absolute Y position of the top-left corner.
fca67db0 93 */
d36057df 94 private int y = 0;
fca67db0
KL
95
96 /**
d36057df 97 * Width.
fca67db0 98 */
d36057df 99 private int width = 0;
48e27807
KL
100
101 /**
d36057df 102 * Height.
48e27807 103 */
d36057df 104 private int height = 0;
fca67db0
KL
105
106 /**
d36057df 107 * My tab order inside a window or containing widget.
fca67db0 108 */
d36057df 109 private int tabOrder = 0;
fca67db0
KL
110
111 /**
d36057df 112 * If true, this widget can be tabbed to or receive events.
fca67db0 113 */
d36057df 114 private boolean enabled = true;
48e27807 115
051e2913
KL
116 /**
117 * If true, this widget will be rendered.
118 */
119 private boolean visible = true;
120
48e27807 121 /**
d36057df 122 * If true, this widget has a cursor.
48e27807 123 */
d36057df 124 private boolean cursorVisible = false;
fca67db0
KL
125
126 /**
d36057df 127 * Cursor column position in relative coordinates.
fca67db0 128 */
d36057df 129 private int cursorX = 0;
fca67db0
KL
130
131 /**
d36057df 132 * Cursor row position in relative coordinates.
fca67db0 133 */
d36057df 134 private int cursorY = 0;
48e27807 135
d36057df
KL
136 // ------------------------------------------------------------------------
137 // Constructors -----------------------------------------------------------
138 // ------------------------------------------------------------------------
fca67db0
KL
139
140 /**
d36057df 141 * Default constructor for subclasses.
fca67db0 142 */
d36057df
KL
143 protected TWidget() {
144 children = new ArrayList<TWidget>();
fca67db0
KL
145 }
146
147 /**
d36057df 148 * Protected constructor.
fca67db0 149 *
d36057df 150 * @param parent parent widget
fca67db0 151 */
d36057df
KL
152 protected TWidget(final TWidget parent) {
153 this(parent, true);
fca67db0 154 }
48e27807 155
0ee88b6d 156 /**
d36057df 157 * Protected constructor.
0ee88b6d 158 *
d36057df
KL
159 * @param parent parent widget
160 * @param x column relative to parent
161 * @param y row relative to parent
162 * @param width width of widget
163 * @param height height of widget
0ee88b6d 164 */
d36057df
KL
165 protected TWidget(final TWidget parent, final int x, final int y,
166 final int width, final int height) {
0ee88b6d 167
d36057df 168 this(parent, true, x, y, width, height);
0ee88b6d
KL
169 }
170
48e27807 171 /**
d36057df 172 * Protected constructor used by subclasses that are disabled by default.
48e27807 173 *
d36057df
KL
174 * @param parent parent widget
175 * @param enabled if true assume enabled
48e27807 176 */
d36057df
KL
177 protected TWidget(final TWidget parent, final boolean enabled) {
178 this.enabled = enabled;
179 this.parent = parent;
180 this.window = parent.window;
181 children = new ArrayList<TWidget>();
182
183 // Do not add TStatusBars, they are drawn by TApplication
184 if (this instanceof TStatusBar) {
185 } else {
186 parent.addChild(this);
187 }
48e27807
KL
188 }
189
190 /**
d36057df 191 * Protected constructor used by subclasses that are disabled by default.
48e27807 192 *
d36057df
KL
193 * @param parent parent widget
194 * @param enabled if true assume enabled
195 * @param x column relative to parent
196 * @param y row relative to parent
197 * @param width width of widget
198 * @param height height of widget
48e27807 199 */
d36057df
KL
200 protected TWidget(final TWidget parent, final boolean enabled,
201 final int x, final int y, final int width, final int height) {
202
48e27807 203 this.enabled = enabled;
d36057df
KL
204 this.parent = parent;
205 this.window = parent.window;
206 children = new ArrayList<TWidget>();
207
208 // Do not add TStatusBars, they are drawn by TApplication
209 if (this instanceof TStatusBar) {
210 } else {
211 parent.addChild(this);
48e27807 212 }
48e27807 213
d36057df
KL
214 this.x = x;
215 this.y = y;
216 this.width = width;
217 this.height = height;
218 }
48e27807 219
7272e49f 220 /**
d36057df 221 * Backdoor access for TWindow's constructor. ONLY TWindow USES THIS.
7272e49f 222 *
d36057df
KL
223 * @param window the top-level window
224 * @param x column relative to parent
225 * @param y row relative to parent
226 * @param width width of window
227 * @param height height of window
7272e49f 228 */
d36057df
KL
229 protected final void setupForTWindow(final TWindow window,
230 final int x, final int y, final int width, final int height) {
231
232 this.parent = window;
233 this.window = window;
234 this.x = x;
235 this.y = y;
236 this.width = width;
237 this.height = height;
7272e49f
KL
238 }
239
d36057df
KL
240 // ------------------------------------------------------------------------
241 // Event handlers ---------------------------------------------------------
242 // ------------------------------------------------------------------------
243
a06459bd 244 /**
d36057df
KL
245 * Check if a mouse press/release event coordinate is contained in this
246 * widget.
a06459bd 247 *
d36057df
KL
248 * @param mouse a mouse-based event
249 * @return whether or not a mouse click would be sent to this widget
a06459bd 250 */
d36057df
KL
251 public final boolean mouseWouldHit(final TMouseEvent mouse) {
252
253 if (!enabled) {
24489803
KL
254 return false;
255 }
256
d36057df
KL
257 if ((this instanceof TTreeItem)
258 && ((y < 0) || (y > parent.getHeight() - 1))
24489803
KL
259 ) {
260 return false;
261 }
a06459bd 262
d36057df
KL
263 if ((mouse.getAbsoluteX() >= getAbsoluteX())
264 && (mouse.getAbsoluteX() < getAbsoluteX() + width)
265 && (mouse.getAbsoluteY() >= getAbsoluteY())
266 && (mouse.getAbsoluteY() < getAbsoluteY() + height)
267 ) {
268 return true;
269 }
270 return false;
271 }
48e27807 272
7272e49f 273 /**
d36057df 274 * Method that subclasses can override to handle keystrokes.
7272e49f 275 *
d36057df 276 * @param keypress keystroke event
7272e49f 277 */
d36057df
KL
278 public void onKeypress(final TKeypressEvent keypress) {
279
280 if ((children.size() == 0)
281 || (this instanceof TTreeView)
282 || (this instanceof TText)
283 ) {
284
285 // Defaults:
286 // tab / shift-tab - switch to next/previous widget
287 // left-arrow or up-arrow: same as shift-tab
288 if ((keypress.equals(kbTab))
289 || (keypress.equals(kbDown))
290 ) {
291 parent.switchWidget(true);
292 return;
293 } else if ((keypress.equals(kbShiftTab))
294 || (keypress.equals(kbBackTab))
295 || (keypress.equals(kbUp))
296 ) {
297 parent.switchWidget(false);
298 return;
299 }
300 }
301
302 if ((children.size() == 0)
303 && !(this instanceof TTreeView)
304 ) {
305
306 // Defaults:
307 // right-arrow or down-arrow: same as tab
308 if (keypress.equals(kbRight)) {
309 parent.switchWidget(true);
310 return;
311 } else if (keypress.equals(kbLeft)) {
312 parent.switchWidget(false);
313 return;
314 }
315 }
316
317 // If I have any buttons on me AND this is an Alt-key that matches
318 // its mnemonic, send it an Enter keystroke
319 for (TWidget widget: children) {
320 if (widget instanceof TButton) {
321 TButton button = (TButton) widget;
322 if (button.isEnabled()
323 && !keypress.getKey().isFnKey()
324 && keypress.getKey().isAlt()
325 && !keypress.getKey().isCtrl()
326 && (Character.toLowerCase(button.getMnemonic().getShortcut())
327 == Character.toLowerCase(keypress.getKey().getChar()))
328 ) {
329
330 widget.onKeypress(new TKeypressEvent(kbEnter));
331 return;
332 }
333 }
334 }
335
336 // Dispatch the keypress to an active widget
337 for (TWidget widget: children) {
338 if (widget.active) {
339 widget.onKeypress(keypress);
340 return;
341 }
342 }
7272e49f
KL
343 }
344
345 /**
d36057df 346 * Method that subclasses can override to handle mouse button presses.
7272e49f 347 *
d36057df 348 * @param mouse mouse button event
7272e49f 349 */
d36057df
KL
350 public void onMouseDown(final TMouseEvent mouse) {
351 // Default: do nothing, pass to children instead
352 for (int i = children.size() - 1 ; i >= 0 ; i--) {
353 TWidget widget = children.get(i);
354 if (widget.mouseWouldHit(mouse)) {
355 // Dispatch to this child, also activate it
356 activate(widget);
7272e49f 357
d36057df
KL
358 // Set x and y relative to the child's coordinates
359 mouse.setX(mouse.getAbsoluteX() - widget.getAbsoluteX());
360 mouse.setY(mouse.getAbsoluteY() - widget.getAbsoluteY());
361 widget.onMouseDown(mouse);
362 return;
363 }
364 }
365 }
48e27807 366
7272e49f 367 /**
d36057df 368 * Method that subclasses can override to handle mouse button releases.
7272e49f 369 *
d36057df 370 * @param mouse mouse button event
7272e49f 371 */
d36057df
KL
372 public void onMouseUp(final TMouseEvent mouse) {
373 // Default: do nothing, pass to children instead
374 for (int i = children.size() - 1 ; i >= 0 ; i--) {
375 TWidget widget = children.get(i);
376 if (widget.mouseWouldHit(mouse)) {
377 // Dispatch to this child, also activate it
378 activate(widget);
379
380 // Set x and y relative to the child's coordinates
381 mouse.setX(mouse.getAbsoluteX() - widget.getAbsoluteX());
382 mouse.setY(mouse.getAbsoluteY() - widget.getAbsoluteY());
383 widget.onMouseUp(mouse);
384 return;
385 }
386 }
7272e49f
KL
387 }
388
389 /**
d36057df 390 * Method that subclasses can override to handle mouse movements.
7272e49f 391 *
d36057df 392 * @param mouse mouse motion event
7272e49f 393 */
d36057df
KL
394 public void onMouseMotion(final TMouseEvent mouse) {
395 // Default: do nothing, pass it on to ALL of my children. This way
396 // the children can see the mouse "leaving" their area.
397 for (TWidget widget: children) {
398 // Set x and y relative to the child's coordinates
399 mouse.setX(mouse.getAbsoluteX() - widget.getAbsoluteX());
400 mouse.setY(mouse.getAbsoluteY() - widget.getAbsoluteY());
401 widget.onMouseMotion(mouse);
402 }
7272e49f
KL
403 }
404
2ce6dab2 405 /**
d36057df
KL
406 * Method that subclasses can override to handle mouse button
407 * double-clicks.
2ce6dab2 408 *
d36057df 409 * @param mouse mouse button event
2ce6dab2 410 */
d36057df
KL
411 public void onMouseDoubleClick(final TMouseEvent mouse) {
412 // Default: do nothing, pass to children instead
413 for (int i = children.size() - 1 ; i >= 0 ; i--) {
414 TWidget widget = children.get(i);
415 if (widget.mouseWouldHit(mouse)) {
416 // Dispatch to this child, also activate it
417 activate(widget);
418
419 // Set x and y relative to the child's coordinates
420 mouse.setX(mouse.getAbsoluteX() - widget.getAbsoluteX());
421 mouse.setY(mouse.getAbsoluteY() - widget.getAbsoluteY());
422 widget.onMouseDoubleClick(mouse);
423 return;
424 }
425 }
2ce6dab2
KL
426 }
427
428 /**
d36057df
KL
429 * Method that subclasses can override to handle window/screen resize
430 * events.
2ce6dab2 431 *
d36057df 432 * @param resize resize event
2ce6dab2 433 */
d36057df
KL
434 public void onResize(final TResizeEvent resize) {
435 // Default: change my width/height.
436 if (resize.getType() == TResizeEvent.Type.WIDGET) {
437 width = resize.getWidth();
438 height = resize.getHeight();
439 } else {
440 // Let children see the screen resize
441 for (TWidget widget: children) {
442 widget.onResize(resize);
443 }
444 }
2ce6dab2
KL
445 }
446
48e27807 447 /**
d36057df 448 * Method that subclasses can override to handle posted command events.
7668cb45 449 *
d36057df 450 * @param command command event
2b9c27db 451 */
d36057df
KL
452 public void onCommand(final TCommandEvent command) {
453 // Default: do nothing, pass to children instead
454 for (TWidget widget: children) {
455 widget.onCommand(command);
7668cb45 456 }
48e27807
KL
457 }
458
459 /**
d36057df
KL
460 * Method that subclasses can override to handle menu or posted menu
461 * events.
48e27807 462 *
d36057df 463 * @param menu menu event
48e27807 464 */
d36057df
KL
465 public void onMenu(final TMenuEvent menu) {
466 // Default: do nothing, pass to children instead
467 for (TWidget widget: children) {
468 widget.onMenu(menu);
48e27807 469 }
48e27807
KL
470 }
471
472 /**
d36057df
KL
473 * Method that subclasses can override to do processing when the UI is
474 * idle. Note that repainting is NOT assumed. To get a refresh after
475 * onIdle, call doRepaint().
48e27807 476 */
d36057df
KL
477 public void onIdle() {
478 // Default: do nothing, pass to children instead
479 for (TWidget widget: children) {
480 widget.onIdle();
481 }
48e27807
KL
482 }
483
484 /**
d36057df
KL
485 * Consume event. Subclasses that want to intercept all events in one go
486 * can override this method.
48e27807 487 *
d36057df 488 * @param event keyboard, mouse, resize, command, or menu event
48e27807 489 */
d36057df
KL
490 public void handleEvent(final TInputEvent event) {
491 /*
492 System.err.printf("TWidget (%s) event: %s\n", this.getClass().getName(),
493 event);
494 */
495
496 if (!enabled) {
497 // Discard event
498 // System.err.println(" -- discard --");
499 return;
500 }
501
502 if (event instanceof TKeypressEvent) {
503 onKeypress((TKeypressEvent) event);
504 } else if (event instanceof TMouseEvent) {
505
506 TMouseEvent mouse = (TMouseEvent) event;
507
508 switch (mouse.getType()) {
509
510 case MOUSE_DOWN:
511 onMouseDown(mouse);
512 break;
513
514 case MOUSE_UP:
515 onMouseUp(mouse);
516 break;
517
518 case MOUSE_MOTION:
519 onMouseMotion(mouse);
520 break;
521
522 case MOUSE_DOUBLE_CLICK:
523 onMouseDoubleClick(mouse);
524 break;
525
526 default:
527 throw new IllegalArgumentException("Invalid mouse event type: "
528 + mouse.getType());
529 }
530 } else if (event instanceof TResizeEvent) {
531 onResize((TResizeEvent) event);
532 } else if (event instanceof TCommandEvent) {
533 onCommand((TCommandEvent) event);
534 } else if (event instanceof TMenuEvent) {
535 onMenu((TMenuEvent) event);
536 }
537
538 // Do nothing else
539 return;
48e27807
KL
540 }
541
d36057df
KL
542 // ------------------------------------------------------------------------
543 // TWidget ----------------------------------------------------------------
544 // ------------------------------------------------------------------------
545
48e27807 546 /**
d36057df 547 * Get parent widget.
48e27807 548 *
d36057df 549 * @return parent widget
48e27807 550 */
d36057df
KL
551 public final TWidget getParent() {
552 return parent;
48e27807
KL
553 }
554
555 /**
d36057df 556 * Get the list of child widgets that this widget contains.
48e27807 557 *
d36057df 558 * @return the list of child widgets
48e27807 559 */
d36057df
KL
560 public List<TWidget> getChildren() {
561 return children;
48e27807
KL
562 }
563
928811d8 564 /**
d36057df 565 * Get active flag.
928811d8 566 *
d36057df 567 * @return if true, this widget will receive events
928811d8 568 */
d36057df
KL
569 public final boolean isActive() {
570 return active;
928811d8
KL
571 }
572
48e27807 573 /**
d36057df
KL
574 * Set active flag.
575 *
576 * @param active if true, this widget will receive events
48e27807 577 */
d36057df
KL
578 public final void setActive(final boolean active) {
579 this.active = active;
48e27807
KL
580 }
581
582 /**
d36057df
KL
583 * Get the window this widget is on.
584 *
585 * @return the window
48e27807 586 */
d36057df
KL
587 public final TWindow getWindow() {
588 return window;
48e27807
KL
589 }
590
be72cb5c 591 /**
d36057df
KL
592 * Get X position.
593 *
594 * @return absolute X position of the top-left corner
be72cb5c 595 */
d36057df
KL
596 public final int getX() {
597 return x;
be72cb5c
KL
598 }
599
48e27807 600 /**
d36057df
KL
601 * Set X position.
602 *
603 * @param x absolute X position of the top-left corner
48e27807 604 */
d36057df
KL
605 public final void setX(final int x) {
606 this.x = x;
48e27807
KL
607 }
608
609 /**
d36057df 610 * Get Y position.
48e27807 611 *
d36057df 612 * @return absolute Y position of the top-left corner
48e27807 613 */
d36057df
KL
614 public final int getY() {
615 return y;
30d336cc
KL
616 }
617
a83fea2b 618 /**
d36057df 619 * Set Y position.
a83fea2b 620 *
d36057df 621 * @param y absolute Y position of the top-left corner
a83fea2b 622 */
d36057df
KL
623 public final void setY(final int y) {
624 this.y = y;
a83fea2b
KL
625 }
626
30d336cc 627 /**
d36057df 628 * Get the width.
30d336cc 629 *
d36057df 630 * @return widget width
30d336cc 631 */
d36057df
KL
632 public final int getWidth() {
633 return this.width;
48e27807
KL
634 }
635
a83fea2b 636 /**
d36057df 637 * Change the width.
a83fea2b 638 *
d36057df 639 * @param width new widget width
a83fea2b 640 */
d36057df 641 public final void setWidth(final int width) {
a83fea2b 642 this.width = width;
a83fea2b
KL
643 }
644
2ce6dab2 645 /**
d36057df 646 * Get the height.
2ce6dab2 647 *
d36057df 648 * @return widget height
2ce6dab2 649 */
d36057df
KL
650 public final int getHeight() {
651 return this.height;
652 }
2ce6dab2 653
d36057df
KL
654 /**
655 * Change the height.
656 *
657 * @param height new widget height
658 */
659 public final void setHeight(final int height) {
2ce6dab2
KL
660 this.height = height;
661 }
662
48e27807 663 /**
d36057df 664 * Change the dimensions.
48e27807 665 *
d36057df
KL
666 * @param x absolute X position of the top-left corner
667 * @param y absolute Y position of the top-left corner
668 * @param width new widget width
669 * @param height new widget height
48e27807 670 */
d36057df
KL
671 public final void setDimensions(final int x, final int y, final int width,
672 final int height) {
48e27807 673
d36057df
KL
674 setX(x);
675 setY(y);
676 setWidth(width);
677 setHeight(height);
48e27807
KL
678 }
679
680 /**
d36057df 681 * Get enabled flag.
48e27807 682 *
d36057df 683 * @return if true, this widget can be tabbed to or receive events
48e27807 684 */
d36057df
KL
685 public final boolean isEnabled() {
686 return enabled;
687 }
48e27807 688
d36057df
KL
689 /**
690 * Set enabled flag.
691 *
692 * @param enabled if true, this widget can be tabbed to or receive events
693 */
694 public final void setEnabled(final boolean enabled) {
695 this.enabled = enabled;
696 if (!enabled) {
697 active = false;
698 // See if there are any active siblings to switch to
699 boolean foundSibling = false;
700 if (parent != null) {
701 for (TWidget w: parent.children) {
702 if ((w.enabled)
703 && !(this instanceof THScroller)
704 && !(this instanceof TVScroller)
705 ) {
706 parent.activate(w);
707 foundSibling = true;
708 break;
709 }
710 }
711 if (!foundSibling) {
712 parent.activeChild = null;
713 }
48e27807 714 }
48e27807
KL
715 }
716 }
717
051e2913
KL
718 /**
719 * Set visible flag.
720 *
721 * @param visible if true, this widget will be drawn
722 */
723 public final void setVisible(final boolean visible) {
724 this.visible = visible;
725 }
726
727 /**
728 * See if this widget is visible.
729 *
730 * @return if true, this widget will be drawn
731 */
732 public final boolean isVisible() {
733 return visible;
734 }
735
48e27807 736 /**
d36057df 737 * Set visible cursor flag.
48e27807 738 *
d36057df 739 * @param cursorVisible if true, this widget has a cursor
48e27807 740 */
d36057df
KL
741 public final void setCursorVisible(final boolean cursorVisible) {
742 this.cursorVisible = cursorVisible;
48e27807
KL
743 }
744
745 /**
d36057df 746 * See if this widget has a visible cursor.
48e27807 747 *
d36057df 748 * @return if true, this widget has a visible cursor
48e27807 749 */
d36057df
KL
750 public final boolean isCursorVisible() {
751 // If cursor is out of my bounds, it is not visible.
752 if ((cursorX >= width)
753 || (cursorX < 0)
754 || (cursorY >= height)
755 || (cursorY < 0)
756 ) {
757 return false;
758 }
48e27807 759
d36057df
KL
760 // If cursor is out of my window's bounds, it is not visible.
761 if ((getCursorAbsoluteX() >= window.getAbsoluteX()
762 + window.getWidth() - 1)
763 || (getCursorAbsoluteX() < 0)
764 || (getCursorAbsoluteY() >= window.getAbsoluteY()
765 + window.getHeight() - 1)
766 || (getCursorAbsoluteY() < 0)
767 ) {
768 return false;
48e27807 769 }
d36057df
KL
770 return cursorVisible;
771 }
48e27807 772
d36057df
KL
773 /**
774 * Get cursor X value.
775 *
776 * @return cursor column position in relative coordinates
777 */
778 public final int getCursorX() {
779 return cursorX;
780 }
48e27807 781
d36057df
KL
782 /**
783 * Set cursor X value.
784 *
785 * @param cursorX column position in relative coordinates
786 */
787 public final void setCursorX(final int cursorX) {
788 this.cursorX = cursorX;
789 }
48e27807 790
d36057df
KL
791 /**
792 * Get cursor Y value.
793 *
794 * @return cursor row position in relative coordinates
795 */
796 public final int getCursorY() {
797 return cursorY;
798 }
48e27807 799
d36057df
KL
800 /**
801 * Set cursor Y value.
802 *
803 * @param cursorY row position in relative coordinates
804 */
805 public final void setCursorY(final int cursorY) {
806 this.cursorY = cursorY;
807 }
48e27807 808
d36057df
KL
809 /**
810 * Get this TWidget's parent TApplication.
811 *
812 * @return the parent TApplication
813 */
814 public TApplication getApplication() {
815 return window.getApplication();
816 }
48e27807 817
d36057df
KL
818 /**
819 * Get the Screen.
820 *
821 * @return the Screen
822 */
823 public Screen getScreen() {
824 return window.getScreen();
48e27807
KL
825 }
826
827 /**
d36057df
KL
828 * Comparison operator. For various subclasses it sorts on:
829 * <ul>
830 * <li>tabOrder for TWidgets</li>
831 * <li>z for TWindows</li>
832 * <li>text for TTreeItems</li>
833 * </ul>
48e27807 834 *
d36057df
KL
835 * @param that another TWidget, TWindow, or TTreeItem instance
836 * @return difference between this.tabOrder and that.tabOrder, or
837 * difference between this.z and that.z, or String.compareTo(text)
48e27807 838 */
d36057df
KL
839 public final int compareTo(final TWidget that) {
840 if ((this instanceof TWindow)
841 && (that instanceof TWindow)
48e27807 842 ) {
d36057df
KL
843 return (((TWindow) this).getZ() - ((TWindow) that).getZ());
844 }
845 if ((this instanceof TTreeItem)
846 && (that instanceof TTreeItem)
847 ) {
848 return (((TTreeItem) this).getText().compareTo(
849 ((TTreeItem) that).getText()));
48e27807 850 }
d36057df
KL
851 return (this.tabOrder - that.tabOrder);
852 }
48e27807 853
d36057df
KL
854 /**
855 * See if this widget should render with the active color.
856 *
857 * @return true if this widget is active and all of its parents are
858 * active.
859 */
860 public final boolean isAbsoluteActive() {
861 if (parent == this) {
862 return active;
48e27807 863 }
d36057df 864 return (active && parent.isAbsoluteActive());
48e27807
KL
865 }
866
d36057df
KL
867 /**
868 * Returns the cursor X position.
869 *
870 * @return absolute screen column number for the cursor's X position
871 */
872 public final int getCursorAbsoluteX() {
873 return getAbsoluteX() + cursorX;
874 }
2ce6dab2
KL
875
876 /**
d36057df 877 * Returns the cursor Y position.
2ce6dab2 878 *
d36057df 879 * @return absolute screen row number for the cursor's Y position
2ce6dab2 880 */
d36057df
KL
881 public final int getCursorAbsoluteY() {
882 return getAbsoluteY() + cursorY;
883 }
2ce6dab2 884
d36057df
KL
885 /**
886 * Compute my absolute X position as the sum of my X plus all my parent's
887 * X's.
888 *
889 * @return absolute screen column number for my X position
890 */
891 public final int getAbsoluteX() {
892 assert (parent != null);
893 if (parent == this) {
894 return x;
2ce6dab2 895 }
d36057df
KL
896 if ((parent instanceof TWindow)
897 && !(parent instanceof TMenu)
898 && !(parent instanceof TDesktop)
899 ) {
900 // Widgets on a TWindow have (0,0) as their top-left, but this is
901 // actually the TWindow's (1,1).
902 return parent.getAbsoluteX() + x + 1;
903 }
904 return parent.getAbsoluteX() + x;
905 }
2ce6dab2 906
d36057df
KL
907 /**
908 * Compute my absolute Y position as the sum of my Y plus all my parent's
909 * Y's.
910 *
911 * @return absolute screen row number for my Y position
912 */
913 public final int getAbsoluteY() {
914 assert (parent != null);
915 if (parent == this) {
916 return y;
917 }
918 if ((parent instanceof TWindow)
919 && !(parent instanceof TMenu)
920 && !(parent instanceof TDesktop)
2ce6dab2 921 ) {
d36057df
KL
922 // Widgets on a TWindow have (0,0) as their top-left, but this is
923 // actually the TWindow's (1,1).
924 return parent.getAbsoluteY() + y + 1;
2ce6dab2 925 }
d36057df 926 return parent.getAbsoluteY() + y;
2ce6dab2
KL
927 }
928
48e27807 929 /**
d36057df 930 * Get the global color theme.
48e27807 931 *
d36057df 932 * @return the ColorTheme
48e27807 933 */
d36057df
KL
934 public final ColorTheme getTheme() {
935 return window.getApplication().getTheme();
936 }
48e27807 937
d36057df
KL
938 /**
939 * Draw my specific widget. When called, the screen rectangle I draw
940 * into is already setup (offset and clipping).
941 */
942 public void draw() {
943 // Default widget draws nothing.
944 }
48e27807 945
d36057df
KL
946 /**
947 * Called by parent to render to TWindow.
948 */
949 public final void drawChildren() {
950 // Set my clipping rectangle
951 assert (window != null);
952 assert (getScreen() != null);
953 Screen screen = getScreen();
954
955 // Special case: TStatusBar is drawn by TApplication, not anything
956 // else.
957 if (this instanceof TStatusBar) {
958 return;
48e27807
KL
959 }
960
d36057df
KL
961 screen.setClipRight(width);
962 screen.setClipBottom(height);
92554d64 963
d36057df
KL
964 int absoluteRightEdge = window.getAbsoluteX() + window.getWidth();
965 int absoluteBottomEdge = window.getAbsoluteY() + window.getHeight();
966 if (!(this instanceof TWindow) && !(this instanceof TVScroller)) {
967 absoluteRightEdge -= 1;
968 }
969 if (!(this instanceof TWindow) && !(this instanceof THScroller)) {
970 absoluteBottomEdge -= 1;
48e27807 971 }
d36057df
KL
972 int myRightEdge = getAbsoluteX() + width;
973 int myBottomEdge = getAbsoluteY() + height;
974 if (getAbsoluteX() > absoluteRightEdge) {
975 // I am offscreen
976 screen.setClipRight(0);
977 } else if (myRightEdge > absoluteRightEdge) {
978 screen.setClipRight(screen.getClipRight()
979 - (myRightEdge - absoluteRightEdge));
980 }
981 if (getAbsoluteY() > absoluteBottomEdge) {
982 // I am offscreen
983 screen.setClipBottom(0);
984 } else if (myBottomEdge > absoluteBottomEdge) {
985 screen.setClipBottom(screen.getClipBottom()
986 - (myBottomEdge - absoluteBottomEdge));
987 }
988
989 // Set my offset
990 screen.setOffsetX(getAbsoluteX());
991 screen.setOffsetY(getAbsoluteY());
48e27807 992
d36057df
KL
993 // Draw me
994 draw();
995
996 // Continue down the chain
48e27807 997 for (TWidget widget: children) {
051e2913
KL
998 if (widget.isVisible()) {
999 widget.drawChildren();
1000 }
48e27807
KL
1001 }
1002 }
1003
1004 /**
d36057df 1005 * Repaint the screen on the next update.
48e27807 1006 */
051e2913 1007 public final void doRepaint() {
d36057df 1008 window.getApplication().doRepaint();
48e27807
KL
1009 }
1010
1011 /**
d36057df
KL
1012 * Add a child widget to my list of children. We set its tabOrder to 0
1013 * and increment the tabOrder of all other children.
48e27807 1014 *
d36057df 1015 * @param child TWidget to add
48e27807 1016 */
d36057df
KL
1017 private void addChild(final TWidget child) {
1018 children.add(child);
48e27807 1019
d36057df
KL
1020 if ((child.enabled)
1021 && !(child instanceof THScroller)
1022 && !(child instanceof TVScroller)
1023 ) {
1024 for (TWidget widget: children) {
1025 widget.active = false;
48e27807 1026 }
d36057df
KL
1027 child.active = true;
1028 activeChild = child;
48e27807 1029 }
d36057df
KL
1030 for (int i = 0; i < children.size(); i++) {
1031 children.get(i).tabOrder = i;
48e27807
KL
1032 }
1033 }
1034
b6faeac0 1035 /**
d36057df 1036 * Switch the active child.
b6faeac0 1037 *
d36057df 1038 * @param child TWidget to activate
b6faeac0 1039 */
d36057df
KL
1040 public final void activate(final TWidget child) {
1041 assert (child.enabled);
1042 if ((child instanceof THScroller)
1043 || (child instanceof TVScroller)
1044 ) {
1045 return;
b6faeac0 1046 }
b6faeac0 1047
d36057df
KL
1048 if (child != activeChild) {
1049 if (activeChild != null) {
1050 activeChild.active = false;
12b55d76 1051 }
d36057df
KL
1052 child.active = true;
1053 activeChild = child;
48e27807
KL
1054 }
1055 }
1056
1057 /**
d36057df 1058 * Switch the active child.
48e27807 1059 *
d36057df
KL
1060 * @param tabOrder tabOrder of the child to activate. If that child
1061 * isn't enabled, then the next enabled child will be activated.
48e27807 1062 */
d36057df
KL
1063 public final void activate(final int tabOrder) {
1064 if (activeChild == null) {
1065 return;
48e27807 1066 }
d36057df 1067 TWidget child = null;
48e27807 1068 for (TWidget widget: children) {
d36057df
KL
1069 if ((widget.enabled)
1070 && !(widget instanceof THScroller)
1071 && !(widget instanceof TVScroller)
1072 && (widget.tabOrder >= tabOrder)
1073 ) {
1074 child = widget;
1075 break;
1076 }
48e27807 1077 }
d36057df
KL
1078 if ((child != null) && (child != activeChild)) {
1079 activeChild.active = false;
1080 assert (child.enabled);
1081 child.active = true;
1082 activeChild = child;
48e27807
KL
1083 }
1084 }
1085
1086 /**
d36057df 1087 * Switch the active widget with the next in the tab order.
48e27807 1088 *
d36057df
KL
1089 * @param forward if true, then switch to the next enabled widget in the
1090 * list, otherwise switch to the previous enabled widget in the list
48e27807 1091 */
d36057df 1092 public final void switchWidget(final boolean forward) {
48e27807 1093
d36057df
KL
1094 // Only switch if there are multiple enabled widgets
1095 if ((children.size() < 2) || (activeChild == null)) {
48e27807
KL
1096 return;
1097 }
1098
d36057df
KL
1099 int tabOrder = activeChild.tabOrder;
1100 do {
1101 if (forward) {
1102 tabOrder++;
1103 } else {
1104 tabOrder--;
1105 }
1106 if (tabOrder < 0) {
48e27807 1107
d36057df
KL
1108 // If at the end, pass the switch to my parent.
1109 if ((!forward) && (parent != this)) {
1110 parent.switchWidget(forward);
1111 return;
1112 }
48e27807 1113
d36057df
KL
1114 tabOrder = children.size() - 1;
1115 } else if (tabOrder == children.size()) {
1116 // If at the end, pass the switch to my parent.
1117 if ((forward) && (parent != this)) {
1118 parent.switchWidget(forward);
1119 return;
1120 }
48e27807 1121
d36057df
KL
1122 tabOrder = 0;
1123 }
1124 if (activeChild.tabOrder == tabOrder) {
1125 // We wrapped around
48e27807 1126 break;
d36057df
KL
1127 }
1128 } while ((!children.get(tabOrder).enabled)
1129 && !(children.get(tabOrder) instanceof THScroller)
1130 && !(children.get(tabOrder) instanceof TVScroller));
48e27807 1131
d36057df 1132 assert (children.get(tabOrder).enabled);
48e27807 1133
d36057df
KL
1134 activeChild.active = false;
1135 children.get(tabOrder).active = true;
1136 activeChild = children.get(tabOrder);
1137 }
48e27807 1138
d36057df
KL
1139 /**
1140 * Returns my active widget.
1141 *
1142 * @return widget that is active, or this if no children
1143 */
1144 public TWidget getActiveChild() {
1145 if ((this instanceof THScroller)
1146 || (this instanceof TVScroller)
1147 ) {
1148 return parent;
1149 }
b6faeac0 1150
d36057df
KL
1151 for (TWidget widget: children) {
1152 if (widget.active) {
1153 return widget.getActiveChild();
48e27807 1154 }
48e27807 1155 }
d36057df
KL
1156 // No active children, return me
1157 return this;
48e27807
KL
1158 }
1159
2ce6dab2
KL
1160 // ------------------------------------------------------------------------
1161 // Other TWidget constructors ---------------------------------------------
1162 // ------------------------------------------------------------------------
48e27807 1163
30d336cc
KL
1164 /**
1165 * Convenience function to add a label to this container/window.
1166 *
1167 * @param text label
1168 * @param x column relative to parent
1169 * @param y row relative to parent
1170 * @return the new label
1171 */
1172 public final TLabel addLabel(final String text, final int x, final int y) {
1173 return addLabel(text, x, y, "tlabel");
1174 }
1175
1176 /**
1177 * Convenience function to add a label to this container/window.
1178 *
1179 * @param text label
1180 * @param x column relative to parent
1181 * @param y row relative to parent
1182 * @param colorKey ColorTheme key color to use for foreground text.
1183 * Default is "tlabel"
1184 * @return the new label
1185 */
1186 public final TLabel addLabel(final String text, final int x, final int y,
1187 final String colorKey) {
1188
1189 return new TLabel(this, text, x, y, colorKey);
1190 }
1191
051e2913
KL
1192 /**
1193 * Convenience function to add a label to this container/window.
1194 *
1195 * @param text label
1196 * @param x column relative to parent
1197 * @param y row relative to parent
1198 * @param colorKey ColorTheme key color to use for foreground text.
1199 * Default is "tlabel"
1200 * @param useWindowBackground if true, use the window's background color
1201 * @return the new label
1202 */
1203 public final TLabel addLabel(final String text, final int x, final int y,
1204 final String colorKey, final boolean useWindowBackground) {
1205
1206 return new TLabel(this, text, x, y, colorKey, useWindowBackground);
1207 }
1208
30d336cc
KL
1209 /**
1210 * Convenience function to add a button to this container/window.
1211 *
1212 * @param text label on the button
1213 * @param x column relative to parent
1214 * @param y row relative to parent
051e2913 1215 * @param action action to call when button is pressed
30d336cc
KL
1216 * @return the new button
1217 */
1218 public final TButton addButton(final String text, final int x, final int y,
1219 final TAction action) {
1220
1221 return new TButton(this, text, x, y, action);
1222 }
1223
7272e49f
KL
1224 /**
1225 * Convenience function to add a checkbox to this container/window.
1226 *
1227 * @param x column relative to parent
1228 * @param y row relative to parent
1229 * @param label label to display next to (right of) the checkbox
1230 * @param checked initial check state
1231 * @return the new checkbox
1232 */
051e2913 1233 public final TCheckBox addCheckBox(final int x, final int y,
7272e49f
KL
1234 final String label, final boolean checked) {
1235
051e2913
KL
1236 return new TCheckBox(this, x, y, label, checked);
1237 }
1238
1239 /**
1240 * Convenience function to add a combobox to this container/window.
1241 *
1242 * @param x column relative to parent
1243 * @param y row relative to parent
1244 * @param width visible combobox width, including the down-arrow
1245 * @param values the possible values for the box, shown in the drop-down
1246 * @param valuesIndex the initial index in values, or -1 for no default
1247 * value
1248 * @param valuesHeight the height of the values drop-down when it is
1249 * visible
1250 * @param updateAction action to call when a new value is selected from
1251 * the list or enter is pressed in the edit field
1252 * @return the new combobox
1253 */
1254 public final TComboBox addComboBox(final int x, final int y,
1255 final int width, final List<String> values, final int valuesIndex,
1256 final int valuesHeight, final TAction updateAction) {
1257
1258 return new TComboBox(this, x, y, width, values, valuesIndex,
1259 valuesHeight, updateAction);
1260 }
1261
1262 /**
1263 * Convenience function to add a spinner to this container/window.
1264 *
1265 * @param x column relative to parent
1266 * @param y row relative to parent
1267 * @param upAction action to call when the up arrow is clicked or pressed
1268 * @param downAction action to call when the down arrow is clicked or
1269 * pressed
1270 * @return the new spinner
1271 */
1272 public final TSpinner addSpinner(final int x, final int y,
1273 final TAction upAction, final TAction downAction) {
1274
1275 return new TSpinner(this, x, y, upAction, downAction);
1276 }
1277
1278 /**
1279 * Convenience function to add a calendar to this container/window.
1280 *
1281 * @param x column relative to parent
1282 * @param y row relative to parent
1283 * @param updateAction action to call when the user changes the value of
1284 * the calendar
1285 * @return the new calendar
1286 */
1287 public final TCalendar addCalendar(final int x, final int y,
1288 final TAction updateAction) {
1289
1290 return new TCalendar(this, x, y, updateAction);
7272e49f 1291 }
30d336cc 1292
d502a0e9
KL
1293 /**
1294 * Convenience function to add a progress bar to this container/window.
1295 *
1296 * @param x column relative to parent
1297 * @param y row relative to parent
1298 * @param width width of progress bar
1299 * @param value initial value of percent complete
00d2622b 1300 * @return the new progress bar
d502a0e9
KL
1301 */
1302 public final TProgressBar addProgressBar(final int x, final int y,
1303 final int width, final int value) {
1304
1305 return new TProgressBar(this, x, y, width, value);
1306 }
1307
00d2622b
KL
1308 /**
1309 * Convenience function to add a radio button group to this
1310 * container/window.
1311 *
1312 * @param x column relative to parent
1313 * @param y row relative to parent
1314 * @param label label to display on the group box
1315 * @return the new radio button group
1316 */
1317 public final TRadioGroup addRadioGroup(final int x, final int y,
1318 final String label) {
1319
1320 return new TRadioGroup(this, x, y, label);
1321 }
1322
128e5be1
KL
1323 /**
1324 * Convenience function to add a text field to this container/window.
1325 *
1326 * @param x column relative to parent
1327 * @param y row relative to parent
1328 * @param width visible text width
1329 * @param fixed if true, the text cannot exceed the display width
1330 * @return the new text field
1331 */
1332 public final TField addField(final int x, final int y,
1333 final int width, final boolean fixed) {
1334
1335 return new TField(this, x, y, width, fixed);
1336 }
1337
1338 /**
1339 * Convenience function to add a text field to this container/window.
1340 *
1341 * @param x column relative to parent
1342 * @param y row relative to parent
1343 * @param width visible text width
1344 * @param fixed if true, the text cannot exceed the display width
1345 * @param text initial text, default is empty string
1346 * @return the new text field
1347 */
1348 public final TField addField(final int x, final int y,
1349 final int width, final boolean fixed, final String text) {
1350
1351 return new TField(this, x, y, width, fixed, text);
1352 }
1353
1354 /**
1355 * Convenience function to add a text field to this container/window.
1356 *
1357 * @param x column relative to parent
1358 * @param y row relative to parent
1359 * @param width visible text width
1360 * @param fixed if true, the text cannot exceed the display width
1361 * @param text initial text, default is empty string
1362 * @param enterAction function to call when enter key is pressed
1363 * @param updateAction function to call when the text is updated
1364 * @return the new text field
1365 */
1366 public final TField addField(final int x, final int y,
1367 final int width, final boolean fixed, final String text,
1368 final TAction enterAction, final TAction updateAction) {
1369
1370 return new TField(this, x, y, width, fixed, text, enterAction,
1371 updateAction);
1372 }
00d2622b 1373
cc99cba8
KL
1374 /**
1375 * Convenience function to add a scrollable text box to this
1376 * container/window.
1377 *
1378 * @param text text on the screen
1379 * @param x column relative to parent
1380 * @param y row relative to parent
1381 * @param width width of text area
1382 * @param height height of text area
1383 * @param colorKey ColorTheme key color to use for foreground text
1384 * @return the new text box
1385 */
c6940ed9 1386 public final TText addText(final String text, final int x,
cc99cba8
KL
1387 final int y, final int width, final int height, final String colorKey) {
1388
1389 return new TText(this, text, x, y, width, height, colorKey);
1390 }
1391
1392 /**
1393 * Convenience function to add a scrollable text box to this
1394 * container/window.
1395 *
1396 * @param text text on the screen
1397 * @param x column relative to parent
1398 * @param y row relative to parent
1399 * @param width width of text area
1400 * @param height height of text area
1401 * @return the new text box
1402 */
c6940ed9 1403 public final TText addText(final String text, final int x, final int y,
cc99cba8
KL
1404 final int width, final int height) {
1405
1406 return new TText(this, text, x, y, width, height, "ttext");
1407 }
1408
12b55d76
KL
1409 /**
1410 * Convenience function to add an editable text area box to this
1411 * container/window.
1412 *
1413 * @param text text on the screen
1414 * @param x column relative to parent
1415 * @param y row relative to parent
1416 * @param width width of text area
1417 * @param height height of text area
1418 * @return the new text box
1419 */
1420 public final TEditorWidget addEditor(final String text, final int x,
1421 final int y, final int width, final int height) {
1422
1423 return new TEditorWidget(this, text, x, y, width, height);
1424 }
1425
c6940ed9
KL
1426 /**
1427 * Convenience function to spawn a message box.
1428 *
1429 * @param title window title, will be centered along the top border
1430 * @param caption message to display. Use embedded newlines to get a
1431 * multi-line box.
1432 * @return the new message box
1433 */
1434 public final TMessageBox messageBox(final String title,
1435 final String caption) {
1436
1437 return getApplication().messageBox(title, caption, TMessageBox.Type.OK);
1438 }
1439
1440 /**
1441 * Convenience function to spawn a message box.
1442 *
1443 * @param title window title, will be centered along the top border
1444 * @param caption message to display. Use embedded newlines to get a
1445 * multi-line box.
1446 * @param type one of the TMessageBox.Type constants. Default is
1447 * Type.OK.
1448 * @return the new message box
1449 */
1450 public final TMessageBox messageBox(final String title,
1451 final String caption, final TMessageBox.Type type) {
1452
1453 return getApplication().messageBox(title, caption, type);
1454 }
1455
1456 /**
1457 * Convenience function to spawn an input box.
1458 *
1459 * @param title window title, will be centered along the top border
1460 * @param caption message to display. Use embedded newlines to get a
1461 * multi-line box.
1462 * @return the new input box
1463 */
1464 public final TInputBox inputBox(final String title, final String caption) {
1465
1466 return getApplication().inputBox(title, caption);
1467 }
1468
1469 /**
1470 * Convenience function to spawn an input box.
1471 *
1472 * @param title window title, will be centered along the top border
1473 * @param caption message to display. Use embedded newlines to get a
1474 * multi-line box.
1475 * @param text initial text to seed the field with
1476 * @return the new input box
1477 */
1478 public final TInputBox inputBox(final String title, final String caption,
1479 final String text) {
1480
1481 return getApplication().inputBox(title, caption, text);
1482 }
cc99cba8 1483
87a17f3c
KL
1484 /**
1485 * Convenience function to add a password text field to this
1486 * container/window.
1487 *
1488 * @param x column relative to parent
1489 * @param y row relative to parent
1490 * @param width visible text width
1491 * @param fixed if true, the text cannot exceed the display width
1492 * @return the new text field
1493 */
1494 public final TPasswordField addPasswordField(final int x, final int y,
1495 final int width, final boolean fixed) {
1496
1497 return new TPasswordField(this, x, y, width, fixed);
1498 }
1499
1500 /**
1501 * Convenience function to add a password text field to this
1502 * container/window.
1503 *
1504 * @param x column relative to parent
1505 * @param y row relative to parent
1506 * @param width visible text width
1507 * @param fixed if true, the text cannot exceed the display width
1508 * @param text initial text, default is empty string
1509 * @return the new text field
1510 */
1511 public final TPasswordField addPasswordField(final int x, final int y,
1512 final int width, final boolean fixed, final String text) {
1513
1514 return new TPasswordField(this, x, y, width, fixed, text);
1515 }
1516
1517 /**
1518 * Convenience function to add a password text field to this
1519 * container/window.
1520 *
1521 * @param x column relative to parent
1522 * @param y row relative to parent
1523 * @param width visible text width
1524 * @param fixed if true, the text cannot exceed the display width
1525 * @param text initial text, default is empty string
1526 * @param enterAction function to call when enter key is pressed
1527 * @param updateAction function to call when the text is updated
1528 * @return the new text field
1529 */
1530 public final TPasswordField addPasswordField(final int x, final int y,
1531 final int width, final boolean fixed, final String text,
1532 final TAction enterAction, final TAction updateAction) {
1533
1534 return new TPasswordField(this, x, y, width, fixed, text, enterAction,
1535 updateAction);
1536 }
1537
7668cb45 1538 /**
d36057df
KL
1539 * Convenience function to add a scrollable tree view to this
1540 * container/window.
7668cb45
KL
1541 *
1542 * @param x column relative to parent
1543 * @param y row relative to parent
1544 * @param width width of tree view
1545 * @param height height of tree view
329fd62e 1546 * @return the new tree view
7668cb45 1547 */
d36057df 1548 public final TTreeViewWidget addTreeViewWidget(final int x, final int y,
7668cb45
KL
1549 final int width, final int height) {
1550
d36057df 1551 return new TTreeViewWidget(this, x, y, width, height);
7668cb45
KL
1552 }
1553
1554 /**
d36057df
KL
1555 * Convenience function to add a scrollable tree view to this
1556 * container/window.
7668cb45
KL
1557 *
1558 * @param x column relative to parent
1559 * @param y row relative to parent
1560 * @param width width of tree view
1561 * @param height height of tree view
1562 * @param action action to perform when an item is selected
329fd62e 1563 * @return the new tree view
7668cb45 1564 */
d36057df 1565 public final TTreeViewWidget addTreeViewWidget(final int x, final int y,
7668cb45
KL
1566 final int width, final int height, final TAction action) {
1567
d36057df 1568 return new TTreeViewWidget(this, x, y, width, height, action);
7668cb45
KL
1569 }
1570
0d47c546
KL
1571 /**
1572 * Convenience function to spawn a file open box.
1573 *
1574 * @param path path of selected file
1575 * @return the result of the new file open box
329fd62e 1576 * @throws IOException if a java.io operation throws
0d47c546
KL
1577 */
1578 public final String fileOpenBox(final String path) throws IOException {
1579 return getApplication().fileOpenBox(path);
1580 }
1581
1582 /**
1583 * Convenience function to spawn a file open box.
1584 *
1585 * @param path path of selected file
1586 * @param type one of the Type constants
1587 * @return the result of the new file open box
329fd62e 1588 * @throws IOException if a java.io operation throws
0d47c546
KL
1589 */
1590 public final String fileOpenBox(final String path,
1591 final TFileOpenBox.Type type) throws IOException {
1592
1593 return getApplication().fileOpenBox(path, type);
1594 }
1595 /**
1596 * Convenience function to add a directory list to this container/window.
1597 *
1598 * @param path directory path, must be a directory
1599 * @param x column relative to parent
1600 * @param y row relative to parent
1601 * @param width width of text area
1602 * @param height height of text area
329fd62e 1603 * @return the new directory list
0d47c546
KL
1604 */
1605 public final TDirectoryList addDirectoryList(final String path, final int x,
1606 final int y, final int width, final int height) {
1607
1608 return new TDirectoryList(this, path, x, y, width, height, null);
1609 }
1610
1611 /**
1612 * Convenience function to add a directory list to this container/window.
1613 *
1614 * @param path directory path, must be a directory
1615 * @param x column relative to parent
1616 * @param y row relative to parent
1617 * @param width width of text area
1618 * @param height height of text area
1619 * @param action action to perform when an item is selected
329fd62e 1620 * @return the new directory list
0d47c546
KL
1621 */
1622 public final TDirectoryList addDirectoryList(final String path, final int x,
1623 final int y, final int width, final int height, final TAction action) {
1624
1625 return new TDirectoryList(this, path, x, y, width, height, action);
1626 }
7668cb45 1627
3649b921
KL
1628 /**
1629 * Convenience function to add a directory list to this container/window.
1630 *
1631 * @param strings list of strings to show
1632 * @param x column relative to parent
1633 * @param y row relative to parent
1634 * @param width width of text area
1635 * @param height height of text area
1636 * @return the new directory list
1637 */
1638 public final TList addList(final List<String> strings, final int x,
1639 final int y, final int width, final int height) {
1640
1641 return new TList(this, strings, x, y, width, height, null);
1642 }
1643
1644 /**
1645 * Convenience function to add a directory list to this container/window.
1646 *
1647 * @param strings list of strings to show
1648 * @param x column relative to parent
1649 * @param y row relative to parent
1650 * @param width width of text area
1651 * @param height height of text area
1652 * @param enterAction action to perform when an item is selected
1653 * @return the new directory list
1654 */
1655 public final TList addList(final List<String> strings, final int x,
1656 final int y, final int width, final int height,
1657 final TAction enterAction) {
1658
1659 return new TList(this, strings, x, y, width, height, enterAction);
1660 }
1661
1662 /**
1663 * Convenience function to add a directory list to this container/window.
1664 *
1665 * @param strings list of strings to show
1666 * @param x column relative to parent
1667 * @param y row relative to parent
1668 * @param width width of text area
1669 * @param height height of text area
1670 * @param enterAction action to perform when an item is selected
1671 * @param moveAction action to perform when the user navigates to a new
1672 * item with arrow/page keys
1673 * @return the new directory list
1674 */
1675 public final TList addList(final List<String> strings, final int x,
1676 final int y, final int width, final int height,
1677 final TAction enterAction, final TAction moveAction) {
1678
1679 return new TList(this, strings, x, y, width, height, enterAction,
1680 moveAction);
1681 }
1682
48e27807 1683}