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