Pull demo into jar
[fanfix.git] / src / jexer / demos / Demo1.java
CommitLineData
70f5b2bb
KL
1/*
2 * Jexer - Java Text User Interface
7d4115a5
KL
3 *
4 * License: LGPLv3 or later
5 *
70f5b2bb
KL
6 * This module is licensed under the GNU Lesser General Public License
7 * Version 3. Please see the file "COPYING" in this directory for more
8 * information about the GNU Lesser General Public License Version 3.
7d4115a5
KL
9 *
10 * Copyright (C) 2015 Kevin Lamonte
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU Lesser General Public License
14 * as published by the Free Software Foundation; either version 3 of
15 * the License, or (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU Lesser General Public
23 * License along with this program; if not, see
24 * http://www.gnu.org/licenses/, or write to the Free Software
25 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
26 * 02110-1301 USA
70f5b2bb
KL
27 *
28 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
29 * @version 1
7d4115a5 30 */
70f5b2bb 31package jexer.demos;
2420f903 32
a06459bd 33import jexer.*;
cc99cba8 34import jexer.event.*;
8e688b92 35import jexer.menu.*;
a06459bd 36
70f5b2bb
KL
37/**
38 * This window demonstates the TText, THScroller, and TVScroller widgets.
39 */
cc99cba8
KL
40class DemoTextWindow extends TWindow {
41
42 /**
43 * Hang onto my TText so I can resize it with the window.
44 */
45 private TText textField;
46
47 /**
48 * Public constructor.
70f5b2bb
KL
49 *
50 * @param parent the main application
cc99cba8 51 */
70f5b2bb 52 public DemoTextWindow(final TApplication parent) {
cc99cba8
KL
53 super(parent, "Text Areas", 0, 0, 44, 20, RESIZABLE);
54
55 textField = addText(
56"This is an example of a reflowable text field. Some example text follows.\n" +
57"\n" +
58"This library implements a text-based windowing system loosely\n" +
59"reminiscient of Borland's [Turbo\n" +
60"Vision](http://en.wikipedia.org/wiki/Turbo_Vision) library. For those\n" +
61"wishing to use the actual C++ Turbo Vision library, see [Sergio\n" +
62"Sigala's updated version](http://tvision.sourceforge.net/) that runs\n" +
63"on many more platforms.\n" +
64"\n" +
65"Currently the only console platform supported is Posix (tested on\n" +
66"Linux). Input/output is handled through terminal escape sequences\n" +
67"generated by the library itself: ncurses is not required or linked to. \n" +
68"xterm mouse tracking using UTF8 coordinates is supported.\n" +
69"\n" +
70"This library is licensed LGPL (\"GNU Lesser General Public License\")\n" +
71"version 3 or greater. See the file COPYING for the full license text,\n" +
72"which includes both the GPL v3 and the LGPL supplemental terms.\n" +
73"\n",
74 1, 1, 40, 16);
75 }
76
77 /**
78 * Handle window/screen resize events.
79 *
80 * @param event resize event
81 */
82 @Override
83 public void onResize(final TResizeEvent event) {
84 if (event.getType() == TResizeEvent.Type.WIDGET) {
85 // Resize the text field
86 textField.setWidth(event.getWidth() - 4);
87 textField.setHeight(event.getHeight() - 4);
88 textField.reflow();
89 return;
90 }
91
92 // Pass to children instead
93 for (TWidget widget: getChildren()) {
94 widget.onResize(event);
95 }
96 }
97}
98
70f5b2bb
KL
99/**
100 * This window demonstates the TRadioGroup, TRadioButton, and TCheckbox
101 * widgets.
102 */
7272e49f
KL
103class DemoCheckboxWindow extends TWindow {
104
105 /**
cc99cba8 106 * Constructor.
70f5b2bb
KL
107 *
108 * @param parent the main application
7272e49f 109 */
70f5b2bb 110 DemoCheckboxWindow(final TApplication parent) {
7272e49f
KL
111 this(parent, CENTERED | RESIZABLE);
112 }
113
114 /**
cc99cba8 115 * Constructor.
70f5b2bb
KL
116 *
117 * @param parent the main application
118 * @param flags bitmask of MODAL, CENTERED, or RESIZABLE
7272e49f 119 */
70f5b2bb
KL
120 DemoCheckboxWindow(final TApplication parent, final int flags) {
121 // Construct a demo window. X and Y don't matter because it will be
122 // centered on screen.
7272e49f
KL
123 super(parent, "Radiobuttons and Checkboxes", 0, 0, 60, 15, flags);
124
125 int row = 1;
126
127 // Add some widgets
128 addLabel("Check box example 1", 1, row);
129 addCheckbox(35, row++, "Checkbox 1", false);
130 addLabel("Check box example 2", 1, row);
131 addCheckbox(35, row++, "Checkbox 2", true);
132 row += 2;
133
00d2622b 134 TRadioGroup group = addRadioGroup(1, row, "Group 1");
7272e49f
KL
135 group.addRadioButton("Radio option 1");
136 group.addRadioButton("Radio option 2");
137 group.addRadioButton("Radio option 3");
138
00d2622b
KL
139 addButton("&Close Window", (getWidth() - 14) / 2, getHeight() - 4,
140 new TAction() {
141 public void DO() {
70f5b2bb
KL
142 DemoCheckboxWindow.this.getApplication()
143 .closeWindow(DemoCheckboxWindow.this);
00d2622b 144 }
7272e49f 145 }
7272e49f 146 );
7272e49f
KL
147 }
148
149}
150
151
70f5b2bb
KL
152/**
153 * This window demonstates the TMessageBox and TInputBox widgets.
154 */
30d336cc
KL
155class DemoMsgBoxWindow extends TWindow {
156 /*
157 private void openYNCMessageBox() {
7272e49f
KL
158 application.messageBox("Yes/No/Cancel MessageBox",
159 q"EOS
30d336cc
KL
160This is an example of a Yes/No/Cancel MessageBox.
161
162Note that the MessageBox text can span multiple
163lines.
164
165The default result (if someone hits the top-left
166close button) is CANCEL.
167EOS",
7272e49f 168 TMessageBox.Type.YESNOCANCEL);
30d336cc
KL
169 }
170
171 private void openYNMessageBox() {
7272e49f
KL
172 application.messageBox("Yes/No MessageBox",
173 q"EOS
30d336cc
KL
174This is an example of a Yes/No MessageBox.
175
176Note that the MessageBox text can span multiple
177lines.
178
179The default result (if someone hits the top-left
180close button) is NO.
181EOS",
7272e49f 182 TMessageBox.Type.YESNO);
30d336cc
KL
183 }
184
185 private void openOKCMessageBox() {
7272e49f
KL
186 application.messageBox("OK/Cancel MessageBox",
187 q"EOS
30d336cc
KL
188This is an example of a OK/Cancel MessageBox.
189
190Note that the MessageBox text can span multiple
191lines.
192
193The default result (if someone hits the top-left
194close button) is CANCEL.
195EOS",
7272e49f 196 TMessageBox.Type.OKCANCEL);
30d336cc
KL
197 }
198
199 private void openOKMessageBox() {
7272e49f
KL
200 application.messageBox("OK MessageBox",
201 q"EOS
30d336cc
KL
202This is an example of a OK MessageBox. This is the
203default MessageBox.
204
205Note that the MessageBox text can span multiple
206lines.
207
208The default result (if someone hits the top-left
209close button) is OK.
210EOS",
7272e49f 211 TMessageBox.Type.OK);
30d336cc
KL
212 }
213
214 */
215
216 /**
217 * Constructor.
70f5b2bb
KL
218 *
219 * @param parent the main application
30d336cc
KL
220 */
221 DemoMsgBoxWindow(final TApplication parent) {
7272e49f 222 this(parent, TWindow.CENTERED | TWindow.RESIZABLE);
30d336cc
KL
223 }
224
225 /**
226 * Constructor.
70f5b2bb
KL
227 *
228 * @param parent the main application
229 * @param flags bitmask of MODAL, CENTERED, or RESIZABLE
30d336cc
KL
230 */
231 DemoMsgBoxWindow(final TApplication parent, final int flags) {
7272e49f
KL
232 // Construct a demo window. X and Y don't matter because it
233 // will be centered on screen.
234 super(parent, "Message Boxes", 0, 0, 60, 15, flags);
30d336cc 235 /*
7272e49f
KL
236 uint row = 1;
237
238 // Add some widgets
239 addLabel("Default OK message box", 1, row);
240 addButton("Open O&K MB", 35, row, &openOKMessageBox);
241 row += 2;
242
243 addLabel("OK/Cancel message box", 1, row);
244 addButton("O&pen OKC MB", 35, row, &openOKCMessageBox);
245 row += 2;
246
247 addLabel("Yes/No message box", 1, row);
248 addButton("Open &YN MB", 35, row, &openYNMessageBox);
249 row += 2;
250
251 addLabel("Yes/No/Cancel message box", 1, row);
252 addButton("Ope&n YNC MB", 35, row, &openYNCMessageBox);
253 row += 2;
254
255 addLabel("Input box", 1, row);
256 addButton("Open &input box", 35, row,
257 {
258 application.inputBox("Input Box",
259 q"EOS
30d336cc
KL
260This is an example of an InputBox.
261
262Note that the InputBox text can span multiple
263lines.
264EOS",
7272e49f
KL
265 "some input text");
266 }
267 );
268
269 addButton("&Close Window", (width - 14) / 2, height - 4,
270 {
271 application.closeWindow(this);
272 }
273 );
30d336cc
KL
274 */
275 }
276}
277
70f5b2bb
KL
278/**
279 * This is the main "demo" application window. It makes use of the TTimer,
280 * TProgressBox, TLabel, TButton, and TField widgets.
281 */
a06459bd 282class DemoMainWindow extends TWindow {
cc99cba8
KL
283
284 // Timer that increments a number.
a06459bd
KL
285 private TTimer timer;
286
cc99cba8 287 // Timer label is updated with timer ticks.
d502a0e9
KL
288 TLabel timerLabel;
289
290 /*
a06459bd
KL
291 // The modal window is a more low-level example of controlling a window
292 // "from the outside". Most windows will probably subclass TWindow and
293 // do this kind of logic on their own.
294 private TWindow modalWindow;
295 private void openModalWindow() {
8e688b92
KL
296 modalWindow = application.addWindow("Demo Modal Window", 0, 0,
297 58, 15, TWindow.Flag.MODAL);
298 modalWindow.addLabel("This is an example of a very braindead modal window.", 1, 1);
299 modalWindow.addLabel("Modal windows are centered by default.", 1, 2);
300 modalWindow.addButton("&Close", (modalWindow.width - 8)/2,
301 modalWindow.height - 4, &modalWindowClose);
a06459bd
KL
302 }
303 private void modalWindowClose() {
8e688b92 304 application.closeWindow(modalWindow);
a06459bd 305 }
d502a0e9 306 */
a06459bd 307
d502a0e9
KL
308 /**
309 * We need to override onClose so that the timer will no longer be called
310 * after we close the window. TTimers currently are completely unaware
311 * of the rest of the UI classes.
a06459bd 312 */
d502a0e9
KL
313 @Override
314 public void onClose() {
315 getApplication().removeTimer(timer);
316 }
a06459bd 317
fca67db0
KL
318 /**
319 * Construct demo window. It will be centered on screen.
70f5b2bb
KL
320 *
321 * @param parent the main application
fca67db0 322 */
70f5b2bb 323 public DemoMainWindow(final TApplication parent) {
8e688b92 324 this(parent, CENTERED | RESIZABLE);
a06459bd
KL
325 }
326
70f5b2bb
KL
327 // These are used by the timer loop. They have to be at class scope so
328 // that they can be accessed by the anonymous TAction class.
d502a0e9
KL
329 int timerI = 0;
330 TProgressBar progressBar;
331
fca67db0
KL
332 /**
333 * Constructor.
70f5b2bb
KL
334 *
335 * @param parent the main application
336 * @param flags bitmask of MODAL, CENTERED, or RESIZABLE
fca67db0 337 */
70f5b2bb 338 private DemoMainWindow(final TApplication parent, final int flags) {
8e688b92
KL
339 // Construct a demo window. X and Y don't matter because it will be
340 // centered on screen.
341 super(parent, "Demo Window", 0, 0, 60, 23, flags);
a06459bd 342
8e688b92
KL
343 int row = 1;
344
345 // Add some widgets
30d336cc 346 if (!isModal()) {
8e688b92
KL
347 addLabel("Message Boxes", 1, row);
348 addButton("&MessageBoxes", 35, row,
30d336cc
KL
349 new TAction() {
350 public void DO() {
351 new DemoMsgBoxWindow(getApplication());
352 }
8e688b92
KL
353 }
354 );
355 }
356 row += 2;
357
358 addLabel("Open me as modal", 1, row);
359 addButton("W&indow", 35, row,
7272e49f
KL
360 new TAction() {
361 public void DO() {
362 new DemoMainWindow(getApplication(), MODAL);
363 }
8e688b92
KL
364 }
365 );
366
367 row += 2;
368
369 addLabel("Variable-width text field:", 1, row);
370 addField(35, row++, 15, false, "Field text");
371
372 addLabel("Fixed-width text field:", 1, row);
373 addField(35, row, 15, true);
374 row += 2;
375
7272e49f 376 if (!isModal()) {
8e688b92 377 addLabel("Radio buttons and checkboxes", 1, row);
7272e49f
KL
378 addButton("&Checkboxes", 35, row,
379 new TAction() {
380 public void DO() {
d502a0e9 381 new DemoCheckboxWindow(getApplication());
7272e49f
KL
382 }
383 }
384 );
8e688b92
KL
385 }
386 row += 2;
387
7272e49f
KL
388 /*
389 if (!isModal()) {
8e688b92
KL
390 addLabel("Editor window", 1, row);
391 addButton("Edito&r", 35, row,
392 {
393 new TEditor(application, 0, 0, 60, 15);
394 }
395 );
396 }
397 row += 2;
cc99cba8 398 */
8e688b92 399
7272e49f 400 if (!isModal()) {
8e688b92
KL
401 addLabel("Text areas", 1, row);
402 addButton("&Text", 35, row,
cc99cba8
KL
403 new TAction() {
404 public void DO() {
405 new DemoTextWindow(getApplication());
406 }
8e688b92
KL
407 }
408 );
409 }
410 row += 2;
411
cc99cba8 412 /*
7272e49f 413 if (!isModal()) {
8e688b92
KL
414 addLabel("Tree views", 1, row);
415 addButton("Tree&View", 35, row,
416 {
417 new DemoTreeViewWindow(application);
418 }
419 );
420 }
421 row += 2;
422
7272e49f
KL
423 if (!isModal()) {
424 addLabel("Terminal", 1, row);
425 addButton("Termi&nal", 35, row,
426 {
427 application.openTerminal(0, 0);
428 }
429 );
8e688b92 430 }
7272e49f 431 row += 2;
d502a0e9 432 */
8e688b92 433
d502a0e9 434 progressBar = addProgressBar(1, row, 22, 0);
8e688b92 435 row++;
d502a0e9
KL
436 timerLabel = addLabel("Timer", 1, row);
437 timer = getApplication().addTimer(100, true,
438 new TAction() {
439
440 public void DO() {
441 timerLabel.setText(String.format("Timer: %d", timerI));
442 timerLabel.setWidth(timerLabel.getText().length());
443 if (timerI < 100) {
444 timerI++;
445 }
446 progressBar.setValue(timerI);
447 DemoMainWindow.this.setRepaint();
8e688b92 448 }
d502a0e9
KL
449 }
450 );
a06459bd
KL
451 }
452}
7d4115a5
KL
453
454/**
455 * The demo application itself.
456 */
457class DemoApplication extends TApplication {
cc99cba8 458
2420f903 459 /**
70f5b2bb
KL
460 * Public constructor.
461 *
462 * @throws Exception if TApplication can't instantiate the Backend.
2420f903 463 */
4328bb42 464 public DemoApplication() throws Exception {
8e688b92
KL
465 super(null, null);
466 new DemoMainWindow(this);
467
8e688b92
KL
468 // Add the menus
469 addFileMenu();
470 addEditMenu();
471
472 TMenu demoMenu = addMenu("&Demo");
473 TMenuItem item = demoMenu.addItem(2000, "&Checkable");
474 item.setCheckable(true);
475 item = demoMenu.addItem(2001, "Disabled");
476 item.setEnabled(false);
477 item = demoMenu.addItem(2002, "&Normal");
478 TSubMenu subMenu = demoMenu.addSubMenu("Sub-&Menu");
479 item = demoMenu.addItem(2010, "N&ormal A&&D");
480
481 item = subMenu.addItem(2000, "&Checkable (sub)");
482 item.setCheckable(true);
483 item = subMenu.addItem(2001, "Disabled (sub)");
484 item.setEnabled(false);
485 item = subMenu.addItem(2002, "&Normal (sub)");
486
487 subMenu = subMenu.addSubMenu("Sub-&Menu");
488 item = subMenu.addItem(2000, "&Checkable (sub)");
489 item.setCheckable(true);
490 item = subMenu.addItem(2001, "Disabled (sub)");
491 item.setEnabled(false);
492 item = subMenu.addItem(2002, "&Normal (sub)");
493
494 addWindowMenu();
495
2420f903 496 }
7d4115a5
KL
497}
498
499/**
500 * This class provides a simple demonstration of Jexer's capabilities.
501 */
502public class Demo1 {
503 /**
504 * Main entry point.
505 *
cc99cba8 506 * @param args Command line arguments
7d4115a5 507 */
cc99cba8 508 public static void main(final String [] args) {
8e688b92
KL
509 try {
510 DemoApplication app = new DemoApplication();
511 app.run();
512 } catch (Exception e) {
513 e.printStackTrace();
514 }
7d4115a5
KL
515 }
516
517}