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