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