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