]> git.mxchange.org Git - flightgear.git/blob - src/GUI/sgVec3Slider.cxx
Sync with latest JSBSim CVS
[flightgear.git] / src / GUI / sgVec3Slider.cxx
1 /**
2  *      sgVec3Slider.cxx
3  *
4  *      Simple PUI wrapper around sgVec3 class
5  *
6  *      Created by: Norman Vine [NHV]
7  *         nhv@yahoo.com, nhv@cape.com
8  *
9  *      Revision History
10  *      ---------------- 
11  *  Started 12:53 01/28/2001
12  *
13  */
14
15 #include "sgVec3Slider.hxx"
16 #include <simgear/sg_inlines.h>
17
18 class FloatSlider : public puSlider
19 {
20
21 protected:
22         float maxValue;
23         float origValue;
24         float Adjust;
25         float MyValue;
26         float TmpValue;
27         float SaveValue;
28         char buf[8];
29         char _title[32];
30         char _text[16];
31 public:
32         FloatSlider ( int x, int y, int sz, float f, const char *title,
33                                   float max = 90.0f );
34
35         ~FloatSlider () {;}
36                 
37         static void adj( puObject *);
38
39         void updateText() {
40                 sprintf( _text, "%05.2f", MyValue );
41         }
42
43         float get() { return( MyValue ); }
44         void  set() { MyValue = ((2.0*maxValue) * (TmpValue - 0.5f)) - maxValue; }
45
46         float *getTmp() { return( &TmpValue ); }
47         void   setTmp() { TmpValue += 0.5f; }
48
49         // double the range from -max <-> max
50         void init( float f ) {
51                 Adjust   = 0.5f / maxValue;
52                 setValue((f * Adjust) + 0.5f);
53                 adj( this );
54         }
55
56         void reinit() { init( origValue ); }
57         void cancel() { MyValue = TmpValue; }
58         void reset () { init( origValue ); }
59
60 };
61
62 void FloatSlider::adj( puObject *hs )
63 {
64         FloatSlider *slider = (FloatSlider *)hs->getUserData();
65         slider->getValue ( slider->getTmp() );
66         slider->setTmp();
67         slider->set();
68         slider->updateText();
69 }
70
71 FloatSlider::FloatSlider ( int x, int y, int sz, float f, const char *title,
72                                                    float max ) :  puSlider( x, y, sz, FALSE )
73 {
74         setUserData( this );
75         maxValue = max;
76         origValue = f;
77         init(f);
78         setDelta    ( 0.01 );
79         setCBMode   ( PUSLIDER_DELTA ) ;
80         setCallback ( adj ) ;
81         strcpy      ( _title, title);
82         setLabel    ( _title );
83         setLabelPlace ( PUPLACE_LEFT  );
84         setLegend(_text);
85         // setLegendPlace( PUPLACE_RIGHT );
86 }
87
88
89 /***********************************************/
90
91 class sgVec3Slider : public puDialogBox
92 {
93         static void goAway(puObject *p_obj);
94         static void reset(puObject *p_obj);
95         static void cancel(puObject *p_obj);
96
97 protected:
98         char Label[64];
99         FloatSlider *HS0;
100         FloatSlider *HS1;
101         FloatSlider *HS2;
102         puOneShot *OkButton;
103         puOneShot *ResetButton;
104         puOneShot *CancelButton;
105         sgVec3 Vec, SaveVec;
106         
107 public:
108
109         sgVec3Slider ( int x, int y, sgVec3 vec,
110                                    const char *title = "Vector Adjuster",
111                                    const char *Xtitle = "Heading",
112                                    const char *Ytitle = "Pitch",
113                                    const char *Ztitle = "Radius" );
114
115         ~sgVec3Slider () {;}
116
117         // ???
118         void setVec()
119         {
120                 Vec3FromHeadingPitchRadius( Vec,
121                                                                         (HS0->get() + 90) * 2,
122                                                                         HS1->get(),
123                                                                         HS2->get() );
124         }
125
126         sgVec3 *getVec() { setVec(); return &Vec; };
127
128         sgVec3 *getStashVec() { return &SaveVec; }
129         void stashVec() { 
130                 SaveVec[2] = HS0->get();
131                 SaveVec[1] = HS1->get();
132                 SaveVec[0] = HS2->get();
133         }
134
135         FloatSlider *getHS0() { return HS0; }
136         FloatSlider *getHS1() { return HS1; }
137         FloatSlider *getHS2() { return HS2; }
138
139         static void adjust(puObject *p_obj);
140 };
141
142 sgVec3Slider::sgVec3Slider ( int x, int y, sgVec3 vec, const char *title,
143                              const char *Xtitle,
144                              const char *Ytitle,
145                              const char *Ztitle ): puDialogBox ( x, y )
146 {
147         puFont LegendFont, LabelFont;
148         puGetDefaultFonts ( &LegendFont, &LabelFont );
149
150         int fudge = 20;
151
152         int labelW = LabelFont.getStringWidth(Xtitle);
153         labelW = SG_MAX2( labelW, LabelFont.getStringWidth(Ytitle));
154         labelW = SG_MAX2( labelW, LabelFont.getStringWidth(Ztitle));
155                 
156         int DialogWidth = 300 + fudge + labelW;
157
158         sgCopyVec3(SaveVec, vec);
159         sgCopyVec3(Vec, vec);
160         strcpy( Label, title );
161
162         int nSliders = 3;
163         int slider_x = 70+fudge;
164         int slider_y = 55;
165         int slider_width = 240;
166
167         int horiz_slider_height = LabelFont.getStringHeight()
168             + LabelFont.getStringDescender()
169             + PUSTR_TGAP + PUSTR_BGAP + 5;
170
171         // HACKS
172         setUserData( this );
173         horiz_slider_height += 10;
174
175         new puFrame ( 0, 0,
176                                   DialogWidth,
177                                   85 + nSliders * horiz_slider_height );
178
179         setLabelPlace( PUPLACE_DEFAULT /*PUPLACE_CENTERED*/ );
180         setLabel( Label );
181
182         HS2 = new FloatSlider (  slider_x, slider_y, slider_width, vec[2], Ztitle );
183         slider_y += horiz_slider_height;
184
185         HS1 = new FloatSlider (  slider_x, slider_y, slider_width, vec[1], Ytitle );
186         slider_y += horiz_slider_height;
187
188         HS0 = new FloatSlider (  slider_x, slider_y, slider_width, vec[0], Xtitle );
189
190         OkButton = new puOneShot ( 70+fudge, 10, 120+fudge, 50 );
191         OkButton-> setUserData( this );
192         OkButton-> setLegend ( gui_msg_OK );
193         OkButton-> makeReturnDefault ( TRUE );
194         OkButton-> setCallback ( goAway );
195
196         CancelButton = new puOneShot ( 130+fudge, 10, 210+fudge, 50 );
197         CancelButton-> setUserData( this );
198         CancelButton-> setLegend ( gui_msg_CANCEL );
199         CancelButton-> setCallback ( cancel );
200
201         ResetButton = new puOneShot ( 220+fudge, 10, 280+fudge, 50 );
202         ResetButton-> setUserData( this );
203         ResetButton-> setLegend ( gui_msg_RESET );
204         ResetButton-> setCallback ( reset );
205
206         FG_FINALIZE_PUI_DIALOG( this );
207 }
208
209
210 void sgVec3Slider::goAway(puObject *p_obj)
211 {
212         sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
213         FG_POP_PUI_DIALOG( me );
214 };
215
216 void sgVec3Slider::reset(puObject *p_obj)
217 {
218         sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
219         me->HS0->reinit();
220         me->HS1->reinit();
221         me->HS2->reinit();
222 };
223
224 void sgVec3Slider::cancel(puObject *p_obj)
225 {
226         sgVec3 vec;
227         sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
228         sgVec3 *pvec = me -> getStashVec();
229         sgCopyVec3( vec, *pvec );
230         me->HS0->init(vec[2]);
231         me->HS1->init(vec[1]);
232         me->HS2->init(vec[0]);
233         me->setVec();
234         FG_POP_PUI_DIALOG( me );
235 };
236
237 void sgVec3Slider::adjust(puObject *p_obj)
238 {
239         sgVec3Slider *me = (sgVec3Slider *)p_obj->getUserData();
240         me -> getHS0() -> adj((puObject *)me -> getHS0());
241         me -> getHS1() -> adj((puObject *)me -> getHS1());
242         me -> getHS2() -> adj((puObject *)me -> getHS2());
243         me -> setVec();
244 };
245
246 void sgVec3SliderAdjust( puObject *p_obj )
247 {
248         sgVec3Slider *me = (sgVec3Slider *)p_obj -> getUserData();
249         me -> adjust( me );
250         FG_PUSH_PUI_DIALOG( me );
251 }
252
253 // These are globals for now
254 static puObject *PO_vec = 0;
255
256 void PilotOffsetInit() {
257         sgVec3 v;
258         sgSetVec3(v,0.0,0.0,20.0);
259         PilotOffsetInit(v);
260 }
261
262 void PilotOffsetInit( sgVec3 vec )
263 {
264         // Only one of these things for now
265         if( PO_vec == 0 ) {
266                 sgVec3Slider *PO = new sgVec3Slider ( 200, 200, vec, "Pilot Offset" );
267                 PO_vec = PO;
268         }
269 }
270
271 void PilotOffsetAdjust( puObject * )
272 {
273         if( PO_vec == 0 ) {
274                 PilotOffsetInit();
275         }
276         sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
277         me -> stashVec();
278         me -> adjust( me );
279         FG_PUSH_PUI_DIALOG( me );
280 }
281
282 sgVec3 *PilotOffsetGet()
283 {
284         if( PO_vec == 0 ) {
285                 PilotOffsetInit();
286         }
287         sgVec3Slider *me = (sgVec3Slider *)PO_vec -> getUserData();
288         return( me -> getVec() );
289 }
290
291
292 // Heading == longitude of point on sphere
293 // Pitch      == latitude of point on sphere
294 // Radius  == radius of sphere
295
296 #define MIN_VIEW_OFFSET 5.0
297 void Vec3FromHeadingPitchRadius ( sgVec3 vec3, float heading, float pitch,
298 float radius )
299 {
300   double ch, sh, cp, sp;
301
302   if ( heading == SG_ZERO )
303   {
304     ch = SGD_ONE ;
305     sh = SGD_ZERO ;
306   }
307   else
308   {
309     sh = sin( (double)( heading * SG_DEGREES_TO_RADIANS )) ;
310     ch = cos( (double)( heading * SG_DEGREES_TO_RADIANS )) ;
311   }
312
313   if ( pitch == SG_ZERO )
314   {
315     cp = SGD_ONE ;
316     sp = SGD_ZERO ;
317   }
318   else
319   {
320     sp = sin( (double)( pitch * SG_DEGREES_TO_RADIANS )) ;
321     cp = cos( (double)( pitch * SG_DEGREES_TO_RADIANS )) ;
322   }
323
324   if ( radius < MIN_VIEW_OFFSET )
325           radius = MIN_VIEW_OFFSET ;
326
327   vec3[2] = (SGfloat)( ch * cp ) * radius ; // X
328   vec3[1] = (SGfloat)( sh * cp ) * radius ; // Y
329   vec3[0] = (SGfloat)(  sp ) * radius ; // Z
330 }