]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/KLN89/kln89_page_int.cxx
Support for multiple data dirs.
[flightgear.git] / src / Instrumentation / KLN89 / kln89_page_int.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 - daveluff AT ntlworld.com
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 <cstdio>
29
30 #include "kln89_page_int.hxx"
31 #include <Navaids/fix.hxx>
32 #include <Navaids/navrecord.hxx>
33
34 using std::string;
35
36 KLN89IntPage::KLN89IntPage(KLN89* parent) 
37 : KLN89Page(parent) {
38         _nSubPages = 2;
39         _subPage = 0;
40         _name = "INT";
41         _int_id = "PORTE";
42         _last_int_id = "";
43         _fp = NULL;
44         _nearestVor = NULL;
45         _refNav = NULL;
46 }
47
48 KLN89IntPage::~KLN89IntPage() {
49 }
50
51 void KLN89IntPage::Update(double dt) {
52         bool actPage = (_kln89->_activePage->GetName() == "ACT" ? true : false);
53         bool multi;  // Not set by FindFirst...
54         bool exact = false;
55         if(_int_id.size() == 5) exact = true;
56         if(_fp == NULL) {
57                 _fp = _kln89->FindFirstIntById(_int_id, multi, exact);
58         } else if(_fp->get_ident() != _int_id) {
59                 _fp = _kln89->FindFirstIntById(_int_id, multi, exact);
60         }
61         
62         if(_fp) {
63                 _int_id = _fp->get_ident();
64                 if(_kln89->GetActiveWaypoint()) {
65                         if(_int_id == _kln89->GetActiveWaypoint()->id) {
66                                 if(!(_kln89->_waypointAlert && _kln89->_blink)) {
67                                         // Active waypoint arrow
68                                         _kln89->DrawSpecialChar(4, 2, 0, 3);
69                                 }
70                         }
71                 }
72                 if(_int_id != _last_int_id) {
73                         _nearestVor = _kln89->FindClosestVor(_fp->get_lat() * SG_DEGREES_TO_RADIANS, _fp->get_lon() * SG_DEGREES_TO_RADIANS);
74                         if(_nearestVor) {
75                                 _nvRadial = _kln89->GetMagHeadingFromTo(_nearestVor->get_lat() * SG_DEGREES_TO_RADIANS, _nearestVor->get_lon() * SG_DEGREES_TO_RADIANS,
76                                                                     _fp->get_lat() * SG_DEGREES_TO_RADIANS, _fp->get_lon() * SG_DEGREES_TO_RADIANS);
77                                 _nvDist = _kln89->GetGreatCircleDistance(_nearestVor->get_lat() * SG_DEGREES_TO_RADIANS, _nearestVor->get_lon() * SG_DEGREES_TO_RADIANS,
78                                                                      _fp->get_lat() * SG_DEGREES_TO_RADIANS, _fp->get_lon() * SG_DEGREES_TO_RADIANS);
79                                 _refNav = _nearestVor;  // TODO - check that this *always* holds - eg. when changing INT id after explicitly setting ref nav 
80                                                                         // but with no loss of focus.
81                         } else {
82                                 _refNav = NULL;
83                         }
84                         _last_int_id = _int_id;
85                 }
86                 if(_kln89->_mode != KLN89_MODE_CRSR) {
87                         if(!_entInvert) {
88                                 if(!actPage) {
89                                         _kln89->DrawText(_fp->get_ident(), 2, 1, 3);
90                                 } else {
91                                         // If it's the ACT page, The ID is shifted slightly right to make space for the waypoint index.
92                                         _kln89->DrawText(_fp->get_ident(), 2, 4, 3);
93                                         char buf[3];
94                                         int n = snprintf(buf, 3, "%i", _kln89->GetActiveWaypointIndex() + 1);
95                                         _kln89->DrawText((string)buf, 2, 3 - n, 3);
96                                         // We also draw an I to differentiate INT from USR when it's the ACT page
97                                         _kln89->DrawText("I", 2, 11, 3);
98                                 }
99                         } else {
100                                 if(!_kln89->_blink) {
101                                         _kln89->DrawText(_fp->get_ident(), 2, 1, 3, false, 99);
102                                         _kln89->DrawEnt();
103                                 }
104                         }
105                 }
106                 if(_subPage == 0) {
107                         _kln89->DrawLatitude(_fp->get_lat(), 2, 3, 2);
108                         _kln89->DrawLongitude(_fp->get_lon(), 2, 3, 1);
109                         _kln89->DrawDirDistField(_fp->get_lat() * SG_DEGREES_TO_RADIANS, _fp->get_lon() * SG_DEGREES_TO_RADIANS, 2, 0, 0, 
110                                                  _to_flag, (_kln89->_mode == KLN89_MODE_CRSR && _uLinePos == 6 ? true : false));
111                 } else {
112                         _kln89->DrawText("Ref:", 2, 1, 2);
113                         _kln89->DrawText("Rad:", 2, 1, 1);
114                         _kln89->DrawText("Dis:", 2, 1, 0);
115                         if(_refNav) {
116                                 _kln89->DrawText(_refNav->get_ident(), 2, 9, 2);        // TODO - flash and allow to change if under cursor
117                                 //_kln89->DrawHeading(_nvRadial, 2, 11, 1);
118                                 //_kln89->DrawDist(_nvDist, 2, 11, 0);
119                                 // Currently our draw heading and draw dist functions don't do as many decimal points as we want here,
120                                 // so draw it ourselves!
121                                 // Heading
122                                 char buf[10];
123                                 snprintf(buf, 6, "%.1f", _nvRadial);
124                                 string s = buf;
125                                 _kln89->DrawText(s, 2, 13 - s.size(), 1);
126                                 _kln89->DrawSpecialChar(0, 2, 13, 1);   // Degrees symbol
127                                 // Dist
128                                 double d = _nvDist;
129                                 d *= (_kln89->_distUnits == GPS_DIST_UNITS_NM ? 1.0 : SG_NM_TO_METER * 0.001);
130                                 snprintf(buf, 9, "%.1f", d);
131                                 s = buf;
132                                 s += (_kln89->_distUnits == GPS_DIST_UNITS_NM ? "nm" : "Km");
133                                 _kln89->DrawText(s, 2, 14 - s.size(), 0);
134                         }
135                 }
136         } else {
137                 // TODO - when we leave the page with invalid id and return it should
138                 // revert to showing the last valid id.  Same for vor/ndb/probably apt etc.
139                 if(_kln89->_mode != KLN89_MODE_CRSR) _kln89->DrawText(_int_id, 2, 1, 3);
140                 if(_subPage == 0) {
141                         _kln89->DrawText("- -- --.--'", 2, 3, 2);
142                         _kln89->DrawText("---- --.--'", 2, 3, 1);
143                         _kln89->DrawSpecialChar(0, 2, 7, 2);
144                         _kln89->DrawSpecialChar(0, 2, 7, 1);
145                         _kln89->DrawText(">---    ----", 2, 0, 0);
146                         _kln89->DrawSpecialChar(0, 2, 4, 0);
147                         _kln89->DrawText(_to_flag ? "To" : "Fr", 2, 5, 0);
148                         _kln89->DrawText(_kln89->_distUnits == GPS_DIST_UNITS_NM ? "nm" : "km", 2, 12, 0);
149                 }
150         }
151         
152         if(_kln89->_mode == KLN89_MODE_CRSR) {
153                 if(_uLinePos > 0 && _uLinePos < 6) {
154                         // TODO - blink as well
155                         _kln89->Underline(2, _uLinePos, 3, 1);
156                 }
157                 for(unsigned int i = 0; i < _int_id.size(); ++i) {
158                         if(_uLinePos != (i + 1)) {
159                                 _kln89->DrawChar(_int_id[i], 2, i + 1, 3);
160                         } else {
161                                 if(!_kln89->_blink) _kln89->DrawChar(_int_id[i], 2, i + 1, 3);
162                         }
163                 }
164         }
165         
166         // TODO - fix this duplication - use _id instead of _apt_id, _vor_id, _ndb_id, _int_id etc!
167         _id = _int_id;
168         
169         KLN89Page::Update(dt);
170 }
171
172 void KLN89IntPage::SetId(const string& s) {
173         _last_int_id = _int_id;
174         _save_int_id = _int_id;
175         _int_id = s;
176         _fp = NULL;
177 }
178
179 void KLN89IntPage::CrsrPressed() {
180         if(_kln89->_mode == KLN89_MODE_DISP) return;
181         if(_kln89->_obsMode) {
182                 _uLinePos = 0;
183         } else {
184                 _uLinePos = 1;
185         }
186         if(_subPage == 0) {
187                 _maxULinePos = 6;
188         } else {
189                 _maxULinePos = 6;
190         }
191 }
192
193 void KLN89IntPage::ClrPressed() {
194         if(_subPage == 0 && _uLinePos == 6) {
195                 _to_flag = !_to_flag;
196         }
197 }
198
199 void KLN89IntPage::EntPressed() {
200         if(_entInvert) {
201                 _entInvert = false;
202                 _entInvert = false;
203                 if(_kln89->_dtoReview) {
204                         _kln89->DtoInitiate(_int_id);
205                 } else {
206                         _last_int_id = _int_id;
207                         _int_id = _save_int_id;
208                 }
209         }
210 }
211
212 void KLN89IntPage::Knob2Left1() {
213         if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
214                 KLN89Page::Knob2Left1();
215         } else {
216                 if(_uLinePos < 6) {
217                         // Same logic for both pages - set the ID
218                         _int_id = _int_id.substr(0, _uLinePos);
219                         // ASSERT(_uLinePos > 0);
220                         if(_uLinePos == (_int_id.size() + 1)) {
221                                 _int_id += '9';
222                         } else {
223                                 _int_id[_uLinePos - 1] = _kln89->DecChar(_int_id[_uLinePos - 1], (_uLinePos == 1 ? false : true));
224                         }
225                 } else {
226                         if(_subPage == 0) {
227                                 // NO-OP - from/to field is switched by clr button, not inner knob.
228                         } else {
229                                 // TODO - LNR type field.
230                         }
231                 }
232         }
233 }
234
235 void KLN89IntPage::Knob2Right1() {
236         if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
237                 KLN89Page::Knob2Right1();
238         } else {
239                 if(_uLinePos < 6) {
240                         // Same logic for both pages - set the ID
241                         _int_id = _int_id.substr(0, _uLinePos);
242                         // ASSERT(_uLinePos > 0);
243                         if(_uLinePos == (_int_id.size() + 1)) {
244                                 _int_id += 'A';
245                         } else {
246                                 _int_id[_uLinePos - 1] = _kln89->IncChar(_int_id[_uLinePos - 1], (_uLinePos == 1 ? false : true));
247                         }
248                 } else {
249                         if(_subPage == 0) {
250                                 // NO-OP - from/to field is switched by clr button, not inner knob.
251                         } else {
252                                 // TODO - LNR type field.
253                         }
254                 }
255         }
256 }
257