39#include <wx/datetime.h>
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"
51#include "ocpn_frame.h"
52#include "OCPNPlatform.h"
58extern bool g_bShowActiveRouteHighway;
61bool g_bShowRouteTotal;
65enum eMenuItems { ID_NAVLEG = 1, ID_NAVROUTE, ID_NAVHIGHWAY } menuItems;
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)
82 m_speedUsed = SPEED_SOG;
86 long style = wxSIMPLE_BORDER | wxCLIP_CHILDREN | wxFRAME_FLOAT_ON_PARENT;
89 style |= wxFRAME_NO_TASKBAR;
92 wxFrame::Create(frame, wxID_ANY, _T(
""), wxDefaultPosition, wxDefaultSize,
97 m_pitemBoxSizerLeg =
new wxBoxSizer(wxVERTICAL);
99 pThisLegText =
new wxStaticText(
this, -1, _(
"This Leg"));
101 m_pitemBoxSizerLeg->Add(pThisLegText, 0, wxALIGN_CENTER_HORIZONTAL, 2);
106 10, wxFONTFAMILY_DEFAULT, qFont->GetStyle(), wxFONTWEIGHT_BOLD,
false,
107 qFont->GetFaceName());
108 pThisLegText->SetFont(*pThisLegFont);
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);
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);
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);
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);
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);
132 pCDI =
new CDI(
this, -1, wxSIMPLE_BORDER, _T(
"CDI"));
133 m_pitemBoxSizerLeg->AddSpacer(5);
134 m_pitemBoxSizerLeg->Add(pCDI, 0, wxALL | wxEXPAND, 2);
136 SetSizer(m_pitemBoxSizerLeg);
137 m_pitemBoxSizerLeg->SetSizeHints(
this);
141 if (g_bShowRouteTotal)
142 pThisLegText->SetLabel(_(
"Route"));
144 pThisLegText->SetLabel(_(
"This Leg"));
149ConsoleCanvas::~ConsoleCanvas() {
delete pCDI; }
151void ConsoleCanvas::SetColorScheme(ColorScheme cs) {
152 pbackBrush = wxTheBrushList->FindOrCreateBrush(
153 GetGlobalColor(_T(
"DILG1" )), wxBRUSHSTYLE_SOLID);
154 SetBackgroundColour(GetGlobalColor(_T(
"DILG1" )));
156 if (g_bShowRouteTotal)
157 pThisLegText->SetLabel(_(
"Route"));
159 pThisLegText->SetLabel(_(
"This Leg"));
163 pThisLegText->SetBackgroundColour(GetGlobalColor(_T(
"DILG1" )));
165 pXTE->SetColorScheme(cs);
166 pBRG->SetColorScheme(cs);
167 pRNG->SetColorScheme(cs);
168 pTTG->SetColorScheme(cs);
169 pVMG->SetColorScheme(cs);
171 pCDI->SetColorScheme(cs);
174void ConsoleCanvas::OnPaint(wxPaintEvent& event) {
177 if (g_pRouteMan->GetpActiveRoute()) {
179 pThisLegText->Refresh();
180 m_bNeedClear =
false;
186 if (!g_bShowActiveRouteHighway) pCDI->Hide();
189void ConsoleCanvas::OnShow(wxShowEvent& event) {
190 pCDI->Show(g_bShowActiveRouteHighway);
191 m_pitemBoxSizerLeg->SetSizeHints(
this);
194void ConsoleCanvas::LegRoute() {
195 if (g_bShowRouteTotal)
196 pThisLegText->SetLabel(_(
"Route"));
198 pThisLegText->SetLabel(_(
"This Leg"));
200 pThisLegText->Refresh(
true);
201 RefreshConsoleData();
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);
217 btnLeg->Check(!g_bShowRouteTotal);
218 btnRoute->Check(g_bShowRouteTotal);
219 btnHighw->Check(g_bShowActiveRouteHighway);
221 PopupMenu(contextMenu);
226void ConsoleCanvas::OnContextMenuSelection(wxCommandEvent& event) {
227 switch (event.GetId()) {
229 g_bShowRouteTotal =
false;
234 g_bShowRouteTotal =
true;
238 case ID_NAVHIGHWAY: {
239 g_bShowActiveRouteHighway = !g_bShowActiveRouteHighway;
240 if (g_bShowActiveRouteHighway) {
245 m_pitemBoxSizerLeg->SetSizeHints(
this);
255 if (g_bShowRouteTotal) {
256 g_bShowRouteTotal =
false;
257 m_speedUsed = SPEED_SOG;
259 if (m_speedUsed == SPEED_VMG) {
260 g_bShowRouteTotal =
true;
261 m_speedUsed = SPEED_SOG;
263 m_speedUsed = SPEED_VMG;
271 if (g_pRouteMan->GetpActiveRoute()) {
272 if (g_pRouteMan->m_bDataValid) {
274 float rng = g_pRouteMan->GetCurrentRngToActivePoint();
277 float dcog = g_pRouteMan->GetCurrentBrgToActivePoint();
278 if (dcog >= 359.5) dcog = 0;
282 cogstr << wxString::Format(wxString(
"%6.0f", wxConvUTF8), dcog);
284 cogstr << wxString::Format(wxString(
"%6.0f(M)", wxConvUTF8),
287 pBRG->SetAValue(cogstr);
290 if (!std::isnan(gCog) && !std::isnan(gSog)) {
292 BRG = g_pRouteMan->GetCurrentBrgToActivePoint();
293 double vmg = gSog * cos((BRG - gCog) * PI / 180.);
294 str_buf.Printf(_T(
"%6.2f"), toUsrSpeed(vmg));
296 if (m_speedUsed == SPEED_VMG) {
307 pVMG->SetAValue(str_buf);
309 if (!g_bShowRouteTotal) {
310 float nrng = g_pRouteMan->GetCurrentRngToActiveNormalArrival();
312 double deltarng = fabs(rng - nrng);
313 if ((deltarng > .01) && ((deltarng / rng) > .10) &&
318 srng.Printf(_T(
"%5.2f/%5.2f"), toUsrDistance(rng),
319 toUsrDistance(nrng));
321 srng.Printf(_T(
"%5.1f/%5.1f"), toUsrDistance(rng),
322 toUsrDistance(nrng));
325 srng.Printf(_T(
"%6.2f"), toUsrDistance(rng));
327 srng.Printf(_T(
"%6.1f"), toUsrDistance(rng));
331 pRNG->SetAValue(srng);
335 toUsrDistance(g_pRouteMan->GetCurrentXTEToActivePoint()));
336 pXTE->SetAValue(str_buf);
337 if (g_pRouteMan->GetXTEDir() < 0)
338 pXTE->SetALabel(wxString(_(
"XTE L")));
340 pXTE->SetALabel(wxString(_(
"XTE R")));
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();
352 pTTG->SetAValue(ttg_s);
353 if (m_speedUsed == SPEED_VMG) {
354 pTTG->SetALabel(wxString(_(
"TTG @VMG")));
356 pTTG->SetALabel(wxString(_(
"TTG @SOG")));
362 Route* prt = g_pRouteMan->GetpActiveRoute();
368 prp = node->GetData();
373 node = node->GetNext();
379 strng.Printf(_T(
"%6.2f"), toUsrDistance(trng));
381 strng.Printf(_T(
"%6.1f"), toUsrDistance(trng));
383 pRNG->SetAValue(strng);
389 wxTimeSpan tttg_span;
390 float tttg_sec = 0.0;
392 tttg_sec = (trng / gSog) * 3600.;
393 tttg_span = wxTimeSpan::Seconds((
long)tttg_sec);
395 tttg_s = tttg_sec > SECONDS_PER_DAY ? tttg_span.Format(_(
"%Dd %H:%M"))
396 : tttg_span.Format(
"%H:%M:%S");
398 tttg_span = wxTimeSpan::Seconds(0);
402 pTTG->SetAValue(tttg_s);
405 wxDateTime dtnow, eta;
406 dtnow.SetToCurrent();
407 eta = dtnow.Add(tttg_span);
412 seta = tttg_sec > SECONDS_PER_DAY ? eta.Format(_T(
"%d/%m %H:%M"))
413 : eta.Format(_T(
"%H:%M"));
417 pXTE->SetAValue(seta);
418 if (m_speedUsed == SPEED_VMG) {
419 pTTG->SetALabel(wxString(_(
"TTG @VMG")));
420 pXTE->SetALabel(wxString(_(
"ETA @VMG")));
422 pTTG->SetALabel(wxString(_(
"TTG @SOG")));
423 pXTE->SetALabel(wxString(_(
"ETA @SOG")));
436void ConsoleCanvas::RefreshConsoleData(
void) {
452 gFrame->PositionConsole();
456void ConsoleCanvas::UpdateFonts(
void) {
457 pBRG->RefreshFonts();
458 pXTE->RefreshFonts();
459 pTTG->RefreshFonts();
460 pRNG->RefreshFonts();
461 pVMG->RefreshFonts();
463 m_pitemBoxSizerLeg->SetSizeHints(
this);
474EVT_PAINT(AnnunText::OnPaint)
475EVT_MOUSE_EVENTS(AnnunText::MouseEvent)
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(
"-----");
486 14, wxFONTFAMILY_SWISS, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, FALSE,
487 wxString(_T(
"Arial Bold")));
489 24, wxFONTFAMILY_DEFAULT, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_BOLD, FALSE,
490 wxString(_T(
"helvetica")), wxFONTENCODING_ISO8859_1);
492 m_LegendTextElement = LegendElement;
493 m_ValueTextElement = ValueElement;
498AnnunText::~AnnunText() {}
499void AnnunText::MouseEvent(wxMouseEvent& event) {
500 if (event.RightDown()) {
501 wxContextMenuEvent cevt;
502 cevt.SetPosition(event.GetPosition());
505 if (ccp) ccp->OnContextMenu(cevt);
507 }
else if (event.LeftDown()) {
515void AnnunText::CalculateMinSize(
void) {
524 GetTextExtent(_T(
"1234"), &wl, &hl, NULL, NULL, m_plabelFont);
527 GetTextExtent(_T(
"123.4567"), &wv, &hv, NULL, NULL, m_pvalueFont);
543 min.y = (int)((hl + hv) * 1.2);
549 if (style->consoleTextBackground.IsOk()) {
550 wxImage img = style->consoleTextBackground.ConvertToImage();
551 style->consoleTextBackground = wxBitmap(img.Rescale(min.x, min.y));
555void AnnunText::SetColorScheme(ColorScheme cs) {
557 m_backBrush = *wxTheBrushList->FindOrCreateBrush(GetGlobalColor(_T(
"UBLCK")),
560 m_default_text_color = style->consoleFontColor;
564void AnnunText::RefreshFonts() {
565 wxFont* pl = FontMgr::Get().
GetFont(m_LegendTextElement);
568 pl->GetStyle(), pl->GetWeight(), FALSE, pl->GetFaceName());
570 wxFont* pv = FontMgr::Get().
GetFont(m_ValueTextElement);
573 pv->GetStyle(), pv->GetWeight(), FALSE, pv->GetFaceName());
575 m_legend_color = FontMgr::Get().
GetFontColor(_(
"Console Legend"));
576 m_val_color = FontMgr::Get().
GetFontColor(_(
"Console Value"));
582 if (m_backBrush.IsOk()) {
583 wxColour back_color = m_backBrush.GetColour();
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;
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;
599void AnnunText::SetLegendElement(
const wxString& element) {
600 m_LegendTextElement = element;
603void AnnunText::SetValueElement(
const wxString& element) {
604 m_ValueTextElement = element;
607void AnnunText::SetALabel(
const wxString& l) { m_label = l; }
609void AnnunText::SetAValue(
const wxString& v) { m_value = v; }
611void AnnunText::OnPaint(wxPaintEvent& event) {
613 GetClientSize(&sx, &sy);
620 wxBitmap m_bitmap(sx, sy, -1);
621 mdc.SelectObject(m_bitmap);
622 mdc.SetBackground(m_backBrush);
625 if (style->consoleTextBackground.IsOk())
626 mdc.DrawBitmap(style->consoleTextBackground, 0, 0);
628 mdc.SetTextForeground(m_default_text_color);
631 mdc.SetFont(*m_plabelFont);
632 mdc.SetTextForeground(m_legend_color);
633 mdc.DrawText(m_label, 5, 2);
637 mdc.SetFont(*m_pvalueFont);
638 mdc.SetTextForeground(m_val_color);
641 mdc.GetTextExtent(m_value, &w, &h);
643 mdc.GetSize(&cw, &ch);
645 mdc.DrawText(m_value, cw - w - 2, ch - h - 2);
649 dc.Blit(0, 0, sx, sy, &mdc, 0, 0);
654BEGIN_EVENT_TABLE(
CDI, wxWindow)
656EVT_MOUSE_EVENTS(CDI::MouseEvent)
659CDI::
CDI(wxWindow* parent, wxWindowID
id,
long style, const wxString& name)
660 : wxWindow(parent,
id, wxDefaultPosition, wxDefaultSize, style, name)
663 SetMinSize(wxSize(10, 150));
666void CDI::MouseEvent(wxMouseEvent& event) {
668 if (event.RightDown()) {
669 qDebug() <<
"right down";
671 wxContextMenuEvent cevt;
672 cevt.SetPosition(event.GetPosition());
675 if (ccp) ccp->OnContextMenu(cevt);
680void CDI::SetColorScheme(ColorScheme cs) {
681 m_pbackBrush = wxTheBrushList->FindOrCreateBrush(GetGlobalColor(_T(
"DILG2")),
683 m_proadBrush = wxTheBrushList->FindOrCreateBrush(GetGlobalColor(_T(
"DILG1")),
685 m_proadPen = wxThePenList->FindOrCreatePen(GetGlobalColor(_T(
"CHBLK")), 1,
691 GetClientSize(&sx, &sy);
697 wxBitmap m_bitmap(sx, sy, -1);
698 mdc.SelectObject(m_bitmap);
699 mdc.SetBackground(*m_pbackBrush);
703 int yp = sy * 9 / 10;
705 int path_length = sy * 3;
706 int pix_per_xte = 120;
708 if (g_pRouteMan->GetpActiveRoute()) {
709 double angle = 90 - (g_pRouteMan->GetCurrentSegmentCourse() - gCog);
711 double dy = path_length * sin(angle * PI / 180.);
712 double dx = path_length * cos(angle * PI / 180.);
715 xtedir = g_pRouteMan->GetXTEDir();
716 double xte = g_pRouteMan->GetCurrentXTEToActivePoint();
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.);
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;
731 int road_top_width = 10;
732 int road_bot_width = 40;
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.));
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.));
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.));
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.));
746 mdc.SetBrush(*m_proadBrush);
747 mdc.SetPen(*m_proadPen);
748 mdc.DrawPolygon(4, road, 0, 0, wxODDEVEN_RULE);
752 mdc.DrawLine(0, yp, sx, yp);
753 mdc.DrawCircle(xp, yp, 6);
754 mdc.DrawLine(xp, yp + 5, xp, yp - 5);
758 dc.Blit(0, 0, sx, sy, &mdc, 0, 0);
Annunciator Text display.
Course Deviation Indicator display.
void OnPaint(wxPaintEvent &event)
Primary navigation console display for route and vessel tracking.
void ShowWithFreshFonts(void)
Recomputes and applies new fonts to console elements.
void UpdateRouteData()
Updates route-related data displays.
void ToggleRouteTotalDisplay()
Toggles between route total and current leg display modes.
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.
wxColour GetFontColor(const wxString &TextElement) const
Gets the text color for a UI element.
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Gets a font object for a UI element.
Represents a waypoint or mark within the navigation system.
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.
RoutePointList * pRoutePointList
Ordered list of waypoints (RoutePoints) that make up this route.
RoutePoint * m_pRouteActivePoint
Pointer to the currently active waypoint within this route.
wxFont * GetOCPNScaledFont(wxString item, int default_size)
Retrieves a font from FontMgr, optionally scaled for physical readability.
General purpose GUI support.
PlugIn Object Definition/API.
double OCPN_GetWinDIPScaleFactor()
Gets Windows-specific DPI scaling factor.