]> icculus.org git repositories - taylor/freespace2.git/blob - src/ui/slider2.cpp
fix various code issues
[taylor/freespace2.git] / src / ui / slider2.cpp
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
6  * the source.
7  */
8
9 /*
10  * $Logfile: /Freespace2/code/Ui/SLIDER2.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Implements UI_SLIDER2 control
16  *
17  * $Log$
18  * Revision 1.4  2004/09/20 01:31:45  theoddone33
19  * GCC 3.4 fixes.
20  *
21  * Revision 1.3  2002/06/09 04:41:29  relnev
22  * added copyright header
23  *
24  * Revision 1.2  2002/05/07 03:16:53  theoddone33
25  * The Great Newline Fix
26  *
27  * Revision 1.1.1.1  2002/05/03 03:28:11  root
28  * Initial import.
29  *
30  * 
31  * 9     8/16/99 4:06p Dave
32  * Big honking checkin.
33  * 
34  * 8     8/11/99 12:18p Jefff
35  * added option to slider2 class to not force slider reset on
36  * set_numberItems
37  * 
38  * 7     8/10/99 6:54p Dave
39  * Mad optimizations. Added paging to the nebula effect.
40  * 
41  * 6     5/04/99 5:20p Dave
42  * Fixed up multiplayer join screen and host options screen. Should both
43  * be at 100% now.
44  * 
45  * 5     5/03/99 11:04p Dave
46  * Most of the way done with the multi join screen.
47  * 
48  * 4     4/29/99 2:15p Neilk
49  * fixed slider so there is an extra callback for mouse locks
50  * 
51  * 3     4/26/99 5:05p Neilk
52  * removed some excess debug output
53  * 
54  * 2     4/16/99 5:22p Neilk
55  * First implementation of UI_SLIDER2
56  *
57  * $NoKeywords: $
58  */
59
60 #include "uidefs.h"
61 #include "ui.h"
62 #include "freespace.h"
63 #include "bmpman.h"
64 #include "timer.h"
65
66 // captureCallback is called when an item is "selected" by mouse release. That is, the user has clicked, dragged and _released_. 
67 // the callback is called when the scrollbar has been released
68 void UI_SLIDER2::create(UI_WINDOW *wnd, int _x, int _y, int _w, int _h, int _numberItems, const char *_bitmapSliderControl, void (* _upCallback)(), void (*_downCallback)(),
69                                 void (* _captureCallback)()) {
70
71         int buttonHeight, buttonWidth;
72
73         base_create( wnd, UI_KIND_SLIDER2, _x, _y, _w, _h );
74
75         SDL_assert(_upCallback != NULL);
76         SDL_assert(_downCallback != NULL);
77
78         upCallback = _upCallback;
79         downCallback = _downCallback;
80
81         captureCallback = _captureCallback;     
82
83         SDL_assert(_bitmapSliderControl);
84
85         last_scrolled = 0;
86
87         // set bitmap
88         set_bmaps(_bitmapSliderControl, 3, 0);
89         
90         // determine possible positions
91         bm_get_info(bmap_ids[S2_NORMAL],&buttonWidth, &buttonHeight, NULL, NULL, NULL);
92         slider_w = buttonWidth;
93         slider_h = buttonHeight;
94         SDL_assert(buttonHeight > 5);
95         slider_half_h = (int)(buttonHeight / 2);
96         numberPositions = _h - buttonHeight;
97         
98         SDL_assert(numberPositions >= 0);
99         currentItem = 0;
100         currentPosition = 0;
101
102         numberItems = _numberItems;
103         if (numberItems <= 0) {
104                 disabled_flag = 1;
105         }
106
107         slider_mode = S2M_DEFAULT;
108 }
109
110 void UI_SLIDER2::draw() {
111         SDL_assert((currentPosition >= 0) && (currentPosition <= numberPositions));
112         if (uses_bmaps & !disabled_flag) {
113                 gr_reset_clip();
114                 switch (slider_mode) {
115                 case S2M_ON_ME:
116                         gr_set_bitmap(bmap_ids[S2_HIGHLIGHT], GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);  // draw slider level
117                         break;
118                 case S2M_MOVING:
119                         gr_set_bitmap(bmap_ids[S2_PRESSED], GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);
120                         break;
121                 case S2M_DEFAULT:
122                 default:
123                         gr_set_bitmap(bmap_ids[S2_NORMAL], GR_ALPHABLEND_NONE, GR_BITBLT_MODE_NORMAL, 1.0f, -1, -1);  // draw slider level
124                         break;
125                 }
126                 gr_bitmap(x, y+currentPosition);
127         }
128 }
129
130 void UI_SLIDER2::process(int focus)
131 {
132         int OnMe, mouse_lock_move;
133
134         if (disabled_flag) {
135                 return;
136         }
137
138         OnMe = is_mouse_on();
139         if ( OnMe ) {
140                 // are we on the button?
141                 if ( (ui_mouse.y >= (y+currentPosition)) && (ui_mouse.y <= (y+currentPosition+slider_h)) ) {
142                         slider_mode = S2M_ON_ME;
143                         if ( B1_PRESSED ) {
144                                 mouse_locked = 1;
145                         }
146                 }
147         } else
148                 slider_mode = S2M_DEFAULT;
149
150         if ( !B1_PRESSED) {
151                 if (mouse_locked == 1)
152                         if (captureCallback != NULL) {
153                                 captureCallback();
154                                 mprintf(("Called captureCallback()!\n"));
155                         }
156                 mouse_locked = 0;
157         }                       
158         
159         if (!OnMe && !mouse_locked)
160                 return;
161         
162         // could we possibly be moving up?
163         if ((OnMe && B1_PRESSED && ui_mouse.y < (currentPosition+y+slider_half_h-1)) || (mouse_locked && (ui_mouse.y < (currentPosition+y+slider_half_h-1))) ) {                
164                 // make sure we wait at least 50 ms between events unless mouse locked 
165                 if ( (timer_get_milliseconds() > last_scrolled+50) || B1_JUST_PRESSED || mouse_locked ) {
166                         last_scrolled = timer_get_milliseconds();
167                         if (!mouse_locked) {
168                                 if (currentItem > 0) {
169                                         currentItem--;
170                                         if (upCallback != NULL) {
171                                                 upCallback();
172                                                 if (captureCallback != NULL)
173                                                         captureCallback();
174                                         }
175                                 }
176                                 currentPosition = fl2i((((float)currentItem/(float)numberItems) * (float)numberPositions)-.49);
177                         } else {
178                                 mouse_lock_move = fl2i( ((((float)ui_mouse.y - (float)y - (float)slider_half_h)/(float)numberPositions) * (float)numberItems) -.49);                            
179                                 mouse_lock_move = currentItem - mouse_lock_move;
180                                 if (mouse_lock_move > 0) {
181                                         while (mouse_lock_move >  0) {                                          
182                                                 if (currentItem > 0) {
183                                                         currentItem--;
184                                                         if (upCallback != NULL)
185                                                                 upCallback();
186                                                 }
187                                                 mouse_lock_move--;
188                                         }
189                                 }
190                                 // currentPosition = ui_mouse.y - y - slider_half_h;
191                                 currentPosition = fl2i((((float)currentItem/(float)numberItems) * (float)numberPositions)-.49);
192                         }
193                         if (currentPosition < 0)
194                                 currentPosition = 0;
195                         if (currentPosition > numberPositions)
196                         currentPosition = numberPositions;
197                         slider_mode = S2M_MOVING;       
198                 }
199         }
200
201         if ( ( OnMe && B1_PRESSED && ui_mouse.y > (currentPosition+y+slider_half_h+1)) || (mouse_locked && (ui_mouse.y > (currentPosition+y+slider_half_h+1)))  ) {             
202                 // make sure we wait at least 50 ms between events unless mouse locked 
203                 if ( (timer_get_milliseconds() > last_scrolled+50) || B1_JUST_PRESSED || mouse_locked ) {
204                         last_scrolled = timer_get_milliseconds();
205                         if (!mouse_locked) {
206                                 if (currentItem < numberItems) {
207                                         currentItem++;
208                                         if (downCallback != NULL) {
209                                                 downCallback();
210                                                 if (captureCallback != NULL)
211                                                         captureCallback();
212                                         }
213                                 }
214                                 currentPosition = fl2i((((float)currentItem/(float)numberItems) * (float)numberPositions)-.49);
215                         } else {
216                                 mouse_lock_move = fl2i( ((((float)ui_mouse.y - (float)y - (float)slider_half_h)/(float)numberPositions) * (float)numberItems) -.49);                            
217                                 mouse_lock_move -= currentItem;
218                                 if (mouse_lock_move > 0) {
219                                         while (mouse_lock_move > 0) {                                           
220                                                 if  (currentItem < numberItems) {
221                                                         currentItem++;
222                                                         if (downCallback != NULL)
223                                                                 downCallback();
224                                                 }
225                                                 mouse_lock_move--;
226                                         }
227                                 }
228                                 // currentPosition = ui_mouse.y - y - slider_half_h;
229                                 currentPosition = fl2i((((float)currentItem/(float)numberItems) * (float)numberPositions)-.49);
230                         }       
231                         if (currentPosition < 0){
232                                 currentPosition = 0;
233                         }
234                         if (currentPosition > numberPositions){
235                                 currentPosition = numberPositions;
236                         }
237                         slider_mode = S2M_MOVING;
238                 } 
239         } 
240
241         // if we are centerd on the bitmap and still in mouse lock mode, we need to make sure the MOVING bitmap is still shown
242         // or if mouse is on us and we are pressing the mouse button
243         if (mouse_locked || (OnMe && B1_PRESSED)){
244                 slider_mode = S2M_MOVING;
245         }
246 }
247
248 void UI_SLIDER2::hide(int n)
249 {
250         hidden = 1;
251 }
252
253 void UI_SLIDER2::unhide()
254 {
255         hidden = 0;
256 }
257
258 int UI_SLIDER2::get_hidden()
259 {
260         return hidden;
261 }
262
263
264 // return number of itmes
265 int UI_SLIDER2::get_numberItems() {
266         return numberItems;
267 }
268
269 // return current position
270 int UI_SLIDER2::get_currentPosition() {
271         return currentPosition;
272 }
273
274 // return current item
275 int UI_SLIDER2::get_currentItem() {
276         return currentItem;
277 }
278
279 // change range. reset back to position 0
280 void UI_SLIDER2::set_numberItems(int _numberItems, int reset) {
281         numberItems = _numberItems;
282
283         if (reset) {
284                 currentItem = 0;
285                 currentPosition = 0;
286         } else {
287                 // recalcluate current position
288                 currentPosition = fl2i((((float)currentItem/(float)numberItems) * (float)numberPositions)-.49);
289                 if (currentPosition < 0){
290                         currentPosition = 0;
291                 }
292                 if (currentPosition > numberPositions){
293                         currentPosition = numberPositions;
294                 }
295         }
296         if (numberItems <= 0){
297                 disabled_flag = 1;
298         } else {
299                 disabled_flag = 0;
300         }
301 }
302
303 // force slider to new position manually
304 void UI_SLIDER2::set_currentItem(int _currentItem) {
305         if (_currentItem > numberItems) 
306                 return;
307
308         if (_currentItem == currentItem)
309                 return;
310
311         if (_currentItem < 0)
312                 return;
313
314         if (_currentItem > currentItem) {
315                 while (currentItem != _currentItem) {
316                         currentItem++;
317                         if (downCallback != NULL)
318                                 downCallback();
319                 }
320         } else if (_currentItem < currentItem) {
321                 while (currentItem != _currentItem) {
322                         currentItem--;
323                         if (upCallback != NULL)
324                                 upCallback();
325                 }
326         }       
327         
328         currentPosition = fl2i(((float)currentItem/(float)numberItems) * (float)numberPositions);       
329         CAP(currentPosition, 0, numberPositions);
330 }
331
332 void UI_SLIDER2::force_currentItem(int _currentItem) {  
333         currentItem = _currentItem;     
334         if(currentItem < 0){
335                 currentItem = 0;
336         };
337         currentPosition = fl2i(((float)currentItem/(float)numberItems) * (float)numberPositions);       
338         CAP(currentPosition, 0, numberPositions);
339 }
340
341 void UI_SLIDER2::forceDown() {
342         if (currentItem < numberItems) {
343                 currentItem++;
344                 currentPosition = fl2i(((float)currentItem/(float)numberItems) * (float)numberPositions);
345                 CAP(currentPosition, 0, numberPositions);
346         }
347 }
348
349 void UI_SLIDER2::forceUp() {
350         if (currentItem > 0) {
351                 currentItem--;
352                 currentPosition = fl2i(((float)currentItem/(float)numberItems) * (float)numberPositions);
353                 CAP(currentPosition, 0, numberPositions);
354         }
355 }
356