39#include <wx/datetime.h>
46#include "navutil_base.h"
48#include "wx28compat.h"
50#include "ocpn_frame.h"
51#include "OCPNPlatform.h"
52#include "ocpn_plugin.h"
56extern bool g_bShowActiveRouteHighway;
59extern bool g_bShowTrue, g_bShowMag;
62bool g_bShowRouteTotal;
66enum eMenuItems { ID_NAVLEG = 1, ID_NAVROUTE, ID_NAVHIGHWAY } menuItems;
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)
83 m_speedUsed = SPEED_VMG;
87 long style = wxSIMPLE_BORDER | wxCLIP_CHILDREN | wxFRAME_FLOAT_ON_PARENT;
90 style |= wxFRAME_NO_TASKBAR;
93 wxFrame::Create(frame, wxID_ANY, _T(
""), wxDefaultPosition, wxDefaultSize,
98 m_pitemBoxSizerLeg =
new wxBoxSizer(wxVERTICAL);
100 pThisLegText =
new wxStaticText(
this, -1, _(
"This Leg"));
102 m_pitemBoxSizerLeg->Add(pThisLegText, 0, wxALIGN_CENTER_HORIZONTAL, 2);
104 wxFont* qFont = GetOCPNScaledFont(_(
"Dialog"));
106 wxFont* pThisLegFont = FontMgr::Get().FindOrCreateFont(
107 10, wxFONTFAMILY_DEFAULT, qFont->GetStyle(), wxFONTWEIGHT_BOLD,
false,
108 qFont->GetFaceName());
109 pThisLegText->SetFont(*pThisLegFont);
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);
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);
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);
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);
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);
133 pCDI =
new CDI(
this, -1, wxSIMPLE_BORDER, _T(
"CDI"));
134 m_pitemBoxSizerLeg->AddSpacer(5);
135 m_pitemBoxSizerLeg->Add(pCDI, 0, wxALL | wxEXPAND, 2);
137 SetSizer(m_pitemBoxSizerLeg);
138 m_pitemBoxSizerLeg->SetSizeHints(
this);
142 if (g_bShowRouteTotal)
143 pThisLegText->SetLabel(_(
"Route"));
145 pThisLegText->SetLabel(_(
"This Leg"));
150ConsoleCanvas::~ConsoleCanvas() {
delete pCDI; }
152void ConsoleCanvas::SetColorScheme(ColorScheme cs) {
153 pbackBrush = wxTheBrushList->FindOrCreateBrush(
154 GetGlobalColor(_T(
"DILG1" )), wxBRUSHSTYLE_SOLID);
155 SetBackgroundColour(GetGlobalColor(_T(
"DILG1" )));
157 if (g_bShowRouteTotal)
158 pThisLegText->SetLabel(_(
"Route"));
160 pThisLegText->SetLabel(_(
"This Leg"));
164 pThisLegText->SetBackgroundColour(GetGlobalColor(_T(
"DILG1" )));
166 pXTE->SetColorScheme(cs);
167 pBRG->SetColorScheme(cs);
168 pRNG->SetColorScheme(cs);
169 pTTG->SetColorScheme(cs);
170 pVMG->SetColorScheme(cs);
172 pCDI->SetColorScheme(cs);
175void ConsoleCanvas::OnPaint(wxPaintEvent& event) {
178 if (g_pRouteMan->GetpActiveRoute()) {
180 pThisLegText->Refresh();
181 m_bNeedClear =
false;
187 if (!g_bShowActiveRouteHighway) pCDI->Hide();
190void ConsoleCanvas::OnShow(wxShowEvent& event) {
191 pCDI->Show(g_bShowActiveRouteHighway);
192 m_pitemBoxSizerLeg->SetSizeHints(
this);
195void ConsoleCanvas::LegRoute() {
196 if (g_bShowRouteTotal)
197 pThisLegText->SetLabel(_(
"Route"));
199 pThisLegText->SetLabel(_(
"This Leg"));
201 pThisLegText->Refresh(
true);
202 RefreshConsoleData();
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);
218 btnLeg->Check(!g_bShowRouteTotal);
219 btnRoute->Check(g_bShowRouteTotal);
220 btnHighw->Check(g_bShowActiveRouteHighway);
222 PopupMenu(contextMenu);
227void ConsoleCanvas::OnContextMenuSelection(wxCommandEvent& event) {
228 switch (event.GetId()) {
230 g_bShowRouteTotal =
false;
235 g_bShowRouteTotal =
true;
239 case ID_NAVHIGHWAY: {
240 g_bShowActiveRouteHighway = !g_bShowActiveRouteHighway;
241 if (g_bShowActiveRouteHighway) {
246 m_pitemBoxSizerLeg->SetSizeHints(
this);
252void ConsoleCanvas::ToggleRouteTotalDisplay() {
253 if (m_speedUsed == SPEED_VMG) {
254 m_speedUsed = SPEED_SOG;
256 m_speedUsed = SPEED_VMG;
257 g_bShowRouteTotal = !g_bShowRouteTotal;
262void ConsoleCanvas::UpdateRouteData() {
265 if (g_pRouteMan->GetpActiveRoute()) {
266 if (g_pRouteMan->m_bDataValid) {
268 float rng = g_pRouteMan->GetCurrentRngToActivePoint();
271 float dcog = g_pRouteMan->GetCurrentBrgToActivePoint();
272 if (dcog >= 359.5) dcog = 0;
276 cogstr << wxString::Format(wxString(
"%6.0f", wxConvUTF8), dcog);
278 cogstr << wxString::Format(wxString(
"%6.0f(M)", wxConvUTF8),
279 gFrame->GetMag(dcog));
281 pBRG->SetAValue(cogstr);
284 if (!std::isnan(gCog) && !std::isnan(gSog)) {
286 BRG = g_pRouteMan->GetCurrentBrgToActivePoint();
287 double vmg = gSog * cos((BRG - gCog) * PI / 180.);
288 str_buf.Printf(_T(
"%6.2f"), toUsrSpeed(vmg));
290 if (m_speedUsed == SPEED_VMG) {
301 pVMG->SetAValue(str_buf);
303 if (!g_bShowRouteTotal) {
304 float nrng = g_pRouteMan->GetCurrentRngToActiveNormalArrival();
306 double deltarng = fabs(rng - nrng);
307 if ((deltarng > .01) && ((deltarng / rng) > .10) &&
312 srng.Printf(_T(
"%5.2f/%5.2f"), toUsrDistance(rng),
313 toUsrDistance(nrng));
315 srng.Printf(_T(
"%5.1f/%5.1f"), toUsrDistance(rng),
316 toUsrDistance(nrng));
319 srng.Printf(_T(
"%6.2f"), toUsrDistance(rng));
321 srng.Printf(_T(
"%6.1f"), toUsrDistance(rng));
325 pRNG->SetAValue(srng);
329 toUsrDistance(g_pRouteMan->GetCurrentXTEToActivePoint()));
330 pXTE->SetAValue(str_buf);
331 if (g_pRouteMan->GetXTEDir() < 0)
332 pXTE->SetALabel(wxString(_(
"XTE L")));
334 pXTE->SetALabel(wxString(_(
"XTE R")));
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();
346 pTTG->SetAValue(ttg_s);
347 if (m_speedUsed == SPEED_VMG) {
348 pTTG->SetALabel(wxString(_(
"TTG @VMG")));
350 pTTG->SetALabel(wxString(_(
"TTG @SOG")));
356 Route* prt = g_pRouteMan->GetpActiveRoute();
357 wxRoutePointListNode* node = (prt->pRoutePointList)->GetFirst();
362 prp = node->GetData();
363 if (n_addflag) trng += prp->m_seg_len;
365 if (prp == prt->m_pRouteActivePoint) n_addflag++;
367 node = node->GetNext();
373 strng.Printf(_T(
"%6.2f"), toUsrDistance(trng));
375 strng.Printf(_T(
"%6.1f"), toUsrDistance(trng));
377 pRNG->SetAValue(strng);
383 wxTimeSpan tttg_span;
384 float tttg_sec = 0.0;
386 tttg_sec = (trng / gSog) * 3600.;
387 tttg_span = wxTimeSpan::Seconds((
long)tttg_sec);
389 tttg_s = tttg_sec > SECONDS_PER_DAY ? tttg_span.Format(_(
"%Dd %H:%M"))
390 : tttg_span.Format(
"%H:%M:%S");
392 tttg_span = wxTimeSpan::Seconds(0);
396 pTTG->SetAValue(tttg_s);
399 wxDateTime dtnow, eta;
400 dtnow.SetToCurrent();
401 eta = dtnow.Add(tttg_span);
406 seta = tttg_sec > SECONDS_PER_DAY ? eta.Format(_T(
"%d/%m %H:%M"))
407 : eta.Format(_T(
"%H:%M"));
411 pXTE->SetAValue(seta);
412 if (m_speedUsed == SPEED_VMG) {
413 pTTG->SetALabel(wxString(_(
"TTG @VMG")));
414 pXTE->SetALabel(wxString(_(
"ETA @VMG")));
416 pTTG->SetALabel(wxString(_(
"TTG @SOG")));
417 pXTE->SetALabel(wxString(_(
"ETA @SOG")));
430void ConsoleCanvas::RefreshConsoleData(
void) {
441void ConsoleCanvas::ShowWithFreshFonts(
void) {
446 gFrame->PositionConsole();
450void ConsoleCanvas::UpdateFonts(
void) {
451 pBRG->RefreshFonts();
452 pXTE->RefreshFonts();
453 pTTG->RefreshFonts();
454 pRNG->RefreshFonts();
455 pVMG->RefreshFonts();
457 m_pitemBoxSizerLeg->SetSizeHints(
this);
468EVT_PAINT(AnnunText::OnPaint)
469EVT_MOUSE_EVENTS(AnnunText::MouseEvent)
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(
"-----");
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);
486 m_LegendTextElement = LegendElement;
487 m_ValueTextElement = ValueElement;
492AnnunText::~AnnunText() {}
493void AnnunText::MouseEvent(wxMouseEvent& event) {
494 if (event.RightDown()) {
495 wxContextMenuEvent cevt;
496 cevt.SetPosition(event.GetPosition());
499 if (ccp) ccp->OnContextMenu(cevt);
501 }
else if (event.LeftDown()) {
504 ccp->ToggleRouteTotalDisplay();
509void AnnunText::CalculateMinSize(
void) {
518 GetTextExtent(_T(
"1234"), &wl, &hl, NULL, NULL, m_plabelFont);
521 GetTextExtent(_T(
"123.4567"), &wv, &hv, NULL, NULL, m_pvalueFont);
523 double pdifactor = g_BasePlatform->GetDisplayDIPMult(gFrame);
524 wl *= pdifactor; hl *= pdifactor;
525 wv *= pdifactor; hv *= pdifactor;
531#ifdef __OCPN__ANDROID__
535 min.y = (int)((hl + hv) * 1.2);
541 if (style->consoleTextBackground.IsOk()) {
542 wxImage img = style->consoleTextBackground.ConvertToImage();
543 style->consoleTextBackground = wxBitmap(img.Rescale(min.x, min.y));
547void AnnunText::SetColorScheme(ColorScheme cs) {
549 m_backBrush = *wxTheBrushList->FindOrCreateBrush(GetGlobalColor(_T(
"UBLCK")),
552 m_default_text_color = style->consoleFontColor;
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,
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,
571 m_legend_color = FontMgr::Get().GetFontColor(_(
"Console Legend"));
572 m_val_color = FontMgr::Get().GetFontColor(_(
"Console Value"));
578 if (m_backBrush.IsOk()) {
579 wxColour back_color = m_backBrush.GetColour();
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;
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;
595void AnnunText::SetLegendElement(
const wxString& element) {
596 m_LegendTextElement = element;
599void AnnunText::SetValueElement(
const wxString& element) {
600 m_ValueTextElement = element;
603void AnnunText::SetALabel(
const wxString& l) { m_label = l; }
605void AnnunText::SetAValue(
const wxString& v) { m_value = v; }
607void AnnunText::OnPaint(wxPaintEvent& event) {
609 GetClientSize(&sx, &sy);
616 wxBitmap m_bitmap(sx, sy, -1);
617 mdc.SelectObject(m_bitmap);
618 mdc.SetBackground(m_backBrush);
621 if (style->consoleTextBackground.IsOk())
622 mdc.DrawBitmap(style->consoleTextBackground, 0, 0);
624 mdc.SetTextForeground(m_default_text_color);
627 mdc.SetFont(*m_plabelFont);
628 mdc.SetTextForeground(m_legend_color);
629 mdc.DrawText(m_label, 5, 2);
633 mdc.SetFont(*m_pvalueFont);
634 mdc.SetTextForeground(m_val_color);
637 mdc.GetTextExtent(m_value, &w, &h);
639 mdc.GetSize(&cw, &ch);
641 mdc.DrawText(m_value, cw - w - 2, ch - h - 2);
645 dc.Blit(0, 0, sx, sy, &mdc, 0, 0);
650BEGIN_EVENT_TABLE(
CDI, wxWindow)
652EVT_MOUSE_EVENTS(CDI::MouseEvent)
655CDI::
CDI(wxWindow* parent, wxWindowID
id,
long style, const wxString& name)
656 : wxWindow(parent,
id, wxDefaultPosition, wxDefaultSize, style, name)
659 SetMinSize(wxSize(10, 150));
662void CDI::MouseEvent(wxMouseEvent& event) {
663#ifdef __OCPN__ANDROID__
664 if (event.RightDown()) {
665 qDebug() <<
"right down";
667 wxContextMenuEvent cevt;
668 cevt.SetPosition(event.GetPosition());
671 if (ccp) ccp->OnContextMenu(cevt);
676void CDI::SetColorScheme(ColorScheme cs) {
677 m_pbackBrush = wxTheBrushList->FindOrCreateBrush(GetGlobalColor(_T(
"DILG2")),
679 m_proadBrush = wxTheBrushList->FindOrCreateBrush(GetGlobalColor(_T(
"DILG1")),
681 m_proadPen = wxThePenList->FindOrCreatePen(GetGlobalColor(_T(
"CHBLK")), 1,
687 GetClientSize(&sx, &sy);
693 wxBitmap m_bitmap(sx, sy, -1);
694 mdc.SelectObject(m_bitmap);
695 mdc.SetBackground(*m_pbackBrush);
699 int yp = sy * 9 / 10;
701 int path_length = sy * 3;
702 int pix_per_xte = 120;
704 if (g_pRouteMan->GetpActiveRoute()) {
705 double angle = 90 - (g_pRouteMan->GetCurrentSegmentCourse() - gCog);
707 double dy = path_length * sin(angle * PI / 180.);
708 double dx = path_length * cos(angle * PI / 180.);
711 xtedir = g_pRouteMan->GetXTEDir();
712 double xte = g_pRouteMan->GetCurrentXTEToActivePoint();
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.);
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;
727 int road_top_width = 10;
728 int road_bot_width = 40;
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.));
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.));
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.));
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.));
742 mdc.SetBrush(*m_proadBrush);
743 mdc.SetPen(*m_proadPen);
744 mdc.DrawPolygon(4, road, 0, 0, wxODDEVEN_RULE);
748 mdc.DrawLine(0, yp, sx, yp);
749 mdc.DrawCircle(xp, yp, 6);
750 mdc.DrawLine(xp, yp + 5, xp, yp - 5);
754 dc.Blit(0, 0, sx, sy, &mdc, 0, 0);
void OnPaint(wxPaintEvent &event)