1 /*
2      PUI Auxiliary Widget Library
3      Derived from PLIB, the Portable Game Library by Steve Baker.
4 
5      This library is free software; you can redistribute it and/or
6      modify it under the terms of the GNU Library General Public
7      License as published by the Free Software Foundation; either
8      version 2 of the License, or (at your option) any later version.
9 
10      This library is distributed in the hope that it will be useful,
11      but WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      Library General Public License for more details.
14 
15      You should have received a copy of the GNU Library General Public
16      License along with this library; if not, write to the Free Software
17      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 
19      For further information visit http://plib.sourceforge.net
20 
21      $Id: puAux.h 2094 2006-10-26 20:48:04Z fayjf $
22 */
23 
24 #ifndef _PUI_AUX_WIDGETS_H_
25 #define _PUI_AUX_WIDGETS_H_ 1
26 
27 #include "pu.h"
28 
29 // Widget Class Bit Patterns
30 // PUI classes take up 0x00000001 through 0x00020000
31 
32 #define PUCLASS_FILESELECTOR        0x00040000 /* Because FilePicker is obsolete */
33 #define PUCLASS_BISLIDER            0x00080000
34 #define PUCLASS_TRISLIDER           0x00100000
35 #define PUCLASS_VERTMENU            0x00200000
36 #define PUCLASS_LARGEINPUT          0x00400000
37 #define PUCLASS_COMBOBOX            0x00800000
38 #define PUCLASS_SELECTBOX           0x01000000
39 #define PUCLASS_SPINBOX             0x02000000
40 #define PUCLASS_SCROLLBAR           0x04000000
41 #define PUCLASS_BISLIDERWITHENDS    0x08000000
42 #define PUCLASS_SLIDERWITHINPUT     0x10000000
43 #define PUCLASS_COMPASS             0x20000000
44 #define PUCLASS_CHOOSER             0x40000000
45 #define PUCLASS_LIST                0x80000000
46 
47 
48 // Widget Declarations
49 class puaSpinBox          ;
50 class puaFileSelector     ;
51 class puaBiSlider         ;
52 class puaTriSlider        ;
53 class puaVerticalMenu     ;
54 class puaLargeInput       ;
55 class puaComboBox         ;
56 class puaSelectBox        ;
57 class puaScrollBar        ;
58 class puaBiSliderWithEnds ;
59 class puaCompass          ;
60 class puaSliderWithInput  ;
61 class puaChooser          ;
62 class puaList             ;
63 
64 
65 // A File selector widget
66 class puaFileSelector : public puDialogBox
67 {
68   UL_TYPE_DATA
69 
70 protected:
71   char** files ;
72   char*  dflag ;
73   int num_files   ;
74   int arrow_count ;
75 
76   char *startDir ;
77 
78   void find_files ( void ) ;
79   static void handle_select ( puObject* ) ;
80   static void input_entered ( puObject* ) ;
81 
82   puFrame   *frame         ;
83   puListBox *list_box      ;
84   puSlider  *slider        ;
85   puOneShot *cancel_button ;
86   puOneShot *ok_button     ;
87   puInput   *input         ;
88   puArrowButton *up_arrow       ;
89   puArrowButton *down_arrow     ;
90   puArrowButton *fastup_arrow   ;
91   puArrowButton *fastdown_arrow ;
92 
93   void puaFileSelectorInit ( int x, int y, int w, int h,
94                              int arrows, const char *dir, const char *title ) ;
95 
96 public:
97 
98   puaFileSelector ( int x, int y, int w, int h, int arrows,
99                     const char *dir, const char *title = "Pick a file" ) :
puDialogBox(x,y)100       puDialogBox ( x, y )
101   {
102     puaFileSelectorInit ( x, y, w, h, arrows, dir, title ) ;
103   }
104 
105   puaFileSelector ( int x, int y, int w, int h,
106                     const char *dir, const char *title = "Pick a file" ) :
puDialogBox(x,y)107       puDialogBox ( x, y )
108   {
109     puaFileSelectorInit ( x, y, w, h, 1, dir, title ) ;
110   }
111 
112   puaFileSelector ( int x, int y, int arrows,
113                     const char *dir, const char *title = "Pick a file" ) :
puDialogBox(x,y)114       puDialogBox ( x, y )
115   {
116     puaFileSelectorInit ( x, y, 220, 170, arrows, dir, title ) ;
117   }
118 
119   puaFileSelector ( int x, int y,
120                     const char *dir, const char *title = "Pick a file" ) :
puDialogBox(x,y)121       puDialogBox ( x, y )
122   {
123     puaFileSelectorInit ( x, y, 220, 170, 1, dir, title ) ;
124   }
125 
126   ~puaFileSelector () ;
127 
128   /* Not for application use!! */
__getInput(void)129   puInput *__getInput ( void ) const { return input ; }
__getStartDir(void)130   char *__getStartDir ( void ) const { return (char *) startDir ; }
131 
132   void setInitialValue ( const char *fname ) ;
133   void setSize ( int w, int h ) ;
134 } ;
135 
136 
137 // An input box that takes an arbitrary number of lines of input
138 class puaLargeInput : public puInputBase, public puGroup
139 {
140   UL_TYPE_DATA
141 
142 protected:
143   int num_lines ;               // Number of lines of text in the box
144   int lines_in_window ;         // Number of lines showing in the window
145   int top_line_in_window ;      // Number of the first line in the window
146   float max_width ;             // Width of longest line of text in box, in pixels
147   int slider_width ;
148 
149   puFrame *frame ;
150 
151   puSlider *bottom_slider ;     // Horizontal slider at bottom of window
152   puaScrollBar *right_slider ;  // Vertical slider at right of window
153 
154   int arrow_count ;             // Number of up/down arrows above and below the right slider
155 
156   void normalizeCursors ( void ) ;
157   void removeSelectRegion ( void ) ;
158 
159   void wrapText ( void ) ;
160 
161 public:
162   puaLargeInput ( int x, int y, int w, int h, int arrows, int sl_width, int wrap_text = FALSE ) ;
~puaLargeInput()163   ~puaLargeInput ()
164   {
165     if ( puActiveWidget() == this )
166       puDeactivateWidget () ;
167   }
168 
169   void setSize ( int w, int h ) ;
170 
getNumLines(void)171   int getNumLines ( void ) const {  return num_lines ;  }
getLinesInWindow(void)172   int getLinesInWindow ( void ) const { return lines_in_window ; }
setTopLineInWindow(int val)173   void setTopLineInWindow ( int val ) {  top_line_in_window = (val<0) ? 0 : ( (val>num_lines-2) ? num_lines-2 : val ) ;  }
174 
175   void draw     ( int dx, int dy ) ;
176   int  checkHit ( int button, int updown, int x, int y ) ;
177   void doHit    ( int button, int updown, int x, int y ) ;
178   int  checkKey ( int key, int updown ) ;
179 
180   void setSelectRegion ( int s, int e ) ;
181   void selectEntireLine ( void ) ;
182 
invokeDownCallback(void)183   void invokeDownCallback ( void )
184   {
185     rejectInput () ;
186     normalizeCursors () ;
187     if ( down_cb != NULL ) (*down_cb)(this) ;
188   }
189 
190   void  setValue ( const char *s ) ;
setText(const char * l)191   void  setText ( const char *l ) { setValue ( l ) ; }  /* DEPRECATED */
getText(void)192   char *getText ( void ) { return getStringValue () ; }  /* DEPRECATED */
193   void  addNewLine ( const char *l ) ;
194   void  addText ( const char *l ) ;
195   void  appendText ( const char *l ) ;
196   void  removeText ( int start, int end ) ;
getDisplayedText(void)197   char *getDisplayedText ( void )
198   {
199     return ( displayed_text == NULL ? getStringValue () : displayed_text ) ;
200   }
getWrappedText(void)201   char *getWrappedText ( void )  // THIS FUNCTION IS DEPRECATED  3/21/06
202   {  return getDisplayedText () ;  }
203 } ;
204 
205 
206 // A box that contains a set of alternatives that drop down when the user clicks on the down-arrow
207 // Defined constants telling how the callback got triggered.  This is needed for
208 // cases in which the user has deleted the entry in the input box and wants that
209 // entry deleted from the list of items.
210 #define PUACOMBOBOX_CALLBACK_NONE      0
211 #define PUACOMBOBOX_CALLBACK_INPUT     1
212 #define PUACOMBOBOX_CALLBACK_ARROW     2
213 class puaComboBox : public puGroup
214 {
215   UL_TYPE_DATA
216 
217 protected:
218   char ** list  ;
219   int num_items ;
220 
221   int curr_item ;
222 
223   puInput *input ;
224   puArrowButton *arrow_btn ;
225   puPopupMenu *popup_menu  ;
226 
227   int callback_source ;
228 
229   static void input_cb ( puObject *inp   ) ;
230   static void input_active_cb ( puObject *inp   ) ;
231   static void input_down_cb ( puObject *inp   ) ;
232   static void handle_arrow ( puObject *arrow  ) ;
233   static void handle_popup ( puObject *popupm ) ;
234 
235   void update_widgets ( void ) ;
236   void update_current_item ( void ) ;
setCallbackSource(int s)237   void setCallbackSource ( int s )  {  callback_source = s ;  }
238 
239 public:
240   /* Not for application use ! */
__getPopupMenu(void)241   puPopupMenu * __getPopupMenu ( void ) const { return popup_menu ; }
242 
243   void newList ( char ** _list ) ;
getNumItems(void)244   int  getNumItems ( void ) const { return num_items ; }
getNewEntry(void)245   char *getNewEntry ( void ) const { return input->getStringValue () ; }
246 
247   int  getCurrentItem ( void ) ;
setCurrentItem(int item)248   void setCurrentItem ( int item )
249   {
250     if ( ( item >= 0 ) && ( item < num_items ) )
251     {
252       curr_item = item ;
253       update_widgets () ;
254 
255       callback_source = PUACOMBOBOX_CALLBACK_ARROW ;
256       invokeCallback () ;
257     }
258   }
259 
260   void setCurrentItem ( const char *item_ptr ) ;
261 
setPosition(int x,int y)262   void setPosition ( int x, int y )
263   {
264     puGroup::setPosition ( x, y ) ;
265 
266     /* Ensure that popup menu will show up at the right place */
267     newList ( list ) ;
268   }
269 
270   void setSize ( int w, int h ) ;
271 
setValue(float f)272   void setValue ( float f ) { puValue::setValue ( f ) ;  input->setValue ( f ) ; }
setValue(int i)273   void setValue ( int i ) { puValue::setValue ( i ) ;  input->setValue ( i ) ; }
setValue(const char * s)274   void setValue ( const char *s ) { puValue::setValue ( s ) ;  input->setValue ( s ) ; }
setValue(puValue * pv)275   void setValue ( puValue *pv ) { puValue::setValue ( pv ) ;  input->setValue ( pv ) ; }
276 
277   void draw ( int dx, int dy ) ;
278   int  checkHit ( int button, int updown, int x, int y ) ;
279   int  checkKey ( int key, int updown ) ;
280 
getCallbackSource(void)281   int  getCallbackSource ( void ) const  {  return callback_source ;  }
282 
283   virtual void setColourScheme ( float r, float g, float b, float a = 1.0f ) ;
284   virtual void setColour ( int which, float r, float g, float b, float a = 1.0f ) ;
285 
286   puaComboBox ( int minx, int miny, int maxx, int maxy,
287                 char **list, int editable = TRUE ) ;
288 
~puaComboBox()289   ~puaComboBox ()
290   {
291     int i ;
292     for ( i = 0; i < num_items; i++ )
293       delete [] list[i] ;
294 
295     delete [] list ;
296   }
297 } ;
298 
299 
300 // Like a menu bar, but the selections are one above the other
301 class puaVerticalMenu : public puGroup
302 {
303   UL_TYPE_DATA
304 
305 protected:
306 public:
307   puaVerticalMenu ( int x = -1, int y = -1 ) :
308 
309   puGroup ( x < 0 ? puGetWindowWidth() -
310                      ( puGetDefaultLegendFont().getStringWidth ( " " )
311                        + PUSTR_TGAP + PUSTR_BGAP ) : x,
312 
313           y < 0 ? puGetWindowHeight() -
314                    ( puGetDefaultLegendFont().getStringHeight ()
315                      + PUSTR_TGAP + PUSTR_BGAP ) : y)
316   {
317     type |= PUCLASS_VERTMENU ;
318     floating = TRUE ;  // DEPRECATED! -- we need to replace this code.
319     if ( y < 0 ) { setVStatus( TRUE ) ; } /* It is now supposed to stick to the top left - JCJ*/
320   }
321 
322   void add_submenu ( const char *str, char *items[], puCallback _cb[],
323                      void *_user_data[] = NULL ) ;
324   void close ( void ) ;
325 } ;
326 
327 
328 // Not sure what this one does ...
329 class puaSelectBox : public puGroup
330 {
331   UL_TYPE_DATA
332 
333 protected:
334   char ** list  ;
335   int num_items ;
336 
337   int curr_item ;
338 
339   puInput *input ;
340   puArrowButton *down_arrow ;
341   puArrowButton *up_arrow   ;
342 
343   static void handle_arrow ( puObject *arrow ) ;
344 
345   void update_widgets ( void ) ;
346 
347 public:
348   void newList ( char ** _list ) ;
getNumItems(void)349   int  getNumItems ( void ) const { return num_items ; }
350 
getCurrentItem(void)351   int  getCurrentItem ( void ) const { return curr_item ; }
setCurrentItem(int item)352   void setCurrentItem ( int item )
353   {
354     if ( ( item >= 0 ) && ( item < num_items ) )
355     {
356       curr_item = item ;
357       update_widgets () ;
358 
359       invokeCallback () ;
360     }
361   }
362 
363   void setSize ( int w, int h ) ;
364   void draw ( int dx, int dy ) ;
365   int  checkKey ( int key, int updown ) ;
366 
367   virtual void setColourScheme ( float r, float g, float b, float a = 1.0f ) ;
368   virtual void setColour ( int which, float r, float g, float b, float a = 1.0f ) ;
369 
370   puaSelectBox ( int minx, int miny, int maxx, int maxy,
371                  char **list ) ;
372 } ;
373 
374 
375 // A slider with up- and down-arrows on its ends
376 class puaScrollBar : public puSlider
377 {
378   UL_TYPE_DATA
379 
380 protected:
381   int arrow_count ;
382   int fast_up_arrow_active, fast_down_arrow_active ;
383   int up_arrow_active, down_arrow_active ;
384 
385 public:
386   void doHit ( int button, int updown, int x, int y ) ;
387   void draw  ( int dx, int dy ) ;
388   puaScrollBar ( int minx, int miny, int sz, int arrows, int vertical = FALSE ) :
puSlider(minx,miny,sz,vertical)389       puSlider ( minx, miny, sz, vertical )
390   {
391     type |= PUCLASS_SCROLLBAR ;
392     arrow_count = arrows ;
393     fast_up_arrow_active = fast_down_arrow_active = up_arrow_active = down_arrow_active = FALSE ;
394   }
395 
396   /* Alternate constructor which lets you explicitly set width */
397 
puaScrollBar(int minx,int miny,int sz,int arrows,int vertical,int width)398   puaScrollBar ( int minx, int miny, int sz, int arrows, int vertical, int width ) :
399       puSlider ( minx, miny, sz, vertical, width )
400   {
401     type |= PUCLASS_SCROLLBAR ;
402     arrow_count = arrows ;
403     fast_up_arrow_active = fast_down_arrow_active = up_arrow_active = down_arrow_active = FALSE ;
404   }
405 
setMaxValue(float f)406   void setMaxValue ( float f )
407   {
408     maximum_value = f ;
409     slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ;
410     puPostRefresh () ;
411   }
412 
413 
setMinValue(float i)414   void setMinValue ( float i )
415   {
416     minimum_value = i ;
417     slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ;
418     puPostRefresh () ;
419   }
420 } ;
421 
422 
423 
424 // A puSlider with two slide boxes instead of one
425 class puaBiSlider : public puSlider
426 {
427   UL_TYPE_DATA
428 
429 protected:
430   float current_max ;
431   float current_min ;
432 
433   int active_button ;  // Zero for none, one for min, two for max
434 public:
435   void doHit ( int button, int updown, int x, int y ) ;
436   void draw  ( int dx, int dy ) ;
437   puaBiSlider ( int minx, int miny, int sz, int vertical = FALSE ) :
puSlider(minx,miny,sz,vertical)438      puSlider ( minx, miny, sz, vertical )
439   {
440     type |= PUCLASS_BISLIDER ;
441     setMaxValue ( 1.0f ) ;
442     setMinValue ( 0.0f ) ;
443     setStepSize ( 1.0f ) ;
444     current_max = 1.0f ;
445     current_min = 0.0f ;
446     active_button = 0 ;
447   }
448 
449   /* Alternate constructor which lets you explicitly set width */
450 
puaBiSlider(int minx,int miny,int sz,int vertical,int width)451   puaBiSlider ( int minx, int miny, int sz, int vertical, int width ) :
452      puSlider ( minx, miny, sz, vertical, width )
453   {
454     type |= PUCLASS_BISLIDER ;
455     setMaxValue ( 1.0f ) ;
456     setMinValue ( 0.0f ) ;
457     setStepSize ( 1.0f ) ;
458     current_max = 1.0f ;
459     current_min = 0.0f ;
460     active_button = 0 ;
461   }
462 
setMaxValue(float i)463   void setMaxValue ( float i )
464   {
465     maximum_value = i ;
466     slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ;
467     puPostRefresh () ;
468   }
469 
470 
setMinValue(float i)471   void setMinValue ( float i )
472   {
473     minimum_value = i ;
474     slider_fraction = 1.0f / ( getMaxValue() - getMinValue() + 1.0f ) ;
475     puPostRefresh () ;
476   }
477 
setCurrentMax(int i)478   void setCurrentMax ( int i ) { current_max = (float) i ; puPostRefresh () ; } /* DEPRECATED */
setCurrentMax(float f)479   void setCurrentMax ( float f ) { current_max = f ; puPostRefresh () ; }
getCurrentMax(void)480   float getCurrentMax ( void ) const { return current_max ; }
481 
setCurrentMin(int i)482   void setCurrentMin ( int i ) { current_min = (float) i ; puPostRefresh () ; } /* DEPRECATED */
setCurrentMin(float f)483   void setCurrentMin ( float f ) { current_min = f ; puPostRefresh () ; }
getCurrentMin(void)484   float getCurrentMin ( void ) const { return current_min ; }
485 
setActiveButton(int i)486   void setActiveButton ( int i ) { active_button = i ; }
getActiveButton(void)487   int getActiveButton ( void ) const { return active_button ; }
488 } ;
489 
490 
491 // A puSlider with three slide boxes
492 
493 class puaTriSlider : public puaBiSlider
494 {
495   UL_TYPE_DATA
496 
497 protected:
498   // "active_button" is now zero for none, one for min, two for middle, three for max
499   int freeze_ends ;  // true to make end sliders unmovable
500 public:
501   void doHit ( int button, int updown, int x, int y ) ;
502   void draw  ( int dx, int dy ) ;
503   puaTriSlider ( int minx, int miny, int sz, int vertical = FALSE ) :
puaBiSlider(minx,miny,sz,vertical)504      puaBiSlider ( minx, miny, sz, vertical )
505   {
506     type |= PUCLASS_TRISLIDER ;
507     freeze_ends = TRUE ;
508   }
509 
510   /* Alternate constructor which lets you explicitly set width */
511 
puaTriSlider(int minx,int miny,int sz,int vertical,int width)512   puaTriSlider ( int minx, int miny, int sz, int vertical, int width ) :
513      puaBiSlider ( minx, miny, sz, vertical, width )
514   {
515     type |= PUCLASS_TRISLIDER ;
516     freeze_ends = TRUE ;
517   }
518 
getFreezeEnds(void)519   int getFreezeEnds ( void ) const { return freeze_ends ; }
setFreezeEnds(int val)520   void setFreezeEnds ( int val )   { freeze_ends = val ; puPostRefresh () ; }
521 } ;
522 
523 
524 // A vertical puBiSlider with a puInput box above it showing the current maximum
525 // value and a puInput box below it showing the current minimum value
526 
527 class puaBiSliderWithEnds : public puGroup
528 {
529   UL_TYPE_DATA
530 
531 protected:
532   puaBiSlider *slider ;
533   puInput *max_box ;
534   puInput *min_box  ;
535 
536   static void handle_slider ( puObject *obj ) ;
537   static void handle_max ( puObject *obj  ) ;
538   static void handle_min ( puObject *obj ) ;
539   static void input_down_callback ( puObject *obj ) ;
540 
541   void update_widgets ( void ) ;
542 
543 public:
544   // For internal use only:
__setMax(float f)545   void __setMax ( float f ) { max_box->setValue ( f ) ; }
__setMin(float f)546   void __setMin ( float f ) { min_box->setValue ( f ) ; }
547 
548   // For public use:
549 
550   void draw ( int dx, int dy ) ;
checkHit(int button,int updown,int x,int y)551   int  checkHit ( int button, int updown, int x, int y )
552   {
553     return puGroup::checkHit ( button, updown, x, y ) ;
554   }
555 
556   int  checkKey ( int key, int updown ) ;
557 
558   puaBiSliderWithEnds ( int minx, int miny, int maxx, int maxy ) ;
559 
560   void setSize ( int w, int h ) ;
561 
setMaxValue(float f)562   void setMaxValue ( float f ) { slider->setMaxValue ( f ) ; }
getMaxValue(void)563   float getMaxValue ( void ) const { return slider->getMaxValue () ; }
setMinValue(float f)564   void setMinValue ( float f ) { slider->setMinValue ( f ) ; }
getMinValue(void)565   float getMinValue ( void ) const { return slider->getMinValue () ; }
566 
setCurrentMax(float f)567   void setCurrentMax ( float f )
568   {
569     slider->setCurrentMax ( f ) ;
570     max_box->setValue ( f ) ;
571   }
572 
getCurrentMax(void)573   float getCurrentMax ( void ) const { return slider->getCurrentMax () ; }
574 
setCurrentMin(float f)575   void setCurrentMin ( float f )
576   {
577     slider->setCurrentMin ( f ) ;
578     min_box->setValue ( f ) ;
579   }
580 
getCurrentMin(void)581   float getCurrentMin ( void ) const { return slider->getCurrentMin () ; }
582 
setActiveButton(int i)583   void setActiveButton ( int i ) { slider->setActiveButton ( i ) ; }
getActiveButton(void)584   int getActiveButton ( void ) const { return slider->getActiveButton () ; }
585 
getValidData(void)586   char *getValidData ( void ) const { return max_box->getValidData () ; }
setValidData(char * data)587   void setValidData ( char *data ) { max_box->setValidData ( data ) ; min_box->setValidData ( data ) ; }
addValidData(char * data)588   void addValidData ( char *data ) { max_box->addValidData ( data ) ; min_box->addValidData ( data ) ; }
589 
setCBMode(int m)590   void setCBMode ( int m ) { slider->setCBMode ( m ) ; }
getCBMode(void)591   int getCBMode ( void ) const { return slider->getCBMode () ; }
592 
setDelta(float f)593   void setDelta ( float f ) { slider->setDelta ( f ) ; }
getDelta(void)594   float getDelta ( void ) const { return slider->getDelta () ; }
595 
getStepSize(void)596   float getStepSize ( void ) const { return slider->getStepSize () ; }
setStepSize(float f)597   void setStepSize ( float f )     { slider->setStepSize ( f )     ; }
598 } ;
599 
600 
601 // A vertical puSlider with a puInput box above or below it showing its value
602 
603 class puaSliderWithInput : public puGroup
604 {
605   UL_TYPE_DATA
606 
607 protected:
608   puSlider *slider ;
609   puInput *input_box ;
610   int input_position ;
611 
612   static void handle_slider ( puObject *obj ) ;
613   static void handle_input ( puObject *obj ) ;
614   static void input_down_callback ( puObject *obj ) ;
615 
616   void update_widgets ( void ) ;
617 
618 public:
619   // For internal use only:
__setInputBox(float f)620   void __setInputBox ( float f ) { input_box->setValue ( f ) ; }
621 
622   // For public use:
623 
624   void draw ( int dx, int dy ) ;
checkHit(int button,int updown,int x,int y)625   int  checkHit ( int button, int updown, int x, int y )
626   {
627     return puGroup::checkHit ( button, updown, x, y ) ;
628   }
629 
630   int  checkKey ( int key, int updown ) ;
631 
632   puaSliderWithInput ( int minx, int miny, int maxx, int maxy, int above = 0 ) ;
633 
634   void setSize ( int w, int h ) ;
635 
setMaxValue(float f)636   void setMaxValue ( float f ) { slider->setMaxValue ( f ) ; }
getMaxValue(void)637   float getMaxValue ( void ) const { return slider->getMaxValue () ; }
setMinValue(float f)638   void setMinValue ( float f ) { slider->setMinValue ( f ) ; }
getMinValue(void)639   float getMinValue ( void ) const { return slider->getMinValue () ; }
640 
setValue(int i)641   void setValue ( int i ) { slider->setValue ( i ) ;  input_box->setValue ( i ) ; }
setValue(float f)642   void setValue ( float f ) { slider->setValue ( f ) ;  input_box->setValue ( f ) ; }
setValue(const char * s)643   virtual void setValue ( const char *s ) { slider->setValue ( s ) ; }
setValue(bool b)644   virtual void setValue ( bool b ) { slider->setValue ( b ) ; }
645 
getIntegerValue(void)646   int   getIntegerValue ( void ) { return slider->getIntegerValue () ; }
getFloatValue(void)647   float getFloatValue ( void )   { return slider->getFloatValue ()   ; }
getCharValue(void)648   char  getCharValue ( void )    { return slider->getCharValue ()    ; }
getStringValue(void)649   char *getStringValue ( void )  { return slider->getStringValue ()  ; }
getBooleanValue(void)650   bool  getBooleanValue ( void ) { return slider->getBooleanValue () ; }
651 
getValidData(void)652   char *getValidData ( void ) const { return input_box->getValidData () ; }
setValidData(char * data)653   void setValidData ( char *data ) { input_box->setValidData ( data ) ; }
addValidData(char * data)654   void addValidData ( char *data ) { input_box->addValidData ( data ) ; }
655 
setCBMode(int m)656   void setCBMode ( int m ) { slider->setCBMode ( m ) ; }
getCBMode(void)657   int getCBMode ( void ) const { return slider->getCBMode () ; }
658 
setDelta(float f)659   void setDelta ( float f ) { slider->setDelta ( f ) ; }
getDelta(void)660   float getDelta ( void ) const { return slider->getDelta () ; }
661 
getStepSize(void)662   float getStepSize ( void ) const { return slider->getStepSize () ; }
setStepSize(float f)663   void setStepSize ( float f )     { slider->setStepSize ( f )     ; }
664 } ;
665 
666 class puaSpinBox : public puRange, public puGroup
667 {
668   UL_TYPE_DATA
669 
670 protected :
671   puInput *input_box ;
672   puArrowButton *up_arrow ;
673   puArrowButton *down_arrow ;
674 
675   int arrow_position ;
676 
677 public :
678   /* Whether the arrows are on the LEFT of the input box (0) or RIGHT (1 DEFAULT) */
getArrowPosition(void)679   int getArrowPosition ( void ) const { return arrow_position ; }
680   /* Offered as a proportion of the input box height. Default = 0.5 */
setArrowHeight(float height)681   void setArrowHeight ( float height )
682   {
683     puBox ibox = *(input_box->getABox()) ;
684     int size = int(height * ( ibox.max[1] - ibox.min[1] )) ;
685     up_arrow->setSize ( size, size ) ;
686     down_arrow->setSize ( size, size ) ;
687     int xpos = getArrowPosition () ? ibox.max[0] : ibox.min[0] - size ;
688     int ymid = ( ibox.max[1] + ibox.min[1] ) / 2 ;
689     if ( getArrowPosition () == 0 )  /* Arrows are on the left, adjust the x-position of the input box */
690     {
691       ibox.min[0] -= xpos ;
692       input_box->setPosition ( ibox.min[0], ibox.min[1] ) ;
693       abox.min[0] += xpos ;
694       xpos = 0 ;
695     }
696 
697     if ( height > 0.5f )  /* Adjust the input box to be up from the bottom */
698     {
699       input_box->setPosition ( ibox.min[0], ibox.min[1] + size - ymid ) ;
700       abox.min[1] += ymid - size ;
701       ymid = size ;
702     }
703     else  /* Input box is at the bottom of the group area */
704     {
705       input_box->setPosition ( ibox.min[0], 0 ) ;
706       abox.min[1] += ibox.min[1] ;
707     }
708 
709     up_arrow->setPosition ( xpos, ymid ) ;
710     down_arrow->setPosition ( xpos, ymid - size ) ;
711     recalc_bbox() ;
712   }
713 
getArrowHeight(void)714   float getArrowHeight ( void ) const
715   {
716     int awid, ahgt, iwid, ihgt ;
717     input_box->getSize ( &iwid, &ihgt ) ;
718     up_arrow->getSize ( &awid, &ahgt ) ;
719     return float(ahgt) / float(ihgt) ;
720   }
721 
722   puaSpinBox ( int minx, int miny, int maxx, int maxy, int arrow_pos = 1 ) ;
723 
setValue(float f)724   void setValue ( float f ) { puValue::setValue ( f ) ;  input_box->setValue ( f ) ; }
setValue(int i)725   void setValue ( int i ) { puValue::setValue ( i ) ;  input_box->setValue ( i ) ; }
setValue(const char * s)726   void setValue ( const char *s ) { puValue::setValue ( s ) ;  input_box->setValue ( s ) ; }
setValue(puValue * pv)727   void setValue ( puValue *pv ) { puValue::setValue ( pv ) ;  input_box->setValue ( pv ) ; }
728 } ;
729 
730 
731 /*
732  * Widget that looks like a 3-d coordinate system with quarter-circles in the coordinate planes.
733  * It is used in 3-d modeling to translate and rotate the scene.  The coordinates rotate with
734  * the scene but do not translate.  Defined values are:
735  *  0 - Nothing active
736  *  1 - Dot at origin active:  reset (usually)
737  *  2 - X-axis dot active:  rotate about y- and z-axes
738  *  3 - Y-axis dot active:  rotate about z- and x-axes
739  *  4 - Z-axis dot active:  rotate about x- and y-axes
740  *  5 - X-axis bar active:  translate along x-axis
741  *  6 - Y-axis bar active:  translate along y-axis
742  *  7 - Z-axis bar active:  translate along z-axis
743  *  8 - XY-plane arc active:  rotate about z-axis
744  *  9 - YZ-plane arc active:  rotate about x-axis
745  * 10 - ZX-plane arc active:  rotate about y-axis
746  * 11 - X-axis, Y-axis, and XY-arc active:  translate in xy-plane
747  * 12 - Y-axis, Z-axis, and YZ-arc active:  translate in yz-plane
748  * 13 - Z-axis, X-axis, and ZX-arc active:  translate in zx-plane
749  */
750 #define PUACOMPASS_INACTIVE          0
751 #define PUACOMPASS_RESET             1
752 #define PUACOMPASS_ROTATE_Y_Z        2
753 #define PUACOMPASS_ROTATE_Z_X        3
754 #define PUACOMPASS_ROTATE_X_Y        4
755 #define PUACOMPASS_TRANSLATE_X       5
756 #define PUACOMPASS_TRANSLATE_Y       6
757 #define PUACOMPASS_TRANSLATE_Z       7
758 #define PUACOMPASS_ROTATE_Z          8
759 #define PUACOMPASS_ROTATE_X          9
760 #define PUACOMPASS_ROTATE_Y         10
761 #define PUACOMPASS_TRANSLATE_X_Y    11
762 #define PUACOMPASS_TRANSLATE_Y_Z    12
763 #define PUACOMPASS_TRANSLATE_Z_X    13
764 
765 class puaCompass : public puObject
766 {
767   UL_TYPE_DATA
768 
769 protected :
770   sgQuat rotation ;
771   sgVec3 translation ;
772   float point_size ;
773   int button_state ;
774   int trigger_button ;
775   float mouse_x, mouse_y, mouse_z ;
776   float translation_sensitivity ;
777 
778   float xint, yint, zint ;
779   float prev_angle ;
780   sgQuat prev_rotation ;
781 
782 public :
puaCompass(int minx,int miny,int maxx,int maxy)783   puaCompass ( int minx, int miny, int maxx, int maxy ) : puObject ( minx, miny, maxx, maxy )
784   {
785     setValue ( PUACOMPASS_INACTIVE ) ;
786 
787 //    sgSetQuat ( rotation, 1.0f, 0.0f, 0.0f, 0.0f ) ;
788 //    sgSetQuat ( rotation, 0.707107f, 0.707107f, 0.0f, 0.0f ) ;
789 //    sgSetQuat ( rotation, 0.5f, -0.5f, 0.5f, 0.5f ) ;
790 //    sgSetQuat ( rotation, 0.866025f, -0.166667f, 0.166667f, 0.166667f ) ;
791     sgSetQuat ( rotation, 0.866025f, -0.408248f, 0.288675f, 0.0f ) ;
792     sgSetVec3 ( translation, 0.0f, 0.0f, 0.0f ) ;
793 
794     point_size = 10.0f ;
795 
796     button_state = PU_UP ;
797     trigger_button = active_mouse_button ;
798     mouse_x = mouse_y = mouse_z = 0.0f ;
799     translation_sensitivity = 1.0f ;
800 
801     xint = yint = zint = 0.0f ;
802     prev_angle = 0.0f ;
803     sgCopyQuat ( prev_rotation, rotation ) ;
804   }
805 
806   void draw ( int dx, int dy ) ;
807   void doHit ( int button, int updown, int x, int y ) ;
808 
809   // Accessors and mutators
getRotation(sgQuat q)810   void getRotation ( sgQuat q ) const  {  memcpy ( q, rotation, 4 * sizeof(sgFloat) ) ;  }
setRotation(sgQuat q)811   void setRotation ( sgQuat q )  {  memcpy ( rotation, q, 4 * sizeof(sgFloat) ) ;  }
setRotation(sgFloat t,sgFloat x,sgFloat y,sgFloat z)812   void setRotation ( sgFloat t, sgFloat x, sgFloat y, sgFloat z )
813   {
814     sgFloat sinth = sgSin ( t / 2.0f ) ;
815     sgFloat norm = sgSqrt ( x * x + y * y + z * z ) ;
816     if ( norm == 0.0 ) norm = 1.0 ;
817     rotation[SG_W] = sgCos ( t / 2.0f ) ;
818     rotation[SG_X] = sinth * x / norm ;
819     rotation[SG_Y] = sinth * y / norm ;
820     rotation[SG_Z] = sinth * z / norm ;
821   }
822 
getTranslation(sgVec3 t)823   void getTranslation ( sgVec3 t ) const  {  memcpy ( t, translation, 3 * sizeof(sgFloat) ) ;  }
setTranslation(sgVec3 t)824   void setTranslation ( sgVec3 t )  {  memcpy ( translation, t, 3 * sizeof(sgFloat) ) ;  }
setTranslation(sgFloat x,sgFloat y,sgFloat z)825   void setTranslation ( sgFloat x, sgFloat y, sgFloat z )  {  translation[SG_X] = x ;  translation[SG_Y] = y ;  translation[SG_Z] = z ;  }
826 
getPointSize()827   float getPointSize () const  {  return point_size ;  }
setPointSize(float p)828   void setPointSize ( float p )  {  point_size = p ;  }
829 
getTriggerButton()830   int getTriggerButton () const  {  return trigger_button ;  }
setTriggerButton(int b)831   void setTriggerButton ( int b )  {  trigger_button = b ;  }
832 
getTranslationSensitivity()833   float getTranslationSensitivity () const  {  return translation_sensitivity ;  }
setTranslationSensitivity(float t)834   void setTranslationSensitivity ( float t )  {  translation_sensitivity = t ;  }
835 } ;
836 
837 
838 class puaChooser
839 {
840   UL_TYPE_DATA
841 
842   puButton    *chooser_button ;
843   puPopupMenu *popup_menu ;
844 
845   int x1, y1, x2, y2 ;
846 
847   static void static_popup_cb ( puObject * ) ;
848   static void static_menu_cb  ( puObject * ) ;
849 
850 public:
851 
~puaChooser()852   virtual ~puaChooser ()
853   {
854     delete chooser_button ;
855     delete popup_menu     ;
856   }
857 
858   puaChooser ( int _x1, int _y1, int _x2, int _y2, char *legend ) ;
859 
860   void add_item ( char *str, puCallback _cb, void *_user_data = NULL ) ;
861   void close () ;
862 
863   void popup_cb () ;
864 
865   void menuCleanup  ( const char *s ) ;
866 
hide()867   void hide   () { chooser_button -> hide   () ; popup_menu -> hide   () ; }
reveal()868   void reveal () { chooser_button -> reveal () ; popup_menu -> hide   () ; }
869 
870   static void menuCleanup  ( puObject * ) ;
871 } ;
872 
873 
874 /**
875  * A scrolling list for PUI.
876  *
877  * Believe it or not, PUI does not have one of these.
878  *
879  *  This widget consists of a puListBox, a slider and two
880  *  arrow buttons. This makes the ListBox scrollable,
881  *  very handy if the box is too small to show all items
882  *  at once.
883  *
884  *  (Original code taken from FlightGear 0.9.6 sources,
885  *   modified by Jan Reucker)
886  */
887 class puaList : public puGroup
888 {
889   UL_TYPE_DATA
890 
891   char ** _contents;
892   puFrame * _frame;
893   puSlider * _slider;
894   puArrowButton * _up_arrow;
895   puArrowButton * _down_arrow;
896   int _style;
897   int _sw;       // slider width
898   int _width, _height;
899 
900 protected:
901   virtual void init (int w, int h, short transparent);
902   puListBox * _list_box;
903 
904 public:
905   puaList (int x, int y, int w, int h, int sl_width = 20);
906   puaList (int x, int y, int w, int h, char ** contents, int sl_width = 20);
907   puaList (int x, int y, int w, int h, short transparent, int sl_width = 20);
908   puaList (int x, int y, int w, int h, short transparent, char ** contents, int sl_width = 20);
909   virtual ~puaList ();
910 
911   virtual void newList (char ** contents);
912 
913   virtual char * getStringValue ();
914   virtual int    getIntegerValue ();
915   virtual void   getValue (char **ps);
916   virtual void   getValue (int  *i);
917 
918   virtual void   setColourScheme (float r, float g, float b, float a);
919   virtual void   setColour (int which, float r, float g, float b, float a);
920   virtual void   setSize (int w, int h);
921 
getNumVisible(void)922   int  getNumVisible ( void ) const { return _list_box->getNumVisible(); }
getNumItems(void)923   int  getNumItems   ( void ) const { return _list_box->getNumItems(); }
getTopItem(void)924   int  getTopItem    ( void ) const { return _list_box->getTopItem(); }
925   void setTopItem    ( int item_index );
926 };
927 
928 #endif
929 
930