Imported Upstream version 2.81
[platform/upstream/libbullet.git] / Extras / glui / glui_radio.cpp
1 /****************************************************************************
2   
3   GLUI User Interface Toolkit
4   ---------------------------
5
6      glui_radio.cpp - GLUI_RadioGroup and GLUI_RadioButton control classes
7
8
9           --------------------------------------------------
10
11   Copyright (c) 1998 Paul Rademacher
12
13   WWW:    http://sourceforge.net/projects/glui/
14   Forums: http://sourceforge.net/forum/?group_id=92496
15
16   This library is free software; you can redistribute it and/or
17   modify it under the terms of the GNU Lesser General Public
18   License as published by the Free Software Foundation; either
19   version 2.1 of the License, or (at your option) any later version.
20
21   This library is distributed in the hope that it will be useful,
22   but WITHOUT ANY WARRANTY; without even the implied warranty of
23   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24   Lesser General Public License for more details.
25
26   You should have received a copy of the GNU Lesser General Public
27   License along with this library; if not, write to the Free Software
28   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
29
30 *****************************************************************************/
31
32 #include "glui_internal_control.h"
33 #include <cassert>
34
35 /****************************** GLUI_RadioGroup::GLUI_RadioGroup() **********/
36
37 GLUI_RadioGroup::GLUI_RadioGroup(GLUI_Node *parent,
38                                  int *value_ptr,
39                                  int id, GLUI_CB cb)
40 {
41   common_init();
42   GLUI_String      buf;
43
44   set_ptr_val( value_ptr );
45   if ( value_ptr ) {
46     int_val = *value_ptr;  /** Can't call set_int_val(), b/c that 
47                                function will try to call the 
48                                callback, etc */
49     /** Actually, maybe not **/
50     last_live_int = *value_ptr;
51   }
52
53   user_id    = id;
54   glui_format_str( buf, "RadioGroup: %p", this );
55   set_name( buf.c_str() );
56   callback   = cb;
57
58   parent->add_control( this );
59
60   init_live();
61 }
62
63
64 /****************************** GLUI_RadioGroup::draw() **********/
65
66 void    GLUI_RadioGroup::draw( int x, int y )
67 {
68   if ( NOT can_draw() )
69     return;
70
71   draw_group(false);
72 }
73
74
75 /********************* GLUI_RadioGroup::draw_group(int translate) **********/
76
77 void    GLUI_RadioGroup::draw_group( int translate )
78 {
79   GLUI_DRAWINGSENTINAL_IDIOM
80   GLUI_RadioButton *button;
81   this->int_val = int_val;
82
83   glMatrixMode(GL_MODELVIEW );
84
85   button = (GLUI_RadioButton*) first_child();
86   while( button != NULL ) {
87     glPushMatrix();
88     if (translate) {
89       button->translate_to_origin();
90     }
91     else {
92       glTranslatef(button->x_abs-x_abs,
93                    button->y_abs-y_abs,0.0);
94     }
95
96     if ( button->int_val ) 
97       button->draw_checked();
98     else 
99       button->draw_unchecked();
100     
101     glPopMatrix();
102
103     button = (GLUI_RadioButton*) button->next();
104   }
105 }
106
107
108 /****************************** GLUI_RadioGroup::set_name() **********/
109
110 void    GLUI_RadioGroup::set_name( const char *text )
111 {
112   name = text;
113
114   if ( glui )
115     glui->refresh();
116 }
117
118
119 /********************************* GLUI_RadioGroup::set_selected() **********/
120
121 void    GLUI_RadioGroup::set_selected( int int_val )
122 {
123   GLUI_RadioButton *button;
124
125   this->int_val = int_val;
126
127   button = (GLUI_RadioButton*) first_child();
128   while( button != NULL ) {
129     if ( int_val == -1 ) {       /*** All buttons in group are deselected ***/
130       button->set_int_val(0);
131     }
132     else if ( int_val == button->user_id ) { /*** This is selected button ***/
133       button->set_int_val(1);
134     }
135     else {                               /*** This is NOT selected button ***/
136       button->set_int_val(0);
137
138     }
139     button = (GLUI_RadioButton*) button->next();
140   }
141   redraw();
142 }
143
144
145 /************************ GLUI_RadioButton::GLUI_RadioButton() **********/
146
147 GLUI_RadioButton::GLUI_RadioButton( GLUI_RadioGroup *grp, const char *name )
148 {
149   common_init();
150
151   set_int_val( 0 );
152
153   /** A radio button's user id is always its ordinal number (zero-indexed)
154       within the group */
155   user_id    = grp->num_buttons;
156   set_name( name );
157   group = grp;
158   
159   group->num_buttons++;   /* Increments radiogroup's button count */
160   group->add_control( this );
161
162   /*** Now update button states ***/
163   group->set_int_val( group->int_val ); /* This tells the group to
164                                            reset itself to its
165                                            current value, thereby
166                                            updating all its buttons */
167 }
168
169
170 /************************ GLUI_RadioButton::mouse_down_handler() **********/
171
172 int    GLUI_RadioButton::mouse_down_handler( int local_x, int local_y )
173 {
174   if ( NOT group )
175     return false;
176
177   orig_value = group->int_val;
178   
179   currently_inside = true;
180
181   group->set_selected( this->user_id );
182   redraw();
183   
184   return false;
185 }
186
187 /********************** GLUI_RadioButton::mouse_held_down_handler() ******/
188
189 int    GLUI_RadioButton::mouse_held_down_handler( int local_x, int local_y,
190                                                   bool inside)
191 {
192   if (inside != currently_inside) {
193      if (inside) group->set_selected( this->user_id );
194      else group->set_selected( orig_value );
195      currently_inside = inside;
196      redraw();
197   }
198   
199   return false;
200 }
201
202
203 /*************************** GLUI_RadioButton::mouse_up_handler() **********/
204
205 int    GLUI_RadioButton::mouse_up_handler( int local_x, int local_y, 
206                                            bool inside )
207 {
208   if ( NOT group )
209     return false;
210
211   if ( NOT inside ) {
212     group->set_selected( orig_value );
213     redraw();
214   }
215   else {
216     /** Now we update the radio button group.  We tell the group
217       handler to set the currently-selected item to this button, which
218       is reference by its user_id/ordinal number within group **/
219       
220     group->set_selected( this->user_id );
221     redraw();
222
223     /*** Now update the linked variable, and call the callback,
224       but ONLY if the value of the radio group actually changed ***/
225     if ( group->int_val != orig_value ) {
226       group->output_live(true); /** Output live and update gfx ***/
227       
228       group->execute_callback();
229     }
230   }
231
232   return false;
233 }
234
235 /****************************** GLUI_RadioButton::draw() **********/
236
237 void    GLUI_RadioButton::draw( int x, int y )
238 {
239   GLUI_DRAWINGSENTINAL_IDIOM
240
241   if ( NOT group OR NOT can_draw() )
242     return;
243
244   /*** See if we're the currently-selected button.  If so, draw ***/
245   if ( group->int_val == this->user_id ) {
246     if ( enabled )
247       glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_ON, 0, 0 );
248     else
249       glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_ON_DIS, 0, 0 );
250   }
251   else {
252     if ( enabled ) 
253       glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_OFF, 0, 0 );
254     else
255       glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_OFF_DIS, 0, 0 );
256   }
257
258   draw_active_area();
259
260   draw_name( text_x_offset, 10 );
261 }
262
263
264 /************************************ GLUI_RadioButton::draw_checked() ******/
265
266 void   GLUI_RadioButton::draw_checked( void )
267 {
268   GLUI_DRAWINGSENTINAL_IDIOM
269   if ( enabled )
270     glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_ON, 0, 0 );
271   else
272     glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_ON_DIS, 0, 0 );    
273   draw_active_area();
274 }
275
276
277 /*********************************** GLUI_RadioButton::draw_unchecked() ******/
278
279 void   GLUI_RadioButton::draw_unchecked( void )
280 {
281   GLUI_DRAWINGSENTINAL_IDIOM
282   
283   if ( enabled )
284     glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_OFF, 0, 0 );
285   else
286     glui->std_bitmaps.draw( GLUI_STDBITMAP_RADIOBUTTON_OFF_DIS, 0, 0 );
287   draw_active_area();
288 }
289
290
291 /**************************************** GLUI_RadioButton::draw_O() ********/
292
293 void   GLUI_RadioButton::draw_O( void )
294 {
295   GLUI_DRAWINGSENTINAL_IDIOM
296   int i, j;
297
298   glBegin( GL_POINTS );
299   for(i=3; i<=GLUI_RADIOBUTTON_SIZE-3; i++ )
300     for(j=3; j<=GLUI_RADIOBUTTON_SIZE-3; j++ )
301       glVertex2i(i,j);
302   glEnd();
303 }
304
305
306 /******************************** GLUI_RadioButton::update_size() **********/
307
308 void   GLUI_RadioButton::update_size( void )
309 {
310   int text_size;
311
312   if ( NOT glui )
313     return;
314
315   text_size = _glutBitmapWidthString( glui->font, name.c_str() );
316
317   /*  if ( w < text_x_offset + text_size + 6 )              */
318   w = text_x_offset + text_size + 6 ;
319 }
320
321
322 /************************* GLUI_RadioButton::draw_active_area() **************/
323
324 void    GLUI_RadioButton::draw_active_area( void )
325 {
326   GLUI_DRAWINGSENTINAL_IDIOM
327   int text_width, left, right;
328
329   text_width = _glutBitmapWidthString( glui->font, name.c_str() );
330   left       = text_x_offset-3;
331   right      = left + 7 + text_width;
332
333   if ( active ) {
334     glEnable( GL_LINE_STIPPLE );
335     glLineStipple( 1, 0x5555 );
336     glColor3f( 0., 0., 0. );
337   } else {
338     glColor3ub( glui->bkgd_color.r, glui->bkgd_color.g, glui->bkgd_color.b );
339   }
340
341   glBegin( GL_LINE_LOOP );
342   glVertex2i(left,0);     glVertex2i( right,0);
343   glVertex2i(right,h+1);   glVertex2i( left,h+1);
344   glEnd();
345   
346   glDisable( GL_LINE_STIPPLE );
347 }
348
349
350 /********************************* GLUI_RadioGroup::set_int_val() **********/
351
352 void    GLUI_RadioGroup::set_int_val( int new_val )
353 {
354   if ( new_val == int_val )
355     return;
356
357   set_selected( new_val );
358   redraw();  
359
360   output_live(true);
361      
362 }