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