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