update README
[fanfix.git] / src / jexer / TScrollableWindow.java
1 /*
2 * Jexer - Java Text User Interface
3 *
4 * The MIT License (MIT)
5 *
6 * Copyright (C) 2019 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 jexer.event.TMouseEvent;
32 import jexer.event.TResizeEvent;
33
34 /**
35 * TScrollableWindow is a convenience superclass for windows that have
36 * scrollbars.
37 */
38 public class TScrollableWindow extends TWindow implements Scrollable {
39
40 // ------------------------------------------------------------------------
41 // Variables --------------------------------------------------------------
42 // ------------------------------------------------------------------------
43
44 /**
45 * The horizontal scrollbar.
46 */
47 protected THScroller hScroller = null;
48
49 /**
50 * The vertical scrollbar.
51 */
52 protected TVScroller vScroller = null;
53
54 // ------------------------------------------------------------------------
55 // Constructors -----------------------------------------------------------
56 // ------------------------------------------------------------------------
57
58 /**
59 * Public constructor. Window will be located at (0, 0).
60 *
61 * @param application TApplication that manages this window
62 * @param title window title, will be centered along the top border
63 * @param width width of window
64 * @param height height of window
65 */
66 public TScrollableWindow(final TApplication application, final String title,
67 final int width, final int height) {
68
69 super(application, title, width, height);
70 }
71
72 /**
73 * Public constructor. Window will be located at (0, 0).
74 *
75 * @param application TApplication that manages this window
76 * @param title window title, will be centered along the top border
77 * @param width width of window
78 * @param height height of window
79 * @param flags bitmask of RESIZABLE, CENTERED, or MODAL
80 */
81 public TScrollableWindow(final TApplication application, final String title,
82 final int width, final int height, final int flags) {
83
84 super(application, title, width, height, flags);
85 }
86
87 /**
88 * Public constructor.
89 *
90 * @param application TApplication that manages this window
91 * @param title window title, will be centered along the top border
92 * @param x column relative to parent
93 * @param y row relative to parent
94 * @param width width of window
95 * @param height height of window
96 */
97 public TScrollableWindow(final TApplication application, final String title,
98 final int x, final int y, final int width, final int height) {
99
100 super(application, title, x, y, width, height);
101 }
102
103 /**
104 * Public constructor.
105 *
106 * @param application TApplication that manages this window
107 * @param title window title, will be centered along the top border
108 * @param x column relative to parent
109 * @param y row relative to parent
110 * @param width width of window
111 * @param height height of window
112 * @param flags mask of RESIZABLE, CENTERED, or MODAL
113 */
114 public TScrollableWindow(final TApplication application, final String title,
115 final int x, final int y, final int width, final int height,
116 final int flags) {
117
118 super(application, title, x, y, width, height, flags);
119 }
120
121 // ------------------------------------------------------------------------
122 // TWindow ----------------------------------------------------------------
123 // ------------------------------------------------------------------------
124
125 /**
126 * Handle window/screen resize events.
127 *
128 * @param event resize event
129 */
130 @Override
131 public void onResize(final TResizeEvent event) {
132 if (event.getType() == TResizeEvent.Type.WIDGET) {
133 reflowData();
134 placeScrollbars();
135 return;
136 } else {
137 super.onResize(event);
138 }
139 }
140
141 /**
142 * Maximize window.
143 */
144 @Override
145 public void maximize() {
146 super.maximize();
147 placeScrollbars();
148 }
149
150 /**
151 * Restore (unmaximize) window.
152 */
153 @Override
154 public void restore() {
155 super.restore();
156 placeScrollbars();
157 }
158
159 // ------------------------------------------------------------------------
160 // TScrollableWindow ------------------------------------------------------
161 // ------------------------------------------------------------------------
162
163 /**
164 * Place the scrollbars on the edge of this widget, and adjust bigChange
165 * to match the new size. This is called by onResize().
166 */
167 protected void placeScrollbars() {
168 if (hScroller != null) {
169 hScroller.setY(getHeight() - 2);
170 hScroller.setWidth(getWidth() - hScroller.getX() - 3);
171 hScroller.setBigChange(getWidth() - hScroller.getX() - 3);
172 }
173 if (vScroller != null) {
174 vScroller.setX(getWidth() - 2);
175 vScroller.setHeight(getHeight() - 2);
176 vScroller.setBigChange(getHeight() - 2);
177 }
178 }
179
180 /**
181 * Recompute whatever data is displayed by this widget.
182 */
183 public void reflowData() {
184 // Default: nothing to do
185 }
186
187 /**
188 * Get the horizontal scrollbar, or null if this Viewport does not
189 * support horizontal scrolling.
190 *
191 * @return the horizontal scrollbar
192 */
193 public THScroller getHorizontalScroller() {
194 return hScroller;
195 }
196
197 /**
198 * Get the vertical scrollbar, or null if this Viewport does not support
199 * vertical scrolling.
200 *
201 * @return the vertical scrollbar
202 */
203 public TVScroller getVerticalScroller() {
204 return vScroller;
205 }
206
207 /**
208 * Get the value that corresponds to being on the top edge of the
209 * vertical scroll bar.
210 *
211 * @return the scroll value
212 */
213 public int getTopValue() {
214 if (vScroller == null) {
215 return 0;
216 } else {
217 return vScroller.getTopValue();
218 }
219 }
220
221 /**
222 * Set the value that corresponds to being on the top edge of the
223 * vertical scroll bar.
224 *
225 * @param topValue the new scroll value
226 */
227 public void setTopValue(final int topValue) {
228 if (vScroller == null) {
229 return;
230 } else {
231 vScroller.setTopValue(topValue);
232 }
233 }
234
235 /**
236 * Get the value that corresponds to being on the bottom edge of the
237 * vertical scroll bar.
238 *
239 * @return the scroll value
240 */
241 public int getBottomValue() {
242 if (vScroller == null) {
243 return 0;
244 } else {
245 return vScroller.getBottomValue();
246 }
247 }
248
249 /**
250 * Set the value that corresponds to being on the bottom edge of the
251 * vertical scroll bar.
252 *
253 * @param bottomValue the new scroll value
254 */
255 public void setBottomValue(final int bottomValue) {
256 if (vScroller == null) {
257 return;
258 } else {
259 vScroller.setBottomValue(bottomValue);
260 }
261 }
262
263 /**
264 * Get current value of the vertical scroll.
265 *
266 * @return the scroll value
267 */
268 public int getVerticalValue() {
269 if (vScroller == null) {
270 return 0;
271 } else {
272 return vScroller.getValue();
273 }
274 }
275
276 /**
277 * Set current value of the vertical scroll.
278 *
279 * @param value the new scroll value
280 */
281 public void setVerticalValue(final int value) {
282 if (vScroller == null) {
283 return;
284 } else {
285 vScroller.setValue(value);
286 }
287 }
288
289 /**
290 * Get the increment for clicking on an arrow on the vertical scrollbar.
291 *
292 * @return the increment value
293 */
294 public int getVerticalSmallChange() {
295 if (vScroller == null) {
296 return 0;
297 } else {
298 return vScroller.getSmallChange();
299 }
300 }
301
302 /**
303 * Set the increment for clicking on an arrow on the vertical scrollbar.
304 *
305 * @param smallChange the new increment value
306 */
307 public void setVerticalSmallChange(final int smallChange) {
308 if (vScroller == null) {
309 return;
310 } else {
311 vScroller.setSmallChange(smallChange);
312 }
313 }
314
315 /**
316 * Get the increment for clicking in the bar between the box and an
317 * arrow on the vertical scrollbar.
318 *
319 * @return the increment value
320 */
321 public int getVerticalBigChange() {
322 if (vScroller == null) {
323 return 0;
324 } else {
325 return vScroller.getBigChange();
326 }
327 }
328
329 /**
330 * Set the increment for clicking in the bar between the box and an
331 * arrow on the vertical scrollbar.
332 *
333 * @param bigChange the new increment value
334 */
335 public void setVerticalBigChange(final int bigChange) {
336 if (vScroller == null) {
337 return;
338 } else {
339 vScroller.setBigChange(bigChange);
340 }
341 }
342
343 /**
344 * Perform a small step change up.
345 */
346 public void verticalDecrement() {
347 if (vScroller == null) {
348 return;
349 } else {
350 vScroller.decrement();
351 }
352 }
353
354 /**
355 * Perform a small step change down.
356 */
357 public void verticalIncrement() {
358 if (vScroller == null) {
359 return;
360 } else {
361 vScroller.increment();
362 }
363 }
364
365 /**
366 * Perform a big step change up.
367 */
368 public void bigVerticalDecrement() {
369 if (vScroller == null) {
370 return;
371 } else {
372 vScroller.bigDecrement();
373 }
374 }
375
376 /**
377 * Perform a big step change down.
378 */
379 public void bigVerticalIncrement() {
380 if (vScroller == null) {
381 return;
382 } else {
383 vScroller.bigIncrement();
384 }
385 }
386
387 /**
388 * Go to the top edge of the vertical scroller.
389 */
390 public void toTop() {
391 if (vScroller == null) {
392 return;
393 } else {
394 vScroller.toTop();
395 }
396 }
397
398 /**
399 * Go to the bottom edge of the vertical scroller.
400 */
401 public void toBottom() {
402 if (vScroller == null) {
403 return;
404 } else {
405 vScroller.toBottom();
406 }
407 }
408
409 /**
410 * Get the value that corresponds to being on the left edge of the
411 * horizontal scroll bar.
412 *
413 * @return the scroll value
414 */
415 public int getLeftValue() {
416 if (hScroller == null) {
417 return 0;
418 } else {
419 return hScroller.getLeftValue();
420 }
421 }
422
423 /**
424 * Set the value that corresponds to being on the left edge of the
425 * horizontal scroll bar.
426 *
427 * @param leftValue the new scroll value
428 */
429 public void setLeftValue(final int leftValue) {
430 if (hScroller == null) {
431 return;
432 } else {
433 hScroller.setLeftValue(leftValue);
434 }
435 }
436
437 /**
438 * Get the value that corresponds to being on the right edge of the
439 * horizontal scroll bar.
440 *
441 * @return the scroll value
442 */
443 public int getRightValue() {
444 if (hScroller == null) {
445 return 0;
446 } else {
447 return hScroller.getRightValue();
448 }
449 }
450
451 /**
452 * Set the value that corresponds to being on the right edge of the
453 * horizontal scroll bar.
454 *
455 * @param rightValue the new scroll value
456 */
457 public void setRightValue(final int rightValue) {
458 if (hScroller == null) {
459 return;
460 } else {
461 hScroller.setRightValue(rightValue);
462 }
463 }
464
465 /**
466 * Get current value of the horizontal scroll.
467 *
468 * @return the scroll value
469 */
470 public int getHorizontalValue() {
471 if (hScroller == null) {
472 return 0;
473 } else {
474 return hScroller.getValue();
475 }
476 }
477
478 /**
479 * Set current value of the horizontal scroll.
480 *
481 * @param value the new scroll value
482 */
483 public void setHorizontalValue(final int value) {
484 if (hScroller == null) {
485 return;
486 } else {
487 hScroller.setValue(value);
488 }
489 }
490
491 /**
492 * Get the increment for clicking on an arrow on the horizontal
493 * scrollbar.
494 *
495 * @return the increment value
496 */
497 public int getHorizontalSmallChange() {
498 if (hScroller == null) {
499 return 0;
500 } else {
501 return hScroller.getSmallChange();
502 }
503 }
504
505 /**
506 * Set the increment for clicking on an arrow on the horizontal
507 * scrollbar.
508 *
509 * @param smallChange the new increment value
510 */
511 public void setHorizontalSmallChange(final int smallChange) {
512 if (hScroller == null) {
513 return;
514 } else {
515 hScroller.setSmallChange(smallChange);
516 }
517 }
518
519 /**
520 * Get the increment for clicking in the bar between the box and an
521 * arrow on the horizontal scrollbar.
522 *
523 * @return the increment value
524 */
525 public int getHorizontalBigChange() {
526 if (hScroller == null) {
527 return 0;
528 } else {
529 return hScroller.getBigChange();
530 }
531 }
532
533 /**
534 * Set the increment for clicking in the bar between the box and an
535 * arrow on the horizontal scrollbar.
536 *
537 * @param bigChange the new increment value
538 */
539 public void setHorizontalBigChange(final int bigChange) {
540 if (hScroller == null) {
541 return;
542 } else {
543 hScroller.setBigChange(bigChange);
544 }
545 }
546
547 /**
548 * Perform a small step change left.
549 */
550 public void horizontalDecrement() {
551 if (hScroller == null) {
552 return;
553 } else {
554 hScroller.decrement();
555 }
556 }
557
558 /**
559 * Perform a small step change right.
560 */
561 public void horizontalIncrement() {
562 if (hScroller == null) {
563 return;
564 } else {
565 hScroller.increment();
566 }
567 }
568
569 /**
570 * Perform a big step change left.
571 */
572 public void bigHorizontalDecrement() {
573 if (hScroller == null) {
574 return;
575 } else {
576 hScroller.bigDecrement();
577 }
578 }
579
580 /**
581 * Perform a big step change right.
582 */
583 public void bigHorizontalIncrement() {
584 if (hScroller == null) {
585 return;
586 } else {
587 hScroller.bigIncrement();
588 }
589 }
590
591 /**
592 * Go to the left edge of the horizontal scroller.
593 */
594 public void toLeft() {
595 if (hScroller == null) {
596 return;
597 } else {
598 hScroller.toLeft();
599 }
600 }
601
602 /**
603 * Go to the right edge of the horizontal scroller.
604 */
605 public void toRight() {
606 if (hScroller == null) {
607 return;
608 } else {
609 hScroller.toRight();
610 }
611 }
612
613 /**
614 * Go to the top-left edge of the horizontal and vertical scrollers.
615 */
616 public void toHome() {
617 if (hScroller != null) {
618 hScroller.toLeft();
619 }
620 if (vScroller != null) {
621 vScroller.toTop();
622 }
623 }
624
625 /**
626 * Go to the bottom-right edge of the horizontal and vertical scrollers.
627 */
628 public void toEnd() {
629 if (hScroller != null) {
630 hScroller.toRight();
631 }
632 if (vScroller != null) {
633 vScroller.toBottom();
634 }
635 }
636
637 /**
638 * Check if a mouse press/release/motion event coordinate is over the
639 * vertical scrollbar.
640 *
641 * @param mouse a mouse-based event
642 * @return whether or not the mouse is on the scrollbar
643 */
644 protected final boolean mouseOnVerticalScroller(final TMouseEvent mouse) {
645 if (vScroller == null) {
646 return false;
647 }
648 if ((mouse.getAbsoluteX() == vScroller.getAbsoluteX())
649 && (mouse.getAbsoluteY() >= vScroller.getAbsoluteY())
650 && (mouse.getAbsoluteY() < vScroller.getAbsoluteY() +
651 vScroller.getHeight())
652 ) {
653 return true;
654 }
655 return false;
656 }
657
658 /**
659 * Check if a mouse press/release/motion event coordinate is over the
660 * horizontal scrollbar.
661 *
662 * @param mouse a mouse-based event
663 * @return whether or not the mouse is on the scrollbar
664 */
665 protected final boolean mouseOnHorizontalScroller(final TMouseEvent mouse) {
666 if (hScroller == null) {
667 return false;
668 }
669 if ((mouse.getAbsoluteY() == hScroller.getAbsoluteY())
670 && (mouse.getAbsoluteX() >= hScroller.getAbsoluteX())
671 && (mouse.getAbsoluteX() < hScroller.getAbsoluteX() +
672 hScroller.getWidth())
673 ) {
674 return true;
675 }
676 return false;
677 }
678
679 }