]> git.mxchange.org Git - flightgear.git/blob - src/Instrumentation/KLN89/kln89_page_dir.cxx
Make traffic take-off roll look a little better.
[flightgear.git] / src / Instrumentation / KLN89 / kln89_page_dir.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 "kln89_page_dir.hxx"
29 #include <Main/fg_props.hxx>
30
31 using std::string;
32
33 KLN89DirPage::KLN89DirPage(KLN89* parent)
34 : KLN89Page(parent) {
35         _nSubPages = 1;
36         _subPage = 0;
37         _name = "DIR";
38         _maxULinePos = 4;
39         _DToWpDispMode = 2;
40 }
41
42 KLN89DirPage::~KLN89DirPage() {
43 }
44
45 void KLN89DirPage::Update(double dt) {
46         // TODO - this can apparently be "ACTIVATE:" under some circumstances
47         _kln89->DrawText("DIRECT TO:", 2, 2, 3);
48         
49         if(_kln89->_mode == KLN89_MODE_CRSR) {
50                 string s = _id;
51                 while(s.size() < 5) s += ' ';
52                 if(_DToWpDispMode == 0) {
53                         if(!_kln89->_blink) {
54                                 _kln89->DrawText(s, 2, 4, 1, false, 99);
55                                 _kln89->DrawEnt(1, 0, 1);
56                         }
57                 } else if(_DToWpDispMode == 1) {
58                         if(!_kln89->_blink) {
59                                 _kln89->DrawText(s, 2, 4, 1, false, _uLinePos);
60                                 _kln89->DrawEnt(1, 0, 1);
61                         }
62                         _kln89->Underline(2, 4, 1, 5);
63                 } else {
64                         if(!_kln89->_blink) _kln89->DrawText("_____", 2, 4, 1);
65                         _kln89->Underline(2, 4, 1, 5);
66                 }
67         } else {
68                 _kln89->DrawText("_____", 2, 4, 1);
69         }
70         
71         KLN89Page::Update(dt);
72 }
73
74 // This can only be called from the KLN89 when DTO is pressed from outside of the DIR page.
75 // DO NOT USE IT to set _id internally from the DIR page, since it initialises various state 
76 // based on the assumption that the DIR page is being first entered.
77 void KLN89DirPage::SetId(const string& s) {
78         if(s.size()) {
79                 _id = s;
80                 _DToWpDispMode = 0;
81                 if(!_kln89->_activeFP->IsEmpty()) {
82                         _DToWpDispIndex = (int)_kln89->_activeFP->waypoints.size() - 1;
83                 }
84         } else {
85                 _DToWpDispMode = 2;
86         }
87         _saveMasterMode = _kln89->_mode;
88         _uLinePos = 1;  // Needed to stop Leg flashing
89 }
90
91 void KLN89DirPage::CrsrPressed() {
92         // Pressing CRSR clears the ID field (from sim).
93         _DToWpDispMode = 2;
94 }
95
96 void KLN89DirPage::ClrPressed() {
97         if(_kln89->_mode == KLN89_MODE_CRSR) {
98                 if(_DToWpDispMode <= 1) {
99                         _DToWpDispMode = 2;
100                         _id.clear();
101                 } else {
102                         // Restore the original master mode
103                         _kln89->_mode = _saveMasterMode;
104                         // Stop displaying dir page
105                         _kln89->_activePage = _kln89->_pages[_kln89->_curPage];
106                 }
107         } else {
108                 // TODO
109         }
110 }
111
112 void KLN89DirPage::EntPressed() {
113         // Trim any RH whitespace from _id
114         while(!_id.empty()) {
115                 if(_id[_id.size()-1] == ' ') {
116                         _id = _id.substr(0, _id.size()-1);
117                 } else {
118                         // Important to break, since usr waypoint names may contain space.
119                         break;
120                 }
121         }
122         if(_DToWpDispMode == 2 || _id.empty()) {
123                 _kln89->DtoCancel();
124         } else {
125                 if(_DToWpDispMode == 0) {
126                         // It's a waypoint from the active flightplan - these get processed without data page review.
127                         _kln89->DtoInitiate(_id);
128                 } else {
129                         // Display the appropriate data page for review (USR page if the ident is not currently valid)
130                         _kln89->_dtoReview = true;
131                         GPSWaypoint* wp = _kln89->FindFirstByExactId(_id);
132                         if(wp) {
133                                 // Set the current page to be the appropriate data page
134                                 _kln89->_curPage = wp->type;
135                                 delete wp;
136                         } else {
137                                 // Set the current page to be the user page
138                                 _kln89->_curPage = 4;
139                         }
140                         // set the page ID and entInvert, and activate the current page.
141                         _kln89->_activePage = _kln89->_pages[_kln89->_curPage];
142                         _kln89->_activePage->SetId(_id);
143                         _kln89->_activePage->SetEntInvert(true);
144                 }
145         }
146 }
147
148 void KLN89DirPage::Knob2Left1() {
149         if(_kln89->_mode == KLN89_MODE_CRSR) {
150                 if(fgGetBool("/instrumentation/kln89/scan-pull")) {
151                         if(_DToWpDispMode == 2) {
152                                 if(!_kln89->_activeFP->IsEmpty()) {
153                                         // Switch to mode 0, set the position to the end of the active flightplan *and* run the mode 0 case.
154                                         _DToWpDispMode = 0;
155                                         _DToWpDispIndex = (int)_kln89->_activeFP->waypoints.size() - 1;
156                                 }
157                         }
158                         if(_DToWpDispMode == 0) {
159                                 // If the knob is pulled out, then the unit cycles through the waypoints of the active flight plan
160                                 // (This is deduced from the Bendix-King sim, I haven't found it documented in the pilot guide).
161                                 // If the active flight plan is empty it clears the field (this is possible, e.g. if a data page was
162                                 // active when DTO was pressed).
163                                 if(!_kln89->_activeFP->IsEmpty()) {
164                                         if(_DToWpDispIndex == 0) {
165                                                 _DToWpDispIndex = (int)_kln89->_activeFP->waypoints.size() - 1;
166                                         } else {
167                                                 _DToWpDispIndex--;
168                                         }
169                                         _id = _kln89->_activeFP->waypoints[_DToWpDispIndex]->id;
170                                 } else {
171                                         _DToWpDispMode = 2;
172                                 }
173                         }
174                         // _DToWpDispMode == 1 is a NO-OP when the knob is out.
175                 } else {
176                         if(_DToWpDispMode == 0) {
177                                 // If the knob is not pulled out, then turning it transitions the DIR page to the waypoint selection mode
178                                 // and sets the waypoint to the first beginning with '9'
179                                 _id = "9";
180                                 GPSWaypoint* wp = _kln89->FindFirstById(_id);
181                                 if(wp) {
182                                         _id = wp->id;
183                                         delete wp;
184                                 }
185                                 _uLinePos = 0;
186                                 _DToWpDispMode = 1;
187                         } else if(_DToWpDispMode == 1) {
188                                 while(_id.size() < (_uLinePos + 1)) {
189                                         _id += ' ';
190                                 }
191                                 char ch = _id[_uLinePos];
192                                 if(ch == ' ') {
193                                         ch = '9';
194                                 } else if(ch == '0') {
195                                         ch = 'Z';
196                                 } else if(ch == 'A') {
197                                         // It seems that blanks are allowed within the name, but not for the first character
198                                         if(_uLinePos == 0) {
199                                                 ch = '9';
200                                         } else {
201                                                 ch = ' ';
202                                         }
203                                 } else {
204                                         ch--;
205                                 }
206                                 _id[_uLinePos] = ch;
207                                 GPSWaypoint* wp = _kln89->FindFirstById(_id.substr(0, _uLinePos+1));
208                                 if(wp) {
209                                         _id = wp->id;
210                                         delete wp;
211                                 }
212                         } else {
213                                 _id = "9";
214                                 GPSWaypoint* wp = _kln89->FindFirstById(_id);
215                                 if(wp) {
216                                         _id = wp->id;
217                                         delete wp;
218                                 }
219                                 _uLinePos = 0;
220                                 _DToWpDispMode = 1;
221                         }
222                 }
223         } else {
224                 // If the cursor is not displayed, then we return to the page that was displayed prior to DTO being pressed,
225                 // and pass the knob turn to that page, whether pulled out or not.
226                 _kln89->_activePage = _kln89->_pages[_kln89->_curPage];
227                 _kln89->_activePage->Knob2Left1();
228         }
229 }
230
231 void KLN89DirPage::Knob2Right1() {
232         if(_kln89->_mode == KLN89_MODE_CRSR) {
233                 if(fgGetBool("/instrumentation/kln89/scan-pull")) {
234                         if(_DToWpDispMode == 2) {
235                                 if(!_kln89->_activeFP->IsEmpty()) {
236                                         // Switch to mode 0, set the position to the end of the active flightplan *and* run the mode 0 case.
237                                         _DToWpDispMode = 0;
238                                         _DToWpDispIndex = (int)_kln89->_activeFP->waypoints.size() - 1;
239                                 }
240                         }
241                         if(_DToWpDispMode == 0) {
242                                 // If the knob is pulled out, then the unit cycles through the waypoints of the active flight plan
243                                 // (This is deduced from the Bendix-King sim, I haven't found it documented in the pilot guide).
244                                 // If the active flight plan is empty it clears the field (this is possible, e.g. if a data page was
245                                 // active when DTO was pressed).
246                                 if(!_kln89->_activeFP->IsEmpty()) {
247                                         if(_DToWpDispIndex == (int)_kln89->_activeFP->waypoints.size() - 1) {
248                                                 _DToWpDispIndex = 0;
249                                         } else {
250                                                 _DToWpDispIndex++;
251                                         }
252                                         _id = _kln89->_activeFP->waypoints[_DToWpDispIndex]->id;
253                                 } else {
254                                         _DToWpDispMode = 2;
255                                 }
256                         }
257                         // _DToWpDispMode == 1 is a NO-OP when the knob is out.
258                 } else {
259                         if(_DToWpDispMode == 0) {
260                                 // If the knob is not pulled out, then turning it transitions the DIR page to the waypoint selection mode
261                                 // and sets the waypoint to the first beginning with 'A'
262                                 _id = "A";
263                                 GPSWaypoint* wp = _kln89->FindFirstById(_id);
264                                 if(wp) {
265                                         _id = wp->id;
266                                         delete wp;
267                                 }
268                                 _uLinePos = 0;
269                                 _DToWpDispMode = 1;
270                         } else if(_DToWpDispMode == 1) {
271                                 while(_id.size() < (_uLinePos + 1)) {
272                                         _id += ' ';
273                                 }
274                                 char ch = _id[_uLinePos];
275                                 if(ch == ' ') {
276                                         ch = 'A';
277                                 } else if(ch == 'Z') {
278                                         ch = '0';
279                                 } else if(ch == '9') {
280                                         // It seems that blanks are allowed within the name, but not for the first character
281                                         if(_uLinePos == 0) {
282                                                 ch = 'A';
283                                         } else {
284                                                 ch = ' ';
285                                         }
286                                 } else {
287                                         ch++;
288                                 }
289                                 _id[_uLinePos] = ch;
290                                 GPSWaypoint* wp = _kln89->FindFirstById(_id.substr(0, _uLinePos+1));
291                                 if(wp) {
292                                         _id = wp->id;
293                                         delete wp;
294                                 }
295                         } else {
296                                 _id = "A";
297                                 GPSWaypoint* wp = _kln89->FindFirstById(_id);
298                                 if(wp) {
299                                         _id = wp->id;
300                                         delete wp;
301                                 }
302                                 _uLinePos = 0;
303                                 _DToWpDispMode = 1;
304                         }
305                 }
306         } else {
307                 // If the cursor is not displayed, then we return to the page that was displayed prior to DTO being pressed,
308                 // and pass the knob turn to that page, whether pulled out or not.
309                 _kln89->_activePage = _kln89->_pages[_kln89->_curPage];
310                 _kln89->_activePage->Knob2Right1();
311         }
312 }