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