4 * Simple PUI wrapper around sgVec3 class
6 * Created by: Norman Vine [NHV]
7 * nhv@yahoo.com, nhv@cape.com
11 * Started 12:53 01/28/2001
15 #include "sgVec3Slider.hxx"
16 #include <Main/fg_props.hxx>
17 #include <simgear/sg_inlines.h>
19 class FloatSlider : public puSlider
34 FloatSlider ( int x, int y, int sz, float f, const char *title,
35 float max = 100.0f, float min = 0.0f);
39 static void adj( puObject *);
42 sprintf( _text, "%05.2f", MyValue );
45 float get() { return( MyValue ); }
47 // calc actual "setting" by multiplying the pui fraction by highest value setable
48 void set() { MyValue = maxValue * TmpValue; }
50 float *getTmp() { return( &TmpValue ); }
52 // adjust the TmpValue back to 0 to 1 range of pui widget
53 void setTmp() { TmpValue += 0.0f; }
55 // adjust actual "setting" value back to fraction for pui widget
56 void init( float f ) {
57 if (f > maxValue) f = maxValue;
58 if (f < minValue) f = minValue;
59 Adjust = 1.0f / maxValue;
64 void reinit() { init( origValue ); }
65 void cancel() { MyValue = TmpValue; }
66 void reset () { init( origValue ); }
70 void FloatSlider::adj( puObject *hs )
72 FloatSlider *slider = (FloatSlider *)hs->getUserData();
73 slider->getValue ( slider->getTmp() );
79 FloatSlider::FloatSlider ( int x, int y, int sz, float f, const char *title,
80 float max, float min ) : puSlider( x, y, sz, FALSE )
88 setCBMode ( PUSLIDER_DELTA ) ;
90 strcpy ( _title, title);
92 setLabelPlace ( PUPLACE_LEFT );
94 // setLegendPlace( PUPLACE_RIGHT );
98 class FloatDial : public puDial
113 FloatDial ( int x, int y, int sz, float f, const char *title,
114 float max = 180.0f, float min = -180.0f );
118 static void adj( puObject *);
121 sprintf( _text, "%05.2f", MyValue );
124 float get() { return( MyValue ); }
126 // calc actual "setting" by multiplying the pui fraction by highest value setable
127 // in this case we're also turning a 0 to 1 range into a -.05 to +.05 before converting
128 void set() { MyValue = ((2.0*maxValue) * (TmpValue - 0.5f)) - maxValue; }
130 float *getTmp() { return( &TmpValue ); }
132 // adjust the TmpValue back to 0 to 1 range of pui widget
133 void setTmp() { TmpValue += 0.5f; }
135 // adjust actual "setting" value back to fraction for pui widget
136 // double the range from -max <-> max
137 void init( float f ) {
138 if (f > maxValue) f = maxValue;
139 if (f < minValue) f = minValue;
140 Adjust = 0.5f / maxValue;
141 setValue((f * Adjust) + 0.5f);
145 void reinit() { init( origValue ); }
146 void cancel() { MyValue = TmpValue; }
147 void reset () { init( origValue ); }
151 void FloatDial::adj( puObject *hs )
153 FloatDial *dial = (FloatDial *)hs->getUserData();
154 dial->getValue ( dial->getTmp() );
160 FloatDial::FloatDial ( int x, int y, int sz, float f, const char *title,
161 float max, float min ) : puDial( x, y, sz )
169 setCBMode ( PUSLIDER_DELTA ) ;
170 setCallback ( adj ) ;
171 strcpy ( _title, title);
173 setLabelPlace ( PUPLACE_LEFT );
175 // setLegendPlace( PUPLACE_RIGHT );
179 /***********************************************/
181 class sgVec3Slider : public puDialogBox
183 static void goAway(puObject *p_obj);
184 static void reset(puObject *p_obj);
185 static void cancel(puObject *p_obj);
194 puOneShot *ResetButton;
195 puOneShot *CancelButton;
200 sgVec3Slider ( int x, int y, sgVec3 vec,
201 const char *title = "Vector Adjuster",
202 const char *Xtitle = "Heading",
203 const char *Ytitle = "Pitch",
204 const char *Ztitle = "Radius" );
208 // calc the property Vec with the actual point on sphere
211 Vec3FromHeadingPitchRadius( Vec,
217 // return the offset vector according to current widget values
224 // save the Vector before pushing dialog (for cancel button)
225 sgVec3 *getStashVec() { return &SaveVec; }
227 SaveVec[2] = HS0->get();
228 SaveVec[1] = HS1->get();
229 SaveVec[0] = HS2->get();
232 // functions to return pointers to protected pui widget instances
233 FloatDial *getHS0() { return HS0; }
234 FloatDial *getHS1() { return HS1; }
235 FloatSlider *getHS2() { return HS2; }
237 static void adjust(puObject *p_obj);
241 sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 vec, const char *title,
244 const char *Ztitle ): puDialogBox ( x, y )
246 puFont LegendFont, LabelFont;
247 puGetDefaultFonts ( &LegendFont, &LabelFont );
251 int labelW = LabelFont.getStringWidth(Xtitle);
252 labelW = SG_MAX2( labelW, LabelFont.getStringWidth(Ytitle));
253 labelW = SG_MAX2( labelW, LabelFont.getStringWidth(Ztitle));
256 sgCopyVec3(SaveVec, vec);
257 sgCopyVec3(Vec, vec);
258 strcpy( Label, title );
261 int slider_x = 70+fudge;
263 int slider_width = 270;
264 int dialer_x = 70+fudge;
266 int dialer_size = 100;
268 int horiz_slider_height = LabelFont.getStringHeight()
269 + LabelFont.getStringDescender()
270 + PUSTR_TGAP + PUSTR_BGAP + 5;
272 int DialogWidth = slider_width + 20 + fudge + labelW;
273 int DialogHeight = dialer_size + 115 + nSliders * horiz_slider_height;
277 horiz_slider_height += 10;
279 new puFrame ( 0, 0, DialogWidth, DialogHeight );
281 setLabelPlace( PUPLACE_DEFAULT /*PUPLACE_CENTERED*/ );
285 HS0 = new FloatDial ( dialer_x, dialer_y, dialer_size, vec[0], Xtitle, 180.0f, -180.0f );
286 dialer_x = dialer_x + 170;
289 HS1 = new FloatDial ( dialer_x, dialer_y, dialer_size, vec[1], Ytitle, 89.99f, -89.99f );
292 HS2 = new FloatSlider ( slider_x, slider_y, slider_width, vec[2], Ztitle, 100.0f, 0.0f );
294 TitleText = new puText( 130, DialogHeight - 40);
295 TitleText->setLabel("Pilot Offset");
297 OkButton = new puOneShot ( 70+fudge, 20, 120+fudge, 50 );
298 OkButton-> setUserData( this );
299 OkButton-> setLegend ( gui_msg_OK );
300 OkButton-> makeReturnDefault ( TRUE );
301 OkButton-> setCallback ( goAway );
303 CancelButton = new puOneShot ( 130+fudge, 20, 210+fudge, 50 );
304 CancelButton-> setUserData( this );
305 CancelButton-> setLegend ( gui_msg_CANCEL );
306 CancelButton-> setCallback ( cancel );
308 ResetButton = new puOneShot ( 220+fudge, 20, 280+fudge, 50 );
309 ResetButton-> setUserData( this );
310 ResetButton-> setLegend ( gui_msg_RESET );
311 ResetButton-> setCallback ( reset );
313 FG_FINALIZE_PUI_DIALOG( this );
316 void sgVec3Slider::goAway(puObject *p_obj)
318 sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
319 FG_POP_PUI_DIALOG( me );
322 void sgVec3Slider::reset(puObject *p_obj)
324 sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
330 void sgVec3Slider::cancel(puObject *p_obj)
333 sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
334 sgVec3 *pvec = me -> getStashVec();
335 sgCopyVec3( vec, *pvec );
336 me->HS0->init(vec[2]);
337 me->HS1->init(vec[1]);
338 me->HS2->init(vec[0]);
340 FG_POP_PUI_DIALOG( me );
343 void sgVec3Slider::adjust(puObject *p_obj)
345 sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
346 me -> getHS0() -> adj((puObject *)me -> getHS0());
347 me -> getHS1() -> adj((puObject *)me -> getHS1());
348 me -> getHS2() -> adj((puObject *)me -> getHS2());
352 void sgVec3SliderAdjust( puObject *p_obj )
354 sgVec3Slider *me = (sgVec3Slider *)p_obj -> getUserData();
356 FG_PUSH_PUI_DIALOG( me );
359 // These are globals for now
360 static puObject *PO_vec = 0;
362 void PilotOffsetInit() {
365 fgGetFloat("/sim/view[1]/default/pilot-offset/heading-deg"),
366 fgGetFloat("/sim/view[1]/default/pilot-offset/pitch-deg"),
367 fgGetFloat("/sim/view[1]/default/pilot-offset/radius-m")
373 void PilotOffsetInit( sgVec3 vec )
375 // Only one of these things for now
377 /* make change so this gets done once for each vector */
378 fgSetFloat("/sim/view[1]/current/pilot-offset/heading-deg",fgGetFloat("/sim/view[1]/default/pilot-offset/heading-deg"));
379 fgSetFloat("/sim/view[1]/current/pilot-offset/pitch-deg",fgGetFloat("/sim/view[1]/default/pilot-offset/pitch-deg"));
380 fgSetFloat("/sim/view[1]/current/pilot-offset/radius-m",fgGetFloat("/sim/view[1]/default/pilot-offset/radius-m"));
381 sgVec3Slider *PO = new sgVec3Slider ( 200, 200, vec, "Pilot Offset" );
383 // Bindings for Pilot Offset
384 fgTie("/sim/view[1]/current/pilot-offset/heading-deg", getPilotOffsetHeadingDeg, setPilotOffsetHeadingDeg);
385 fgTie("/sim/view[1]/current/pilot-offset/pitch-deg", getPilotOffsetPitchDeg, setPilotOffsetPitchDeg);
386 fgTie("/sim/view[1]/current/pilot-offset/radius-m", getPilotOffsetRadiusM, setPilotOffsetRadiusM);
390 void PilotOffsetAdjust( puObject * )
395 sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
398 FG_PUSH_PUI_DIALOG( me );
401 // external to get pilot offset vector for viewer
402 sgVec3 *PilotOffsetGet()
407 sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
408 return( me -> getVec() );
411 // external function used to tie to FG properties
412 float PilotOffsetGetSetting(int opt)
418 sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
419 if( opt == 0 ) setting = me -> getHS0() -> get();
420 if( opt == 1 ) setting = me -> getHS1() -> get();
421 if( opt == 2 ) setting = me-> getHS2() -> get();
425 // external function used to tie to FG properties
426 void PilotOffsetSet(int opt, float setting)
431 sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
432 if( opt == 0 ) me -> getHS0() -> init( setting );
433 if( opt == 1 ) me -> getHS1() -> init( setting );
434 if( opt == 2 ) me-> getHS2() -> init( setting );
438 // Calculate vector of point on sphere:
439 // input Heading == longitude of point on sphere
440 // input Pitch == latitude of point on sphere
441 // input Radius == radius of sphere
443 #define MIN_VIEW_OFFSET 5.0
444 void Vec3FromHeadingPitchRadius ( sgVec3 vec3, float heading, float pitch,
447 double ch, sh, cp, sp;
449 if ( heading == SG_ZERO )
456 sh = sin( (double)( heading * SG_DEGREES_TO_RADIANS )) ;
457 ch = cos( (double)( heading * SG_DEGREES_TO_RADIANS )) ;
460 if ( pitch == SG_ZERO )
467 sp = sin( (double)( pitch * SG_DEGREES_TO_RADIANS )) ;
468 cp = cos( (double)( pitch * SG_DEGREES_TO_RADIANS )) ;
471 if ( radius < MIN_VIEW_OFFSET )
472 radius = MIN_VIEW_OFFSET ;
474 vec3[2] = (SGfloat)( ch * cp ) * radius ; // X
475 vec3[1] = (SGfloat)( sh * cp ) * radius ; // Y
476 vec3[0] = (SGfloat)( sp ) * radius ; // Z