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