54f3c0b90054aec0511f933751e533664966c1f7
[nikiroo-utils.git] / src / jexer / THScroller.java
1 /*
2 * Jexer - Java Text User Interface
3 *
4 * License: LGPLv3 or later
5 *
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.
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
27 *
28 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
29 * @version 1
30 */
31 package jexer;
32
33 import jexer.bits.CellAttributes;
34 import jexer.bits.GraphicsChars;
35 import jexer.event.TMouseEvent;
36
37 /**
38 * THScroller implements a simple horizontal scroll bar.
39 */
40 public final class THScroller extends TWidget {
41
42 /**
43 * Value that corresponds to being on the left edge of the scroll bar.
44 */
45 private int leftValue = 0;
46
47 /**
48 * Get the value that corresponds to being on the left edge of the scroll
49 * bar.
50 *
51 * @return the scroll value
52 */
53 public int getLeftValue() {
54 return leftValue;
55 }
56
57 /**
58 * Set the value that corresponds to being on the left edge of the
59 * scroll bar.
60 *
61 * @param leftValue the new scroll value
62 */
63 public void setLeftValue(final int leftValue) {
64 this.leftValue = leftValue;
65 }
66
67 /**
68 * Value that corresponds to being on the right edge of the scroll bar.
69 */
70 private int rightValue = 100;
71
72 /**
73 * Get the value that corresponds to being on the right edge of the
74 * scroll bar.
75 *
76 * @return the scroll value
77 */
78 public int getRightValue() {
79 return rightValue;
80 }
81
82 /**
83 * Set the value that corresponds to being on the right edge of the
84 * scroll bar.
85 *
86 * @param rightValue the new scroll value
87 */
88 public void setRightValue(final int rightValue) {
89 this.rightValue = rightValue;
90 }
91
92 /**
93 * Current value of the scroll.
94 */
95 private int value = 0;
96
97 /**
98 * Get current value of the scroll.
99 *
100 * @return the scroll value
101 */
102 public int getValue() {
103 return value;
104 }
105
106 /**
107 * Set current value of the scroll.
108 *
109 * @param value the new scroll value
110 */
111 public void setValue(final int value) {
112 this.value = value;
113 }
114
115 /**
116 * The increment for clicking on an arrow.
117 */
118 private int smallChange = 1;
119
120 /**
121 * Set the increment for clicking on an arrow.
122 *
123 * @param smallChange the new increment value
124 */
125 public void setSmallChange(final int smallChange) {
126 this.smallChange = smallChange;
127 }
128
129 /**
130 * The increment for clicking in the bar between the box and an arrow.
131 */
132 private int bigChange = 20;
133
134 /**
135 * Set the increment for clicking in the bar between the box and an
136 * arrow.
137 *
138 * @param bigChange the new increment value
139 */
140 public void setBigChange(final int bigChange) {
141 this.bigChange = bigChange;
142 }
143
144 /**
145 * When true, the user is dragging the scroll box.
146 */
147 private boolean inScroll = false;
148
149 /**
150 * Public constructor.
151 *
152 * @param parent parent widget
153 * @param x column relative to parent
154 * @param y row relative to parent
155 * @param width height of scroll bar
156 */
157 public THScroller(final TWidget parent, final int x, final int y,
158 final int width) {
159
160 // Set parent and window
161 super(parent, x, y, width, 1);
162 }
163
164 /**
165 * Compute the position of the scroll box (a.k.a. grip, thumb).
166 *
167 * @return Y position of the box, between 1 and width - 2
168 */
169 private int boxPosition() {
170 return (getWidth() - 3) * (value - leftValue) / (rightValue - leftValue) + 1;
171 }
172
173 /**
174 * Draw a horizontal scroll bar.
175 */
176 @Override
177 public void draw() {
178 CellAttributes arrowColor = getTheme().getColor("tscroller.arrows");
179 CellAttributes barColor = getTheme().getColor("tscroller.bar");
180 getScreen().putCharXY(0, 0, GraphicsChars.CP437[0x11], arrowColor);
181 getScreen().putCharXY(getWidth() - 1, 0, GraphicsChars.CP437[0x10],
182 arrowColor);
183
184 // Place the box
185 if (rightValue > leftValue) {
186 getScreen().hLineXY(1, 0, getWidth() - 2, GraphicsChars.CP437[0xB1],
187 barColor);
188 getScreen().putCharXY(boxPosition(), 0, GraphicsChars.BOX,
189 arrowColor);
190 } else {
191 getScreen().hLineXY(1, 0, getWidth() - 2, GraphicsChars.HATCH,
192 barColor);
193 }
194
195 }
196
197 /**
198 * Perform a small step change left.
199 */
200 public void decrement() {
201 if (leftValue == rightValue) {
202 return;
203 }
204 value -= smallChange;
205 if (value < leftValue) {
206 value = leftValue;
207 }
208 }
209
210 /**
211 * Perform a small step change right.
212 */
213 public void increment() {
214 if (leftValue == rightValue) {
215 return;
216 }
217 value += smallChange;
218 if (value > rightValue) {
219 value = rightValue;
220 }
221 }
222
223 /**
224 * Handle mouse button releases.
225 *
226 * @param mouse mouse button release event
227 */
228 @Override
229 public void onMouseUp(final TMouseEvent mouse) {
230
231 if (inScroll) {
232 inScroll = false;
233 return;
234 }
235
236 if (rightValue == leftValue) {
237 return;
238 }
239
240 if ((mouse.getX() == 0)
241 && (mouse.getY() == 0)
242 ) {
243 // Clicked on the left arrow
244 decrement();
245 return;
246 }
247
248 if ((mouse.getY() == 0)
249 && (mouse.getX() == getWidth() - 1)
250 ) {
251 // Clicked on the right arrow
252 increment();
253 return;
254 }
255
256 if ((mouse.getY() == 0)
257 && (mouse.getX() > 0)
258 && (mouse.getX() < boxPosition())
259 ) {
260 // Clicked between the left arrow and the box
261 value -= bigChange;
262 if (value < leftValue) {
263 value = leftValue;
264 }
265 return;
266 }
267
268 if ((mouse.getY() == 0)
269 && (mouse.getX() > boxPosition())
270 && (mouse.getX() < getWidth() - 1)
271 ) {
272 // Clicked between the box and the right arrow
273 value += bigChange;
274 if (value > rightValue) {
275 value = rightValue;
276 }
277 return;
278 }
279 }
280
281 /**
282 * Handle mouse movement events.
283 *
284 * @param mouse mouse motion event
285 */
286 @Override
287 public void onMouseMotion(final TMouseEvent mouse) {
288
289 if (rightValue == leftValue) {
290 inScroll = false;
291 return;
292 }
293
294 if ((mouse.isMouse1())
295 && (inScroll)
296 && (mouse.getX() > 0)
297 && (mouse.getX() < getWidth() - 1)
298 ) {
299 // Recompute value based on new box position
300 value = (rightValue - leftValue)
301 * (mouse.getX()) / (getWidth() - 3) + leftValue;
302 return;
303 }
304 inScroll = false;
305 }
306
307 /**
308 * Handle mouse button press events.
309 *
310 * @param mouse mouse button press event
311 */
312 @Override
313 public void onMouseDown(final TMouseEvent mouse) {
314 if (rightValue == leftValue) {
315 inScroll = false;
316 return;
317 }
318
319 if ((mouse.getY() == 0)
320 && (mouse.getX() == boxPosition())
321 ) {
322 inScroll = true;
323 return;
324 }
325
326 }
327
328 }