]> icculus.org git repositories - taylor/freespace2.git/blob - src/ui/slider.cpp
Fix some more warnings
[taylor/freespace2.git] / src / ui / slider.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/slider.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * C++ file for controlling and displaying a horizontal slider
16  *
17  * $Log$
18  * Revision 1.4  2002/07/13 19:47:02  theoddone33
19  * Fix some more warnings
20  *
21  * Change demo building, edit Makefile if you want the demo.
22  *
23  * Revision 1.3  2002/06/09 04:41:29  relnev
24  * added copyright header
25  *
26  * Revision 1.2  2002/05/07 03:16:53  theoddone33
27  * The Great Newline Fix
28  *
29  * Revision 1.1.1.1  2002/05/03 03:28:11  root
30  * Initial import.
31  *
32  * 
33  * 8     8/10/99 6:54p Dave
34  * Mad optimizations. Added paging to the nebula effect.
35  * 
36  * 7     8/02/99 6:04p Jefff
37  * use_hack_to_get_around_stupid_problem_flag extended to sliders
38  * 
39  * 6     5/03/99 8:33p Dave
40  * New version of multi host options screen.
41  * 
42  * 5     2/11/99 3:08p Dave
43  * PXO refresh button. Very preliminary squad war support.
44  * 
45  * 4     12/02/98 5:47p Dave
46  * Put in interface xstr code. Converted barracks screen to new format.
47  * 
48  * 3     10/13/98 9:29a Dave
49  * Started neatening up freespace.h. Many variables renamed and
50  * reorganized. Added AlphaColors.[h,cpp]
51  * 
52  * 2     10/07/98 10:54a Dave
53  * Initial checkin.
54  * 
55  * 1     10/07/98 10:51a Dave
56  * 
57  * 12    4/17/98 10:34a Hoffoss
58  * Fixed dot slider positionings.
59  * 
60  * 11    3/22/98 10:50p Lawrance
61  * Allow sliders to not have end-buttons.
62  * 
63  * 10    2/03/98 4:21p Hoffoss
64  * Made UI controls draw white text when disabled.
65  * 
66  * 9     1/30/98 11:59a Hoffoss
67  * changed offset of slider child button.
68  * 
69  * 8     1/27/98 7:02p Lawrance
70  * Don't play the "mouse over" sound for the volume circles.
71  * 
72  * 7     1/15/98 12:00p Hoffoss
73  * Embelished file with nifty comments.
74  * 
75  * 6     1/14/98 6:44p Hoffoss
76  * Massive changes to UI code.  A lot cleaner and better now.  Did all
77  * this to get the new UI_DOT_SLIDER to work properly, which the old code
78  * wasn't flexible enough to handle.
79  * 
80  * 5     8/24/97 5:25p Lawrance
81  * improve drawing of buttons 
82  * 
83  * 4     6/12/97 12:39p John
84  * made ui use freespace colors
85  * 
86  * 3     6/11/97 1:13p John
87  * Started fixing all the text colors in the game.
88  * 
89  * 2     5/26/97 10:26a Lawrance
90  * get slider control working 100%
91  *
92  * $NoKeywords: $
93  */
94
95
96 #include "uidefs.h"
97 #include "ui.h"
98 #include "timer.h"
99
100 #include "missionscreencommon.h"
101 #include "bmpman.h"
102 #include "gamesnd.h"
103 #include "alphacolors.h"
104
105 /// DOT_SLIDER class down here
106 void UI_DOT_SLIDER_NEW::create(UI_WINDOW *wnd, int _x, int _y, int _num_pos, char *bm_slider, int slider_mask,
107                                                                                                                                                                         char *bm_left, int left_mask, int left_x, int left_y,
108                                                                                                                                                                         char *bm_right, int right_mask, int right_x, int right_y,
109                                                                                                                                                                         int _dot_width)
110 {
111         // no end buttons yet
112         has_end_buttons = 0;
113
114         // if any of the left/right arrow information is specified, make sure its _all_ specified
115         if((bm_left != NULL) || (left_mask != -1) || (bm_right != NULL) || (right_mask != -1)){
116                 Assert((bm_left != NULL) && (left_mask >= 0) && (bm_right != NULL) && (right_mask >= 0));
117                 if((bm_left == NULL) || (left_mask < 0) || (bm_right == NULL) || (right_mask < 0)){
118                         return;
119                 }
120
121                 // now we know we have end buttons
122                 has_end_buttons = 1;
123         }
124
125         // internal stuff
126         num_pos = _num_pos;
127         base_create(wnd, UI_KIND_DOT_SLIDER_NEW, _x, _y, 0, 20);
128         pos = 0;                
129         dot_width = _dot_width; 
130
131         // set bitmaps for the slider itself    
132         button.create( wnd, "", _x, _y, 0, 0, 0, 1 );
133         button.set_parent(this);
134         button.link_hotspot(slider_mask);
135         button.set_bmaps(bm_slider, num_pos, 0);        
136         button.hide();
137                 
138         // maybe setup buttons for the arrows
139         if ( has_end_buttons ) {
140                 // Second button is the up (increase) button            
141                 up_button.create( wnd, "", right_x, right_y, 0, 0, 1, 1 );
142                 up_button.set_parent(this);
143                 up_button.set_highlight_action(common_play_highlight_sound);
144                 up_button.link_hotspot(right_mask);
145                 up_button.set_bmaps(bm_right);          
146
147                 // Third button is the down (decrease) button           
148                 down_button.create( wnd, "", left_x, left_y, 0, 0, 1, 1 );
149                 down_button.set_parent(this);
150                 down_button.set_highlight_action(common_play_highlight_sound);
151                 down_button.link_hotspot(left_mask);
152                 down_button.set_bmaps(bm_left);         
153         }
154 }
155
156 void UI_DOT_SLIDER_NEW::draw()
157 {
158         // draw end buttons
159         if ( has_end_buttons ) {
160                 up_button.draw();
161                 down_button.draw();
162         }
163         
164         // draw the proper dot
165         Assert((pos >= 0) && (pos <= num_pos)); 
166         
167         // for position -1, we don't draw (no dots)     
168         if(pos >= 0){
169                 button.unhide();        
170                 button.draw_forced(pos);
171                 button.hide();          
172         }
173 }
174
175 void UI_DOT_SLIDER_NEW::process(int focus)
176 {
177         if (disabled_flag) {
178                 if (!hidden && !my_wnd->use_hack_to_get_around_stupid_problem_flag) {
179                         if (button.is_mouse_on() && B1_JUST_PRESSED) {
180                                 gamesnd_play_iface(SND_GENERAL_FAIL);
181                         } else if (has_end_buttons && (up_button.is_mouse_on() || down_button.is_mouse_on())) {
182                                 gamesnd_play_iface(SND_GENERAL_FAIL);
183                         }
184                         
185
186                         if ( (hotkey >= 0) && (my_wnd->keypress == hotkey) ){
187                                 gamesnd_play_iface(SND_GENERAL_FAIL);
188                         }
189                 }
190
191                 return;
192         }
193
194         // check focus and derived focus with one variable
195         if (my_wnd->selected_gadget == this){
196                 focus = 1;
197         }
198
199         // first check the dot area
200         button.process(focus);
201         if (button.button_down() || button.pressed() || mouse_captured()) {
202                 capture_mouse();  // while we are changing level, ignore all other buttons
203                 
204                 pos = (ui_mouse.x - x) / dot_width;             
205
206                 if (pos < 0){
207                         pos = 0;
208                 }
209
210                 // if we have 10 positions, 0 - 9 are valid
211                 if ( pos >= num_pos ) {
212                         pos = num_pos - 1;
213                 }
214
215                 return;
216         }
217
218         if ( has_end_buttons ) {
219                 up_button.process(focus);
220                 if (up_button.pressed()) {
221                         if (pos < num_pos-1){
222                                 pos++;
223                         } else {
224                                 gamesnd_play_iface(SND_GENERAL_FAIL);
225                         }
226                 }
227
228                 down_button.process(focus);
229                 if (down_button.pressed()) {
230                         if(pos){
231                                 pos--;
232                         } else {
233                                 gamesnd_play_iface(SND_GENERAL_FAIL);
234                         }
235                 }
236         }
237 }
238
239 //
240 // OLD DOT SLIDER - TO BE PHASED OUT. IF YOU NEED TO USE A UI_DOT_SLIDER, use a UI_DOT_SLIDER_NEW -------------------
241 //
242
243 /// DOT_SLIDER class down here
244 void UI_DOT_SLIDER::create(UI_WINDOW *wnd, int _x, int _y, char *bm, int id, int end_buttons, int _num_pos)
245 {
246         char    filename[MAX_PATH_LEN];
247         int     bx, by, bw, hotspot;
248
249         has_end_buttons = end_buttons;
250
251         if ( has_end_buttons ) {
252                 bx = _x + 24;
253                 by = _y + 1;
254                 bw = 190;
255                 hotspot = id + 1;
256         } else {
257                 bx = _x;
258                 by = _y;
259                 bw = 80;
260                 hotspot = id;
261         }
262
263         num_pos = _num_pos;
264
265         sprintf(filename, "%s%.2d", bm, hotspot);
266         first_frame = bm_load_animation(filename, &total_frames);
267         if (first_frame < 0) {
268                 Error(LOCATION, "Could not load %s.ani\n", filename);
269                 disable();
270                 hide();
271                 return;
272         }
273
274         base_create(wnd, UI_KIND_DOT_SLIDER, bx, by, bw, 20);
275         pos = 0;
276
277         // A DOT_SLIDER has up to 3 child buttons..
278
279         by = _y;
280
281         // First button is the region with the dots
282         button.create( wnd, "", bx, by, bw, 20, 0, 1 );
283         button.set_parent(this);
284         button.link_hotspot(hotspot);
285         button.hide();
286
287         if ( has_end_buttons ) {
288                 // Second button is the up (increase) button
289                 sprintf(filename, "%s%.2d", bm, id + 2);
290                 up_button.create( wnd, "", _x + 216, _y, 22, 24, 1, 1 );
291                 up_button.set_parent(this);
292                 up_button.set_highlight_action(common_play_highlight_sound);
293                 up_button.set_bmaps(filename);
294                 up_button.link_hotspot(id + 2);
295
296                 // Third button is the down (decrease) button
297                 sprintf(filename, "%s%.2d", bm, id);
298                 down_button.create( wnd, "", _x, _y, 22, 24, 1, 1 );
299                 down_button.set_parent(this);
300                 down_button.set_highlight_action(common_play_highlight_sound);
301                 down_button.set_bmaps(filename);
302                 down_button.link_hotspot(id);
303         }
304 }
305
306 void UI_DOT_SLIDER::destroy()
307 {
308         int i;
309
310         // release ani frames for the dots.
311         for (i=0; i<total_frames; i++){
312                 bm_release(first_frame + i);
313         }
314
315         UI_GADGET::destroy();
316 }
317
318 void UI_DOT_SLIDER::draw()
319 {
320         if ( has_end_buttons ) {
321                 up_button.draw();
322                 down_button.draw();
323         }
324         Assert((pos >= 0) && (pos <= num_pos));
325         gr_set_bitmap(first_frame + pos);  // draw the dot level
326         gr_bitmap(x, y);
327 }
328
329 void UI_DOT_SLIDER::process(int focus)
330 {
331         if (disabled_flag)
332                 return;
333
334         // check focus and derived focus with one variable
335         if (my_wnd->selected_gadget == this)
336                 focus = 1;
337
338         // first check the dot area
339         button.process(focus);
340         if (button.button_down() || button.pressed() || mouse_captured()) {
341                 capture_mouse();  // while we are changing level, ignore all other buttons
342
343                 if ( has_end_buttons ) {
344                         pos = (ui_mouse.x - x + 17) / 19;
345                 } else {
346                         pos = (ui_mouse.x - x) / 19;
347                 }
348
349                 if (pos < 0){
350                         pos = 0;
351                 }
352
353                 if ( pos > num_pos ){
354                         pos = num_pos;
355                 }
356
357                 return;
358         }
359
360         if ( has_end_buttons ) {
361                 up_button.process(focus);
362                 if (up_button.pressed()) {
363                         if (pos < num_pos){
364                                 pos++;
365                         } else {
366                                 gamesnd_play_iface(SND_GENERAL_FAIL);
367                         }
368                 }
369
370                 down_button.process(focus);
371                 if (down_button.pressed()) {
372                         if (pos){
373                                 pos--;
374                         } else {
375                                 gamesnd_play_iface(SND_GENERAL_FAIL);
376                         }
377                 }
378         }
379 }
380
381 /*
382 // --------------------------------------------------------------------
383 // UI_SLIDER::link_hotspot
384 //
385 //
386 void UI_SLIDER::link_hotspot(int left_button_num, int right_button_num)
387 {
388         left_button.link_hotspot(left_button_num);
389         right_button.link_hotspot(right_button_num);
390 }
391
392 // --------------------------------------------------------------------
393 // UI_SLIDER::set_bmaps
394 //
395 // Call the UI_GADGET::set_bmaps() function for the child components
396 // of a scroll bar (the up and down button).  Set up the bmaps for the
397 // line itself.
398 //
399 // We also need to get the dimensions of the bitmap button so we can update
400 // the dimensions of the scrollbar.
401 //
402 // returns:             -1 ==> error
403 //                                       0 ==> success
404 //
405 int UI_SLIDER::set_bmaps(char *left_button_fname, char *right_button_fname, char *bar_fname, char *marker_fname)
406 {
407         int m_w,m_h;
408
409         left_button.set_bmaps(left_button_fname);
410         right_button.set_bmaps(right_button_fname);
411         
412         // set the bitmaps for the rectangle that is the scrollbar itself
413         ((UI_GADGET*)this)->set_bmaps(bar_fname);
414         ((UI_GADGET*)this)->set_bmaps(marker_fname,2);  // skip the first two bitmaps 
415
416         bm_get_info( bmap_ids[SLIDER_MARKER_NORMAL], &m_w, &m_h, NULL );
417         // force the slider dimensions based on size of marker bitmap
418         w = n_positions * m_w;
419         marker_w = m_w;
420         marker_h = m_h;
421         pixel_range = w-marker_w;
422         increment = pixel_range / n_positions;
423
424         right_button.update_dimensions(x+w, y, -1, -1);
425
426         uses_bmaps = 1;
427
428         return 0;
429 }
430
431 void UI_SLIDER::hide()
432 {
433         hidden = 1;
434         left_button.hide();
435         right_button.hide();
436 }
437
438 void UI_SLIDER::unhide()
439 {
440         hidden = 0;
441         left_button.unhide();
442         right_button.unhide();
443 }
444
445 int UI_SLIDER::get_hidden()
446 {
447         return hidden;
448 }
449
450 void UI_SLIDER::create(UI_WINDOW *wnd, int _x, int _y, int _w, int _h, float _start, float _stop, float _current, int _n_positions )
451 {
452         char *up = "<";
453         char *down = ">";
454         int bw, bh, real_w;
455         bw=bh=_h;
456         real_w = _n_positions*bw;
457         base_create( wnd, UI_KIND_SLIDER, _x, _y, real_w, _h);
458
459         left_button.create( wnd, up, _x-bw, _y, _h, _h );
460         left_button.set_parent(this);
461
462         right_button.create( wnd, down, _x+real_w, _y, bh, bh );
463         right_button.set_parent(this);
464
465         horz = 0;
466         start = _start;
467         stop = _stop;
468         current = _current;
469
470         Assert( _current >= _start );
471         Assert( _current <= _stop );
472         Assert( stop >= 0 );
473
474         n_positions = _n_positions;
475
476         dragging = 0;
477         last_scrolled = 0;
478         moved = 1;
479
480         marker_w = _h;
481         marker_h = _h;
482
483         pixel_range = w-marker_w;
484         marker_x = x + fl2i( ( (current - start)/(stop-start) * pixel_range ) );
485         increment = pixel_range / n_positions;
486         Assert(increment >= 1);
487         mouse_locked = 0;
488 };
489
490 void UI_SLIDER::draw()
491 {
492         if ( uses_bmaps ) {
493                 gr_reset_clip();
494                 if ( disabled_flag ) {
495                         if ( bmap_ids[SLIDER_BAR_DISABLED] != -1 ) {
496                                 gr_set_bitmap(bmap_ids[SLIDER_BAR_DISABLED]);
497                                 gr_bitmap(x,y);
498                         }
499
500                         if ( bmap_ids[SLIDER_MARKER_DISABLED] != -1 ) {
501                                 gr_set_bitmap(bmap_ids[SLIDER_MARKER_DISABLED]);
502                                 gr_bitmap(marker_x,marker_y);
503                         }
504
505                 }
506                 else {
507                         if ( bmap_ids[SLIDER_BAR_NORMAL] != -1 ) {
508                                 gr_set_bitmap(bmap_ids[SLIDER_BAR_NORMAL]);
509                                 gr_bitmap(x,y);
510                         }
511
512                         if ( bmap_ids[SLIDER_MARKER_NORMAL] != -1 ) {
513                                 gr_set_bitmap(bmap_ids[SLIDER_MARKER_NORMAL]);
514                                 gr_bitmap(marker_x,marker_y);
515                         }
516                 }
517         }
518         else {
519                 gr_set_font(my_wnd->f_id);
520                 gr_set_clip( x, y, w, h );
521
522                 if (my_wnd->selected_gadget == this)
523                         gr_set_color_fast( &CBRIGHT_GREEN );
524                 else
525                         gr_set_color_fast( &CGRAY );
526
527                 ui_rect( 0, 0, w-1, h-1 );
528
529                 gr_set_clip( marker_x, marker_y, w, h );
530                 ui_draw_box_out(0, 0, marker_w, marker_h);
531         }
532 }
533
534 void UI_SLIDER::process(int focus)
535 {
536         int OnMe, OnMarker, keyfocus;
537         int oldpos, op;
538         float percent;
539         moved = 0;
540
541         if (disabled_flag) {
542                 return;
543         }
544
545         if (my_wnd->selected_gadget == this)
546                 keyfocus = 1;
547
548         left_button.process(focus);
549         right_button.process(focus);
550
551         marker_y = y;
552         keyfocus = 0;
553
554         if (start == stop) {
555                 marker_x = x;
556                 return;
557         }
558
559         op = marker_x;
560         oldpos = fake_position;
561
562         OnMarker = 0;
563         OnMe = is_mouse_on();
564         if ( OnMe ) {
565                 if ( ui_mouse.x >= (marker_x ) && ui_mouse.x <= (marker_x+marker_w) ) {
566                         OnMarker = 1;
567                         if ( B1_PRESSED )
568                                 mouse_locked = 1;
569                 }
570         }
571
572         if ( !B1_PRESSED) {
573                 mouse_locked = 0;
574         }
575
576         if ( (left_button.position!=0) || (keyfocus && keyd_pressed[KEY_LEFT]) || ( OnMe && B1_PRESSED && ui_mouse.x < marker_x) || (mouse_locked && ui_mouse.x < marker_x ) )  {
577                 if ( (timer_get_milliseconds() > last_scrolled+50) || left_button.just_pressed() || B1_JUST_PRESSED || mouse_locked || my_wnd->keypress == KEY_LEFT)    {
578                         if ( left_button.just_pressed() || B1_JUST_PRESSED || mouse_locked || my_wnd->keypress == KEY_LEFT )    {
579                                 last_scrolled = timer_get_milliseconds() + 300;
580                         } else
581                                 last_scrolled = timer_get_milliseconds();
582                         marker_x -= increment;
583                         if (marker_x < x )
584                                 marker_x = x;
585                 }
586         }
587
588         if ( (right_button.position!=0) || (keyfocus && keyd_pressed[KEY_RIGHT]) || ( OnMe && B1_PRESSED && ui_mouse.x > (marker_x+marker_w)) || (mouse_locked && ui_mouse.x > marker_x+marker_w) ) {
589                 if ( (timer_get_milliseconds() > last_scrolled+50) || right_button.just_pressed() || B1_JUST_PRESSED || mouse_locked || my_wnd->keypress == KEY_RIGHT)  {
590                         if ( right_button.just_pressed() || B1_JUST_PRESSED || mouse_locked || my_wnd->keypress == KEY_RIGHT)   
591                                 last_scrolled = timer_get_milliseconds() + 300;
592                         else
593                                 last_scrolled = timer_get_milliseconds();
594                         marker_x += increment;
595                         if (marker_x > (x+n_positions*increment) )
596                                 marker_x = x+n_positions*increment;
597                 }
598         }
599
600         percent = i2fl(marker_x - x)/i2fl(pixel_range);
601         current = percent * (stop - start);
602 }
603
604 int UI_SLIDER::getpos()
605 {
606         return marker_x;
607 }
608
609 float UI_SLIDER::getcurrent()
610 {
611         return current;
612 }
613
614 int UI_SLIDER::changed()
615 {
616         return moved;
617 }
618 */
619