1 /*
2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
3 *
4 * All source code herein is the property of Volition, Inc. You may not sell
5 * or otherwise commercially exploit the source or things you created based on the
6 * source.
7 *
8 */
9
10
11
12 #include "ui/uidefs.h"
13 #include "ui/ui.h"
14 #include "freespace2/freespace.h"
15 #include "bmpman/bmpman.h"
16 #include "io/timer.h"
17
18
19
20 // captureCallback is called when an item is "selected" by mouse release. That is, the user has clicked, dragged and _released_.
21 // the callback is called when the scrollbar has been released
create(UI_WINDOW * wnd,int _x,int _y,int _w,int _h,int _numberItems,char * _bitmapSliderControl,void (* _upCallback)(),void (* _downCallback)(),void (* _captureCallback)())22 void UI_SLIDER2::create(UI_WINDOW *wnd, int _x, int _y, int _w, int _h, int _numberItems, char *_bitmapSliderControl, void (* _upCallback)(), void (*_downCallback)(),
23 void (* _captureCallback)()) {
24
25 int buttonHeight, buttonWidth;
26
27 base_create( wnd, UI_KIND_SLIDER2, _x, _y, _w, _h );
28
29 Assert(_upCallback != NULL);
30 Assert(_downCallback != NULL);
31
32 upCallback = _upCallback;
33 downCallback = _downCallback;
34
35 captureCallback = _captureCallback;
36
37 Assert(_bitmapSliderControl > 0);
38
39 last_scrolled = 0;
40
41 // set bitmap
42 set_bmaps(_bitmapSliderControl, 3, 0);
43
44 // determine possible positions
45 bm_get_info(bmap_ids[S2_NORMAL],&buttonWidth, &buttonHeight, NULL, NULL, NULL);
46 slider_w = buttonWidth;
47 slider_h = buttonHeight;
48 Assert(buttonHeight > 5);
49 slider_half_h = (int)(buttonHeight / 2);
50 numberPositions = _h - buttonHeight;
51
52 Assert(numberPositions >= 0);
53 currentItem = 0;
54 currentPosition = 0;
55
56 numberItems = _numberItems;
57 if (numberItems <= 0) {
58 disabled_flag = 1;
59 }
60
61 slider_mode = S2M_DEFAULT;
62 }
63
draw()64 void UI_SLIDER2::draw() {
65 Assert((currentPosition >= 0) && (currentPosition <= numberPositions));
66 if (uses_bmaps && !disabled_flag) {
67 gr_reset_clip();
68 switch (slider_mode) {
69 case S2M_ON_ME:
70 gr_set_bitmap(bmap_ids[S2_HIGHLIGHT]); // draw slider level
71 break;
72 case S2M_MOVING:
73 gr_set_bitmap(bmap_ids[S2_PRESSED]);
74 break;
75 case S2M_DEFAULT:
76 default:
77 gr_set_bitmap(bmap_ids[S2_NORMAL]); // draw slider level
78 break;
79 }
80 gr_bitmap(x, y+currentPosition, GR_RESIZE_MENU);
81 }
82 }
83
process(int focus)84 void UI_SLIDER2::process(int focus)
85 {
86 int OnMe, mouse_lock_move;
87
88 if (disabled_flag) {
89 return;
90 }
91
92 OnMe = is_mouse_on();
93 if ( OnMe ) {
94 // are we on the button?
95 if ( (ui_mouse.y >= (y+currentPosition)) && (ui_mouse.y <= (y+currentPosition+slider_h)) ) {
96 slider_mode = S2M_ON_ME;
97 if ( B1_PRESSED ) {
98 mouse_locked = 1;
99 }
100 }
101 } else
102 slider_mode = S2M_DEFAULT;
103
104 if ( !B1_PRESSED) {
105 if (mouse_locked == 1)
106 if (captureCallback != NULL) {
107 captureCallback();
108 mprintf(("Called captureCallback()!\n"));
109 }
110 mouse_locked = 0;
111 }
112
113 if (!OnMe && !mouse_locked)
114 return;
115
116 // could we possibly be moving up?
117 if ((OnMe && B1_PRESSED && ui_mouse.y < (currentPosition+y+slider_half_h-1)) || (mouse_locked && (ui_mouse.y < (currentPosition+y+slider_half_h-1))) ) {
118 // make sure we wait at least 50 ms between events unless mouse locked
119 if ( (timer_get_milliseconds() > last_scrolled+50) || B1_JUST_PRESSED || mouse_locked ) {
120 last_scrolled = timer_get_milliseconds();
121 if (!mouse_locked) {
122 if (currentItem > 0) {
123 currentItem--;
124 if (upCallback != NULL) {
125 upCallback();
126 if (captureCallback != NULL)
127 captureCallback();
128 }
129 }
130 currentPosition = fl2i((((float)currentItem/(float)numberItems) * (float)numberPositions)-.49);
131 } else {
132 mouse_lock_move = fl2i( ((((float)ui_mouse.y - (float)y - (float)slider_half_h)/(float)numberPositions) * (float)numberItems) -.49);
133 mouse_lock_move = currentItem - mouse_lock_move;
134 if (mouse_lock_move > 0) {
135 while (mouse_lock_move > 0) {
136 if (currentItem > 0) {
137 currentItem--;
138 if (upCallback != NULL)
139 upCallback();
140 }
141 mouse_lock_move--;
142 }
143 }
144 // currentPosition = ui_mouse.y - y - slider_half_h;
145 currentPosition = fl2i((((float)currentItem/(float)numberItems) * (float)numberPositions)-.49);
146 }
147 if (currentPosition < 0)
148 currentPosition = 0;
149 if (currentPosition > numberPositions)
150 currentPosition = numberPositions;
151 slider_mode = S2M_MOVING;
152 }
153 }
154
155 if ( ( OnMe && B1_PRESSED && ui_mouse.y > (currentPosition+y+slider_half_h+1)) || (mouse_locked && (ui_mouse.y > (currentPosition+y+slider_half_h+1))) ) {
156 // make sure we wait at least 50 ms between events unless mouse locked
157 if ( (timer_get_milliseconds() > last_scrolled+50) || B1_JUST_PRESSED || mouse_locked ) {
158 last_scrolled = timer_get_milliseconds();
159 if (!mouse_locked) {
160 if (currentItem < numberItems) {
161 currentItem++;
162 if (downCallback != NULL) {
163 downCallback();
164 if (captureCallback != NULL)
165 captureCallback();
166 }
167 }
168 currentPosition = fl2i((((float)currentItem/(float)numberItems) * (float)numberPositions)-.49);
169 } else {
170 mouse_lock_move = fl2i( ((((float)ui_mouse.y - (float)y - (float)slider_half_h)/(float)numberPositions) * (float)numberItems) -.49);
171 mouse_lock_move -= currentItem;
172 if (mouse_lock_move > 0) {
173 while (mouse_lock_move > 0) {
174 if (currentItem < numberItems) {
175 currentItem++;
176 if (downCallback != NULL)
177 downCallback();
178 }
179 mouse_lock_move--;
180 }
181 }
182 // currentPosition = ui_mouse.y - y - slider_half_h;
183 currentPosition = fl2i((((float)currentItem/(float)numberItems) * (float)numberPositions)-.49);
184 }
185 if (currentPosition < 0){
186 currentPosition = 0;
187 }
188 if (currentPosition > numberPositions){
189 currentPosition = numberPositions;
190 }
191 slider_mode = S2M_MOVING;
192 }
193 }
194
195 // if we are centerd on the bitmap and still in mouse lock mode, we need to make sure the MOVING bitmap is still shown
196 // or if mouse is on us and we are pressing the mouse button
197 if (mouse_locked || (OnMe && B1_PRESSED)){
198 slider_mode = S2M_MOVING;
199 }
200 }
201
hide()202 void UI_SLIDER2::hide()
203 {
204 hidden = 1;
205 }
206
unhide()207 void UI_SLIDER2::unhide()
208 {
209 hidden = 0;
210 }
211
get_hidden()212 int UI_SLIDER2::get_hidden()
213 {
214 return hidden;
215 }
216
217
218 // return number of itmes
get_numberItems()219 int UI_SLIDER2::get_numberItems() {
220 return numberItems;
221 }
222
223 // return current position
get_currentPosition()224 int UI_SLIDER2::get_currentPosition() {
225 return currentPosition;
226 }
227
228 // return current item
get_currentItem()229 int UI_SLIDER2::get_currentItem() {
230 return currentItem;
231 }
232
233 // change range. reset back to position 0
set_numberItems(int _numberItems,int _reset)234 void UI_SLIDER2::set_numberItems(int _numberItems, int _reset) {
235 numberItems = _numberItems;
236
237 if (_reset) {
238 currentItem = 0;
239 currentPosition = 0;
240 } else {
241 // recalcluate current position
242 currentPosition = fl2i((((float)currentItem/(float)numberItems) * (float)numberPositions)-.49);
243 if (currentPosition < 0){
244 currentPosition = 0;
245 }
246 if (currentPosition > numberPositions){
247 currentPosition = numberPositions;
248 }
249 }
250 if (numberItems <= 0){
251 disabled_flag = 1;
252 } else {
253 disabled_flag = 0;
254 }
255 }
256
257 // force slider to new position manually
set_currentItem(int _currentItem)258 void UI_SLIDER2::set_currentItem(int _currentItem) {
259 if (_currentItem > numberItems)
260 goto cpSafety;
261
262 if (_currentItem == currentItem)
263 goto cpSafety;
264
265 if (_currentItem < 0)
266 goto cpSafety;
267
268 if (_currentItem > currentItem) {
269 while (currentItem != _currentItem) {
270 currentItem++;
271 if (downCallback != NULL)
272 downCallback();
273 }
274 } else if (_currentItem < currentItem) {
275 while (currentItem != _currentItem) {
276 currentItem--;
277 if (upCallback != NULL)
278 upCallback();
279 }
280 }
281
282 currentPosition = fl2i(((float)currentItem/(float)numberItems) * (float)numberPositions);
283
284 cpSafety: // helps fix math problem on x86_64
285 if (currentPosition > numberItems)
286 currentPosition = numberItems;
287
288 if (currentPosition < 0)
289 currentPosition = 0;
290 }
291
force_currentItem(int _currentItem)292 void UI_SLIDER2::force_currentItem(int _currentItem) {
293 if (_currentItem > numberItems)
294 goto cpSafety;
295
296 if (_currentItem == currentItem)
297 goto cpSafety;
298
299 currentItem = _currentItem;
300
301 if(currentItem < 0){
302 currentItem = 0;
303 };
304
305 currentPosition = fl2i(((float)currentItem/(float)numberItems) * (float)numberPositions);
306
307 cpSafety: // helps fix math problem on x86_64
308 if (currentPosition > numberItems)
309 currentPosition = numberItems;
310
311 if (currentPosition < 0)
312 currentPosition = 0;
313 }
314
forceDown()315 void UI_SLIDER2::forceDown() {
316 if (currentItem < numberItems) {
317 currentItem++;
318 currentPosition = fl2i(((float)currentItem/(float)numberItems) * (float)numberPositions);
319 }
320 }
321
forceUp()322 void UI_SLIDER2::forceUp() {
323 if (currentItem > 0) {
324 currentItem--;
325 currentPosition = fl2i(((float)currentItem/(float)numberItems) * (float)numberPositions);
326
327 if (currentPosition < 0)
328 currentPosition = 0;
329 }
330 }
331