Update copyright to 2017
[fanfix.git] / src / jexer / TEditColorThemeWindow.java
1 /*
2 * Jexer - Java Text User Interface
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (C) 2017 Kevin Lamonte
7 *
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:
14 *
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
17 *
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.
25 *
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
27 * @version 1
28 */
29 package jexer;
30
31 import java.util.List;
32
33 import jexer.bits.Color;
34 import jexer.bits.ColorTheme;
35 import jexer.bits.CellAttributes;
36 import jexer.bits.GraphicsChars;
37 import jexer.event.TKeypressEvent;
38 import jexer.event.TMouseEvent;
39 import static jexer.TKeypress.*;
40
41 /**
42 * TEditColorThemeWindow provides an easy UI for users to alter the running
43 * color theme.
44 *
45 */
46 public final class TEditColorThemeWindow extends TWindow {
47
48 /**
49 * The foreground color picker.
50 */
51 class ForegroundPicker extends TWidget {
52
53 /**
54 * The selected color.
55 */
56 Color color;
57
58 /**
59 * The bold flag.
60 */
61 boolean bold;
62
63 /**
64 * Public constructor.
65 *
66 * @param parent parent widget
67 * @param x column relative to parent
68 * @param y row relative to parent
69 * @param width width of text area
70 * @param height height of text area
71 */
72 public ForegroundPicker(final TWidget parent, final int x,
73 final int y, final int width, final int height) {
74
75 super(parent, x, y, width, height);
76 }
77
78 /**
79 * Get the X grid coordinate for this color.
80 *
81 * @param color the Color value
82 * @return the X coordinate
83 */
84 private int getXColorPosition(final Color color) {
85 if (color.equals(Color.BLACK)) {
86 return 2;
87 } else if (color.equals(Color.BLUE)) {
88 return 5;
89 } else if (color.equals(Color.GREEN)) {
90 return 8;
91 } else if (color.equals(Color.CYAN)) {
92 return 11;
93 } else if (color.equals(Color.RED)) {
94 return 2;
95 } else if (color.equals(Color.MAGENTA)) {
96 return 5;
97 } else if (color.equals(Color.YELLOW)) {
98 return 8;
99 } else if (color.equals(Color.WHITE)) {
100 return 11;
101 }
102 throw new IllegalArgumentException("Invalid color: " + color);
103 }
104
105 /**
106 * Get the Y grid coordinate for this color.
107 *
108 * @param color the Color value
109 * @param bold if true use bold color
110 * @return the Y coordinate
111 */
112 private int getYColorPosition(final Color color, final boolean bold) {
113 int dotY = 1;
114 if (color.equals(Color.RED)) {
115 dotY = 2;
116 } else if (color.equals(Color.MAGENTA)) {
117 dotY = 2;
118 } else if (color.equals(Color.YELLOW)) {
119 dotY = 2;
120 } else if (color.equals(Color.WHITE)) {
121 dotY = 2;
122 }
123 if (bold) {
124 dotY += 2;
125 }
126 return dotY;
127 }
128
129 /**
130 * Get the bold value based on Y grid coordinate.
131 *
132 * @param dotY the Y coordinate
133 * @return the bold value
134 */
135 private boolean getBoldFromPosition(final int dotY) {
136 if (dotY > 2) {
137 return true;
138 }
139 return false;
140 }
141
142 /**
143 * Get the color based on (X, Y) grid coordinate.
144 *
145 * @param dotX the X coordinate
146 * @param dotY the Y coordinate
147 * @return the Color value
148 */
149 private Color getColorFromPosition(final int dotX, final int dotY) {
150 int y = dotY;
151 if (y > 2) {
152 y -= 2;
153 }
154 if ((1 <= dotX) && (dotX <= 3) && (y == 1)) {
155 return Color.BLACK;
156 }
157 if ((4 <= dotX) && (dotX <= 6) && (y == 1)) {
158 return Color.BLUE;
159 }
160 if ((7 <= dotX) && (dotX <= 9) && (y == 1)) {
161 return Color.GREEN;
162 }
163 if ((10 <= dotX) && (dotX <= 12) && (y == 1)) {
164 return Color.CYAN;
165 }
166 if ((1 <= dotX) && (dotX <= 3) && (y == 2)) {
167 return Color.RED;
168 }
169 if ((4 <= dotX) && (dotX <= 6) && (y == 2)) {
170 return Color.MAGENTA;
171 }
172 if ((7 <= dotX) && (dotX <= 9) && (y == 2)) {
173 return Color.YELLOW;
174 }
175 if ((10 <= dotX) && (dotX <= 12) && (y == 2)) {
176 return Color.WHITE;
177 }
178
179 throw new IllegalArgumentException("Invalid coordinates: "
180 + dotX + ", " + dotY);
181 }
182
183 /**
184 * Draw the foreground colors grid.
185 */
186 @Override
187 public void draw() {
188 CellAttributes border = getWindow().getBorder();
189 CellAttributes background = getWindow().getBackground();
190 CellAttributes attr = new CellAttributes();
191
192 getScreen().drawBox(0, 0, getWidth(), getHeight(), border,
193 background, 1, false);
194
195 attr.setTo(getTheme().getColor("twindow.background.modal"));
196 if (isActive()) {
197 attr.setForeColor(getTheme().getColor("tlabel").getForeColor());
198 attr.setBold(getTheme().getColor("tlabel").isBold());
199 }
200 getScreen().putStringXY(1, 0, " Foreground ", attr);
201
202 // Have to draw the colors manually because the int value matches
203 // SGR, not CGA.
204 attr.reset();
205 attr.setForeColor(Color.BLACK);
206 putStringXY(1, 1, "\u2588\u2588\u2588", attr);
207 attr.setForeColor(Color.BLUE);
208 putStringXY(4, 1, "\u2588\u2588\u2588", attr);
209 attr.setForeColor(Color.GREEN);
210 putStringXY(7, 1, "\u2588\u2588\u2588", attr);
211 attr.setForeColor(Color.CYAN);
212 putStringXY(10, 1, "\u2588\u2588\u2588", attr);
213 attr.setForeColor(Color.RED);
214 putStringXY(1, 2, "\u2588\u2588\u2588", attr);
215 attr.setForeColor(Color.MAGENTA);
216 putStringXY(4, 2, "\u2588\u2588\u2588", attr);
217 attr.setForeColor(Color.YELLOW);
218 putStringXY(7, 2, "\u2588\u2588\u2588", attr);
219 attr.setForeColor(Color.WHITE);
220 putStringXY(10, 2, "\u2588\u2588\u2588", attr);
221
222 attr.setBold(true);
223 attr.setForeColor(Color.BLACK);
224 putStringXY(1, 3, "\u2588\u2588\u2588", attr);
225 attr.setForeColor(Color.BLUE);
226 putStringXY(4, 3, "\u2588\u2588\u2588", attr);
227 attr.setForeColor(Color.GREEN);
228 putStringXY(7, 3, "\u2588\u2588\u2588", attr);
229 attr.setForeColor(Color.CYAN);
230 putStringXY(10, 3, "\u2588\u2588\u2588", attr);
231 attr.setForeColor(Color.RED);
232 putStringXY(1, 4, "\u2588\u2588\u2588", attr);
233 attr.setForeColor(Color.MAGENTA);
234 putStringXY(4, 4, "\u2588\u2588\u2588", attr);
235 attr.setForeColor(Color.YELLOW);
236 putStringXY(7, 4, "\u2588\u2588\u2588", attr);
237 attr.setForeColor(Color.WHITE);
238 putStringXY(10, 4, "\u2588\u2588\u2588", attr);
239
240 // Draw the dot
241 int dotX = getXColorPosition(color);
242 int dotY = getYColorPosition(color, bold);
243 if (color.equals(Color.BLACK) && !bold) {
244 // Use white-on-black for black. All other colors use
245 // black-on-whatever.
246 attr.reset();
247 getScreen().putCharXY(dotX, dotY, GraphicsChars.CP437[0x07],
248 attr);
249 } else {
250 attr.setForeColor(color);
251 attr.setBold(bold);
252 getScreen().putCharXY(dotX, dotY, '\u25D8', attr);
253 }
254 }
255
256 /**
257 * Handle keystrokes.
258 *
259 * @param keypress keystroke event
260 */
261 @Override
262 public void onKeypress(final TKeypressEvent keypress) {
263 if (keypress.equals(kbRight)) {
264 int dotX = getXColorPosition(color);
265 int dotY = getYColorPosition(color, bold);
266 if (dotX < 10) {
267 dotX += 3;
268 }
269 color = getColorFromPosition(dotX, dotY);
270 } else if (keypress.equals(kbLeft)) {
271 int dotX = getXColorPosition(color);
272 int dotY = getYColorPosition(color, bold);
273 if (dotX > 3) {
274 dotX -= 3;
275 }
276 color = getColorFromPosition(dotX, dotY);
277 } else if (keypress.equals(kbUp)) {
278 int dotX = getXColorPosition(color);
279 int dotY = getYColorPosition(color, bold);
280 if (dotY > 1) {
281 dotY--;
282 }
283 color = getColorFromPosition(dotX, dotY);
284 bold = getBoldFromPosition(dotY);
285 } else if (keypress.equals(kbDown)) {
286 int dotX = getXColorPosition(color);
287 int dotY = getYColorPosition(color, bold);
288 if (dotY < 4) {
289 dotY++;
290 }
291 color = getColorFromPosition(dotX, dotY);
292 bold = getBoldFromPosition(dotY);
293 } else {
294 // Pass to my parent
295 super.onKeypress(keypress);
296 return;
297 }
298
299 // Save this update to the local theme.
300 ((TEditColorThemeWindow) getWindow()).saveToEditTheme();
301 }
302
303 /**
304 * Handle mouse press events.
305 *
306 * @param mouse mouse button press event
307 */
308 @Override
309 public void onMouseDown(final TMouseEvent mouse) {
310 if (mouse.isMouseWheelUp()) {
311 // Do this like kbUp
312 int dotX = getXColorPosition(color);
313 int dotY = getYColorPosition(color, bold);
314 if (dotY > 1) {
315 dotY--;
316 }
317 color = getColorFromPosition(dotX, dotY);
318 bold = getBoldFromPosition(dotY);
319 } else if (mouse.isMouseWheelDown()) {
320 // Do this like kbDown
321 int dotX = getXColorPosition(color);
322 int dotY = getYColorPosition(color, bold);
323 if (dotY < 4) {
324 dotY++;
325 }
326 color = getColorFromPosition(dotX, dotY);
327 bold = getBoldFromPosition(dotY);
328 } else if ((mouse.getX() > 0)
329 && (mouse.getX() < getWidth() - 1)
330 && (mouse.getY() > 0)
331 && (mouse.getY() < getHeight() - 1)
332 ) {
333 color = getColorFromPosition(mouse.getX(), mouse.getY());
334 bold = getBoldFromPosition(mouse.getY());
335 } else {
336 // Let parent class handle it.
337 super.onMouseDown(mouse);
338 return;
339 }
340
341 // Save this update to the local theme.
342 ((TEditColorThemeWindow) getWindow()).saveToEditTheme();
343 }
344
345 }
346
347 /**
348 * The background color picker.
349 */
350 class BackgroundPicker extends TWidget {
351
352 /**
353 * The selected color.
354 */
355 Color color;
356
357 /**
358 * Public constructor.
359 *
360 * @param parent parent widget
361 * @param x column relative to parent
362 * @param y row relative to parent
363 * @param width width of text area
364 * @param height height of text area
365 */
366 public BackgroundPicker(final TWidget parent, final int x,
367 final int y, final int width, final int height) {
368
369 super(parent, x, y, width, height);
370 }
371
372 /**
373 * Get the X grid coordinate for this color.
374 *
375 * @param color the Color value
376 * @return the X coordinate
377 */
378 private int getXColorPosition(final Color color) {
379 if (color.equals(Color.BLACK)) {
380 return 2;
381 } else if (color.equals(Color.BLUE)) {
382 return 5;
383 } else if (color.equals(Color.GREEN)) {
384 return 8;
385 } else if (color.equals(Color.CYAN)) {
386 return 11;
387 } else if (color.equals(Color.RED)) {
388 return 2;
389 } else if (color.equals(Color.MAGENTA)) {
390 return 5;
391 } else if (color.equals(Color.YELLOW)) {
392 return 8;
393 } else if (color.equals(Color.WHITE)) {
394 return 11;
395 }
396 throw new IllegalArgumentException("Invalid color: " + color);
397 }
398
399 /**
400 * Get the Y grid coordinate for this color.
401 *
402 * @param color the Color value
403 * @return the Y coordinate
404 */
405 private int getYColorPosition(final Color color) {
406 int dotY = 1;
407 if (color.equals(Color.RED)) {
408 dotY = 2;
409 } else if (color.equals(Color.MAGENTA)) {
410 dotY = 2;
411 } else if (color.equals(Color.YELLOW)) {
412 dotY = 2;
413 } else if (color.equals(Color.WHITE)) {
414 dotY = 2;
415 }
416 return dotY;
417 }
418
419 /**
420 * Get the color based on (X, Y) grid coordinate.
421 *
422 * @param dotX the X coordinate
423 * @param dotY the Y coordinate
424 * @return the Color value
425 */
426 private Color getColorFromPosition(final int dotX, final int dotY) {
427 if ((1 <= dotX) && (dotX <= 3) && (dotY == 1)) {
428 return Color.BLACK;
429 }
430 if ((4 <= dotX) && (dotX <= 6) && (dotY == 1)) {
431 return Color.BLUE;
432 }
433 if ((7 <= dotX) && (dotX <= 9) && (dotY == 1)) {
434 return Color.GREEN;
435 }
436 if ((10 <= dotX) && (dotX <= 12) && (dotY == 1)) {
437 return Color.CYAN;
438 }
439 if ((1 <= dotX) && (dotX <= 3) && (dotY == 2)) {
440 return Color.RED;
441 }
442 if ((4 <= dotX) && (dotX <= 6) && (dotY == 2)) {
443 return Color.MAGENTA;
444 }
445 if ((7 <= dotX) && (dotX <= 9) && (dotY == 2)) {
446 return Color.YELLOW;
447 }
448 if ((10 <= dotX) && (dotX <= 12) && (dotY == 2)) {
449 return Color.WHITE;
450 }
451
452 throw new IllegalArgumentException("Invalid coordinates: "
453 + dotX + ", " + dotY);
454 }
455
456 /**
457 * Draw the background colors grid.
458 */
459 @Override
460 public void draw() {
461 CellAttributes border = getWindow().getBorder();
462 CellAttributes background = getWindow().getBackground();
463 CellAttributes attr = new CellAttributes();
464
465 getScreen().drawBox(0, 0, getWidth(), getHeight(), border,
466 background, 1, false);
467
468 attr.setTo(getTheme().getColor("twindow.background.modal"));
469 if (isActive()) {
470 attr.setForeColor(getTheme().getColor("tlabel").getForeColor());
471 attr.setBold(getTheme().getColor("tlabel").isBold());
472 }
473 getScreen().putStringXY(1, 0, " Background ", attr);
474
475 // Have to draw the colors manually because the int value matches
476 // SGR, not CGA.
477 attr.reset();
478 attr.setForeColor(Color.BLACK);
479 putStringXY(1, 1, "\u2588\u2588\u2588", attr);
480 attr.setForeColor(Color.BLUE);
481 putStringXY(4, 1, "\u2588\u2588\u2588", attr);
482 attr.setForeColor(Color.GREEN);
483 putStringXY(7, 1, "\u2588\u2588\u2588", attr);
484 attr.setForeColor(Color.CYAN);
485 putStringXY(10, 1, "\u2588\u2588\u2588", attr);
486 attr.setForeColor(Color.RED);
487 putStringXY(1, 2, "\u2588\u2588\u2588", attr);
488 attr.setForeColor(Color.MAGENTA);
489 putStringXY(4, 2, "\u2588\u2588\u2588", attr);
490 attr.setForeColor(Color.YELLOW);
491 putStringXY(7, 2, "\u2588\u2588\u2588", attr);
492 attr.setForeColor(Color.WHITE);
493 putStringXY(10, 2, "\u2588\u2588\u2588", attr);
494
495 // Draw the dot
496 int dotX = getXColorPosition(color);
497 int dotY = getYColorPosition(color);
498 if (color.equals(Color.BLACK)) {
499 // Use white-on-black for black. All other colors use
500 // black-on-whatever.
501 attr.reset();
502 getScreen().putCharXY(dotX, dotY, GraphicsChars.CP437[0x07],
503 attr);
504 } else {
505 attr.setForeColor(color);
506 getScreen().putCharXY(dotX, dotY, '\u25D8', attr);
507 }
508
509 }
510
511 /**
512 * Handle keystrokes.
513 *
514 * @param keypress keystroke event
515 */
516 @Override
517 public void onKeypress(final TKeypressEvent keypress) {
518 if (keypress.equals(kbRight)) {
519 int dotX = getXColorPosition(color);
520 int dotY = getYColorPosition(color);
521 if (dotX < 10) {
522 dotX += 3;
523 }
524 color = getColorFromPosition(dotX, dotY);
525 } else if (keypress.equals(kbLeft)) {
526 int dotX = getXColorPosition(color);
527 int dotY = getYColorPosition(color);
528 if (dotX > 3) {
529 dotX -= 3;
530 }
531 color = getColorFromPosition(dotX, dotY);
532 } else if (keypress.equals(kbUp)) {
533 int dotX = getXColorPosition(color);
534 int dotY = getYColorPosition(color);
535 if (dotY == 2) {
536 dotY--;
537 }
538 color = getColorFromPosition(dotX, dotY);
539 } else if (keypress.equals(kbDown)) {
540 int dotX = getXColorPosition(color);
541 int dotY = getYColorPosition(color);
542 if (dotY == 1) {
543 dotY++;
544 }
545 color = getColorFromPosition(dotX, dotY);
546 } else {
547 // Pass to my parent
548 super.onKeypress(keypress);
549 }
550
551 // Save this update to the local theme.
552 ((TEditColorThemeWindow) getWindow()).saveToEditTheme();
553 }
554
555 /**
556 * Handle mouse press events.
557 *
558 * @param mouse mouse button press event
559 */
560 @Override
561 public void onMouseDown(final TMouseEvent mouse) {
562 if (mouse.isMouseWheelUp()) {
563 // Do this like kbUp
564 int dotX = getXColorPosition(color);
565 int dotY = getYColorPosition(color);
566 if (dotY == 2) {
567 dotY--;
568 }
569 color = getColorFromPosition(dotX, dotY);
570 } else if (mouse.isMouseWheelDown()) {
571 // Do this like kbDown
572 int dotX = getXColorPosition(color);
573 int dotY = getYColorPosition(color);
574 if (dotY == 1) {
575 dotY++;
576 }
577 color = getColorFromPosition(dotX, dotY);
578 return;
579 } else if ((mouse.getX() > 0)
580 && (mouse.getX() < getWidth() - 1)
581 && (mouse.getY() > 0)
582 && (mouse.getY() < getHeight() - 1)
583 ) {
584 color = getColorFromPosition(mouse.getX(), mouse.getY());
585 } else {
586 // Let parent class handle it.
587 super.onMouseDown(mouse);
588 return;
589 }
590
591 // Save this update to the local theme.
592 ((TEditColorThemeWindow) getWindow()).saveToEditTheme();
593 }
594
595 }
596
597 /**
598 * The current editing theme.
599 */
600 private ColorTheme editTheme;
601
602 /**
603 * The left-side list of colors pane.
604 */
605 private TList colorNames;
606
607 /**
608 * The foreground color.
609 */
610 private ForegroundPicker foreground;
611
612 /**
613 * The background color.
614 */
615 private BackgroundPicker background;
616
617 /**
618 * Set various widgets/values to the editing theme color.
619 *
620 * @param colorName name of color from theme
621 */
622 private void refreshFromTheme(final String colorName) {
623 CellAttributes attr = editTheme.getColor(colorName);
624 foreground.color = attr.getForeColor();
625 foreground.bold = attr.isBold();
626 background.color = attr.getBackColor();
627 }
628
629 /**
630 * Examines foreground, background, and colorNames and sets the color in
631 * editTheme.
632 */
633 private void saveToEditTheme() {
634 String colorName = colorNames.getSelected();
635 if (colorName == null) {
636 return;
637 }
638 CellAttributes attr = editTheme.getColor(colorName);
639 attr.setForeColor(foreground.color);
640 attr.setBold(foreground.bold);
641 attr.setBackColor(background.color);
642 editTheme.setColor(colorName, attr);
643 }
644
645 /**
646 * Public constructor. The file open box will be centered on screen.
647 *
648 * @param application the TApplication that manages this window
649 */
650 public TEditColorThemeWindow(final TApplication application) {
651
652 // Register with the TApplication
653 super(application, "Colors", 0, 0, 60, 18, MODAL);
654
655 // Initialize with the first color
656 List<String> colors = getTheme().getColorNames();
657 assert (colors.size() > 0);
658 editTheme = new ColorTheme();
659 for (String key: colors) {
660 CellAttributes attr = new CellAttributes();
661 attr.setTo(getTheme().getColor(key));
662 editTheme.setColor(key, attr);
663 }
664
665 colorNames = addList(colors, 2, 2, 38, getHeight() - 7,
666 new TAction() {
667 // When the user presses Enter
668 public void DO() {
669 refreshFromTheme(colorNames.getSelected());
670 }
671 },
672 new TAction() {
673 // When the user navigates with keyboard
674 public void DO() {
675 refreshFromTheme(colorNames.getSelected());
676 }
677 }
678 );
679 foreground = new ForegroundPicker(this, 42, 1, 14, 6);
680 background = new BackgroundPicker(this, 42, 7, 14, 4);
681 refreshFromTheme(colors.get(0));
682 colorNames.setSelectedIndex(0);
683
684 addButton(" &OK ", getWidth() - 37, getHeight() - 4,
685 new TAction() {
686 public void DO() {
687 ColorTheme global = getTheme();
688 List<String> colors = editTheme.getColorNames();
689 for (String key: colors) {
690 CellAttributes attr = new CellAttributes();
691 attr.setTo(editTheme.getColor(key));
692 global.setColor(key, attr);
693 }
694 getApplication().closeWindow(TEditColorThemeWindow.this);
695 }
696 }
697 );
698
699 addButton("&Cancel", getWidth() - 25, getHeight() - 4,
700 new TAction() {
701 public void DO() {
702 getApplication().closeWindow(TEditColorThemeWindow.this);
703 }
704 }
705 );
706
707 // Default to the color list
708 activate(colorNames);
709
710 // Add shortcut text
711 newStatusBar("Select Colors");
712 }
713
714 /**
715 * Draw me on screen.
716 */
717 @Override
718 public void draw() {
719 super.draw();
720 CellAttributes attr = new CellAttributes();
721
722 // Draw the label on colorNames
723 attr.setTo(getTheme().getColor("twindow.background.modal"));
724 if (colorNames.isActive()) {
725 attr.setForeColor(getTheme().getColor("tlabel").getForeColor());
726 attr.setBold(getTheme().getColor("tlabel").isBold());
727 }
728 getScreen().putStringXY(3, 2, "Color Name", attr);
729
730 // Draw the sample text box
731 attr.reset();
732 attr.setForeColor(foreground.color);
733 attr.setBold(foreground.bold);
734 attr.setBackColor(background.color);
735 getScreen().putStringXY(getWidth() - 17, getHeight() - 6,
736 "Text Text Text", attr);
737 getScreen().putStringXY(getWidth() - 17, getHeight() - 5,
738 "Text Text Text", attr);
739 }
740
741 /**
742 * Handle keystrokes.
743 *
744 * @param keypress keystroke event
745 */
746 @Override
747 public void onKeypress(final TKeypressEvent keypress) {
748 // Escape - behave like cancel
749 if (keypress.equals(kbEsc)) {
750 getApplication().closeWindow(this);
751 return;
752 }
753
754 // Pass to my parent
755 super.onKeypress(keypress);
756 }
757
758 }