OpenCPN Partial API docs
Loading...
Searching...
No Matches
concanv.cpp
Go to the documentation of this file.
1/**************************************************************************
2 * Copyright (C) 2010 by David S. Register *
3 * *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
13 * *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, see <https://www.gnu.org/licenses/>. *
16 ****************************************************************************/
17
24#include <stdlib.h>
25#include <time.h>
26
27#include <wx/wxprec.h>
28
29#ifndef WX_PRECOMP
30#include <wx/wx.h>
31#endif // precompiled headers
32
33#include <wx/datetime.h>
34
35#include "gl_headers.h" // Must be before anything using GL
36
37#include "model/config_vars.h"
38#include "model/navutil_base.h"
39#include "model/own_ship.h"
40#include "model/route.h"
41#include "model/routeman.h"
42
43#include "concanv.h"
44#include "font_mgr.h"
45#include "gui_lib.h"
46#include "navutil.h"
47#include "ocpn_frame.h"
48#include "ocpn_platform.h"
49#include "ocpn_plugin.h"
50#include "styles.h"
51
52enum eMenuItems { ID_NAVLEG = 1, ID_NAVROUTE, ID_NAVHIGHWAY } menuItems;
53
55
56//------------------------------------------------------------------------------
57// ConsoleCanvasWin Implementation
58//------------------------------------------------------------------------------
59BEGIN_EVENT_TABLE(ConsoleCanvasWin, wxWindow)
60EVT_PAINT(ConsoleCanvasWin::OnPaint)
61EVT_SHOW(ConsoleCanvasWin::OnShow)
62EVT_CONTEXT_MENU(ConsoleCanvasWin::OnContextMenu)
63EVT_MENU(ID_NAVLEG, ConsoleCanvasWin::OnContextMenuSelection)
64EVT_MENU(ID_NAVROUTE, ConsoleCanvasWin::OnContextMenuSelection)
65EVT_MENU(ID_NAVHIGHWAY, ConsoleCanvasWin::OnContextMenuSelection)
66END_EVENT_TABLE()
67
68// Define a constructor for my canvas
69ConsoleCanvasWin::ConsoleCanvasWin(wxWindow* parent) {
70 m_speedUsed = SPEED_SOG;
71 pbackBrush = NULL;
72 m_bNeedClear = false;
73
74 long style = wxSIMPLE_BORDER | wxCLIP_CHILDREN | wxFRAME_FLOAT_ON_PARENT;
75
76#ifdef __WXMSW__
77 style |= wxFRAME_NO_TASKBAR;
78#endif
79
80 wxWindow::Create(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize, style);
81
82 m_pParent = parent;
83
84 m_pitemBoxSizerLeg = new wxBoxSizer(wxVERTICAL);
85
86 pThisLegText = new wxStaticText(this, -1, _("This Leg"));
87 pThisLegText->Fit();
88 m_pitemBoxSizerLeg->Add(pThisLegText, 0, wxALIGN_CENTER_HORIZONTAL, 2);
89
90 wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
91
92 wxFont* pThisLegFont = FontMgr::Get().FindOrCreateFont(
93 qFont->GetPointSize(), wxFONTFAMILY_DEFAULT, qFont->GetStyle(),
94 wxFONTWEIGHT_BOLD, false, qFont->GetFaceName());
95 pThisLegText->SetFont(*pThisLegFont);
96
97 pXTE = new AnnunText(this, -1, _("Console Legend"), _("Console Value"));
98 pXTE->SetALabel("XTE");
99 m_pitemBoxSizerLeg->Add(pXTE, 1, wxALIGN_LEFT | wxALL, 2);
100
101 pBRG = new AnnunText(this, -1, _("Console Legend"), _("Console Value"));
102 pBRG->SetALabel("BRG");
103 m_pitemBoxSizerLeg->Add(pBRG, 1, wxALIGN_LEFT | wxALL, 2);
104
105 pVMG = new AnnunText(this, -1, _("Console Legend"), _("Console Value"));
106 pVMG->SetALabel("VMG");
107 m_pitemBoxSizerLeg->Add(pVMG, 1, wxALIGN_LEFT | wxALL, 2);
108
109 pRNG = new AnnunText(this, -1, _("Console Legend"), _("Console Value"));
110 pRNG->SetALabel("RNG");
111 m_pitemBoxSizerLeg->Add(pRNG, 1, wxALIGN_LEFT | wxALL, 2);
112
113 pTTG = new AnnunText(this, -1, _("Console Legend"), _("Console Value"));
114 pTTG->SetALabel("TTG @VMG");
115 m_pitemBoxSizerLeg->Add(pTTG, 1, wxALIGN_LEFT | wxALL, 2);
116
117 // Create CDI Display Window
118
119 pCDI = new CDI(this, -1, wxSIMPLE_BORDER, "CDI");
120 m_pitemBoxSizerLeg->AddSpacer(5);
121 m_pitemBoxSizerLeg->Add(pCDI, 0, wxALL | wxEXPAND, 2);
122
123 SetSizer(m_pitemBoxSizerLeg); // use the sizer for layout
124 m_pitemBoxSizerLeg->SetSizeHints(this);
125 Layout();
126 Fit();
127
128 if (g_bShowRouteTotal)
129 pThisLegText->SetLabel(_("Route"));
130 else
131 pThisLegText->SetLabel(_("This Leg"));
132
133 Hide();
134}
135
136ConsoleCanvasWin::~ConsoleCanvasWin() { delete pCDI; }
137
138void ConsoleCanvasWin::SetColorScheme(ColorScheme cs) {
139 pbackBrush = wxTheBrushList->FindOrCreateBrush(
140 GetGlobalColor("DILG1" /*UIBDR*/), wxBRUSHSTYLE_SOLID);
141 SetBackgroundColour(GetGlobalColor("DILG1" /*"UIBDR"*/));
142
143 if (g_bShowRouteTotal)
144 pThisLegText->SetLabel(_("Route"));
145 else
146 pThisLegText->SetLabel(_("This Leg"));
147
148 // Also apply color scheme to all known children
149
150 pThisLegText->SetBackgroundColour(GetGlobalColor("DILG1" /*"UIBDR"*/));
151
152 pXTE->SetColorScheme(cs);
153 pBRG->SetColorScheme(cs);
154 pRNG->SetColorScheme(cs);
155 pTTG->SetColorScheme(cs);
156 pVMG->SetColorScheme(cs);
157
158 pCDI->SetColorScheme(cs);
159}
160
161void ConsoleCanvasWin::OnPaint(wxPaintEvent& event) {
162 wxPaintDC dc(this);
163
164 if (g_pRouteMan->GetpActiveRoute()) {
165 if (m_bNeedClear) {
166 pThisLegText->Refresh();
167 m_bNeedClear = false;
168 }
169 }
170
171 if (!g_bShowActiveRouteHighway) pCDI->Hide();
172}
173
174void ConsoleCanvasWin::OnShow(wxShowEvent& event) {
175 pCDI->Show(g_bShowActiveRouteHighway);
176 m_pitemBoxSizerLeg->SetSizeHints(this);
177}
178
179void ConsoleCanvasWin::LegRoute() {
180 if (g_bShowRouteTotal)
181 pThisLegText->SetLabel(_("Route"));
182 else
183 pThisLegText->SetLabel(_("This Leg"));
184
185 pThisLegText->Refresh(true);
186 RefreshConsoleData();
187}
188
189void ConsoleCanvasWin::OnContextMenu(wxContextMenuEvent& event) {
190 wxMenu* contextMenu = new wxMenu();
191 wxMenuItem* btnLeg =
192 new wxMenuItem(contextMenu, ID_NAVLEG, _("This Leg"), "", wxITEM_RADIO);
193 wxMenuItem* btnRoute = new wxMenuItem(contextMenu, ID_NAVROUTE,
194 _("Full Route"), "", wxITEM_RADIO);
195 wxMenuItem* btnHighw = new wxMenuItem(contextMenu, ID_NAVHIGHWAY,
196 _("Show Highway"), "", wxITEM_CHECK);
197 contextMenu->Append(btnLeg);
198 contextMenu->Append(btnRoute);
199 contextMenu->AppendSeparator();
200 contextMenu->Append(btnHighw);
201
202 btnLeg->Check(!g_bShowRouteTotal);
203 btnRoute->Check(g_bShowRouteTotal);
204 btnHighw->Check(g_bShowActiveRouteHighway);
205
206 PopupMenu(contextMenu);
207
208 delete contextMenu;
209}
210
211void ConsoleCanvasWin::OnContextMenuSelection(wxCommandEvent& event) {
212 switch (event.GetId()) {
213 case ID_NAVLEG: {
214 g_bShowRouteTotal = false;
215 LegRoute();
216 break;
217 }
218 case ID_NAVROUTE: {
219 g_bShowRouteTotal = true;
220 LegRoute();
221 break;
222 }
223 case ID_NAVHIGHWAY: {
224 g_bShowActiveRouteHighway = !g_bShowActiveRouteHighway;
225 if (g_bShowActiveRouteHighway) {
226 pCDI->Show();
227 } else {
228 pCDI->Hide();
229 }
230 m_pitemBoxSizerLeg->SetSizeHints(this);
231 break;
232 }
233 }
234}
235
236void ConsoleCanvasWin::ToggleShowHighway() {
237 g_bShowActiveRouteHighway = !g_bShowActiveRouteHighway;
238 if (g_bShowActiveRouteHighway) {
239 pCDI->Show();
240 } else {
241 pCDI->Hide();
242 }
243 m_pitemBoxSizerLeg->SetSizeHints(this);
244 Layout();
245}
246
248 // Implement 3-state logic
249 // Route/SOG -> LEG/SOG -> LEG/VMG -> ....
250
251 if (g_bShowRouteTotal) {
252 g_bShowRouteTotal = false;
253 m_speedUsed = SPEED_SOG;
254 } else {
255 if (m_speedUsed == SPEED_VMG) {
256 g_bShowRouteTotal = true;
257 m_speedUsed = SPEED_SOG;
258 } else
259 m_speedUsed = SPEED_VMG;
260 }
261 LegRoute();
262}
263
265 wxString str_buf;
266 if (g_pRouteMan->GetpActiveRoute()) {
267 if (g_pRouteMan->m_bDataValid) {
268 // Range to the next waypoint is needed always
269 float rng = g_pRouteMan->GetCurrentRngToActivePoint();
270
271 // Brg to the next waypoint
272 float dcog = g_pRouteMan->GetCurrentBrgToActivePoint();
273 if (dcog >= 359.5) dcog = 0;
274
275 wxString cogstr;
276 if (g_bShowTrue)
277 cogstr << wxString::Format(wxString("%6.0f", wxConvUTF8), dcog);
278 if (g_bShowMag)
279 cogstr << wxString::Format(wxString("%6.0f(M)", wxConvUTF8),
280 toMagnetic(dcog));
281
282 pBRG->SetAValue(cogstr);
283
284 double speed = 0.;
285 if (!std::isnan(gCog) && !std::isnan(gSog)) {
286 double BRG;
287 BRG = g_pRouteMan->GetCurrentBrgToActivePoint();
288 double vmg = gSog * cos((BRG - gCog) * PI / 180.);
289 str_buf.Printf("%6.2f", toUsrSpeed(vmg));
290
291 if (m_speedUsed == SPEED_VMG) {
292 // VMG
293 // VMG is always to next waypoint, not to end of route
294 // VMG is SOG x cosine (difference between COG and BRG to Waypoint)
295 speed = vmg;
296 } else {
297 speed = gSog;
298 }
299 } else
300 str_buf = "---";
301
302 pVMG->SetAValue(str_buf);
303
304 if (!g_bShowRouteTotal) {
305 float nrng = g_pRouteMan->GetCurrentRngToActiveNormalArrival();
306 wxString srng;
307 double deltarng = fabs(rng - nrng);
308 if ((deltarng > .01) && ((deltarng / rng) > .10) &&
309 (rng < 10.0)) // show if there is more than 10% difference in
310 // ranges, etc...
311 {
312 if (nrng < 10.0)
313 srng.Printf("%5.2f/%5.2f", toUsrDistance(rng), toUsrDistance(nrng));
314 else
315 srng.Printf("%5.1f/%5.1f", toUsrDistance(rng), toUsrDistance(nrng));
316 } else {
317 if (rng < 10.0)
318 srng.Printf("%6.2f", toUsrDistance(rng));
319 else
320 srng.Printf("%6.1f", toUsrDistance(rng));
321 }
322
323 // RNG to the next WPT
324 pRNG->SetAValue(srng);
325 // XTE
326 str_buf.Printf(
327 "%6.2f", toUsrDistance(g_pRouteMan->GetCurrentXTEToActivePoint()));
328 pXTE->SetAValue(str_buf);
329 if (g_pRouteMan->GetXTEDir() < 0)
330 pXTE->SetALabel(wxString(_("XTE L")));
331 else
332 pXTE->SetALabel(wxString(_("XTE R")));
333 // TTG
334 // In all cases, ttg/eta are declared invalid if VMG <= 0.
335 // If showing only "this leg", use VMG for calculation of ttg
336 wxString ttg_s;
337 if ((speed > 0.) && !std::isnan(gCog) && !std::isnan(gSog)) {
338 float ttg_sec = (rng / speed) * 3600.;
339 wxTimeSpan ttg_span(0, 0, long(ttg_sec), 0);
340 ttg_s = ttg_span.Format();
341 } else
342 ttg_s = "---";
343
344 pTTG->SetAValue(ttg_s);
345 if (m_speedUsed == SPEED_VMG) {
346 pTTG->SetALabel(wxString(_("TTG @VMG")));
347 } else {
348 pTTG->SetALabel(wxString(_("TTG @SOG")));
349 }
350 } else {
351 // Remainder of route
352 float trng = rng;
353
354 Route* prt = g_pRouteMan->GetpActiveRoute();
355 int n_addflag = 0;
356 for (RoutePoint* prp : *prt->pRoutePointList) {
357 if (n_addflag) trng += prp->m_seg_len;
358
359 if (prp == prt->m_pRouteActivePoint) n_addflag++;
360 }
361
362 // total rng
363 wxString strng;
364 if (trng < 10.0)
365 strng.Printf("%6.2f", toUsrDistance(trng));
366 else
367 strng.Printf("%6.1f", toUsrDistance(trng));
368
369 pRNG->SetAValue(strng);
370
371 // total TTG
372 // If showing total route TTG/ETA, use gSog for calculation
373
374 wxString tttg_s;
375 wxTimeSpan tttg_span;
376 float tttg_sec = 0.0;
377 if (speed > 0.) {
378 tttg_sec = (trng / gSog) * 3600.;
379 tttg_span = wxTimeSpan::Seconds((long)tttg_sec);
380 // Show also #days if TTG > 24 h
381 tttg_s = tttg_sec > SECONDS_PER_DAY ? tttg_span.Format(_("%Dd %H:%M"))
382 : tttg_span.Format("%H:%M:%S");
383 } else {
384 tttg_span = wxTimeSpan::Seconds(0);
385 tttg_s = "---";
386 }
387
388 pTTG->SetAValue(tttg_s);
389
390 // total ETA to be shown on XTE panel
391 wxDateTime dtnow, eta;
392 dtnow.SetToCurrent();
393 eta = dtnow.Add(tttg_span);
394 wxString seta;
395
396 if (speed > 0.) {
397 // Show date, e.g. Feb 15, if TTG > 24 h
398 seta = tttg_sec > SECONDS_PER_DAY ? eta.Format("%d/%m %H:%M")
399 : eta.Format("%H:%M");
400 } else {
401 seta = "---";
402 }
403 pXTE->SetAValue(seta);
404 if (m_speedUsed == SPEED_VMG) {
405 pTTG->SetALabel(wxString(_("TTG @VMG")));
406 pXTE->SetALabel(wxString(_("ETA @VMG")));
407 } else {
408 pTTG->SetALabel(wxString(_("TTG @SOG")));
409 pXTE->SetALabel(wxString(_("ETA @SOG")));
410 }
411 }
412
413 pRNG->Refresh();
414 pBRG->Refresh();
415 pVMG->Refresh();
416 pTTG->Refresh();
417 pXTE->Refresh();
418 }
419 }
420}
421
422void ConsoleCanvasWin::RefreshConsoleData() {
424
425 pRNG->Refresh();
426 pBRG->Refresh();
427 pVMG->Refresh();
428 pTTG->Refresh();
429 pXTE->Refresh();
430 pCDI->Refresh();
431}
432
434 Hide();
435 UpdateFonts();
436 gFrame->PositionConsole();
437 Show();
438}
439
440void ConsoleCanvasWin::UpdateFonts() {
441 pBRG->RefreshFonts();
442 pXTE->RefreshFonts();
443 pTTG->RefreshFonts();
444 pRNG->RefreshFonts();
445 pVMG->RefreshFonts();
446
447 m_pitemBoxSizerLeg->SetSizeHints(this);
448 Layout();
449 Fit();
450
451 Refresh();
452}
453
454//------------------------------------------------------------------------------
455// ConsoleCanvasFrame Implementation
456//------------------------------------------------------------------------------
457BEGIN_EVENT_TABLE(ConsoleCanvasFrame, wxWindow)
458EVT_PAINT(ConsoleCanvasFrame::OnPaint)
459EVT_SHOW(ConsoleCanvasFrame::OnShow)
460EVT_CONTEXT_MENU(ConsoleCanvasFrame::OnContextMenu)
461EVT_MENU(ID_NAVLEG, ConsoleCanvasFrame::OnContextMenuSelection)
462EVT_MENU(ID_NAVROUTE, ConsoleCanvasFrame::OnContextMenuSelection)
463EVT_MENU(ID_NAVHIGHWAY, ConsoleCanvasFrame::OnContextMenuSelection)
464END_EVENT_TABLE()
465
466// Define a constructor for my canvas
467ConsoleCanvasFrame::ConsoleCanvasFrame(wxWindow* parent) {
468 m_speedUsed = SPEED_SOG;
469 pbackBrush = NULL;
470 m_bNeedClear = false;
471
472 long style = wxSIMPLE_BORDER | wxCLIP_CHILDREN | wxFRAME_FLOAT_ON_PARENT;
473
474#ifdef __WXMSW__
475 style |= wxFRAME_NO_TASKBAR;
476#endif
477
478 wxFrame::Create(parent, wxID_ANY, "", wxDefaultPosition, wxDefaultSize,
479 style);
480
481 m_pParent = parent;
482
483 m_pitemBoxSizerLeg = new wxBoxSizer(wxVERTICAL);
484
485 pThisLegText = new wxStaticText(this, -1, _("This Leg"));
486 pThisLegText->Fit();
487 m_pitemBoxSizerLeg->Add(pThisLegText, 0, wxALIGN_CENTER_HORIZONTAL, 2);
488
489 wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
490
491 wxFont* pThisLegFont = FontMgr::Get().FindOrCreateFont(
492 qFont->GetPointSize(), wxFONTFAMILY_DEFAULT, qFont->GetStyle(),
493 wxFONTWEIGHT_BOLD, false, qFont->GetFaceName());
494 pThisLegText->SetFont(*pThisLegFont);
495
496 pXTE = new AnnunText(this, -1, _("Console Legend"), _("Console Value"));
497 pXTE->SetALabel("XTE");
498 m_pitemBoxSizerLeg->Add(pXTE, 1, wxALIGN_LEFT | wxALL, 2);
499
500 pBRG = new AnnunText(this, -1, _("Console Legend"), _("Console Value"));
501 pBRG->SetALabel("BRG");
502 m_pitemBoxSizerLeg->Add(pBRG, 1, wxALIGN_LEFT | wxALL, 2);
503
504 pVMG = new AnnunText(this, -1, _("Console Legend"), _("Console Value"));
505 pVMG->SetALabel("VMG");
506 m_pitemBoxSizerLeg->Add(pVMG, 1, wxALIGN_LEFT | wxALL, 2);
507
508 pRNG = new AnnunText(this, -1, _("Console Legend"), _("Console Value"));
509 pRNG->SetALabel("RNG");
510 m_pitemBoxSizerLeg->Add(pRNG, 1, wxALIGN_LEFT | wxALL, 2);
511
512 pTTG = new AnnunText(this, -1, _("Console Legend"), _("Console Value"));
513 pTTG->SetALabel("TTG @VMG");
514 m_pitemBoxSizerLeg->Add(pTTG, 1, wxALIGN_LEFT | wxALL, 2);
515
516 // Create CDI Display Window
517
518 pCDI = new CDI(this, -1, wxSIMPLE_BORDER, "CDI");
519 m_pitemBoxSizerLeg->AddSpacer(5);
520 m_pitemBoxSizerLeg->Add(pCDI, 0, wxALL | wxEXPAND, 2);
521
522 SetSizer(m_pitemBoxSizerLeg); // use the sizer for layout
523 m_pitemBoxSizerLeg->SetSizeHints(this);
524 Layout();
525 Fit();
526
527 if (g_bShowRouteTotal)
528 pThisLegText->SetLabel(_("Route"));
529 else
530 pThisLegText->SetLabel(_("This Leg"));
531
532 Hide();
533}
534
535ConsoleCanvasFrame::~ConsoleCanvasFrame() { delete pCDI; }
536
537void ConsoleCanvasFrame::SetColorScheme(ColorScheme cs) {
538 pbackBrush = wxTheBrushList->FindOrCreateBrush(
539 GetGlobalColor("DILG1" /*UIBDR*/), wxBRUSHSTYLE_SOLID);
540 SetBackgroundColour(GetGlobalColor("DILG1" /*"UIBDR"*/));
541
542 if (g_bShowRouteTotal)
543 pThisLegText->SetLabel(_("Route"));
544 else
545 pThisLegText->SetLabel(_("This Leg"));
546
547 // Also apply color scheme to all known children
548
549 pThisLegText->SetBackgroundColour(GetGlobalColor("DILG1" /*"UIBDR"*/));
550
551 pXTE->SetColorScheme(cs);
552 pBRG->SetColorScheme(cs);
553 pRNG->SetColorScheme(cs);
554 pTTG->SetColorScheme(cs);
555 pVMG->SetColorScheme(cs);
556
557 pCDI->SetColorScheme(cs);
558}
559
560void ConsoleCanvasFrame::OnPaint(wxPaintEvent& event) {
561 wxPaintDC dc(this);
562
563 if (g_pRouteMan->GetpActiveRoute()) {
564 if (m_bNeedClear) {
565 pThisLegText->Refresh();
566 m_bNeedClear = false;
567 }
569 }
570
571 if (!g_bShowActiveRouteHighway) pCDI->Hide();
572}
573
574void ConsoleCanvasFrame::OnShow(wxShowEvent& event) {
575 pCDI->Show(g_bShowActiveRouteHighway);
576 m_pitemBoxSizerLeg->SetSizeHints(this);
577}
578
579void ConsoleCanvasFrame::LegRoute() {
580 if (g_bShowRouteTotal)
581 pThisLegText->SetLabel(_("Route"));
582 else
583 pThisLegText->SetLabel(_("This Leg"));
584
585 pThisLegText->Refresh(true);
586 RefreshConsoleData();
587}
588
589void ConsoleCanvasFrame::OnContextMenu(wxContextMenuEvent& event) {
590 wxMenu* contextMenu = new wxMenu();
591 wxMenuItem* btnLeg =
592 new wxMenuItem(contextMenu, ID_NAVLEG, _("This Leg"), "", wxITEM_RADIO);
593 wxMenuItem* btnRoute = new wxMenuItem(contextMenu, ID_NAVROUTE,
594 _("Full Route"), "", wxITEM_RADIO);
595 wxMenuItem* btnHighw = new wxMenuItem(contextMenu, ID_NAVHIGHWAY,
596 _("Show Highway"), "", wxITEM_CHECK);
597
598#ifdef __ANDROID__
599 wxFont sFont = GetOCPNGUIScaledFont(_("Menu"));
600 btnLeg->SetFont(sFont);
601 btnRoute->SetFont(sFont);
602 btnHighw->SetFont(sFont);
603#endif
604
605 contextMenu->Append(btnLeg);
606 contextMenu->Append(btnRoute);
607 contextMenu->AppendSeparator();
608 contextMenu->Append(btnHighw);
609
610 btnLeg->Check(!g_bShowRouteTotal);
611 btnRoute->Check(g_bShowRouteTotal);
612 btnHighw->Check(g_bShowActiveRouteHighway);
613
614 PopupMenu(contextMenu);
615
616 delete contextMenu;
617}
618
619void ConsoleCanvasFrame::OnContextMenuSelection(wxCommandEvent& event) {
620 switch (event.GetId()) {
621 case ID_NAVLEG: {
622 g_bShowRouteTotal = false;
623 LegRoute();
624 break;
625 }
626 case ID_NAVROUTE: {
627 g_bShowRouteTotal = true;
628 LegRoute();
629 break;
630 }
631 case ID_NAVHIGHWAY: {
632 g_bShowActiveRouteHighway = !g_bShowActiveRouteHighway;
633 if (g_bShowActiveRouteHighway) {
634 pCDI->Show();
635 } else {
636 pCDI->Hide();
637 }
638 m_pitemBoxSizerLeg->SetSizeHints(this);
639 break;
640 }
641 }
642}
643
644void ConsoleCanvasFrame::ToggleShowHighway() {
645 g_bShowActiveRouteHighway = !g_bShowActiveRouteHighway;
646 if (g_bShowActiveRouteHighway) {
647 pCDI->Show();
648 } else {
649 pCDI->Hide();
650 }
651 m_pitemBoxSizerLeg->SetSizeHints(this);
652 Layout();
653}
654
656 // Implement 3-state logic
657 // Route/SOG -> LEG/SOG -> LEG/VMG -> ....
658
659 if (g_bShowRouteTotal) {
660 g_bShowRouteTotal = false;
661 m_speedUsed = SPEED_SOG;
662 } else {
663 if (m_speedUsed == SPEED_VMG) {
664 g_bShowRouteTotal = true;
665 m_speedUsed = SPEED_SOG;
666 } else
667 m_speedUsed = SPEED_VMG;
668 }
669 LegRoute();
670}
671
673 wxString str_buf;
674
675 if (g_pRouteMan->GetpActiveRoute()) {
676 if (g_pRouteMan->m_bDataValid) {
677 // Range to the next waypoint is needed always
678 float rng = g_pRouteMan->GetCurrentRngToActivePoint();
679
680 // Brg to the next waypoint
681 float dcog = g_pRouteMan->GetCurrentBrgToActivePoint();
682 if (dcog >= 359.5) dcog = 0;
683
684 wxString cogstr;
685 if (g_bShowTrue)
686 cogstr << wxString::Format(wxString("%6.0f", wxConvUTF8), dcog);
687 if (g_bShowMag)
688 cogstr << wxString::Format(wxString("%6.0f(M)", wxConvUTF8),
689 toMagnetic(dcog));
690
691 pBRG->SetAValue(cogstr);
692
693 double speed = 0.;
694 if (!std::isnan(gCog) && !std::isnan(gSog)) {
695 double BRG;
696 BRG = g_pRouteMan->GetCurrentBrgToActivePoint();
697 double vmg = gSog * cos((BRG - gCog) * PI / 180.);
698 str_buf.Printf("%6.2f", toUsrSpeed(vmg));
699
700 if (m_speedUsed == SPEED_VMG) {
701 // VMG
702 // VMG is always to next waypoint, not to end of route
703 // VMG is SOG x cosine (difference between COG and BRG to Waypoint)
704 speed = vmg;
705 } else {
706 speed = gSog;
707 }
708 } else
709 str_buf = "---";
710
711 pVMG->SetAValue(str_buf);
712
713 if (!g_bShowRouteTotal) {
714 float nrng = g_pRouteMan->GetCurrentRngToActiveNormalArrival();
715 wxString srng;
716 double deltarng = fabs(rng - nrng);
717 if ((deltarng > .01) && ((deltarng / rng) > .10) &&
718 (rng < 10.0)) // show if there is more than 10% difference in
719 // ranges, etc...
720 {
721 if (nrng < 10.0)
722 srng.Printf("%5.2f/%5.2f", toUsrDistance(rng), toUsrDistance(nrng));
723 else
724 srng.Printf("%5.1f/%5.1f", toUsrDistance(rng), toUsrDistance(nrng));
725 } else {
726 if (rng < 10.0)
727 srng.Printf("%6.2f", toUsrDistance(rng));
728 else
729 srng.Printf("%6.1f", toUsrDistance(rng));
730 }
731
732 // RNG to the next WPT
733 pRNG->SetAValue(srng);
734 // XTE
735 str_buf.Printf(
736 "%6.2f", toUsrDistance(g_pRouteMan->GetCurrentXTEToActivePoint()));
737 pXTE->SetAValue(str_buf);
738 if (g_pRouteMan->GetXTEDir() < 0)
739 pXTE->SetALabel(wxString(_("XTE L")));
740 else
741 pXTE->SetALabel(wxString(_("XTE R")));
742 // TTG
743 // In all cases, ttg/eta are declared invalid if VMG <= 0.
744 // If showing only "this leg", use VMG for calculation of ttg
745 wxString ttg_s;
746 if ((speed > 0.) && !std::isnan(gCog) && !std::isnan(gSog)) {
747 float ttg_sec = (rng / speed) * 3600.;
748 wxTimeSpan ttg_span(0, 0, long(ttg_sec), 0);
749 ttg_s = ttg_span.Format();
750 } else
751 ttg_s = "---";
752
753 pTTG->SetAValue(ttg_s);
754 if (m_speedUsed == SPEED_VMG) {
755 pTTG->SetALabel(wxString(_("TTG @VMG")));
756 } else {
757 pTTG->SetALabel(wxString(_("TTG @SOG")));
758 }
759 } else {
760 // Remainder of route
761 float trng = rng;
762
763 Route* prt = g_pRouteMan->GetpActiveRoute();
764 int n_addflag = 0;
765 for (RoutePoint* prp : *prt->pRoutePointList) {
766 if (n_addflag) trng += prp->m_seg_len;
767
768 if (prp == prt->m_pRouteActivePoint) n_addflag++;
769 }
770
771 // total rng
772 wxString strng;
773 if (trng < 10.0)
774 strng.Printf("%6.2f", toUsrDistance(trng));
775 else
776 strng.Printf("%6.1f", toUsrDistance(trng));
777
778 pRNG->SetAValue(strng);
779
780 // total TTG
781 // If showing total route TTG/ETA, use gSog for calculation
782
783 wxString tttg_s;
784 wxTimeSpan tttg_span;
785 float tttg_sec = 0.0;
786 if (speed > 0.) {
787 tttg_sec = (trng / gSog) * 3600.;
788 tttg_span = wxTimeSpan::Seconds((long)tttg_sec);
789 // Show also #days if TTG > 24 h
790 tttg_s = tttg_sec > SECONDS_PER_DAY ? tttg_span.Format(_("%Dd %H:%M"))
791 : tttg_span.Format("%H:%M:%S");
792 } else {
793 tttg_span = wxTimeSpan::Seconds(0);
794 tttg_s = "---";
795 }
796
797 pTTG->SetAValue(tttg_s);
798
799 // total ETA to be shown on XTE panel
800 wxDateTime dtnow, eta;
801 dtnow.SetToCurrent();
802 eta = dtnow.Add(tttg_span);
803 wxString seta;
804
805 if (speed > 0.) {
806 // Show date, e.g. Feb 15, if TTG > 24 h
807 seta = tttg_sec > SECONDS_PER_DAY ? eta.Format("%d/%m %H:%M")
808 : eta.Format("%H:%M");
809 } else {
810 seta = "---";
811 }
812 pXTE->SetAValue(seta);
813 if (m_speedUsed == SPEED_VMG) {
814 pTTG->SetALabel(wxString(_("TTG @VMG")));
815 pXTE->SetALabel(wxString(_("ETA @VMG")));
816 } else {
817 pTTG->SetALabel(wxString(_("TTG @SOG")));
818 pXTE->SetALabel(wxString(_("ETA @SOG")));
819 }
820 }
821
822 pRNG->Refresh();
823 pBRG->Refresh();
824 pVMG->Refresh();
825 pTTG->Refresh();
826 pXTE->Refresh();
827 }
828 }
829}
830
831void ConsoleCanvasFrame::RefreshConsoleData() {
833
834 pRNG->Refresh();
835 pBRG->Refresh();
836 pVMG->Refresh();
837 pTTG->Refresh();
838 pXTE->Refresh();
839 pCDI->Refresh();
840}
841
843 Hide();
844 Move(0, 0);
845 UpdateFonts();
846 gFrame->PositionConsole();
847 Show();
848}
849
850void ConsoleCanvasFrame::UpdateFonts() {
851 pBRG->RefreshFonts();
852 pXTE->RefreshFonts();
853 pTTG->RefreshFonts();
854 pRNG->RefreshFonts();
855 pVMG->RefreshFonts();
856
857 m_pitemBoxSizerLeg->SetSizeHints(this);
858 Layout();
859 Fit();
860
861 Refresh();
862}
863
864//------------------------------------------------------------------------------
865// AnnunText Implementation
866//------------------------------------------------------------------------------
867BEGIN_EVENT_TABLE(AnnunText, wxWindow)
868EVT_PAINT(AnnunText::OnPaint)
869EVT_MOUSE_EVENTS(AnnunText::MouseEvent)
870END_EVENT_TABLE()
871
872AnnunText::AnnunText(wxWindow* parent, wxWindowID id,
873 const wxString& LegendElement,
874 const wxString& ValueElement)
875 : wxWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxNO_BORDER) {
876 m_label = "Label";
877 m_value = "-----";
878
879 m_plabelFont = FontMgr::Get().FindOrCreateFont(
880 14, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, FALSE,
881 wxString("Arial Bold"));
882 m_pvalueFont = FontMgr::Get().FindOrCreateFont(
883 24, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, FALSE,
884 wxString("helvetica"), wxFONTENCODING_ISO8859_1);
885
886 m_LegendTextElement = LegendElement;
887 m_ValueTextElement = ValueElement;
888
889 RefreshFonts();
890}
891
892AnnunText::~AnnunText() {}
893void AnnunText::MouseEvent(wxMouseEvent& event) {
894 ConsoleCanvasWin* ccpw = dynamic_cast<ConsoleCanvasWin*>(GetParent());
895 if (ccpw) {
896 if (event.RightDown()) {
897 wxContextMenuEvent cevt;
898 cevt.SetPosition(event.GetPosition());
899 ccpw->OnContextMenu(cevt);
900 } else if (event.LeftDown()) {
902 }
903 } else {
904 ConsoleCanvasFrame* ccpf = dynamic_cast<ConsoleCanvasFrame*>(GetParent());
905 if (ccpf) {
906 if (event.RightDown()) {
907 wxContextMenuEvent cevt;
908 cevt.SetPosition(event.GetPosition());
909 ccpf->OnContextMenu(cevt);
910 } else if (event.LeftDown()) {
912 }
913 }
914 }
915}
916
917void AnnunText::CalculateMinSize() {
918 // Calculate the minimum required size of the window based on text size
919
920 int wl = 50; // reasonable defaults?
921 int hl = 20;
922 int wv = 50;
923 int hv = 20;
924
925 if (m_plabelFont)
926 GetTextExtent("TTG @SOG", &wl, &hl, NULL, NULL, m_plabelFont);
927
928 if (m_pvalueFont)
929 GetTextExtent("123.4567", &wv, &hv, NULL, NULL, m_pvalueFont);
930
931 double pdifactor = g_BasePlatform->GetDisplayDIPMult(gFrame);
932 wl *= pdifactor;
933 hl *= pdifactor;
934 wv *= pdifactor;
935 hv *= pdifactor;
936
937 wxSize min;
938 min.x = wv * 1.2;
939 min.x = wxMax(min.x, wl * 1.2);
940 min.y = (int)((hl + hv) * 1.2);
941
942 SetMinSize(min);
943
944 // resize background to the necessary size
945 ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
946 if (style->consoleTextBackground.IsOk()) {
947 wxImage img = style->consoleTextBackground.ConvertToImage();
948 style->consoleTextBackground = wxBitmap(img.Rescale(min.x, min.y));
949 }
950}
951
952void AnnunText::SetColorScheme(ColorScheme cs) {
953 ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
954 m_backBrush = *wxTheBrushList->FindOrCreateBrush(GetGlobalColor("UBLCK"),
955 wxBRUSHSTYLE_SOLID);
956
957 m_default_text_color = style->consoleFontColor;
958 RefreshFonts();
959}
960
961void AnnunText::RefreshFonts() {
962 wxFont* pl = FontMgr::Get().GetFont(m_LegendTextElement);
963 m_plabelFont = FontMgr::Get().FindOrCreateFont(
964 pl->GetPointSize() / OCPN_GetWinDIPScaleFactor(), pl->GetFamily(),
965 pl->GetStyle(), pl->GetWeight(), FALSE, pl->GetFaceName());
966
967 wxFont* pv = FontMgr::Get().GetFont(m_ValueTextElement);
968 m_pvalueFont = FontMgr::Get().FindOrCreateFont(
969 pv->GetPointSize() / OCPN_GetWinDIPScaleFactor(), pv->GetFamily(),
970 pv->GetStyle(), pv->GetWeight(), FALSE, pv->GetFaceName());
971
972 m_legend_color = FontMgr::Get().GetFontColor(_("Console Legend"));
973 m_val_color = FontMgr::Get().GetFontColor(_("Console Value"));
974
975 CalculateMinSize();
976
977 // Make sure that the background color and the text colors are not too close,
978 // for contrast
979 if (m_backBrush.IsOk()) {
980 wxColour back_color = m_backBrush.GetColour();
981
982 wxColour legend_color = m_legend_color;
983 if ((abs(legend_color.Red() - back_color.Red()) < 5) &&
984 (abs(legend_color.Green() - back_color.Blue()) < 5) &&
985 (abs(legend_color.Blue() - back_color.Blue()) < 5))
986 m_legend_color = m_default_text_color;
987
988 wxColour value_color = m_val_color;
989 if ((abs(value_color.Red() - back_color.Red()) < 5) &&
990 (abs(value_color.Green() - back_color.Blue()) < 5) &&
991 (abs(value_color.Blue() - back_color.Blue()) < 5))
992 m_val_color = m_default_text_color;
993 }
994}
995
996void AnnunText::SetLegendElement(const wxString& element) {
997 m_LegendTextElement = element;
998}
999
1000void AnnunText::SetValueElement(const wxString& element) {
1001 m_ValueTextElement = element;
1002}
1003
1004void AnnunText::SetALabel(const wxString& l) { m_label = l; }
1005
1006void AnnunText::SetAValue(const wxString& v) { m_value = v; }
1007
1008void AnnunText::OnPaint(wxPaintEvent& event) {
1009 int sx, sy;
1010 GetClientSize(&sx, &sy);
1011 ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
1012
1013 // Do the drawing on an off-screen memory DC, and blit into place
1014 // to avoid objectionable flashing
1015 wxMemoryDC mdc;
1016
1017 wxBitmap m_bitmap(sx, sy, -1);
1018 mdc.SelectObject(m_bitmap);
1019 mdc.SetBackground(m_backBrush);
1020 mdc.Clear();
1021
1022 if (style->consoleTextBackground.IsOk())
1023 mdc.DrawBitmap(style->consoleTextBackground, 0, 0);
1024
1025 mdc.SetTextForeground(m_default_text_color);
1026
1027 if (m_plabelFont) {
1028 mdc.SetFont(*m_plabelFont);
1029 mdc.SetTextForeground(m_legend_color);
1030 mdc.DrawText(m_label, 5, 2);
1031 }
1032
1033 if (m_pvalueFont) {
1034 mdc.SetFont(*m_pvalueFont);
1035 mdc.SetTextForeground(m_val_color);
1036
1037 int w, h;
1038 mdc.GetTextExtent(m_value, &w, &h);
1039 int cw, ch;
1040 mdc.GetSize(&cw, &ch);
1041
1042 mdc.DrawText(m_value, cw - w - 2, ch - h - 2);
1043 }
1044
1045 wxPaintDC dc(this);
1046 dc.Blit(0, 0, sx, sy, &mdc, 0, 0);
1047}
1048//------------------------------------------------------------------------------
1049// CDI Implementation
1050//------------------------------------------------------------------------------
1051BEGIN_EVENT_TABLE(CDI, wxWindow)
1052EVT_PAINT(CDI::OnPaint)
1053EVT_MOUSE_EVENTS(CDI::MouseEvent)
1054END_EVENT_TABLE()
1055
1056CDI::CDI(wxWindow* parent, wxWindowID id, long style, const wxString& name)
1057 : wxWindow(parent, id, wxDefaultPosition, wxDefaultSize, style, name)
1058
1059{
1060 SetMinSize(wxSize(10, 150));
1061}
1062
1063void CDI::MouseEvent(wxMouseEvent& event) {
1064#ifdef __ANDROID__
1065 if (event.RightDown()) {
1066 qDebug() << "right down";
1067
1068 wxContextMenuEvent cevt;
1069 cevt.SetPosition(event.GetPosition());
1070
1071 ConsoleCanvasFrame* ccp = dynamic_cast<ConsoleCanvasFrame*>(GetParent());
1072 if (ccp) ccp->OnContextMenu(cevt);
1073 }
1074#endif
1075}
1076
1077void CDI::SetColorScheme(ColorScheme cs) {
1078 m_pbackBrush = wxTheBrushList->FindOrCreateBrush(GetGlobalColor("DILG2"),
1079 wxBRUSHSTYLE_SOLID);
1080 m_proadBrush = wxTheBrushList->FindOrCreateBrush(GetGlobalColor("DILG1"),
1081 wxBRUSHSTYLE_SOLID);
1082 m_proadPen = wxThePenList->FindOrCreatePen(GetGlobalColor("CHBLK"), 1,
1083 wxPENSTYLE_SOLID);
1084}
1085
1086void CDI::OnPaint(wxPaintEvent& event) {
1087 int sx, sy;
1088 GetClientSize(&sx, &sy);
1089
1090 // Do the drawing on an off-screen memory DC, and blit into place
1091 // to avoid objectionable flashing
1092 wxMemoryDC mdc;
1093
1094 wxBitmap m_bitmap(sx, sy, -1);
1095 mdc.SelectObject(m_bitmap);
1096 mdc.SetBackground(*m_pbackBrush);
1097 mdc.Clear();
1098
1099 int xp = sx / 2;
1100 int yp = sy * 9 / 10;
1101
1102 int path_length = sy * 3;
1103 int pix_per_xte = 120;
1104
1105 if (g_pRouteMan->GetpActiveRoute()) {
1106 double angle = 90 - (g_pRouteMan->GetCurrentSegmentCourse() - gCog);
1107
1108 double dy = path_length * sin(angle * PI / 180.);
1109 double dx = path_length * cos(angle * PI / 180.);
1110
1111 int xtedir;
1112 xtedir = g_pRouteMan->GetXTEDir();
1113 double xte = g_pRouteMan->GetCurrentXTEToActivePoint();
1114
1115 double ddy = xtedir * pix_per_xte * xte * sin((90 - angle) * PI / 180.);
1116 double ddx = xtedir * pix_per_xte * xte * cos((90 - angle) * PI / 180.);
1117
1118 int ddxi = (int)ddx;
1119 int ddyi = (int)ddy;
1120
1121 int xc1 = xp - (int)(dx / 2) + ddxi;
1122 int yc1 = yp + (int)(dy / 2) + ddyi;
1123 int xc2 = xp + (int)(dx / 2) + ddxi;
1124 int yc2 = yp - (int)(dy / 2) + ddyi;
1125
1126 wxPoint road[4];
1127
1128 int road_top_width = 10;
1129 int road_bot_width = 40;
1130
1131 road[0].x = xc1 - (int)(road_bot_width * cos((90 - angle) * PI / 180.));
1132 road[0].y = yc1 - (int)(road_bot_width * sin((90 - angle) * PI / 180.));
1133
1134 road[1].x = xc2 - (int)(road_top_width * cos((90 - angle) * PI / 180.));
1135 road[1].y = yc2 - (int)(road_top_width * sin((90 - angle) * PI / 180.));
1136
1137 road[2].x = xc2 + (int)(road_top_width * cos((90 - angle) * PI / 180.));
1138 road[2].y = yc2 + (int)(road_top_width * sin((90 - angle) * PI / 180.));
1139
1140 road[3].x = xc1 + (int)(road_bot_width * cos((90 - angle) * PI / 180.));
1141 road[3].y = yc1 + (int)(road_bot_width * sin((90 - angle) * PI / 180.));
1142
1143 mdc.SetBrush(*m_proadBrush);
1144 mdc.SetPen(*m_proadPen);
1145 mdc.DrawPolygon(4, road, 0, 0, wxODDEVEN_RULE);
1146
1148
1149 mdc.DrawLine(0, yp, sx, yp);
1150 mdc.DrawCircle(xp, yp, 6);
1151 mdc.DrawLine(xp, yp + 5, xp, yp - 5);
1152 }
1153
1154 wxPaintDC dc(this);
1155 dc.Blit(0, 0, sx, sy, &mdc, 0, 0);
1156}
1157
1158#if defined(__WXMSW__) || defined(__WXMAC__) || defined(__ANDROID__)
1159APConsole::APConsole(wxWindow* parent) {
1160 m_con_frame = new ConsoleCanvasFrame(gFrame);
1161}
1162APConsole::~APConsole() {}
1163void APConsole::SetColorScheme(ColorScheme cs) {
1164 m_con_frame->SetColorScheme(cs);
1165}
1166bool APConsole::IsShown() { return m_con_frame->IsShown(); }
1167void APConsole::UpdateFonts() { m_con_frame->UpdateFonts(); }
1168void APConsole::RefreshConsoleData() { m_con_frame->RefreshConsoleData(); }
1169void APConsole::Raise() { m_con_frame->Raise(); }
1170void APConsole::ShowWithFreshFonts() { m_con_frame->ShowWithFreshFonts(); }
1171void APConsole::Show(bool bshow) { m_con_frame->Show(bshow); }
1172CDI* APConsole::GetCDI() { return m_con_frame->pCDI; }
1173wxSize APConsole::GetSize() { return m_con_frame->GetSize(); }
1174void APConsole::ToggleShowHighway() { m_con_frame->ToggleShowHighway(); }
1175void APConsole::Move(wxPoint p) { m_con_frame->Move(p); }
1176
1177#else
1178
1179APConsole::APConsole(wxWindow* parent) {
1180 m_con_win = new ConsoleCanvasWin(parent);
1181}
1182APConsole::~APConsole() {}
1183void APConsole::SetColorScheme(ColorScheme cs) {
1184 m_con_win->SetColorScheme(cs);
1185}
1186bool APConsole::IsShown() { return m_con_win->IsShown(); }
1187void APConsole::UpdateFonts() { m_con_win->UpdateFonts(); }
1188void APConsole::RefreshConsoleData() { m_con_win->RefreshConsoleData(); }
1189void APConsole::Raise() {}
1190void APConsole::ShowWithFreshFonts() { m_con_win->ShowWithFreshFonts(); }
1191void APConsole::Show(bool bshow) { m_con_win->Show(bshow); }
1192CDI* APConsole::GetCDI() { return m_con_win->pCDI; }
1193wxSize APConsole::GetSize() { return m_con_win->GetSize(); }
1194void APConsole::ToggleShowHighway() { m_con_win->ToggleShowHighway(); }
1195void APConsole::Move(wxPoint p) { m_con_win->Move(p); }
1196
1197#endif
BasePlatform * g_BasePlatform
points to g_platform, handles brain-dead MS linker.
double GetDisplayDIPMult(wxWindow *win)
Get the display scaling factor for DPI-aware rendering.
Annunciator Text display.
Definition concanv.h:60
Course Deviation Indicator display.
Definition concanv.h:41
void OnPaint(wxPaintEvent &event)
Definition concanv.cpp:1086
void ToggleRouteTotalDisplay()
Toggles between route total and current leg display modes.
Definition concanv.cpp:655
void ShowWithFreshFonts(void)
Recomputes and applies new fonts to console elements.
Definition concanv.cpp:842
void UpdateRouteData()
Updates route-related data displays.
Definition concanv.cpp:672
Primary navigation console display for route and vessel tracking.
Definition concanv.h:118
void UpdateRouteData()
Updates route-related data displays.
Definition concanv.cpp:264
void ShowWithFreshFonts(void)
Recomputes and applies new fonts to console elements.
Definition concanv.cpp:433
void ToggleRouteTotalDisplay()
Toggles between route total and current leg display modes.
Definition concanv.cpp:247
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
Definition font_mgr.cpp:442
wxColour GetFontColor(const wxString &TextElement) const
Gets the text color for a UI element.
Definition font_mgr.cpp:110
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Get a font object for a UI element.
Definition font_mgr.cpp:193
Represents a waypoint or mark within the navigation system.
Definition route_point.h:71
Represents a navigational route in the navigation system.
Definition route.h:99
RoutePointList * pRoutePointList
Ordered list of waypoints (RoutePoints) that make up this route.
Definition route.h:336
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
Definition route.h:214
APConsole * console
Global instance.
Definition concanv.cpp:54
Primary navigation console display for route and vessel tracking.
Global variables stored in configuration file.
Font list manager.
Platform independent GL includes.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
Definition gui_lib.cpp:61
wxFont GetOCPNGUIScaledFont(wxString item)
Retrieves a font optimized for touch and high-resolution interfaces.
Definition gui_lib.cpp:90
General purpose GUI support.
Utility functions.
double toUsrDistance(double nm_distance, int unit)
Convert a distance from nautical miles (NMi) to user display units.
Navigation Utility Functions without GUI dependencies.
OpenCPN top window.
OpenCPN Platform specific support utilities.
PlugIn Object Definition/API.
double OCPN_GetWinDIPScaleFactor()
Gets Windows-specific DPI scaling factor.
double gCog
Course over ground in degrees (0-359.99).
Definition own_ship.cpp:28
double gSog
Speed over ground in knots.
Definition own_ship.cpp:29
Position, course, speed, etc.
Route abstraction.
Routeman * g_pRouteMan
Global instance.
Definition routeman.cpp:60
Route Manager.
Chart Symbols.