Not dead note
[fanfix.git] / src / jexer / THScroller.java
CommitLineData
daa4106c 1/*
48e27807
KL
2 * Jexer - Java Text User Interface
3 *
e16dda65 4 * The MIT License (MIT)
48e27807 5 *
a2018e99 6 * Copyright (C) 2017 Kevin Lamonte
48e27807 7 *
e16dda65
KL
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:
48e27807 14 *
e16dda65
KL
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
48e27807 17 *
e16dda65
KL
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.
48e27807
KL
25 *
26 * @author Kevin Lamonte [kevin.lamonte@gmail.com]
27 * @version 1
28 */
29package jexer;
30
cc99cba8
KL
31import jexer.bits.CellAttributes;
32import jexer.bits.GraphicsChars;
33import jexer.event.TMouseEvent;
34
48e27807
KL
35/**
36 * THScroller implements a simple horizontal scroll bar.
37 */
051e2913 38public class THScroller extends TWidget {
48e27807 39
d36057df
KL
40 // ------------------------------------------------------------------------
41 // Variables --------------------------------------------------------------
42 // ------------------------------------------------------------------------
43
cc99cba8
KL
44 /**
45 * Value that corresponds to being on the left edge of the scroll bar.
46 */
47 private int leftValue = 0;
48
d36057df
KL
49 /**
50 * Value that corresponds to being on the right edge of the scroll bar.
51 */
52 private int rightValue = 100;
53
54 /**
55 * Current value of the scroll.
56 */
57 private int value = 0;
58
59 /**
60 * The increment for clicking on an arrow.
61 */
62 private int smallChange = 1;
63
64 /**
65 * The increment for clicking in the bar between the box and an arrow.
66 */
67 private int bigChange = 20;
68
69 /**
70 * When true, the user is dragging the scroll box.
71 */
72 private boolean inScroll = false;
73
74 // ------------------------------------------------------------------------
75 // Constructors -----------------------------------------------------------
76 // ------------------------------------------------------------------------
77
78 /**
79 * Public constructor.
80 *
81 * @param parent parent widget
82 * @param x column relative to parent
83 * @param y row relative to parent
84 * @param width height of scroll bar
85 */
86 public THScroller(final TWidget parent, final int x, final int y,
87 final int width) {
88
89 // Set parent and window
90 super(parent, x, y, width, 1);
91 }
92
93 // ------------------------------------------------------------------------
94 // Event handlers ---------------------------------------------------------
95 // ------------------------------------------------------------------------
96
97 /**
98 * Handle mouse button releases.
99 *
100 * @param mouse mouse button release event
101 */
102 @Override
103 public void onMouseUp(final TMouseEvent mouse) {
104
105 if (inScroll) {
106 inScroll = false;
107 return;
108 }
109
110 if (rightValue == leftValue) {
111 return;
112 }
113
114 if ((mouse.getX() == 0)
115 && (mouse.getY() == 0)
116 ) {
117 // Clicked on the left arrow
118 decrement();
119 return;
120 }
121
122 if ((mouse.getY() == 0)
123 && (mouse.getX() == getWidth() - 1)
124 ) {
125 // Clicked on the right arrow
126 increment();
127 return;
128 }
129
130 if ((mouse.getY() == 0)
131 && (mouse.getX() > 0)
132 && (mouse.getX() < boxPosition())
133 ) {
134 // Clicked between the left arrow and the box
135 value -= bigChange;
136 if (value < leftValue) {
137 value = leftValue;
138 }
139 return;
140 }
141
142 if ((mouse.getY() == 0)
143 && (mouse.getX() > boxPosition())
144 && (mouse.getX() < getWidth() - 1)
145 ) {
146 // Clicked between the box and the right arrow
147 value += bigChange;
148 if (value > rightValue) {
149 value = rightValue;
150 }
151 return;
152 }
153 }
154
155 /**
156 * Handle mouse movement events.
157 *
158 * @param mouse mouse motion event
159 */
160 @Override
161 public void onMouseMotion(final TMouseEvent mouse) {
162
163 if (rightValue == leftValue) {
164 inScroll = false;
165 return;
166 }
167
168 if ((mouse.isMouse1())
169 && (inScroll)
170 && (mouse.getX() > 0)
171 && (mouse.getX() < getWidth() - 1)
172 ) {
173 // Recompute value based on new box position
174 value = (rightValue - leftValue)
175 * (mouse.getX()) / (getWidth() - 3) + leftValue;
176 if (value > rightValue) {
177 value = rightValue;
178 }
179 if (value < leftValue) {
180 value = leftValue;
181 }
182 return;
183 }
184 inScroll = false;
185 }
186
187 /**
188 * Handle mouse button press events.
189 *
190 * @param mouse mouse button press event
191 */
192 @Override
193 public void onMouseDown(final TMouseEvent mouse) {
194 if (rightValue == leftValue) {
195 inScroll = false;
196 return;
197 }
198
199 if ((mouse.getY() == 0)
200 && (mouse.getX() == boxPosition())
201 ) {
202 inScroll = true;
203 return;
204 }
205
206 }
207
208 // ------------------------------------------------------------------------
209 // TWidget ----------------------------------------------------------------
210 // ------------------------------------------------------------------------
211
212 /**
213 * Draw a horizontal scroll bar.
214 */
215 @Override
216 public void draw() {
217 CellAttributes arrowColor = getTheme().getColor("tscroller.arrows");
218 CellAttributes barColor = getTheme().getColor("tscroller.bar");
219 getScreen().putCharXY(0, 0, GraphicsChars.CP437[0x11], arrowColor);
220 getScreen().putCharXY(getWidth() - 1, 0, GraphicsChars.CP437[0x10],
221 arrowColor);
222
223 // Place the box
224 if (rightValue > leftValue) {
225 getScreen().hLineXY(1, 0, getWidth() - 2, GraphicsChars.CP437[0xB1],
226 barColor);
227 getScreen().putCharXY(boxPosition(), 0, GraphicsChars.BOX,
228 arrowColor);
229 } else {
230 getScreen().hLineXY(1, 0, getWidth() - 2, GraphicsChars.HATCH,
231 barColor);
232 }
233
234 }
235
236 // ------------------------------------------------------------------------
237 // THScroller -------------------------------------------------------------
238 // ------------------------------------------------------------------------
239
cc99cba8
KL
240 /**
241 * Get the value that corresponds to being on the left edge of the scroll
242 * bar.
243 *
244 * @return the scroll value
245 */
246 public int getLeftValue() {
247 return leftValue;
248 }
249
250 /**
251 * Set the value that corresponds to being on the left edge of the
252 * scroll bar.
253 *
254 * @param leftValue the new scroll value
255 */
256 public void setLeftValue(final int leftValue) {
257 this.leftValue = leftValue;
258 }
259
cc99cba8
KL
260 /**
261 * Get the value that corresponds to being on the right edge of the
262 * scroll bar.
263 *
264 * @return the scroll value
265 */
266 public int getRightValue() {
267 return rightValue;
268 }
269
270 /**
271 * Set the value that corresponds to being on the right edge of the
272 * scroll bar.
273 *
274 * @param rightValue the new scroll value
275 */
276 public void setRightValue(final int rightValue) {
277 this.rightValue = rightValue;
278 }
279
cc99cba8
KL
280 /**
281 * Get current value of the scroll.
282 *
283 * @return the scroll value
284 */
285 public int getValue() {
286 return value;
287 }
288
289 /**
290 * Set current value of the scroll.
291 *
292 * @param value the new scroll value
293 */
294 public void setValue(final int value) {
295 this.value = value;
296 }
297
56661844
KL
298 /**
299 * Get the increment for clicking on an arrow.
300 *
301 * @return the increment value
302 */
303 public int getSmallChange() {
304 return smallChange;
305 }
306
cc99cba8
KL
307 /**
308 * Set the increment for clicking on an arrow.
309 *
310 * @param smallChange the new increment value
311 */
312 public void setSmallChange(final int smallChange) {
313 this.smallChange = smallChange;
314 }
315
56661844
KL
316 /**
317 * Set the increment for clicking in the bar between the box and an
318 * arrow.
319 *
320 * @return the increment value
321 */
322 public int getBigChange() {
323 return bigChange;
324 }
325
cc99cba8
KL
326 /**
327 * Set the increment for clicking in the bar between the box and an
328 * arrow.
329 *
330 * @param bigChange the new increment value
331 */
332 public void setBigChange(final int bigChange) {
333 this.bigChange = bigChange;
334 }
335
cc99cba8
KL
336 /**
337 * Compute the position of the scroll box (a.k.a. grip, thumb).
338 *
339 * @return Y position of the box, between 1 and width - 2
340 */
341 private int boxPosition() {
342 return (getWidth() - 3) * (value - leftValue) / (rightValue - leftValue) + 1;
343 }
344
cc99cba8
KL
345 /**
346 * Perform a small step change left.
347 */
348 public void decrement() {
349 if (leftValue == rightValue) {
350 return;
351 }
352 value -= smallChange;
353 if (value < leftValue) {
354 value = leftValue;
355 }
356 }
357
358 /**
359 * Perform a small step change right.
360 */
361 public void increment() {
362 if (leftValue == rightValue) {
363 return;
364 }
365 value += smallChange;
366 if (value > rightValue) {
367 value = rightValue;
368 }
369 }
370
56661844
KL
371 /**
372 * Perform a big step change left.
373 */
374 public void bigDecrement() {
375 if (leftValue == rightValue) {
376 return;
377 }
378 value -= bigChange;
379 if (value < leftValue) {
380 value = leftValue;
381 }
382 }
383
384 /**
385 * Perform a big step change right.
386 */
387 public void bigIncrement() {
388 if (rightValue == leftValue) {
389 return;
390 }
391 value += bigChange;
392 if (value > rightValue) {
393 value = rightValue;
394 }
395 }
396
397 /**
398 * Go to the left edge of the scroller.
399 */
400 public void toLeft() {
401 value = leftValue;
402 }
403
404 /**
405 * Go to the right edge of the scroller.
406 */
407 public void toRight() {
408 value = rightValue;
409 }
410
48e27807 411}