]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/KLN89/kln89_page_nav.cxx
Win32 fixes
[flightgear.git] / src / Instrumentation / KLN89 / kln89_page_nav.cxx
1 // kln89_page_*.[ch]xx - this file is one of the "pages" that
2 //                       are used in the KLN89 GPS unit simulation. 
3 //
4 // Written by David Luff, started 2005.
5 //
6 // Copyright (C) 2005 - David C Luff - david.luff@nottingham.ac.uk
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 //
22 // $Id$
23
24 #ifdef HAVE_CONFIG_H
25 #  include "config.h"
26 #endif
27
28 #include "kln89_page_nav.hxx"
29 #include <Main/fg_props.hxx>
30
31 KLN89NavPage::KLN89NavPage(KLN89* parent) 
32 : KLN89Page(parent) {
33         _nSubPages = 4;
34         _subPage = 0;
35         _name = "NAV";
36         _posFormat = 0;         // Check - should this default to ref from waypoint?
37         _vnv = 0;
38         _nav4DataSnippet = 0;
39         _cdiFormat = 0;
40         _menuActive = false;
41         _menuPos = 0;
42         _suspendAVS = false;
43         _scanWpSet = false;
44 }
45
46 KLN89NavPage::~KLN89NavPage() {
47 }
48
49 void KLN89NavPage::Update(double dt) {
50         GPSFlightPlan* fp = ((KLN89*)_parent)->_activeFP;
51         GPSWaypoint* awp = _parent->GetActiveWaypoint();
52         // Scan-pull out on nav4 page switches off the cursor
53         if(3 == _subPage && fgGetBool("/instrumentation/kln89/scan-pull")) { _kln89->_mode = KLN89_MODE_DISP; }
54         bool crsr = (_kln89->_mode == KLN89_MODE_CRSR);
55         bool blink = _kln89->_blink;
56         double lat = _kln89->_gpsLat * SG_RADIANS_TO_DEGREES;
57         double lon = _kln89->_gpsLon * SG_RADIANS_TO_DEGREES;
58         
59         if(_subPage != 3) { _scanWpSet = false; }
60         
61         if(0 == _subPage) {
62                 if(_kln89->_navFlagged) {
63                         _kln89->DrawText(">    F L A G", 2, 0, 2);
64                         _kln89->DrawText("DTK ---  TK ---", 2, 0, 1);
65                         _kln89->DrawText(">--- To    --:--", 2, 0, 0);
66                         _kln89->DrawSpecialChar(0, 2, 7, 1);
67                         _kln89->DrawSpecialChar(0, 2, 15, 1);
68                         _kln89->DrawSpecialChar(0, 2, 4, 0);
69                         _kln89->DrawSpecialChar(1, 2, 3, 2);
70                         _kln89->DrawSpecialChar(1, 2, 4, 2);
71                         _kln89->DrawSpecialChar(1, 2, 6, 2);
72                         _kln89->DrawSpecialChar(1, 2, 10, 2);
73                         _kln89->DrawSpecialChar(1, 2, 12, 2);
74                         _kln89->DrawSpecialChar(1, 2, 13, 2);
75                 } else {
76                         if(_kln89->_dto) {
77                                 _kln89->DrawDTO(2, 7, 3);
78                         } else {
79                                 if(!(_kln89->_waypointAlert && _kln89->_blink)) {
80                                         _kln89->DrawSpecialChar(3, 2, 8, 3);
81                                 }
82                         }
83                         _kln89->DrawText(awp->id, 2, 10, 3);
84                         if(!_kln89->_dto && !_kln89->_obsMode && !_kln89->_fromWaypoint.id.empty()) {
85                                 _kln89->DrawText(_kln89->_fromWaypoint.id, 2, 1, 3);
86                         }
87                         if(!(crsr && blink && _uLinePos == 1)) {
88                                 if(_cdiFormat == 0) {
89                                         _kln89->DrawCDI();
90                                 } else if(_cdiFormat == 1) {
91                                         _kln89->DrawText("Fly", 2, 2, 2);
92                                         double x = _kln89->CalcCrossTrackDeviation();
93                                         // TODO - check the R/L from sign of x below - I *think* it holds but not sure!
94                                         // Note also that we're setting Fly R or L based on the aircraft
95                                         // position only, not the heading.  Not sure if this is correct or not.
96                                         _kln89->DrawText(x < 0.0 ? "R" : "L", 2, 6, 2);
97                                         char buf[6];
98                                         int n;
99                                         x = fabs(x * (_kln89->_distUnits == GPS_DIST_UNITS_NM ? 1.0 : SG_NM_TO_METER * 0.001));
100                                         if(x < 1.0) {
101                                                 n = snprintf(buf, 6, "%0.2f", x);
102                                         } else if(x < 100.0) {
103                                                 n = snprintf(buf, 6, "%0.1f", x);
104                                         } else {
105                                                 n = snprintf(buf, 6, "%i", (int)(x+0.5));
106                                         }
107                                         _kln89->DrawText((string)buf, 2, 13-n, 2);
108                                         _kln89->DrawText(_kln89->_distUnits == GPS_DIST_UNITS_NM ? "nm" : "km", 2, 13, 2);
109                                 } else {
110                                         _kln89->DrawText("CDI Scale:", 2, 1, 2);
111                                         double d = _kln89->_cdiScales[_kln89->_currentCdiScaleIndex] * (_kln89->_distUnits == GPS_DIST_UNITS_NM ? 1.0 : SG_NM_TO_METER * 0.001);
112                                         char buf[5];
113                                         string s;
114                                         if(d >= 1.0) {
115                                                 snprintf(buf, 4, "%2.1f", d);
116                                                 s = buf;
117                                         } else {
118                                                 snprintf(buf, 5, "%2.2f", d);
119                                                 // trim the leading zero
120                                                 s = buf;
121                                                 s = s.substr(1, s.size() - 1);
122                                         }
123                                         _kln89->DrawText(s, 2, 11, 2);
124                                         _kln89->DrawText(_kln89->_distUnits == GPS_DIST_UNITS_NM ? "nm" : "km", 2, 14, 2);
125                                 }
126                         }
127                         _kln89->DrawChar('>', 2, 0, 2);
128                         _kln89->DrawChar('>', 2, 0, 0);
129                         if(crsr) {
130                                 if(_uLinePos == 1) _kln89->Underline(2, 1, 2, 15);
131                                 else if(_uLinePos == 2) _kln89->Underline(2, 1, 0, 9);
132                         }
133                         // Desired and actual magnetic track
134                         if(!_kln89->_obsMode) {
135                                 _kln89->DrawText("DTK", 2, 0, 1);
136                                 _kln89->DrawHeading((int)_kln89->_dtkMag, 2, 7, 1);
137                         }
138                         _kln89->DrawText("TK", 2, 9, 1);
139                         if(_kln89->_groundSpeed_ms > 3) {       // about 6 knots, don't know exactly what value to disable track
140                                 // The trouble with relying on FG gps's track value is we don't know when it's valid.
141                                 _kln89->DrawHeading((int)_kln89->_magTrackDeg, 2, 15, 1);
142                         } else {
143                                 _kln89->DrawText("---", 2, 12, 1);
144                                 _kln89->DrawSpecialChar(0, 2, 15, 1);
145                         }
146                         
147                         // Radial to/from active waypoint.
148                         // TODO - Not sure if this either is or should be true or mag!!!!!!!
149                         if(!(crsr && blink && _uLinePos == 2)) {
150                                 if(0 == _vnv) {
151                                         _kln89->DrawHeading((int)_kln89->GetHeadingToActiveWaypoint(), 2, 4, 0);
152                                         _kln89->DrawText("To", 2, 5, 0);
153                                 } else if(1 == _vnv) {
154                                         _kln89->DrawHeading((int)_kln89->GetHeadingFromActiveWaypoint(), 2, 4, 0);
155                                         _kln89->DrawText("Fr", 2, 5, 0);
156                                 } else {
157                                         _kln89->DrawText("Vnv Off", 2, 1, 0);
158                                 }
159                         }
160                         // It seems that the floating point groundspeed must be at least 30kt
161                         // for an ETA to be calculated.  Note that this means that (integer) 30kt
162                         // can appear in the frame 1 display both with and without an ETA displayed.
163                         // TODO - need to switch off track (and heading bug change) based on instantaneous speed as well
164                         // since the long gps lag filter means we can still be displaying when stopped on ground.
165                         if(_kln89->_groundSpeed_kts > 30.0) {
166                                 // Assuming eta display is always hh:mm
167                                 // Does it ever switch to seconds when close?
168                                 if(_kln89->_eta / 3600.0 > 100.0) {
169                                         // More that 100 hours ! - Doesn't fit.
170                                         _kln89->DrawText("--:--", 2, 11, 0);
171                                 } else {
172                                         _kln89->DrawTime(_kln89->_eta, 2, 15, 0);
173                                 }
174                         } else {
175                                 _kln89->DrawText("--:--", 2, 11, 0);
176                         }
177                 }
178         } else if(1 == _subPage) {
179                 // Present position
180                 _kln89->DrawChar('>', 2, 1, 3);
181                 if(!(crsr && blink && _uLinePos == 1)) _kln89->DrawText("PRESENT POSN", 2, 2, 3);
182                 if(crsr && _uLinePos == 1) _kln89->Underline(2, 2, 3, 12);
183                 if(0 == _posFormat) {
184                         // Lat/lon
185                         _kln89->DrawLatitude(lat, 2, 3, 1);
186                         _kln89->DrawLongitude(lon, 2, 3, 0);
187                 } else {
188                         // Ref from wp - defaults to nearest vor (and resets to default when page left and re-entered).
189                 }
190         } else if(2 == _subPage) {
191                 _kln89->DrawText("Time", 2, 0, 3);
192                 // TODO - hardwired to UTC at the moment
193                 _kln89->DrawText("UTC", 2, 6, 3);
194                 string th = fgGetString("/instrumentation/clock/indicated-hour");
195                 string tm = fgGetString("/instrumentation/clock/indicated-min");
196                 if(th.size() == 1) th = "0" + th;
197                 if(tm.size() == 1) tm = "0" + tm;
198                 _kln89->DrawText(th + tm, 2, 11, 3);
199                 _kln89->DrawText("Depart", 2, 0, 2);
200                 _kln89->DrawText(_kln89->_departureTimeString, 2, 11, 2);
201                 _kln89->DrawText("ETA", 2, 0, 1);
202                 if(_kln89->_departed) {
203                         /* Rules of ETA waypoint are:
204                          If the active waypoint is part of the active flightplan, then display
205                          the ETA to the final (destination) waypoint of the active flightplan.
206                          If the active waypoint is not part of the active flightplan, then
207                          display the ETA to the active waypoint. */
208                         // TODO - implement the above properly - we haven't below!
209                         string wid = "";
210                         if(fp->waypoints.size()) {
211                                 wid = fp->waypoints[fp->waypoints.size() - 1]->id;
212                         } else if(awp) {
213                                 wid = awp->id;
214                         }
215                         if(!wid.empty()) {
216                                 _kln89->DrawText(wid, 2, 4, 1);
217                                 double tsec = _kln89->GetTimeToWaypoint(wid);
218                                 if(tsec < 0.0) {
219                                         _kln89->DrawText("----", 2, 11, 1);
220                                 } else {
221                                         int etah = (int)tsec / 3600;
222                                         int etam = ((int)tsec - etah * 3600) / 60;
223                                         etah += atoi(fgGetString("/instrumentation/clock/indicated-hour"));
224                                         etam += atoi(fgGetString("/instrumentation/clock/indicated-min"));
225                                         while(etam > 59) {
226                                                 etam -= 60;
227                                                 etah += 1;
228                                         }
229                                         while(etah > 23) {
230                                                 etah -= 24;
231                                         }
232                                         char buf[6];
233                                         int n = snprintf(buf, 6, "%02i%02i", etah, etam);
234                                         _kln89->DrawText((string)buf, 2, 15-n, 1);
235                                 }
236                         } else {
237                                 _kln89->DrawText("----", 2, 11, 1);
238                         }
239                 } else {
240                         _kln89->DrawText("----", 2, 11, 1);
241                 }
242                 _kln89->DrawText("Flight", 2, 0, 0);
243                 if(_kln89->_departed) {
244                         int eh = (int)_kln89->_elapsedTime / 3600;
245                         int em = ((int)_kln89->_elapsedTime - eh * 3600) / 60;
246                         char buf[6];
247                         int n = snprintf(buf, 6, "%i:%02i", eh, em);
248                         _kln89->DrawText((string)buf, 2, 15-n, 0);
249                 } else {
250                         _kln89->DrawText("-:--", 2, 11, 0);
251                 }
252         } else {        // if(3 == _subPage)
253                 // Switch the cursor off if scan-pull is out on this page.
254                 if(fgGetBool("/instrumentation/kln89/scan-pull")) { _kln89->_mode = KLN89_MODE_DISP; } 
255                 // The moving map page the core KLN89 class draws this.
256                 if(_kln89->_mapOrientation == 2 && _kln89->_groundSpeed_kts < 2) {
257                         // Don't draw it if in track up mode and groundspeed < 2kts, as per real-life unit.
258                 } else {
259                         _kln89->DrawMap(!_suspendAVS);
260                 }
261                 // Now draw any annotation over it.
262                 int scale = KLN89MapScales[_kln89->_mapScaleUnits][_kln89->_mapScaleIndex];
263                 string scle_str = GPSitoa(scale);
264                 if(crsr) {
265                         if(_menuActive) {
266                                 // Draw a background quad to encompass on/off for the first three at 'off' length
267                                 _kln89->DrawMapQuad(28, 9, 48, 36, true);
268                                 _kln89->DrawMapText("SUA:", 1, 27, true);
269                                 if(!(_menuPos == 0 && _kln89->_blink)) _kln89->DrawMapText((_kln89->_drawSUA ? "on" : "off"), 29, 27, true);
270                                 if(_menuPos == 0) _kln89->DrawLine(28, 27, 48, 27);
271                                 _kln89->DrawMapText("VOR:", 1, 18, true);
272                                 if(!(_menuPos == 1 && _kln89->_blink)) _kln89->DrawMapText((_kln89->_drawVOR ? "on" : "off"), 29, 18, true);
273                                 if(_menuPos == 1) _kln89->DrawLine(28, 18, 48, 18);
274                                 _kln89->DrawMapText("APT:", 1, 9, true);
275                                 if(!(_menuPos == 2 && _kln89->_blink)) _kln89->DrawMapText((_kln89->_drawApt ? "on" : "off"), 29, 9, true);
276                                 if(_menuPos == 2) _kln89->DrawLine(28, 9, 48, 9);
277                                 _kln89->DrawMapQuad(0, 0, 27, 8, true);
278                                 if(!(_menuPos == 3 && _kln89->_blink)) {
279                                         if(_kln89->_mapOrientation == 0) {
280                                                 _kln89->DrawMapText("N", 1, 0, true);
281                                                 _kln89->DrawMapUpArrow(7, 1);
282                                         } else if(_kln89->_mapOrientation == 1) {
283                                                 _kln89->DrawMapText("DTK", 1, 0, true);
284                                                 _kln89->DrawMapUpArrow(21, 1);
285                                         } else {
286                                                 // Don't bother with heading up for now!
287                                                 _kln89->DrawMapText("TK", 1, 0, true);
288                                                 _kln89->DrawMapUpArrow(14, 1);
289                                         }
290                                 }
291                                 if(_menuPos == 3) _kln89->DrawLine(0, 0, 27, 0);
292                         } else {
293                                 if(_uLinePos == 2) {
294                                         if(!_kln89->_blink) {
295                                                 _kln89->DrawMapText("Menu?", 1, 9, true);
296                                                 _kln89->DrawEnt();
297                                                 _kln89->DrawLine(0, 9, 34, 9);
298                                         } else {
299                                                 _kln89->DrawMapQuad(0, 9, 34, 17, true);
300                                         }
301                                 } else {
302                                         _kln89->DrawMapText("Menu?", 1, 9, true);
303                                 }
304                                 // right-justify the scale when _uLinePos == 3
305                                 if(!(_uLinePos == 3 && _kln89->_blink)) _kln89->DrawMapText(scle_str, (_uLinePos == 3 ? 29 - (scle_str.size() * 7) : 1), 0, true);
306                                 if(_uLinePos == 3) _kln89->DrawLine(0, 0, 27, 0);
307                         }
308                 } else {
309                         // Just draw the scale
310                         _kln89->DrawMapText(scle_str, 1, 0, true);
311                 }
312                 // If the scan-pull knob is out, draw one of the waypoints (if applicable).
313                 if(fgGetBool("/instrumentation/kln89/scan-pull")) {
314                         if(_kln89->_activeFP->waypoints.size()) {
315                                 //cout << "Need to draw a waypoint!\n";
316                                 _kln89->DrawLine(70, 0, 111, 0);
317                                 if(!_kln89->_blink) {
318                                         //_kln89->DrawMapQuad(45, 0, 97, 8, true);
319                                         if(!_scanWpSet) {
320                                                 _scanWpIndex = _kln89->GetActiveWaypointIndex();
321                                                 _scanWpSet = true;
322                                         }
323                                         _kln89->DrawMapText(_kln89->_activeFP->waypoints[_scanWpIndex]->id, 71, 0, true);
324                                 }               
325                         }
326                 }
327                 // And do part of the field 1 update, since NAV 4 is a special case for the last line.
328                 _kln89->DrawChar('>', 1, 0, 0);
329                 if(crsr && _uLinePos == 1) _kln89->Underline(1, 1, 0, 5);
330                 if(!(crsr && _uLinePos == 1 && _kln89->_blink)) {
331                         if(_kln89->_obsMode && _nav4DataSnippet == 0) _nav4DataSnippet = 1;
332                         double tsec;
333                         switch(_nav4DataSnippet) {
334                         case 0:
335                                 // DTK
336                                 _kln89->DrawLabel("DTK", -39, 6); 
337                                 // TODO - check we have an active FP / dtk and draw dashes if not.
338                                 char buf0[4];
339                                 snprintf(buf0, 4, "%03i", (int)(_kln89->_dtkMag));
340                                 _kln89->DrawText((string)buf0, 1, 3, 0);
341                                 break;
342                         case 1:
343                                 // groundspeed
344                                 _kln89->DrawSpeed(_kln89->_groundSpeed_kts, 1, 5, 0);
345                                 break;
346                         case 2:
347                                 // ETE
348                                 tsec = _kln89->GetETE();
349                                 if(tsec < 0.0) {
350                                         _kln89->DrawText("--:--", 1, 1, 0);
351                                 } else {
352                                         int eteh = (int)tsec / 3600;
353                                         int etem = ((int)tsec - eteh * 3600) / 60;
354                                         char buf[6];
355                                         int n = snprintf(buf, 6, "%02i:%02i", eteh, etem);
356                                         _kln89->DrawText((string)buf, 1, 6-n, 0);
357                                 }
358                                 break;
359                         case 3:
360                                 // Cross-track correction
361                                 double x = _kln89->CalcCrossTrackDeviation();
362                                 if(x < 0.0) {
363                                         _kln89->DrawSpecialChar(3, 1, 5, 0);
364                                 } else {
365                                         _kln89->DrawSpecialChar(7, 1, 5, 0);
366                                 }
367                                 char buf3[6];
368                                 int n;
369                                 x = fabs(x * (_kln89->_distUnits == GPS_DIST_UNITS_NM ? 1.0 : SG_NM_TO_METER * 0.001));
370                                 if(x < 1.0) {
371                                         n = snprintf(buf3, 6, "%0.2f", x);
372                                 } else if(x < 100.0) {
373                                         n = snprintf(buf3, 6, "%0.1f", x);
374                                 } else {
375                                         n = snprintf(buf3, 6, "%i", (int)(x+0.5));
376                                 }
377                                 _kln89->DrawText((string)buf3, 1, 5-n, 0);
378                                 break;
379                         }
380                 }
381         }
382         
383         KLN89Page::Update(dt);
384 }
385
386 // Returns the id string of the selected waypoint on NAV4 if valid, else returns an empty string.
387 string KLN89NavPage::GetNav4WpId() {
388         if(3 == _subPage) {
389                 if(fgGetBool("/instrumentation/kln89/scan-pull")) {
390                         if(_kln89->_activeFP->waypoints.size()) {
391                                 if(!_scanWpSet) {
392                                         return(_kln89->_activeWaypoint.id);
393                                 } else {
394                                         return(_kln89->_activeFP->waypoints[_scanWpIndex]->id);
395                                 }               
396                         }
397                 }
398         }
399         return("");
400 }
401
402 void KLN89NavPage::LooseFocus() {
403         _suspendAVS = false;
404         _scanWpSet = false;
405 }
406
407 void KLN89NavPage::CrsrPressed() {
408         if(_kln89->_mode == KLN89_MODE_DISP) {
409                 // Crsr just switched off
410                 _menuActive = false;
411         } else {
412                 // Crsr just switched on
413                 if(_subPage < 3) {
414                         _uLinePos = 1;
415                 } else {
416                         _uLinePos = 3;
417                 }
418         }
419 }
420
421 void KLN89NavPage::EntPressed() {
422         if(_kln89->_mode == KLN89_MODE_CRSR) {
423                 if(_subPage == 3 && _uLinePos == 2 && !_menuActive) {
424                         _menuActive = true;
425                         _menuPos = 0;
426                         _suspendAVS = false;
427                 }
428         }
429 }
430
431 void KLN89NavPage::ClrPressed() {
432         if(_kln89->_mode == KLN89_MODE_CRSR) {
433                 if(_subPage == 0) {
434                         if(_uLinePos == 1) {
435                                 _cdiFormat++;
436                                 if(_cdiFormat > 2) _cdiFormat = 0;
437                         } else if(_uLinePos == 2) {
438                                 _vnv++;
439                                 if(_vnv > 2) _vnv = 0;
440                         }
441                 }
442                 if(_subPage == 3) {
443                         if(_uLinePos > 1) {
444                                 _suspendAVS = !_suspendAVS;
445                                 _menuActive = false;
446                         } else if(_uLinePos == 1) {
447                                 _nav4DataSnippet++;
448                                 if(_nav4DataSnippet > 3) _nav4DataSnippet = 0;
449                         }
450                 }
451         } else {
452                 if(_subPage == 3) {
453                         _suspendAVS = !_suspendAVS;
454                 }
455         }
456 }
457
458 void KLN89NavPage::Knob1Left1() {
459         if(_kln89->_mode == KLN89_MODE_CRSR) {
460                 if(!(_subPage == 3 && _menuActive)) {
461                         if(_uLinePos > 0) _uLinePos--;
462                 } else {
463                         if(_menuPos > 0) _menuPos--;
464                 }
465         }
466 }
467
468 void KLN89NavPage::Knob1Right1() {
469         if(_kln89->_mode == KLN89_MODE_CRSR) {
470                 if(_subPage < 2) {
471                         if(_uLinePos < 2) _uLinePos++;
472                 } else if(_subPage == 2) {
473                         _uLinePos = 1;
474                 } else {
475                         // NAV 4 - this is complicated by whether the menu is displayed or not.
476                         if(_menuActive) {
477                                 if(_menuPos < 3) _menuPos++;
478                         } else {
479                                 if(_uLinePos < 3) _uLinePos++;
480                         }
481                 }
482         }
483 }
484
485 void KLN89NavPage::Knob2Left1() {
486         // If the inner-knob is out on the nav4 page, the only effect is to cycle the displayed waypoint.
487         if(3 == _subPage && fgGetBool("/instrumentation/kln89/scan-pull")) {
488                 if(_kln89->_activeFP->waypoints.size()) {       // TODO - find out what happens when scan-pull is on on nav4 without an active FP.
489                         // It's unlikely that we could get here without _scanWpSet, but theoretically possible, so we need to cover it.
490                         if(!_scanWpSet) {
491                                 _scanWpIndex = _kln89->GetActiveWaypointIndex();
492                                 _scanWpSet = true;
493                         } else {
494                                 if(0 == _scanWpIndex) {
495                                         _scanWpIndex = _kln89->_activeFP->waypoints.size() - 1;
496                                 } else {
497                                         _scanWpIndex--;
498                                 }
499                         }
500                 }
501                 return;
502         }
503         if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
504                 KLN89Page::Knob2Left1();
505                 return;
506         }
507         if(_subPage == 0) {
508                 if(_uLinePos == 1 && _cdiFormat == 2) {
509                         _kln89->CDIFSDIncrease();
510                 }
511         } else if(_subPage == 3) {
512                 if(_menuActive) {
513                         if(_menuPos == 0) {
514                                 _kln89->_drawSUA = !_kln89->_drawSUA;
515                         } else if(_menuPos == 1) {
516                                 _kln89->_drawVOR = !_kln89->_drawVOR;
517                         } else if(_menuPos == 2) {
518                                 _kln89->_drawApt = !_kln89->_drawApt;
519                         } else {
520                                 if(_kln89->_mapOrientation == 0) {
521                                         // Don't allow heading up for now
522                                         _kln89->_mapOrientation = 2;
523                                 } else {
524                                         _kln89->_mapOrientation--;
525                                 }
526                                 _kln89->UpdateMapHeading();
527                         }
528                 } else if(_uLinePos == 3) {
529                         // TODO - add AUTO
530                         if(_kln89->_mapScaleIndex == 0) {
531                                 _kln89->_mapScaleIndex = 20;
532                         } else {
533                                 _kln89->_mapScaleIndex--;
534                         }
535                 }
536         }
537 }
538
539 void KLN89NavPage::Knob2Right1() {
540         // If the inner-knob is out on the nav4 page, the only effect is to cycle the displayed waypoint.
541         if(3 == _subPage && fgGetBool("/instrumentation/kln89/scan-pull")) {
542                 if(_kln89->_activeFP->waypoints.size()) {       // TODO - find out what happens when scan-pull is on on nav4 without an active FP.
543                         // It's unlikely that we could get here without _scanWpSet, but theoretically possible, so we need to cover it.
544                         if(!_scanWpSet) {
545                                 _scanWpIndex = _kln89->GetActiveWaypointIndex();
546                                 _scanWpSet = true;
547                         } else {
548                                 _scanWpIndex++;
549                                 if(_scanWpIndex > _kln89->_activeFP->waypoints.size() - 1) {
550                                         _scanWpIndex = 0;
551                                 }
552                         }
553                 }
554                 return;
555         }
556         if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
557                 KLN89Page::Knob2Right1();
558                 return;
559         }
560         if(_subPage == 0) {
561                 if(_uLinePos == 1 && _cdiFormat == 2) {
562                         _kln89->CDIFSDDecrease();
563                 }
564         } else if(_subPage == 3) {
565                 if(_menuActive) {
566                         if(_menuPos == 0) {
567                                 _kln89->_drawSUA = !_kln89->_drawSUA;
568                         } else if(_menuPos == 1) {
569                                 _kln89->_drawVOR = !_kln89->_drawVOR;
570                         } else if(_menuPos == 2) {
571                                 _kln89->_drawApt = !_kln89->_drawApt;
572                         } else {
573                                 if(_kln89->_mapOrientation >= 2) {
574                                         // Don't allow heading up for now
575                                         _kln89->_mapOrientation = 0;
576                                 } else {
577                                         _kln89->_mapOrientation++;
578                                 }
579                                 _kln89->UpdateMapHeading();
580                         }
581                 } else if(_uLinePos == 3) {
582                         // TODO - add AUTO
583                         if(_kln89->_mapScaleIndex == 20) {
584                                 _kln89->_mapScaleIndex = 0;
585                         } else {
586                                 _kln89->_mapScaleIndex++;
587                         }
588                 }
589         }
590 }