1 // kln89_page_*.[ch]xx - this file is one of the "pages" that
2 // are used in the KLN89 GPS unit simulation.
4 // Written by David Luff, started 2005.
6 // Copyright (C) 2005 - David C Luff - daveluff AT ntlworld.com
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.
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.
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.
30 #include "kln89_page_int.hxx"
31 #include <Navaids/fix.hxx>
32 #include <Navaids/navrecord.hxx>
36 KLN89IntPage::KLN89IntPage(KLN89* parent)
48 KLN89IntPage::~KLN89IntPage() {
51 void KLN89IntPage::Update(double dt) {
52 bool actPage = (_kln89->_activePage->GetName() == "ACT" ? true : false);
53 bool multi; // Not set by FindFirst...
55 if(_int_id.size() == 5) exact = true;
57 _fp = _kln89->FindFirstIntById(_int_id, multi, exact);
58 } else if(_fp->get_ident() != _int_id) {
59 _fp = _kln89->FindFirstIntById(_int_id, multi, exact);
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);
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);
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.
84 _last_int_id = _int_id;
86 if(_kln89->_mode != KLN89_MODE_CRSR) {
89 _kln89->DrawText(_fp->get_ident(), 2, 1, 3);
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);
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);
100 if(!_kln89->_blink) {
101 _kln89->DrawText(_fp->get_ident(), 2, 1, 3, false, 99);
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));
112 _kln89->DrawText("Ref:", 2, 1, 2);
113 _kln89->DrawText("Rad:", 2, 1, 1);
114 _kln89->DrawText("Dis:", 2, 1, 0);
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!
123 snprintf(buf, 6, "%.1f", _nvRadial);
125 _kln89->DrawText(s, 2, 13 - s.size(), 1);
126 _kln89->DrawSpecialChar(0, 2, 13, 1); // Degrees symbol
129 d *= (_kln89->_distUnits == GPS_DIST_UNITS_NM ? 1.0 : SG_NM_TO_METER * 0.001);
130 snprintf(buf, 9, "%.1f", d);
132 s += (_kln89->_distUnits == GPS_DIST_UNITS_NM ? "nm" : "Km");
133 _kln89->DrawText(s, 2, 14 - s.size(), 0);
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);
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);
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);
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);
161 if(!_kln89->_blink) _kln89->DrawChar(_int_id[i], 2, i + 1, 3);
166 // TODO - fix this duplication - use _id instead of _apt_id, _vor_id, _ndb_id, _int_id etc!
169 KLN89Page::Update(dt);
172 void KLN89IntPage::SetId(const string& s) {
173 _last_int_id = _int_id;
174 _save_int_id = _int_id;
179 void KLN89IntPage::CrsrPressed() {
180 if(_kln89->_mode == KLN89_MODE_DISP) return;
181 if(_kln89->_obsMode) {
193 void KLN89IntPage::ClrPressed() {
194 if(_subPage == 0 && _uLinePos == 6) {
195 _to_flag = !_to_flag;
199 void KLN89IntPage::EntPressed() {
203 if(_kln89->_dtoReview) {
204 _kln89->DtoInitiate(_int_id);
206 _last_int_id = _int_id;
207 _int_id = _save_int_id;
212 void KLN89IntPage::Knob2Left1() {
213 if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
214 KLN89Page::Knob2Left1();
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)) {
223 _int_id[_uLinePos - 1] = _kln89->DecChar(_int_id[_uLinePos - 1], (_uLinePos == 1 ? false : true));
227 // NO-OP - from/to field is switched by clr button, not inner knob.
229 // TODO - LNR type field.
235 void KLN89IntPage::Knob2Right1() {
236 if(_kln89->_mode != KLN89_MODE_CRSR || _uLinePos == 0) {
237 KLN89Page::Knob2Right1();
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)) {
246 _int_id[_uLinePos - 1] = _kln89->IncChar(_int_id[_uLinePos - 1], (_uLinePos == 1 ? false : true));
250 // NO-OP - from/to field is switched by clr button, not inner knob.
252 // TODO - LNR type field.