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