]> git.mxchange.org Git - flightgear.git/blob - src/Autopilot/auto_gui.cxx
Patch from Julian Foad:
[flightgear.git] / src / Autopilot / auto_gui.cxx
1 // auto_gui.cxx -- autopilot gui interface
2 //
3 // Written by Norman Vine <nhv@cape.com>
4 // Arranged by Curt Olson <curt@flightgear.org>
5 //
6 // Copyright (C) 1998 - 2000
7 //
8 // This program is free software; you can redistribute it and/or
9 // modify it under the terms of the GNU General Public License as
10 // published by the Free Software Foundation; either version 2 of the
11 // License, or (at your option) any later version.
12 //
13 // This program is distributed in the hope that it will be useful, but
14 // WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16 // General Public License for more details.
17 //
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the Free Software
20 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 //
22 // $Id$
23
24
25 #ifdef HAVE_CONFIG_H
26 #  include <config.h>
27 #endif
28
29 #include <simgear/compiler.h>
30
31 #include <simgear/route/route.hxx>
32
33 #include <assert.h>
34 #include <stdlib.h>
35 #include <string.h>
36
37 #include STL_STRING
38
39 #include <Aircraft/aircraft.hxx>
40 #include <FDM/flight.hxx>
41 #include <Controls/controls.hxx>
42 #include <Scenery/scenery.hxx>
43
44 #include <simgear/constants.h>
45 #include <simgear/sg_inlines.h>
46 #include <simgear/debug/logstream.hxx>
47 #include <simgear/math/sg_geodesy.hxx>
48 #include <simgear/misc/sg_path.hxx>
49
50 #include <Airports/simple.hxx>
51 #include <GUI/gui.h>
52 #include <Main/fg_init.hxx>
53 #include <Main/globals.hxx>
54 #include <Main/fg_props.hxx>
55 #include <Navaids/fixlist.hxx>
56
57 #include "auto_gui.hxx"
58 #include "newauto.hxx"
59
60 SG_USING_STD(string);
61
62
63 #define mySlider puSlider
64
65 // Climb speed constants
66 const double min_climb = 70.0;  // kts
67 const double best_climb = 75.0; // kts
68 const double ideal_climb_rate = 500.0; // fpm
69
70 /// These statics will eventually go into the class
71 /// they are just here while I am experimenting -- NHV :-)
72 // AutoPilot Gain Adjuster members
73 static double MaxRollAdjust;        // MaxRollAdjust       = 2 * APData->MaxRoll;
74 static double RollOutAdjust;        // RollOutAdjust       = 2 * APData->RollOut;
75 static double MaxAileronAdjust;     // MaxAileronAdjust    = 2 * APData->MaxAileron;
76 static double RollOutSmoothAdjust;  // RollOutSmoothAdjust = 2 * APData->RollOutSmooth;
77
78 static float MaxRollValue;          // 0.1 -> 1.0
79 static float RollOutValue;
80 static float MaxAileronValue;
81 static float RollOutSmoothValue;
82
83 static float TmpMaxRollValue;       // for cancel operation
84 static float TmpRollOutValue;
85 static float TmpMaxAileronValue;
86 static float TmpRollOutSmoothValue;
87
88 static puDialogBox *APAdjustDialog;
89 static puFrame     *APAdjustFrame;
90 static puText      *APAdjustDialogMessage;
91 static puFont      APAdjustLegendFont;
92 static puFont      APAdjustLabelFont;
93
94 static puOneShot *APAdjustOkButton;
95 static puOneShot *APAdjustResetButton;
96 static puOneShot *APAdjustCancelButton;
97
98 //static puButton        *APAdjustDragButton;
99
100 static puText *APAdjustMaxRollTitle;
101 static puText *APAdjustRollOutTitle;
102 static puText *APAdjustMaxAileronTitle;
103 static puText *APAdjustRollOutSmoothTitle;
104
105 static puText *APAdjustMaxAileronText;
106 static puText *APAdjustMaxRollText;
107 static puText *APAdjustRollOutText;
108 static puText *APAdjustRollOutSmoothText;
109
110 static mySlider *APAdjustHS0;
111 static mySlider *APAdjustHS1;
112 static mySlider *APAdjustHS2;
113 static mySlider *APAdjustHS3;
114
115 static char SliderText[ 4 ][ 8 ];
116
117 ///////// AutoPilot New Heading Dialog
118
119 static puDialogBox     *ApHeadingDialog;
120 static puFrame         *ApHeadingDialogFrame;
121 static puText          *ApHeadingDialogMessage;
122 static puInput         *ApHeadingDialogInput;
123 static puOneShot       *ApHeadingDialogOkButton;
124 static puOneShot       *ApHeadingDialogCancelButton;
125
126
127 ///////// AutoPilot New Altitude Dialog
128
129 static puDialogBox     *ApAltitudeDialog = 0;
130 static puFrame         *ApAltitudeDialogFrame = 0;
131 static puText          *ApAltitudeDialogMessage = 0;
132 static puInput         *ApAltitudeDialogInput = 0;
133
134 static puOneShot       *ApAltitudeDialogOkButton = 0;
135 static puOneShot       *ApAltitudeDialogCancelButton = 0;
136
137
138 /// The beginnings of Lock AutoPilot to target location :-)
139 //  Needs cleaning up but works
140 //  These statics should disapear when this is a class
141 static puDialogBox     *TgtAptDialog = 0;
142 static puFrame         *TgtAptDialogFrame = 0;
143 static puText          *TgtAptDialogMessage = 0;
144 static puInput         *TgtAptDialogInput = 0;
145 static puListBox       *TgtAptDialogWPList = 0;
146 static puSlider        *TgtAptDialogSlider = 0;
147 static puArrowButton   *TgtAptDialogUPArrow = 0;
148 static puArrowButton   *TgtAptDialogDNArrow = 0;
149 static char**          WPList;
150 static int             WPListsize;
151
152 static char NewTgtAirportId[16];
153 static char NewTgtAirportLabel[] = "New Apt/Fix ID";
154
155 static puOneShot       *TgtAptDialogOkButton = 0;
156 static puOneShot       *TgtAptDialogCancelButton = 0;
157 static puOneShot       *TgtAptDialogResetButton = 0;
158
159
160 // extern char *coord_format_lat(float);
161 // extern char *coord_format_lon(float);
162
163 // THIS NEEDS IMPROVEMENT !!!!!!!!!!!!!
164 static int scan_number(char *s, double *new_value)
165 {
166     int ret = 0;
167     char WordBuf[64];
168     char *cptr = s;
169     char *WordBufPtr = WordBuf;
170     if (*cptr == '+')
171         cptr++;
172     if (*cptr == '-') {
173         *WordBufPtr++ = *cptr++;
174     }
175     while (isdigit(*cptr) ) {
176         *WordBufPtr++ = *cptr++;
177         ret = 1;
178     }
179     if (*cptr == '.') 
180         *WordBufPtr++ = *cptr++;  // put the '.' into the string
181     while (isdigit(*cptr)) {
182         *WordBufPtr++ = *cptr++;
183         ret = 1;
184     }
185     if( ret == 1 ) {
186         *WordBufPtr = '\0';
187         sscanf(WordBuf, "%lf", new_value);
188     }
189
190     return(ret);
191 } // scan_number
192
193
194 void ApHeadingDialog_Cancel(puObject *)
195 {
196     ApHeadingDialogInput->rejectInput();
197     FG_POP_PUI_DIALOG( ApHeadingDialog );
198 }
199
200 void ApHeadingDialog_OK (puObject *me)
201 {
202     int error = 0;
203     char *c;
204     string s;
205     ApHeadingDialogInput -> getValue( &c );
206
207     if( strlen(c) ) {
208         double NewHeading;
209         if( scan_number( c, &NewHeading ) )
210             {
211                 if ( !globals->get_autopilot()->get_HeadingEnabled() ) {
212                     globals->get_autopilot()->set_HeadingEnabled( true );
213                 }
214                 globals->get_autopilot()->HeadingSet( NewHeading );
215             } else {
216                 error = 1;
217                 s = c;
218                 s += " is not a valid number.";
219             }
220     }
221     ApHeadingDialog_Cancel(me);
222     if( error )  mkDialog(s.c_str());
223 }
224
225 void NewHeading(puObject *cb)
226 {
227     //  string ApHeadingLabel( "Enter New Heading" );
228     //  ApHeadingDialogMessage  -> setLabel(ApHeadingLabel.c_str());
229     float heading = globals->get_autopilot()->get_DGTargetHeading();
230     while ( heading < 0.0 ) { heading += 360.0; }
231     ApHeadingDialogInput   ->    setValue ( heading );
232     ApHeadingDialogInput    -> acceptInput();
233     FG_PUSH_PUI_DIALOG( ApHeadingDialog );
234 }
235
236 void NewHeadingInit()
237 {
238     //  printf("NewHeadingInit\n");
239     char NewHeadingLabel[] = "Enter New Heading";
240     char *s;
241
242     float heading = fgGetDouble("/orientation/heading-deg");
243     int len = 260/2 -
244         (puGetDefaultLabelFont().getStringWidth( NewHeadingLabel ) / 2 );
245
246     ApHeadingDialog = new puDialogBox (150, 50);
247     {
248         ApHeadingDialogFrame   = new puFrame (0, 0, 260, 150);
249
250         ApHeadingDialogMessage = new puText   (len, 110);
251         ApHeadingDialogMessage    -> setDefaultValue (NewHeadingLabel);
252         ApHeadingDialogMessage    -> getDefaultValue (&s);
253         ApHeadingDialogMessage    -> setLabel        (s);
254
255         ApHeadingDialogInput   = new puInput  ( 50, 70, 210, 100 );
256         ApHeadingDialogInput   ->    setValue ( heading );
257
258         ApHeadingDialogOkButton     =  new puOneShot         (50, 10, 110, 50);
259         ApHeadingDialogOkButton     ->     setLegend         (gui_msg_OK);
260         ApHeadingDialogOkButton     ->     makeReturnDefault (TRUE);
261         ApHeadingDialogOkButton     ->     setCallback       (ApHeadingDialog_OK);
262
263         ApHeadingDialogCancelButton =  new puOneShot         (140, 10, 210, 50);
264         ApHeadingDialogCancelButton ->     setLegend         (gui_msg_CANCEL);
265         ApHeadingDialogCancelButton ->     setCallback       (ApHeadingDialog_Cancel);
266
267     }
268     FG_FINALIZE_PUI_DIALOG( ApHeadingDialog );
269 }
270
271 void ApAltitudeDialog_Cancel(puObject *)
272 {
273     ApAltitudeDialogInput -> rejectInput();
274     FG_POP_PUI_DIALOG( ApAltitudeDialog );
275 }
276
277 void ApAltitudeDialog_OK (puObject *me)
278 {
279     int error = 0;
280     string s;
281     char *c;
282     ApAltitudeDialogInput->getValue( &c );
283
284     if( strlen( c ) ) {
285         double NewAltitude;
286         if( scan_number( c, &NewAltitude) )
287             {
288                 if ( !globals->get_autopilot()->get_AltitudeEnabled() ) {
289                     globals->get_autopilot()->set_AltitudeEnabled( true );
290                 }
291                 globals->get_autopilot()->AltitudeSet( NewAltitude );
292             } else {
293                 error = 1;
294                 s = c;
295                 s += " is not a valid number.";
296             }
297     }
298     ApAltitudeDialog_Cancel(me);
299     if( error )  mkDialog(s.c_str());
300 }
301
302 void NewAltitude(puObject *cb)
303 {
304     float altitude = globals->get_autopilot()->get_TargetAltitude() * SG_METER_TO_FEET;
305     ApAltitudeDialogInput -> setValue( altitude );
306     ApAltitudeDialogInput -> acceptInput();
307     FG_PUSH_PUI_DIALOG( ApAltitudeDialog );
308 }
309
310 void NewAltitudeInit()
311 {
312     //  printf("NewAltitudeInit\n");
313     char NewAltitudeLabel[] = "Enter New Altitude";
314     char *s;
315
316     float alt = cur_fdm_state->get_Altitude();
317
318     if ( !strcmp(fgGetString("/sim/startup/units"), "meters")) {
319         alt *= SG_FEET_TO_METER;
320     }
321
322     int len = 260/2 -
323         (puGetDefaultLabelFont().getStringWidth( NewAltitudeLabel ) / 2);
324
325     //  ApAltitudeDialog = new puDialogBox (150, 50);
326     ApAltitudeDialog = new puDialogBox (150, 200);
327     {
328         ApAltitudeDialogFrame   = new puFrame  (0, 0, 260, 150);
329         ApAltitudeDialogMessage = new puText   (len, 110);
330         ApAltitudeDialogMessage    -> setDefaultValue (NewAltitudeLabel);
331         ApAltitudeDialogMessage    -> getDefaultValue (&s);
332         ApAltitudeDialogMessage    -> setLabel (s);
333
334         ApAltitudeDialogInput   = new puInput  ( 50, 70, 210, 100 );
335         ApAltitudeDialogInput      -> setValue ( alt );
336         // Uncomment the next line to have input active on startup
337         // ApAltitudeDialogInput   ->    acceptInput       ( );
338         // cursor at begining or end of line ?
339         //len = strlen(s);
340         //              len = 0;
341         //              ApAltitudeDialogInput   ->    setCursor         ( len );
342         //              ApAltitudeDialogInput   ->    setSelectRegion   ( 5, 9 );
343
344         ApAltitudeDialogOkButton     =  new puOneShot         (50, 10, 110, 50);
345         ApAltitudeDialogOkButton     ->     setLegend         (gui_msg_OK);
346         ApAltitudeDialogOkButton     ->     makeReturnDefault (TRUE);
347         ApAltitudeDialogOkButton     ->     setCallback       (ApAltitudeDialog_OK);
348
349         ApAltitudeDialogCancelButton =  new puOneShot         (140, 10, 210, 50);
350         ApAltitudeDialogCancelButton ->     setLegend         (gui_msg_CANCEL);
351         ApAltitudeDialogCancelButton ->     setCallback       (ApAltitudeDialog_Cancel);
352
353     }
354     FG_FINALIZE_PUI_DIALOG( ApAltitudeDialog );
355 }
356
357
358 static void maxroll_adj( puObject *hs ) {
359     float val ;
360     
361     hs-> getValue ( &val ) ;
362     SG_CLAMP_RANGE ( val, 0.1f, 1.0f ) ;
363     //    printf ( "maxroll_adj( %p ) %f %f\n", hs, val, MaxRollAdjust * val ) ;
364     globals->get_autopilot()->set_MaxRoll( MaxRollAdjust * val );
365     sprintf( SliderText[ 0 ], "%05.2f", globals->get_autopilot()->get_MaxRoll() );
366     APAdjustMaxRollText -> setLabel ( SliderText[ 0 ] ) ;
367 }
368
369 static void rollout_adj( puObject *hs ) {
370     float val ;
371
372     hs-> getValue ( &val ) ;
373     SG_CLAMP_RANGE ( val, 0.1f, 1.0f ) ;
374     //    printf ( "rollout_adj( %p ) %f %f\n", hs, val, RollOutAdjust * val ) ;
375     globals->get_autopilot()->set_RollOut( RollOutAdjust * val );
376     sprintf( SliderText[ 1 ], "%05.2f", globals->get_autopilot()->get_RollOut() );
377     APAdjustRollOutText -> setLabel ( SliderText[ 1 ] );
378 }
379
380 static void maxaileron_adj( puObject *hs ) {
381     float val ;
382
383     hs-> getValue ( &val ) ;
384     SG_CLAMP_RANGE ( val, 0.1f, 1.0f ) ;
385     //    printf ( "maxaileron_adj( %p ) %f %f\n", hs, val, MaxAileronAdjust * val ) ;
386     globals->get_autopilot()->set_MaxAileron( MaxAileronAdjust * val );
387     sprintf( SliderText[ 3 ], "%05.2f", globals->get_autopilot()->get_MaxAileron() );
388     APAdjustMaxAileronText -> setLabel ( SliderText[ 3 ] );
389 }
390
391 static void rolloutsmooth_adj( puObject *hs ) {
392     float val ;
393
394     hs -> getValue ( &val ) ;
395     SG_CLAMP_RANGE ( val, 0.1f, 1.0f ) ;
396     //    printf ( "rolloutsmooth_adj( %p ) %f %f\n", hs, val, RollOutSmoothAdjust * val ) ;
397     globals->get_autopilot()->set_RollOutSmooth( RollOutSmoothAdjust * val );
398     sprintf( SliderText[ 2 ], "%5.2f", globals->get_autopilot()->get_RollOutSmooth() );
399     APAdjustRollOutSmoothText-> setLabel ( SliderText[ 2 ] );
400
401 }
402
403 static void goAwayAPAdjust (puObject *)
404 {
405     FG_POP_PUI_DIALOG( APAdjustDialog );
406 }
407
408 void cancelAPAdjust( puObject *self ) {
409     globals->get_autopilot()->set_MaxRoll( TmpMaxRollValue );
410     globals->get_autopilot()->set_RollOut( TmpRollOutValue );
411     globals->get_autopilot()->set_MaxAileron( TmpMaxAileronValue );
412     globals->get_autopilot()->set_RollOutSmooth( TmpRollOutSmoothValue );
413
414     goAwayAPAdjust(self);
415 }
416
417 void resetAPAdjust( puObject *self ) {
418     globals->get_autopilot()->set_MaxRoll( MaxRollAdjust / 2 );
419     globals->get_autopilot()->set_RollOut( RollOutAdjust / 2 );
420     globals->get_autopilot()->set_MaxAileron( MaxAileronAdjust / 2 );
421     globals->get_autopilot()->set_RollOutSmooth( RollOutSmoothAdjust / 2 );
422
423     FG_POP_PUI_DIALOG( APAdjustDialog );
424
425     fgAPAdjust( self );
426 }
427
428 void fgAPAdjust( puObject *self ) {
429     TmpMaxRollValue       = globals->get_autopilot()->get_MaxRoll();
430     TmpRollOutValue       = globals->get_autopilot()->get_RollOut();
431     TmpMaxAileronValue    = globals->get_autopilot()->get_MaxAileron();
432     TmpRollOutSmoothValue = globals->get_autopilot()->get_RollOutSmooth();
433
434     MaxRollValue       = globals->get_autopilot()->get_MaxRoll() / MaxRollAdjust;
435     RollOutValue       = globals->get_autopilot()->get_RollOut() / RollOutAdjust;
436     MaxAileronValue    = globals->get_autopilot()->get_MaxAileron() / MaxAileronAdjust;
437     RollOutSmoothValue = globals->get_autopilot()->get_RollOutSmooth()
438         / RollOutSmoothAdjust;
439
440     APAdjustHS0-> setValue ( MaxRollValue ) ;
441     APAdjustHS1-> setValue ( RollOutValue ) ;
442     APAdjustHS2-> setValue ( RollOutSmoothValue ) ;
443     APAdjustHS3-> setValue ( MaxAileronValue ) ;
444
445     FG_PUSH_PUI_DIALOG( APAdjustDialog );
446 }
447
448 // Done once at system initialization
449 void fgAPAdjustInit() {
450
451     //  printf("fgAPAdjustInit\n");
452 #define HORIZONTAL  FALSE
453
454     int DialogX = 40;
455     int DialogY = 100;
456     int DialogWidth = 230;
457
458     char Label[] =  "AutoPilot Adjust";
459     char *s;
460
461     int labelX = (DialogWidth / 2) -
462         (puGetDefaultLabelFont().getStringWidth( Label ) / 2);
463     labelX -= 30;  // KLUDGEY
464
465     int nSliders = 4;
466     int slider_x = 10;
467     int slider_y = 55;
468     int slider_width = 210;
469     int slider_title_x = 15;
470     int slider_value_x = 160;
471     float slider_delta = 0.1f;
472
473     TmpMaxRollValue       = globals->get_autopilot()->get_MaxRoll();
474     TmpRollOutValue       = globals->get_autopilot()->get_RollOut();
475     TmpMaxAileronValue    = globals->get_autopilot()->get_MaxAileron();
476     TmpRollOutSmoothValue = globals->get_autopilot()->get_RollOutSmooth();
477
478     MaxRollAdjust = 2 * globals->get_autopilot()->get_MaxRoll();
479     RollOutAdjust = 2 * globals->get_autopilot()->get_RollOut();
480     MaxAileronAdjust = 2 * globals->get_autopilot()->get_MaxAileron();
481     RollOutSmoothAdjust = 2 * globals->get_autopilot()->get_RollOutSmooth();
482
483     MaxRollValue       = globals->get_autopilot()->get_MaxRoll() / MaxRollAdjust;
484     RollOutValue       = globals->get_autopilot()->get_RollOut() / RollOutAdjust;
485     MaxAileronValue    = globals->get_autopilot()->get_MaxAileron() / MaxAileronAdjust;
486     RollOutSmoothValue = globals->get_autopilot()->get_RollOutSmooth()
487         / RollOutSmoothAdjust;
488
489     puGetDefaultFonts (  &APAdjustLegendFont,  &APAdjustLabelFont );
490     APAdjustDialog = new puDialogBox ( DialogX, DialogY ); {
491         int horiz_slider_height = APAdjustLabelFont.getStringHeight() +
492             APAdjustLabelFont.getStringDescender() +
493             PUSTR_TGAP + PUSTR_BGAP + 5;
494
495         APAdjustFrame = new puFrame ( 0, 0,
496                                       DialogWidth,
497                                       85 + nSliders * horiz_slider_height );
498
499         APAdjustDialogMessage = new puText ( labelX,
500                                              52 + nSliders
501                                              * horiz_slider_height );
502         APAdjustDialogMessage -> setDefaultValue ( Label );
503         APAdjustDialogMessage -> getDefaultValue ( &s );
504         APAdjustDialogMessage -> setLabel        ( s );
505
506         APAdjustHS0 = new mySlider ( slider_x, slider_y,
507                                      slider_width, HORIZONTAL ) ;
508         APAdjustHS0-> setDelta ( slider_delta ) ;
509         APAdjustHS0-> setValue ( MaxRollValue ) ;
510         APAdjustHS0-> setCBMode ( PUSLIDER_DELTA ) ;
511         APAdjustHS0-> setCallback ( maxroll_adj ) ;
512
513         sprintf( SliderText[ 0 ], "%05.2f", globals->get_autopilot()->get_MaxRoll() );
514         APAdjustMaxRollTitle = new puText ( slider_title_x, slider_y ) ;
515         APAdjustMaxRollTitle-> setDefaultValue ( "MaxRoll" ) ;
516         APAdjustMaxRollTitle-> getDefaultValue ( &s ) ;
517         APAdjustMaxRollTitle-> setLabel ( s ) ;
518         APAdjustMaxRollText = new puText ( slider_value_x, slider_y ) ;
519         APAdjustMaxRollText-> setLabel ( SliderText[ 0 ] ) ;
520
521         slider_y += horiz_slider_height;
522
523         APAdjustHS1 = new mySlider ( slider_x, slider_y, slider_width,
524                                      HORIZONTAL ) ;
525         APAdjustHS1-> setDelta ( slider_delta ) ;
526         APAdjustHS1-> setValue ( RollOutValue ) ;
527         APAdjustHS1-> setCBMode ( PUSLIDER_DELTA ) ;
528         APAdjustHS1-> setCallback ( rollout_adj ) ;
529
530         sprintf( SliderText[ 1 ], "%05.2f", globals->get_autopilot()->get_RollOut() );
531         APAdjustRollOutTitle = new puText ( slider_title_x, slider_y ) ;
532         APAdjustRollOutTitle-> setDefaultValue ( "AdjustRollOut" ) ;
533         APAdjustRollOutTitle-> getDefaultValue ( &s ) ;
534         APAdjustRollOutTitle-> setLabel ( s ) ;
535         APAdjustRollOutText = new puText ( slider_value_x, slider_y ) ;
536         APAdjustRollOutText-> setLabel ( SliderText[ 1 ] );
537
538         slider_y += horiz_slider_height;
539
540         APAdjustHS2 = new mySlider ( slider_x, slider_y, slider_width,
541                                      HORIZONTAL ) ;
542         APAdjustHS2-> setDelta ( slider_delta ) ;
543         APAdjustHS2-> setValue ( RollOutSmoothValue ) ;
544         APAdjustHS2-> setCBMode ( PUSLIDER_DELTA ) ;
545         APAdjustHS2-> setCallback ( rolloutsmooth_adj ) ;
546
547         sprintf( SliderText[ 2 ], "%5.2f", 
548                  globals->get_autopilot()->get_RollOutSmooth() );
549         APAdjustRollOutSmoothTitle = new puText ( slider_title_x, slider_y ) ;
550         APAdjustRollOutSmoothTitle-> setDefaultValue ( "RollOutSmooth" ) ;
551         APAdjustRollOutSmoothTitle-> getDefaultValue ( &s ) ;
552         APAdjustRollOutSmoothTitle-> setLabel ( s ) ;
553         APAdjustRollOutSmoothText = new puText ( slider_value_x, slider_y ) ;
554         APAdjustRollOutSmoothText-> setLabel ( SliderText[ 2 ] );
555
556         slider_y += horiz_slider_height;
557
558         APAdjustHS3 = new mySlider ( slider_x, slider_y, slider_width,
559                                      HORIZONTAL ) ;
560         APAdjustHS3-> setDelta ( slider_delta ) ;
561         APAdjustHS3-> setValue ( MaxAileronValue ) ;
562         APAdjustHS3-> setCBMode ( PUSLIDER_DELTA ) ;
563         APAdjustHS3-> setCallback ( maxaileron_adj ) ;
564
565         sprintf( SliderText[ 3 ], "%05.2f", 
566                  globals->get_autopilot()->get_MaxAileron() );
567         APAdjustMaxAileronTitle = new puText ( slider_title_x, slider_y ) ;
568         APAdjustMaxAileronTitle-> setDefaultValue ( "MaxAileron" ) ;
569         APAdjustMaxAileronTitle-> getDefaultValue ( &s ) ;
570         APAdjustMaxAileronTitle-> setLabel ( s ) ;
571         APAdjustMaxAileronText = new puText ( slider_value_x, slider_y ) ;
572         APAdjustMaxAileronText-> setLabel ( SliderText[ 3 ] );
573
574         APAdjustOkButton = new puOneShot ( 10, 10, 60, 50 );
575         APAdjustOkButton-> setLegend ( gui_msg_OK );
576         APAdjustOkButton-> makeReturnDefault ( TRUE );
577         APAdjustOkButton-> setCallback ( goAwayAPAdjust );
578
579         APAdjustCancelButton = new puOneShot ( 70, 10, 150, 50 );
580         APAdjustCancelButton-> setLegend ( gui_msg_CANCEL );
581         APAdjustCancelButton-> setCallback ( cancelAPAdjust );
582
583         APAdjustResetButton = new puOneShot ( 160, 10, 220, 50 );
584         APAdjustResetButton-> setLegend ( gui_msg_RESET );
585         APAdjustResetButton-> setCallback ( resetAPAdjust );
586     }
587     FG_FINALIZE_PUI_DIALOG( APAdjustDialog );
588
589 #undef HORIZONTAL
590 }
591
592 // Simple Dialog to input Target Airport
593 void TgtAptDialog_Cancel(puObject *)
594 {
595     FG_POP_PUI_DIALOG( TgtAptDialog );
596 }
597
598 void TgtAptDialog_OK (puObject *)
599 {
600     string TgtAptId;
601     
602     //    FGTime *t = FGTime::cur_time_params;
603     //    int PauseMode = t->getPause();
604     //    if(!PauseMode)
605     //        t->togglePauseMode();
606     
607     char *s;
608     TgtAptDialogInput->getValue(&s);
609
610     string tmp = s;
611     double alt = 0.0;
612     unsigned int pos = tmp.find( "@" );
613     if ( pos != string::npos ) {
614         TgtAptId = tmp.substr( 0, pos );
615         string alt_str = tmp.substr( pos + 1 );
616         alt = atof( alt_str.c_str() );
617         if ( !strcmp(fgGetString("/sim/startup/units"), "feet") ) {
618             alt *= SG_FEET_TO_METER;
619         }
620     } else {
621         TgtAptId = tmp;
622     }
623
624     TgtAptDialog_Cancel( NULL );
625     
626     FGAirport a;
627     FGFix f;
628     double t1, t2;
629     if ( fgFindAirportID( TgtAptId, &a ) ) {
630
631          SG_LOG( SG_GENERAL, SG_INFO,
632                  "Adding waypoint (airport) = " << TgtAptId );
633         
634          sprintf( NewTgtAirportId, "%s", TgtAptId.c_str() );
635
636          SGWayPoint wp( a.longitude, a.latitude, alt,
637                         SGWayPoint::WGS84, TgtAptId );
638          globals->get_route()->add_waypoint( wp );
639
640          /* and turn on the autopilot */
641          globals->get_autopilot()->set_HeadingEnabled( true );
642          globals->get_autopilot()->set_HeadingMode( FGAutopilot::FG_HEADING_WAYPOINT );
643
644     } else if ( current_fixlist->query( TgtAptId, 0.0, 0.0, 0.0,
645                                         &f, &t1, &t2 ) )
646     {
647          SG_LOG( SG_GENERAL, SG_INFO,
648                  "Adding waypoint (fix) = " << TgtAptId );
649         
650          sprintf( NewTgtAirportId, "%s", TgtAptId.c_str() );
651
652          SGWayPoint wp( f.get_lon(), f.get_lat(), alt,
653                         SGWayPoint::WGS84, TgtAptId );
654          globals->get_route()->add_waypoint( wp );
655
656          /* and turn on the autopilot */
657          globals->get_autopilot()->set_HeadingEnabled( true );
658          globals->get_autopilot()->set_HeadingMode( FGAutopilot::FG_HEADING_WAYPOINT );
659     } else {
660         TgtAptId  += " not in database.";
661         mkDialog(TgtAptId.c_str());
662     }
663 }
664
665 void TgtAptDialog_Reset(puObject *)
666 {
667     sprintf( NewTgtAirportId, "%s", fgGetString("/sim/startup/airport-id") );
668     TgtAptDialogInput->setValue ( NewTgtAirportId );
669     TgtAptDialogInput->setCursor( 0 ) ;
670 }
671
672 void TgtAptDialog_HandleSlider ( puObject * slider )
673 {
674   float val ;
675   slider -> getValue ( &val ) ;
676   val = 1.0f - val ;
677
678   int index = int ( TgtAptDialogWPList -> getNumItems () * val ) ;
679   TgtAptDialogWPList -> setTopItem ( index ) ;
680 }
681
682 void TgtAptDialog_HandleArrow( puObject *arrow )
683 {
684     int type = ((puArrowButton *)arrow)->getArrowType() ;
685     int inc = ( type == PUARROW_DOWN     ) ?   1 :
686             ( type == PUARROW_UP       ) ?  -1 :
687             ( type == PUARROW_FASTDOWN ) ?  10 :
688             ( type == PUARROW_FASTUP   ) ? -10 : 0 ;
689
690     float val ;
691     TgtAptDialogSlider -> getValue ( &val ) ;
692     val = 1.0f - val ;
693     int num_items = TgtAptDialogWPList->getNumItems () - 1 ;
694     if ( num_items > 0 )
695     {
696       int index = int ( num_items * val + 0.5 ) + inc ;
697       if ( index > num_items ) index = num_items ;
698       if ( index < 0 ) index = 0 ;
699
700       TgtAptDialogSlider -> setValue ( 1.0f - (float)index / num_items ) ;
701       TgtAptDialogWPList -> setTopItem ( index ) ;
702   }
703
704 }
705
706 void AddWayPoint(puObject *cb)
707 {
708     sprintf( NewTgtAirportId, "%s", fgGetString("/sim/startup/airport-id") );
709     TgtAptDialogInput->setValue( NewTgtAirportId );
710     
711     /* refresh waypoint list */
712     char WPString[100];
713
714     int i;
715     if ( WPList != NULL ) {
716         for (i = 0; i < WPListsize; i++ ) {
717           delete WPList[i];
718         }
719         delete [] WPList[i];
720     }
721     if ( globals->get_route()->size() > 0 ) { 
722         WPListsize = globals->get_route()->size();
723         WPList = new char* [ WPListsize + 1 ];
724         for (i = 0; i < globals->get_route()->size(); i++ ) {
725            sprintf(WPString, "%5s %3.2flon %3.2flat", globals->get_route()->get_waypoint(i).get_id().c_str(), globals->get_route()->get_waypoint(i).get_target_lon(), globals->get_route()->get_waypoint(i).get_target_lat());
726            WPList [i] = new char[ strlen(WPString) ];
727            strcpy ( WPList [i], WPString );
728         }
729     } else {
730         WPListsize = 1;
731         WPList = new char* [ 2 ];
732         WPList [0] = new char[18];
733         strcpy ( WPList [0], "** List Empty **");
734     }    
735     WPList [ WPListsize ] = NULL;
736     TgtAptDialogWPList->newList( WPList );
737
738    // if non-empty list, adjust the size of the slider...
739    TgtAptDialogSlider->setSliderFraction (0.9999f) ;
740    TgtAptDialogSlider->hide();
741    TgtAptDialogUPArrow->hide();
742    TgtAptDialogDNArrow->hide();
743    if (WPListsize > 10) {
744       TgtAptDialogSlider->setSliderFraction (10.0f/(WPListsize-1)) ;
745       TgtAptDialogSlider->reveal();
746       TgtAptDialogUPArrow->reveal();
747       TgtAptDialogDNArrow->reveal();
748     }
749
750     FG_PUSH_PUI_DIALOG( TgtAptDialog );
751 }
752
753 void PopWayPoint(puObject *cb)
754 {
755     globals->get_route()->delete_first();
756
757     // see if there are more waypoints on the list
758     if ( globals->get_route()->size() ) {
759         // more waypoints
760         globals->get_autopilot()->set_HeadingMode( FGAutopilot::FG_HEADING_WAYPOINT );
761     } else {
762         // end of the line
763         globals->get_autopilot()->set_HeadingMode( FGAutopilot::FG_TC_HEADING_LOCK );
764
765         // use current heading
766         globals->get_autopilot()
767             ->set_TargetHeading(fgGetDouble("/orientation/heading-deg"));
768     }
769 }
770
771 void ClearRoute(puObject *cb)
772 {
773     globals->get_route()->clear();
774 }
775
776 void NewTgtAirportInit()
777 {
778     SG_LOG( SG_AUTOPILOT, SG_INFO, " enter NewTgtAirportInit()" );
779     sprintf( NewTgtAirportId, "%s", fgGetString("/sim/startup/airport-id") );
780     SG_LOG( SG_AUTOPILOT, SG_INFO, " NewTgtAirportId " << NewTgtAirportId );
781     
782     TgtAptDialog = new puDialogBox (150, 350);
783     {
784         TgtAptDialogFrame   = new puFrame           (0,0,350, 350);
785         
786         TgtAptDialogWPList = new puListBox ( 50, 130, 300, 320 ) ;
787         TgtAptDialogWPList -> setLabel ( "Flight Plan" );
788         TgtAptDialogWPList -> setLabelPlace ( PUPLACE_ABOVE ) ;
789         TgtAptDialogWPList -> setStyle ( -PUSTYLE_SMALL_SHADED ) ;
790         TgtAptDialogWPList -> setValue ( 0 ) ;
791
792         TgtAptDialogSlider = new puSlider (300, 150, 150 ,TRUE,20);
793         TgtAptDialogSlider->setValue(1.0f);
794         TgtAptDialogSlider->setSliderFraction (0.2f) ;
795         TgtAptDialogSlider->setDelta(0.1f);
796         TgtAptDialogSlider->setCBMode( PUSLIDER_DELTA );
797         TgtAptDialogSlider->setCallback( TgtAptDialog_HandleSlider );
798
799         TgtAptDialogUPArrow = new puArrowButton ( 300, 300, 320, 320, PUARROW_UP ) ;
800         TgtAptDialogUPArrow->setCallback ( TgtAptDialog_HandleArrow ) ;
801
802         TgtAptDialogDNArrow = new puArrowButton ( 300, 130, 320, 150, PUARROW_DOWN ) ;
803         TgtAptDialogDNArrow->setCallback ( TgtAptDialog_HandleArrow ) ;
804
805
806         TgtAptDialogInput   = new puInput           (50, 70, 300, 100);
807         TgtAptDialogInput -> setLabel ( NewTgtAirportLabel );
808         TgtAptDialogInput -> setLabelPlace ( PUPLACE_ABOVE ) ;
809         TgtAptDialogInput   ->    setValue          (NewTgtAirportId);
810         TgtAptDialogInput   ->    acceptInput();
811         
812         TgtAptDialogOkButton     =  new puOneShot   (50, 10, 110, 50);
813         TgtAptDialogOkButton     ->     setLegend   (gui_msg_OK);
814         TgtAptDialogOkButton     ->     setCallback (TgtAptDialog_OK);
815         TgtAptDialogOkButton     ->     makeReturnDefault(TRUE);
816         
817         TgtAptDialogCancelButton =  new puOneShot   (140, 10, 210, 50);
818         TgtAptDialogCancelButton ->     setLegend   (gui_msg_CANCEL);
819         TgtAptDialogCancelButton ->     setCallback (TgtAptDialog_Cancel);
820         
821         TgtAptDialogResetButton  =  new puOneShot   (240, 10, 300, 50);
822         TgtAptDialogResetButton  ->     setLegend   (gui_msg_RESET);
823         TgtAptDialogResetButton  ->     setCallback (TgtAptDialog_Reset);
824
825     }
826
827     FG_FINALIZE_PUI_DIALOG( TgtAptDialog );
828     printf("leave NewTgtAirportInit()");
829 }
830
831
832