2 * Jexer - Java Text User Interface
4 * The MIT License (MIT)
6 * Copyright (C) 2017 Kevin Lamonte
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:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
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.
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
31 import jexer
.bits
.CellAttributes
;
32 import jexer
.bits
.GraphicsChars
;
33 import jexer
.event
.TMouseEvent
;
36 * TVScroller implements a simple vertical scroll bar.
38 public final class TVScroller
extends TWidget
{
41 * Value that corresponds to being on the top edge of the scroll bar.
43 private int topValue
= 0;
46 * Get the value that corresponds to being on the top edge of the scroll
49 * @return the scroll value
51 public int getTopValue() {
56 * Set the value that corresponds to being on the top edge of the scroll
59 * @param topValue the new scroll value
61 public void setTopValue(final int topValue
) {
62 this.topValue
= topValue
;
66 * Value that corresponds to being on the bottom edge of the scroll bar.
68 private int bottomValue
= 100;
71 * Get the value that corresponds to being on the bottom edge of the
74 * @return the scroll value
76 public int getBottomValue() {
81 * Set the value that corresponds to being on the bottom edge of the
84 * @param bottomValue the new scroll value
86 public void setBottomValue(final int bottomValue
) {
87 this.bottomValue
= bottomValue
;
91 * Current value of the scroll.
93 private int value
= 0;
96 * Get current value of the scroll.
98 * @return the scroll value
100 public int getValue() {
105 * Set current value of the scroll.
107 * @param value the new scroll value
109 public void setValue(final int value
) {
114 * The increment for clicking on an arrow.
116 private int smallChange
= 1;
119 * Set the increment for clicking on an arrow.
121 * @param smallChange the new increment value
123 public void setSmallChange(final int smallChange
) {
124 this.smallChange
= smallChange
;
128 * The increment for clicking in the bar between the box and an arrow.
130 private int bigChange
= 20;
133 * Set the increment for clicking in the bar between the box and an
136 * @param bigChange the new increment value
138 public void setBigChange(final int bigChange
) {
139 this.bigChange
= bigChange
;
143 * When true, the user is dragging the scroll box.
145 private boolean inScroll
= false;
148 * Public constructor.
150 * @param parent parent widget
151 * @param x column relative to parent
152 * @param y row relative to parent
153 * @param height height of scroll bar
155 public TVScroller(final TWidget parent
, final int x
, final int y
,
158 // Set parent and window
159 super(parent
, x
, y
, 1, height
);
163 * Compute the position of the scroll box (a.k.a. grip, thumb).
165 * @return Y position of the box, between 1 and height - 2
167 private int boxPosition() {
168 return (getHeight() - 3) * (value
- topValue
) / (bottomValue
- topValue
) + 1;
172 * Draw a vertical scroll bar.
176 CellAttributes arrowColor
= getTheme().getColor("tscroller.arrows");
177 CellAttributes barColor
= getTheme().getColor("tscroller.bar");
178 getScreen().putCharXY(0, 0, GraphicsChars
.CP437
[0x1E], arrowColor
);
179 getScreen().putCharXY(0, getHeight() - 1, GraphicsChars
.CP437
[0x1F],
183 if (bottomValue
> topValue
) {
184 getScreen().vLineXY(0, 1, getHeight() - 2,
185 GraphicsChars
.CP437
[0xB1], barColor
);
186 getScreen().putCharXY(0, boxPosition(), GraphicsChars
.BOX
,
189 getScreen().vLineXY(0, 1, getHeight() - 2, GraphicsChars
.HATCH
,
196 * Perform a small step change up.
198 public void decrement() {
199 if (bottomValue
== topValue
) {
202 value
-= smallChange
;
203 if (value
< topValue
) {
209 * Perform a small step change down.
211 public void increment() {
212 if (bottomValue
== topValue
) {
215 value
+= smallChange
;
216 if (value
> bottomValue
) {
222 * Perform a big step change up.
224 public void bigDecrement() {
225 if (bottomValue
== topValue
) {
229 if (value
< topValue
) {
235 * Perform a big step change down.
237 public void bigIncrement() {
238 if (bottomValue
== topValue
) {
242 if (value
> bottomValue
) {
248 * Go to the top edge of the scroller.
250 public void toTop() {
255 * Go to the bottom edge of the scroller.
257 public void toBottom() {
262 * Handle mouse button releases.
264 * @param mouse mouse button release event
267 public void onMouseUp(final TMouseEvent mouse
) {
268 if (bottomValue
== topValue
) {
277 if ((mouse
.getX() == 0)
278 && (mouse
.getY() == 0)
280 // Clicked on the top arrow
285 if ((mouse
.getX() == 0)
286 && (mouse
.getY() == getHeight() - 1)
288 // Clicked on the bottom arrow
293 if ((mouse
.getX() == 0)
294 && (mouse
.getY() > 0)
295 && (mouse
.getY() < boxPosition())
297 // Clicked between the top arrow and the box
299 if (value
< topValue
) {
305 if ((mouse
.getX() == 0)
306 && (mouse
.getY() > boxPosition())
307 && (mouse
.getY() < getHeight() - 1)
309 // Clicked between the box and the bottom arrow
311 if (value
> bottomValue
) {
319 * Handle mouse movement events.
321 * @param mouse mouse motion event
324 public void onMouseMotion(final TMouseEvent mouse
) {
325 if (bottomValue
== topValue
) {
329 if ((mouse
.isMouse1())
331 && (mouse
.getY() > 0)
332 && (mouse
.getY() < getHeight() - 1)
334 // Recompute value based on new box position
335 value
= (bottomValue
- topValue
)
336 * (mouse
.getY()) / (getHeight() - 3) + topValue
;
344 * Handle mouse press events.
346 * @param mouse mouse button press event
349 public void onMouseDown(final TMouseEvent mouse
) {
350 if (bottomValue
== topValue
) {
354 if ((mouse
.getX() == 0)
355 && (mouse
.getY() == boxPosition())