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