OpenCPN Partial API docs
Loading...
Searching...
No Matches
concanv.cpp
1/******************************************************************************
2 *
3 * Project: OpenCPN
4 * Purpose: Console Canvas
5 * Author: David Register
6 *
7 ***************************************************************************
8 * Copyright (C) 2010 by David S. Register *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
24 ***************************************************************************
25 *
26 *
27 *
28 */
29
30#include <wx/wxprec.h>
31
32#ifndef WX_PRECOMP
33#include <wx/wx.h>
34#endif // precompiled headers
35
36#include <stdlib.h>
37#include <math.h>
38#include <time.h>
39#include <wx/datetime.h>
40
41#include "model/navutil_base.h"
42#include "model/own_ship.h"
43#include "model/route.h"
44#include "model/routeman.h"
45#include "model/wx28compat.h"
46
47#include "concanv.h"
48#include "FontMgr.h"
49#include "gui_lib.h"
50#include "navutil.h"
51#include "ocpn_frame.h"
52#include "OCPNPlatform.h"
53#include "ocpn_plugin.h"
54#include "styles.h"
55
56extern Routeman* g_pRouteMan;
57extern MyFrame* gFrame;
58extern bool g_bShowActiveRouteHighway;
59extern BasePlatform* g_BasePlatform;
60
61bool g_bShowRouteTotal;
62
63extern ocpnStyle::StyleManager* g_StyleManager;
64
65enum eMenuItems { ID_NAVLEG = 1, ID_NAVROUTE, ID_NAVHIGHWAY } menuItems;
66
67//------------------------------------------------------------------------------
68// ConsoleCanvas Implementation
69//------------------------------------------------------------------------------
70BEGIN_EVENT_TABLE(ConsoleCanvas, wxWindow)
71EVT_PAINT(ConsoleCanvas::OnPaint)
72EVT_SHOW(ConsoleCanvas::OnShow)
73EVT_CONTEXT_MENU(ConsoleCanvas::OnContextMenu)
74EVT_MENU(ID_NAVLEG, ConsoleCanvas::OnContextMenuSelection)
75EVT_MENU(ID_NAVROUTE, ConsoleCanvas::OnContextMenuSelection)
76EVT_MENU(ID_NAVHIGHWAY, ConsoleCanvas::OnContextMenuSelection)
77
78END_EVENT_TABLE()
79
80// Define a constructor for my canvas
81ConsoleCanvas::ConsoleCanvas(wxWindow* frame) {
82 m_speedUsed = SPEED_SOG;
83 pbackBrush = NULL;
84 m_bNeedClear = false;
85
86 long style = wxSIMPLE_BORDER | wxCLIP_CHILDREN | wxFRAME_FLOAT_ON_PARENT;
87
88#ifdef __WXMSW__
89 style |= wxFRAME_NO_TASKBAR;
90#endif
91
92 wxFrame::Create(frame, wxID_ANY, _T(""), wxDefaultPosition, wxDefaultSize,
93 style);
94
95 m_pParent = frame;
96
97 m_pitemBoxSizerLeg = new wxBoxSizer(wxVERTICAL);
98
99 pThisLegText = new wxStaticText(this, -1, _("This Leg"));
100 pThisLegText->Fit();
101 m_pitemBoxSizerLeg->Add(pThisLegText, 0, wxALIGN_CENTER_HORIZONTAL, 2);
102
103 wxFont* qFont = GetOCPNScaledFont(_("Dialog"));
104
105 wxFont* pThisLegFont = FontMgr::Get().FindOrCreateFont(
106 10, wxFONTFAMILY_DEFAULT, qFont->GetStyle(), wxFONTWEIGHT_BOLD, false,
107 qFont->GetFaceName());
108 pThisLegText->SetFont(*pThisLegFont);
109
110 pXTE = new AnnunText(this, -1, _("Console Legend"), _("Console Value"));
111 pXTE->SetALabel(_T("XTE"));
112 m_pitemBoxSizerLeg->Add(pXTE, 1, wxALIGN_LEFT | wxALL, 2);
113
114 pBRG = new AnnunText(this, -1, _("Console Legend"), _("Console Value"));
115 pBRG->SetALabel(_T("BRG"));
116 m_pitemBoxSizerLeg->Add(pBRG, 1, wxALIGN_LEFT | wxALL, 2);
117
118 pVMG = new AnnunText(this, -1, _("Console Legend"), _("Console Value"));
119 pVMG->SetALabel(_T("VMG"));
120 m_pitemBoxSizerLeg->Add(pVMG, 1, wxALIGN_LEFT | wxALL, 2);
121
122 pRNG = new AnnunText(this, -1, _("Console Legend"), _("Console Value"));
123 pRNG->SetALabel(_T("RNG"));
124 m_pitemBoxSizerLeg->Add(pRNG, 1, wxALIGN_LEFT | wxALL, 2);
125
126 pTTG = new AnnunText(this, -1, _("Console Legend"), _("Console Value"));
127 pTTG->SetALabel(_T("TTG @VMG"));
128 m_pitemBoxSizerLeg->Add(pTTG, 1, wxALIGN_LEFT | wxALL, 2);
129
130 // Create CDI Display Window
131
132 pCDI = new CDI(this, -1, wxSIMPLE_BORDER, _T("CDI"));
133 m_pitemBoxSizerLeg->AddSpacer(5);
134 m_pitemBoxSizerLeg->Add(pCDI, 0, wxALL | wxEXPAND, 2);
135
136 SetSizer(m_pitemBoxSizerLeg); // use the sizer for layout
137 m_pitemBoxSizerLeg->SetSizeHints(this);
138 Layout();
139 Fit();
140
141 if (g_bShowRouteTotal)
142 pThisLegText->SetLabel(_("Route"));
143 else
144 pThisLegText->SetLabel(_("This Leg"));
145
146 Hide();
147}
148
149ConsoleCanvas::~ConsoleCanvas() { delete pCDI; }
150
151void ConsoleCanvas::SetColorScheme(ColorScheme cs) {
152 pbackBrush = wxTheBrushList->FindOrCreateBrush(
153 GetGlobalColor(_T("DILG1" /*UIBDR*/)), wxBRUSHSTYLE_SOLID);
154 SetBackgroundColour(GetGlobalColor(_T("DILG1" /*"UIBDR"*/)));
155
156 if (g_bShowRouteTotal)
157 pThisLegText->SetLabel(_("Route"));
158 else
159 pThisLegText->SetLabel(_("This Leg"));
160
161 // Also apply color scheme to all known children
162
163 pThisLegText->SetBackgroundColour(GetGlobalColor(_T("DILG1" /*"UIBDR"*/)));
164
165 pXTE->SetColorScheme(cs);
166 pBRG->SetColorScheme(cs);
167 pRNG->SetColorScheme(cs);
168 pTTG->SetColorScheme(cs);
169 pVMG->SetColorScheme(cs);
170
171 pCDI->SetColorScheme(cs);
172}
173
174void ConsoleCanvas::OnPaint(wxPaintEvent& event) {
175 wxPaintDC dc(this);
176
177 if (g_pRouteMan->GetpActiveRoute()) {
178 if (m_bNeedClear) {
179 pThisLegText->Refresh();
180 m_bNeedClear = false;
181 }
182
184 }
185
186 if (!g_bShowActiveRouteHighway) pCDI->Hide();
187}
188
189void ConsoleCanvas::OnShow(wxShowEvent& event) {
190 pCDI->Show(g_bShowActiveRouteHighway);
191 m_pitemBoxSizerLeg->SetSizeHints(this);
192}
193
194void ConsoleCanvas::LegRoute() {
195 if (g_bShowRouteTotal)
196 pThisLegText->SetLabel(_("Route"));
197 else
198 pThisLegText->SetLabel(_("This Leg"));
199
200 pThisLegText->Refresh(true);
201 RefreshConsoleData();
202}
203
204void ConsoleCanvas::OnContextMenu(wxContextMenuEvent& event) {
205 wxMenu* contextMenu = new wxMenu();
206 wxMenuItem* btnLeg = new wxMenuItem(contextMenu, ID_NAVLEG, _("This Leg"),
207 _T(""), wxITEM_RADIO);
208 wxMenuItem* btnRoute = new wxMenuItem(contextMenu, ID_NAVROUTE,
209 _("Full Route"), _T(""), wxITEM_RADIO);
210 wxMenuItem* btnHighw = new wxMenuItem(
211 contextMenu, ID_NAVHIGHWAY, _("Show Highway"), _T(""), wxITEM_CHECK);
212 contextMenu->Append(btnLeg);
213 contextMenu->Append(btnRoute);
214 contextMenu->AppendSeparator();
215 contextMenu->Append(btnHighw);
216
217 btnLeg->Check(!g_bShowRouteTotal);
218 btnRoute->Check(g_bShowRouteTotal);
219 btnHighw->Check(g_bShowActiveRouteHighway);
220
221 PopupMenu(contextMenu);
222
223 delete contextMenu;
224}
225
226void ConsoleCanvas::OnContextMenuSelection(wxCommandEvent& event) {
227 switch (event.GetId()) {
228 case ID_NAVLEG: {
229 g_bShowRouteTotal = false;
230 LegRoute();
231 break;
232 }
233 case ID_NAVROUTE: {
234 g_bShowRouteTotal = true;
235 LegRoute();
236 break;
237 }
238 case ID_NAVHIGHWAY: {
239 g_bShowActiveRouteHighway = !g_bShowActiveRouteHighway;
240 if (g_bShowActiveRouteHighway) {
241 pCDI->Show();
242 } else {
243 pCDI->Hide();
244 }
245 m_pitemBoxSizerLeg->SetSizeHints(this);
246 break;
247 }
248 }
249}
250
252 // Implement 3-state logic
253 // Route/SOG -> LEG/SOG -> LEG/VMG -> ....
254
255 if (g_bShowRouteTotal) {
256 g_bShowRouteTotal = false;
257 m_speedUsed = SPEED_SOG;
258 } else {
259 if (m_speedUsed == SPEED_VMG) {
260 g_bShowRouteTotal = true;
261 m_speedUsed = SPEED_SOG;
262 } else
263 m_speedUsed = SPEED_VMG;
264 }
265 LegRoute();
266}
267
269 wxString str_buf;
270
271 if (g_pRouteMan->GetpActiveRoute()) {
272 if (g_pRouteMan->m_bDataValid) {
273 // Range to the next waypoint is needed always
274 float rng = g_pRouteMan->GetCurrentRngToActivePoint();
275
276 // Brg to the next waypoint
277 float dcog = g_pRouteMan->GetCurrentBrgToActivePoint();
278 if (dcog >= 359.5) dcog = 0;
279
280 wxString cogstr;
281 if (g_bShowTrue)
282 cogstr << wxString::Format(wxString("%6.0f", wxConvUTF8), dcog);
283 if (g_bShowMag)
284 cogstr << wxString::Format(wxString("%6.0f(M)", wxConvUTF8),
285 toMagnetic(dcog));
286
287 pBRG->SetAValue(cogstr);
288
289 double speed = 0.;
290 if (!std::isnan(gCog) && !std::isnan(gSog)) {
291 double BRG;
292 BRG = g_pRouteMan->GetCurrentBrgToActivePoint();
293 double vmg = gSog * cos((BRG - gCog) * PI / 180.);
294 str_buf.Printf(_T("%6.2f"), toUsrSpeed(vmg));
295
296 if (m_speedUsed == SPEED_VMG) {
297 // VMG
298 // VMG is always to next waypoint, not to end of route
299 // VMG is SOG x cosine (difference between COG and BRG to Waypoint)
300 speed = vmg;
301 } else {
302 speed = gSog;
303 }
304 } else
305 str_buf = _T("---");
306
307 pVMG->SetAValue(str_buf);
308
309 if (!g_bShowRouteTotal) {
310 float nrng = g_pRouteMan->GetCurrentRngToActiveNormalArrival();
311 wxString srng;
312 double deltarng = fabs(rng - nrng);
313 if ((deltarng > .01) && ((deltarng / rng) > .10) &&
314 (rng < 10.0)) // show if there is more than 10% difference in
315 // ranges, etc...
316 {
317 if (nrng < 10.0)
318 srng.Printf(_T("%5.2f/%5.2f"), toUsrDistance(rng),
319 toUsrDistance(nrng));
320 else
321 srng.Printf(_T("%5.1f/%5.1f"), toUsrDistance(rng),
322 toUsrDistance(nrng));
323 } else {
324 if (rng < 10.0)
325 srng.Printf(_T("%6.2f"), toUsrDistance(rng));
326 else
327 srng.Printf(_T("%6.1f"), toUsrDistance(rng));
328 }
329
330 // RNG to the next WPT
331 pRNG->SetAValue(srng);
332 // XTE
333 str_buf.Printf(
334 _T("%6.2f"),
335 toUsrDistance(g_pRouteMan->GetCurrentXTEToActivePoint()));
336 pXTE->SetAValue(str_buf);
337 if (g_pRouteMan->GetXTEDir() < 0)
338 pXTE->SetALabel(wxString(_("XTE L")));
339 else
340 pXTE->SetALabel(wxString(_("XTE R")));
341 // TTG
342 // In all cases, ttg/eta are declared invalid if VMG <= 0.
343 // If showing only "this leg", use VMG for calculation of ttg
344 wxString ttg_s;
345 if ((speed > 0.) && !std::isnan(gCog) && !std::isnan(gSog)) {
346 float ttg_sec = (rng / speed) * 3600.;
347 wxTimeSpan ttg_span(0, 0, long(ttg_sec), 0);
348 ttg_s = ttg_span.Format();
349 } else
350 ttg_s = _T("---");
351
352 pTTG->SetAValue(ttg_s);
353 if (m_speedUsed == SPEED_VMG) {
354 pTTG->SetALabel(wxString(_("TTG @VMG")));
355 } else {
356 pTTG->SetALabel(wxString(_("TTG @SOG")));
357 }
358 } else {
359 // Remainder of route
360 float trng = rng;
361
362 Route* prt = g_pRouteMan->GetpActiveRoute();
363 wxRoutePointListNode* node = (prt->pRoutePointList)->GetFirst();
364 RoutePoint* prp;
365
366 int n_addflag = 0;
367 while (node) {
368 prp = node->GetData();
369 if (n_addflag) trng += prp->m_seg_len;
370
371 if (prp == prt->m_pRouteActivePoint) n_addflag++;
372
373 node = node->GetNext();
374 }
375
376 // total rng
377 wxString strng;
378 if (trng < 10.0)
379 strng.Printf(_T("%6.2f"), toUsrDistance(trng));
380 else
381 strng.Printf(_T("%6.1f"), toUsrDistance(trng));
382
383 pRNG->SetAValue(strng);
384
385 // total TTG
386 // If showing total route TTG/ETA, use gSog for calculation
387
388 wxString tttg_s;
389 wxTimeSpan tttg_span;
390 float tttg_sec = 0.0;
391 if (speed > 0.) {
392 tttg_sec = (trng / gSog) * 3600.;
393 tttg_span = wxTimeSpan::Seconds((long)tttg_sec);
394 // Show also #days if TTG > 24 h
395 tttg_s = tttg_sec > SECONDS_PER_DAY ? tttg_span.Format(_("%Dd %H:%M"))
396 : tttg_span.Format("%H:%M:%S");
397 } else {
398 tttg_span = wxTimeSpan::Seconds(0);
399 tttg_s = _T("---");
400 }
401
402 pTTG->SetAValue(tttg_s);
403
404 // total ETA to be shown on XTE panel
405 wxDateTime dtnow, eta;
406 dtnow.SetToCurrent();
407 eta = dtnow.Add(tttg_span);
408 wxString seta;
409
410 if (speed > 0.) {
411 // Show date, e.g. Feb 15, if TTG > 24 h
412 seta = tttg_sec > SECONDS_PER_DAY ? eta.Format(_T("%d/%m %H:%M"))
413 : eta.Format(_T("%H:%M"));
414 } else {
415 seta = _T("---");
416 }
417 pXTE->SetAValue(seta);
418 if (m_speedUsed == SPEED_VMG) {
419 pTTG->SetALabel(wxString(_("TTG @VMG")));
420 pXTE->SetALabel(wxString(_("ETA @VMG")));
421 } else {
422 pTTG->SetALabel(wxString(_("TTG @SOG")));
423 pXTE->SetALabel(wxString(_("ETA @SOG")));
424 }
425 }
426
427 pRNG->Refresh();
428 pBRG->Refresh();
429 pVMG->Refresh();
430 pTTG->Refresh();
431 pXTE->Refresh();
432 }
433 }
434}
435
436void ConsoleCanvas::RefreshConsoleData(void) {
438
439 pRNG->Refresh();
440 pBRG->Refresh();
441 pVMG->Refresh();
442 pTTG->Refresh();
443 pXTE->Refresh();
444 pCDI->Refresh();
445}
446
448 Hide();
449 Move(0, 0);
450
451 UpdateFonts();
452 gFrame->PositionConsole();
453 Show();
454}
455
456void ConsoleCanvas::UpdateFonts(void) {
457 pBRG->RefreshFonts();
458 pXTE->RefreshFonts();
459 pTTG->RefreshFonts();
460 pRNG->RefreshFonts();
461 pVMG->RefreshFonts();
462
463 m_pitemBoxSizerLeg->SetSizeHints(this);
464 Layout();
465 Fit();
466
467 Refresh();
468}
469
470//------------------------------------------------------------------------------
471// AnnunText Implementation
472//------------------------------------------------------------------------------
473BEGIN_EVENT_TABLE(AnnunText, wxWindow)
474EVT_PAINT(AnnunText::OnPaint)
475EVT_MOUSE_EVENTS(AnnunText::MouseEvent)
476END_EVENT_TABLE()
477
478AnnunText::AnnunText(wxWindow* parent, wxWindowID id,
479 const wxString& LegendElement,
480 const wxString& ValueElement)
481 : wxWindow(parent, id, wxDefaultPosition, wxDefaultSize, wxNO_BORDER) {
482 m_label = _T("Label");
483 m_value = _T("-----");
484
485 m_plabelFont = FontMgr::Get().FindOrCreateFont(
486 14, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, FALSE,
487 wxString(_T("Arial Bold")));
488 m_pvalueFont = FontMgr::Get().FindOrCreateFont(
489 24, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, FALSE,
490 wxString(_T("helvetica")), wxFONTENCODING_ISO8859_1);
491
492 m_LegendTextElement = LegendElement;
493 m_ValueTextElement = ValueElement;
494
495 RefreshFonts();
496}
497
498AnnunText::~AnnunText() {}
499void AnnunText::MouseEvent(wxMouseEvent& event) {
500 if (event.RightDown()) {
501 wxContextMenuEvent cevt;
502 cevt.SetPosition(event.GetPosition());
503
504 ConsoleCanvas* ccp = dynamic_cast<ConsoleCanvas*>(GetParent());
505 if (ccp) ccp->OnContextMenu(cevt);
506
507 } else if (event.LeftDown()) {
508 ConsoleCanvas* ccp = dynamic_cast<ConsoleCanvas*>(GetParent());
509 if (ccp) {
511 }
512 }
513}
514
515void AnnunText::CalculateMinSize(void) {
516 // Calculate the minimum required size of the window based on text size
517
518 int wl = 50; // reasonable defaults?
519 int hl = 20;
520 int wv = 50;
521 int hv = 20;
522
523 if (m_plabelFont)
524 GetTextExtent(_T("1234"), &wl, &hl, NULL, NULL, m_plabelFont);
525
526 if (m_pvalueFont)
527 GetTextExtent(_T("123.4567"), &wv, &hv, NULL, NULL, m_pvalueFont);
528
529 double pdifactor = g_BasePlatform->GetDisplayDIPMult(gFrame);
530 wl *= pdifactor;
531 hl *= pdifactor;
532 wv *= pdifactor;
533 hv *= pdifactor;
534
535 wxSize min;
536 min.x = wl + wv;
537
538 // Space is tight on Android....
539#ifdef __ANDROID__
540 min.x = wv * 1.2;
541#endif
542
543 min.y = (int)((hl + hv) * 1.2);
544
545 SetMinSize(min);
546
547 // resize background to the necessary size
548 ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
549 if (style->consoleTextBackground.IsOk()) {
550 wxImage img = style->consoleTextBackground.ConvertToImage();
551 style->consoleTextBackground = wxBitmap(img.Rescale(min.x, min.y));
552 }
553}
554
555void AnnunText::SetColorScheme(ColorScheme cs) {
556 ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
557 m_backBrush = *wxTheBrushList->FindOrCreateBrush(GetGlobalColor(_T("UBLCK")),
558 wxBRUSHSTYLE_SOLID);
559
560 m_default_text_color = style->consoleFontColor;
561 RefreshFonts();
562}
563
564void AnnunText::RefreshFonts() {
565 wxFont* pl = FontMgr::Get().GetFont(m_LegendTextElement);
566 m_plabelFont = FontMgr::Get().FindOrCreateFont(
567 pl->GetPointSize() / OCPN_GetWinDIPScaleFactor(), pl->GetFamily(),
568 pl->GetStyle(), pl->GetWeight(), FALSE, pl->GetFaceName());
569
570 wxFont* pv = FontMgr::Get().GetFont(m_ValueTextElement);
571 m_pvalueFont = FontMgr::Get().FindOrCreateFont(
572 pv->GetPointSize() / OCPN_GetWinDIPScaleFactor(), pv->GetFamily(),
573 pv->GetStyle(), pv->GetWeight(), FALSE, pv->GetFaceName());
574
575 m_legend_color = FontMgr::Get().GetFontColor(_("Console Legend"));
576 m_val_color = FontMgr::Get().GetFontColor(_("Console Value"));
577
578 CalculateMinSize();
579
580 // Make sure that the background color and the text colors are not too close,
581 // for contrast
582 if (m_backBrush.IsOk()) {
583 wxColour back_color = m_backBrush.GetColour();
584
585 wxColour legend_color = m_legend_color;
586 if ((abs(legend_color.Red() - back_color.Red()) < 5) &&
587 (abs(legend_color.Green() - back_color.Blue()) < 5) &&
588 (abs(legend_color.Blue() - back_color.Blue()) < 5))
589 m_legend_color = m_default_text_color;
590
591 wxColour value_color = m_val_color;
592 if ((abs(value_color.Red() - back_color.Red()) < 5) &&
593 (abs(value_color.Green() - back_color.Blue()) < 5) &&
594 (abs(value_color.Blue() - back_color.Blue()) < 5))
595 m_val_color = m_default_text_color;
596 }
597}
598
599void AnnunText::SetLegendElement(const wxString& element) {
600 m_LegendTextElement = element;
601}
602
603void AnnunText::SetValueElement(const wxString& element) {
604 m_ValueTextElement = element;
605}
606
607void AnnunText::SetALabel(const wxString& l) { m_label = l; }
608
609void AnnunText::SetAValue(const wxString& v) { m_value = v; }
610
611void AnnunText::OnPaint(wxPaintEvent& event) {
612 int sx, sy;
613 GetClientSize(&sx, &sy);
614 ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
615
616 // Do the drawing on an off-screen memory DC, and blit into place
617 // to avoid objectionable flashing
618 wxMemoryDC mdc;
619
620 wxBitmap m_bitmap(sx, sy, -1);
621 mdc.SelectObject(m_bitmap);
622 mdc.SetBackground(m_backBrush);
623 mdc.Clear();
624
625 if (style->consoleTextBackground.IsOk())
626 mdc.DrawBitmap(style->consoleTextBackground, 0, 0);
627
628 mdc.SetTextForeground(m_default_text_color);
629
630 if (m_plabelFont) {
631 mdc.SetFont(*m_plabelFont);
632 mdc.SetTextForeground(m_legend_color);
633 mdc.DrawText(m_label, 5, 2);
634 }
635
636 if (m_pvalueFont) {
637 mdc.SetFont(*m_pvalueFont);
638 mdc.SetTextForeground(m_val_color);
639
640 int w, h;
641 mdc.GetTextExtent(m_value, &w, &h);
642 int cw, ch;
643 mdc.GetSize(&cw, &ch);
644
645 mdc.DrawText(m_value, cw - w - 2, ch - h - 2);
646 }
647
648 wxPaintDC dc(this);
649 dc.Blit(0, 0, sx, sy, &mdc, 0, 0);
650}
651//------------------------------------------------------------------------------
652// CDI Implementation
653//------------------------------------------------------------------------------
654BEGIN_EVENT_TABLE(CDI, wxWindow)
655EVT_PAINT(CDI::OnPaint)
656EVT_MOUSE_EVENTS(CDI::MouseEvent)
657END_EVENT_TABLE()
658
659CDI::CDI(wxWindow* parent, wxWindowID id, long style, const wxString& name)
660 : wxWindow(parent, id, wxDefaultPosition, wxDefaultSize, style, name)
661
662{
663 SetMinSize(wxSize(10, 150));
664}
665
666void CDI::MouseEvent(wxMouseEvent& event) {
667#ifdef __ANDROID__
668 if (event.RightDown()) {
669 qDebug() << "right down";
670
671 wxContextMenuEvent cevt;
672 cevt.SetPosition(event.GetPosition());
673
674 ConsoleCanvas* ccp = dynamic_cast<ConsoleCanvas*>(GetParent());
675 if (ccp) ccp->OnContextMenu(cevt);
676 }
677#endif
678}
679
680void CDI::SetColorScheme(ColorScheme cs) {
681 m_pbackBrush = wxTheBrushList->FindOrCreateBrush(GetGlobalColor(_T("DILG2")),
682 wxBRUSHSTYLE_SOLID);
683 m_proadBrush = wxTheBrushList->FindOrCreateBrush(GetGlobalColor(_T("DILG1")),
684 wxBRUSHSTYLE_SOLID);
685 m_proadPen = wxThePenList->FindOrCreatePen(GetGlobalColor(_T("CHBLK")), 1,
686 wxPENSTYLE_SOLID);
687}
688
689void CDI::OnPaint(wxPaintEvent& event) {
690 int sx, sy;
691 GetClientSize(&sx, &sy);
692
693 // Do the drawing on an off-screen memory DC, and blit into place
694 // to avoid objectionable flashing
695 wxMemoryDC mdc;
696
697 wxBitmap m_bitmap(sx, sy, -1);
698 mdc.SelectObject(m_bitmap);
699 mdc.SetBackground(*m_pbackBrush);
700 mdc.Clear();
701
702 int xp = sx / 2;
703 int yp = sy * 9 / 10;
704
705 int path_length = sy * 3;
706 int pix_per_xte = 120;
707
708 if (g_pRouteMan->GetpActiveRoute()) {
709 double angle = 90 - (g_pRouteMan->GetCurrentSegmentCourse() - gCog);
710
711 double dy = path_length * sin(angle * PI / 180.);
712 double dx = path_length * cos(angle * PI / 180.);
713
714 int xtedir;
715 xtedir = g_pRouteMan->GetXTEDir();
716 double xte = g_pRouteMan->GetCurrentXTEToActivePoint();
717
718 double ddy = xtedir * pix_per_xte * xte * sin((90 - angle) * PI / 180.);
719 double ddx = xtedir * pix_per_xte * xte * cos((90 - angle) * PI / 180.);
720
721 int ddxi = (int)ddx;
722 int ddyi = (int)ddy;
723
724 int xc1 = xp - (int)(dx / 2) + ddxi;
725 int yc1 = yp + (int)(dy / 2) + ddyi;
726 int xc2 = xp + (int)(dx / 2) + ddxi;
727 int yc2 = yp - (int)(dy / 2) + ddyi;
728
729 wxPoint road[4];
730
731 int road_top_width = 10;
732 int road_bot_width = 40;
733
734 road[0].x = xc1 - (int)(road_bot_width * cos((90 - angle) * PI / 180.));
735 road[0].y = yc1 - (int)(road_bot_width * sin((90 - angle) * PI / 180.));
736
737 road[1].x = xc2 - (int)(road_top_width * cos((90 - angle) * PI / 180.));
738 road[1].y = yc2 - (int)(road_top_width * sin((90 - angle) * PI / 180.));
739
740 road[2].x = xc2 + (int)(road_top_width * cos((90 - angle) * PI / 180.));
741 road[2].y = yc2 + (int)(road_top_width * sin((90 - angle) * PI / 180.));
742
743 road[3].x = xc1 + (int)(road_bot_width * cos((90 - angle) * PI / 180.));
744 road[3].y = yc1 + (int)(road_bot_width * sin((90 - angle) * PI / 180.));
745
746 mdc.SetBrush(*m_proadBrush);
747 mdc.SetPen(*m_proadPen);
748 mdc.DrawPolygon(4, road, 0, 0, wxODDEVEN_RULE);
749
751
752 mdc.DrawLine(0, yp, sx, yp);
753 mdc.DrawCircle(xp, yp, 6);
754 mdc.DrawLine(xp, yp + 5, xp, yp - 5);
755 }
756
757 wxPaintDC dc(this);
758 dc.Blit(0, 0, sx, sy, &mdc, 0, 0);
759}
double GetDisplayDIPMult(wxWindow *win)
Get the display scaling factor for DPI-aware rendering.
Annunciator Text display.
Definition concanv.h:69
Course Deviation Indicator display.
Definition concanv.h:50
void OnPaint(wxPaintEvent &event)
Definition concanv.cpp:689
Primary navigation console display for route and vessel tracking.
Definition concanv.h:127
void ShowWithFreshFonts(void)
Recomputes and applies new fonts to console elements.
Definition concanv.cpp:447
void UpdateRouteData()
Updates route-related data displays.
Definition concanv.cpp:268
void ToggleRouteTotalDisplay()
Toggles between route total and current leg display modes.
Definition concanv.cpp:251
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 FontMgr.cpp:450
wxColour GetFontColor(const wxString &TextElement) const
Gets the text color for a UI element.
Definition FontMgr.cpp:117
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Gets a font object for a UI element.
Definition FontMgr.cpp:186
Main application frame.
Definition ocpn_frame.h:136
Represents a waypoint or mark within the navigation system.
Definition route_point.h:70
double m_seg_len
Length of the leg from previous waypoint to this waypoint in nautical miles.
Represents a navigational route in the navigation system.
Definition route.h:98
RoutePointList * pRoutePointList
Ordered list of waypoints (RoutePoints) that make up this route.
Definition route.h:335
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
Definition route.h:213
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
Definition gui_lib.cpp:54
General purpose GUI support.
PlugIn Object Definition/API.
double OCPN_GetWinDIPScaleFactor()
Gets Windows-specific DPI scaling factor.