*/
#include "sgVec3Slider.hxx"
+#include <Main/fg_props.hxx>
#include <simgear/sg_inlines.h>
class FloatSlider : public puSlider
protected:
float maxValue;
+ float minValue;
float origValue;
float Adjust;
float MyValue;
char _text[16];
public:
FloatSlider ( int x, int y, int sz, float f, const char *title,
- float max = 90.0f );
+ float max = 100.0f, float min = 0.0f);
~FloatSlider () {;}
}
float get() { return( MyValue ); }
- void set() { MyValue = ((2.0*maxValue) * (TmpValue - 0.5f)) - maxValue; }
+
+ // calc actual "setting" by multiplying the pui fraction by highest value setable
+ void set() { MyValue = maxValue * TmpValue; }
float *getTmp() { return( &TmpValue ); }
- void setTmp() { TmpValue += 0.5f; }
- // double the range from -max <-> max
+ // adjust the TmpValue back to 0 to 1 range of pui widget
+ void setTmp() { TmpValue += 0.0f; }
+
+ // adjust actual "setting" value back to fraction for pui widget
void init( float f ) {
- Adjust = 0.5f / maxValue;
- setValue((f * Adjust) + 0.5f);
+ if (f > maxValue) f = maxValue;
+ if (f < minValue) f = minValue;
+ Adjust = 1.0f / maxValue;
+ setValue(f * Adjust);
adj( this );
}
}
FloatSlider::FloatSlider ( int x, int y, int sz, float f, const char *title,
- float max ) : puSlider( x, y, sz, FALSE )
+ float max, float min ) : puSlider( x, y, sz, FALSE )
+{
+ setUserData( this );
+ maxValue = max;
+ minValue = min;
+ origValue = f;
+ init(f);
+ setDelta ( 0.01 );
+ setCBMode ( PUSLIDER_DELTA ) ;
+ setCallback ( adj ) ;
+ strcpy ( _title, title);
+ setLabel ( _title );
+ setLabelPlace ( PUPLACE_LEFT );
+ setLegend(_text);
+ // setLegendPlace( PUPLACE_RIGHT );
+}
+
+
+class FloatDial : public puDial
+{
+
+protected:
+ float maxValue;
+ float minValue;
+ float origValue;
+ float Adjust;
+ float MyValue;
+ float TmpValue;
+ float SaveValue;
+ char buf[8];
+ char _title[32];
+ char _text[16];
+public:
+ FloatDial ( int x, int y, int sz, float f, const char *title,
+ float max = 180.0f, float min = -180.0f );
+
+ ~FloatDial () {;}
+
+ static void adj( puObject *);
+
+ void updateText() {
+ sprintf( _text, "%05.2f", MyValue );
+ }
+
+ float get() { return( MyValue ); }
+
+ // calc actual "setting" by multiplying the pui fraction by highest value setable
+ // in this case we're also turning a 0 to 1 range into a -.05 to +.05 before converting
+ void set() { MyValue = ((2.0*maxValue) * (TmpValue - 0.5f)) - maxValue; }
+
+ float *getTmp() { return( &TmpValue ); }
+
+ // adjust the TmpValue back to 0 to 1 range of pui widget
+ void setTmp() { TmpValue += 0.5f; }
+
+ // adjust actual "setting" value back to fraction for pui widget
+ // double the range from -max <-> max
+ void init( float f ) {
+ if (f > maxValue) f = maxValue;
+ if (f < minValue) f = minValue;
+ Adjust = 0.5f / maxValue;
+ setValue((f * Adjust) + 0.5f);
+ adj( this );
+ }
+
+ void reinit() { init( origValue ); }
+ void cancel() { MyValue = TmpValue; }
+ void reset () { init( origValue ); }
+
+};
+
+void FloatDial::adj( puObject *hs )
+{
+ FloatDial *dial = (FloatDial *)hs->getUserData();
+ dial->getValue ( dial->getTmp() );
+ dial->setTmp();
+ dial->set();
+ dial->updateText();
+}
+
+FloatDial::FloatDial ( int x, int y, int sz, float f, const char *title,
+ float max, float min ) : puDial( x, y, sz )
{
setUserData( this );
maxValue = max;
+ minValue = min;
origValue = f;
init(f);
setDelta ( 0.01 );
protected:
char Label[64];
- FloatSlider *HS0;
- FloatSlider *HS1;
+ FloatDial *HS0;
+ FloatDial *HS1;
FloatSlider *HS2;
+ puText *TitleText;
puOneShot *OkButton;
puOneShot *ResetButton;
puOneShot *CancelButton;
~sgVec3Slider () {;}
- // ???
+ // calc the property Vec with the actual point on sphere
void setVec()
{
Vec3FromHeadingPitchRadius( Vec,
- (HS0->get() + 90) * 2,
- HS1->get(),
- HS2->get() );
+ HS0->get(),
+ HS1->get(),
+ HS2->get());
}
- sgVec3 *getVec() { setVec(); return &Vec; };
+ // return the offset vector according to current widget values
+ sgVec3 *getVec()
+ {
+ setVec();
+ return &Vec;
+ };
+ // save the Vector before pushing dialog (for cancel button)
sgVec3 *getStashVec() { return &SaveVec; }
void stashVec() {
SaveVec[2] = HS0->get();
SaveVec[0] = HS2->get();
}
- FloatSlider *getHS0() { return HS0; }
- FloatSlider *getHS1() { return HS1; }
+ // functions to return pointers to protected pui widget instances
+ FloatDial *getHS0() { return HS0; }
+ FloatDial *getHS1() { return HS1; }
FloatSlider *getHS2() { return HS2; }
static void adjust(puObject *p_obj);
};
+// class constructor
sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 vec, const char *title,
const char *Xtitle,
const char *Ytitle,
labelW = SG_MAX2( labelW, LabelFont.getStringWidth(Ytitle));
labelW = SG_MAX2( labelW, LabelFont.getStringWidth(Ztitle));
- int DialogWidth = 300 + fudge + labelW;
sgCopyVec3(SaveVec, vec);
sgCopyVec3(Vec, vec);
int nSliders = 3;
int slider_x = 70+fudge;
- int slider_y = 55;
- int slider_width = 240;
+ int slider_y = 75;
+ int slider_width = 270;
+ int dialer_x = 70+fudge;
+ int dialer_y = 115;
+ int dialer_size = 100;
int horiz_slider_height = LabelFont.getStringHeight()
+ LabelFont.getStringDescender()
+ PUSTR_TGAP + PUSTR_BGAP + 5;
+ int DialogWidth = slider_width + 20 + fudge + labelW;
+ int DialogHeight = dialer_size + 115 + nSliders * horiz_slider_height;
+
// HACKS
setUserData( this );
horiz_slider_height += 10;
- new puFrame ( 0, 0,
- DialogWidth,
- 85 + nSliders * horiz_slider_height );
+ new puFrame ( 0, 0, DialogWidth, DialogHeight );
setLabelPlace( PUPLACE_DEFAULT /*PUPLACE_CENTERED*/ );
setLabel( Label );
- HS2 = new FloatSlider ( slider_x, slider_y, slider_width, vec[2], Ztitle );
- slider_y += horiz_slider_height;
+ /* heading */
+ HS0 = new FloatDial ( dialer_x, dialer_y, dialer_size, vec[0], Xtitle, 180.0f, -180.0f );
+ dialer_x = dialer_x + 170;
+
+ /* pitch */
+ HS1 = new FloatDial ( dialer_x, dialer_y, dialer_size, vec[1], Ytitle, 89.99f, -89.99f );
- HS1 = new FloatSlider ( slider_x, slider_y, slider_width, vec[1], Ytitle );
- slider_y += horiz_slider_height;
+ /* radius */
+ HS2 = new FloatSlider ( slider_x, slider_y, slider_width, vec[2], Ztitle, 100.0f, 0.0f );
- HS0 = new FloatSlider ( slider_x, slider_y, slider_width, vec[0], Xtitle );
+ TitleText = new puText( 130, DialogHeight - 40);
+ TitleText->setLabel("Pilot Offset");
- OkButton = new puOneShot ( 70+fudge, 10, 120+fudge, 50 );
+ OkButton = new puOneShot ( 70+fudge, 20, 120+fudge, 50 );
OkButton-> setUserData( this );
OkButton-> setLegend ( gui_msg_OK );
OkButton-> makeReturnDefault ( TRUE );
OkButton-> setCallback ( goAway );
- CancelButton = new puOneShot ( 130+fudge, 10, 210+fudge, 50 );
+ CancelButton = new puOneShot ( 130+fudge, 20, 210+fudge, 50 );
CancelButton-> setUserData( this );
CancelButton-> setLegend ( gui_msg_CANCEL );
CancelButton-> setCallback ( cancel );
- ResetButton = new puOneShot ( 220+fudge, 10, 280+fudge, 50 );
+ ResetButton = new puOneShot ( 220+fudge, 20, 280+fudge, 50 );
ResetButton-> setUserData( this );
ResetButton-> setLegend ( gui_msg_RESET );
ResetButton-> setCallback ( reset );
FG_FINALIZE_PUI_DIALOG( this );
}
-
void sgVec3Slider::goAway(puObject *p_obj)
{
sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
void PilotOffsetInit() {
sgVec3 v;
- sgSetVec3(v,0.0,0.0,20.0);
+ sgSetVec3(v,
+ fgGetFloat("/sim/view[1]/default/pilot-offset/heading-deg"),
+ fgGetFloat("/sim/view[1]/default/pilot-offset/pitch-deg"),
+ fgGetFloat("/sim/view[1]/default/pilot-offset/radius-m")
+ );
+
PilotOffsetInit(v);
}
{
// Only one of these things for now
if( PO_vec == 0 ) {
- sgVec3Slider *PO = new sgVec3Slider ( 200, 200, vec, "Pilot Offset" );
+ /* make change so this gets done once for each vector */
+ fgSetFloat("/sim/view[1]/current/pilot-offset/heading-deg",fgGetFloat("/sim/view[1]/default/pilot-offset/heading-deg"));
+ fgSetFloat("/sim/view[1]/current/pilot-offset/pitch-deg",fgGetFloat("/sim/view[1]/default/pilot-offset/pitch-deg"));
+ fgSetFloat("/sim/view[1]/current/pilot-offset/radius-m",fgGetFloat("/sim/view[1]/default/pilot-offset/radius-m"));
+ sgVec3Slider *PO = new sgVec3Slider ( 200, 200, vec, "Pilot Offset" );
PO_vec = PO;
+ // Bindings for Pilot Offset
+ fgTie("/sim/view[1]/current/pilot-offset/heading-deg", getPilotOffsetHeadingDeg, setPilotOffsetHeadingDeg);
+ fgTie("/sim/view[1]/current/pilot-offset/pitch-deg", getPilotOffsetPitchDeg, setPilotOffsetPitchDeg);
+ fgTie("/sim/view[1]/current/pilot-offset/radius-m", getPilotOffsetRadiusM, setPilotOffsetRadiusM);
}
}
FG_PUSH_PUI_DIALOG( me );
}
+// external to get pilot offset vector for viewer
sgVec3 *PilotOffsetGet()
{
if( PO_vec == 0 ) {
return( me -> getVec() );
}
+// external function used to tie to FG properties
+float PilotOffsetGetSetting(int opt)
+{
+ float setting;
+ if( PO_vec == 0 ) {
+ PilotOffsetInit();
+ }
+ sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
+ if( opt == 0 ) setting = me -> getHS0() -> get();
+ if( opt == 1 ) setting = me -> getHS1() -> get();
+ if( opt == 2 ) setting = me-> getHS2() -> get();
+ return( setting );
+}
+
+// external function used to tie to FG properties
+void PilotOffsetSet(int opt, float setting)
+{
+ if( PO_vec == 0 ) {
+ PilotOffsetInit();
+ }
+ sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
+ if( opt == 0 ) me -> getHS0() -> init( setting );
+ if( opt == 1 ) me -> getHS1() -> init( setting );
+ if( opt == 2 ) me-> getHS2() -> init( setting );
+}
+
-// Heading == longitude of point on sphere
-// Pitch == latitude of point on sphere
-// Radius == radius of sphere
+// Calculate vector of point on sphere:
+// input Heading == longitude of point on sphere
+// input Pitch == latitude of point on sphere
+// input Radius == radius of sphere
#define MIN_VIEW_OFFSET 5.0
void Vec3FromHeadingPitchRadius ( sgVec3 vec3, float heading, float pitch,