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