1 /***************************************************************************
2  *
3  * Project:  OpenCPN
4  * Purpose:  OpenCPN Toolbar
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 #include "wx/wxprec.h"
27 
28 #ifndef  WX_PRECOMP
29 #include "wx/wx.h"
30 #endif
31 
32 #include <vector>
33 
34 #include "config.h"
35 #include "ocpn_types.h"
36 #include "navutil.h"
37 #include "styles.h"
38 #include "toolbar.h"
39 #include "chart1.h"
40 #include "pluginmanager.h"
41 #include "FontMgr.h"
42 #include "OCPNPlatform.h"
43 #include "chcanv.h"
44 
45 #ifdef __OCPN__ANDROID__
46 #include "androidUTIL.h"
47 #endif
48 
49 #ifdef ocpnUSE_SVG
50 #include "wxSVG/svg.h"
51 #endif // ocpnUSE_SVG
52 
53 extern bool                       g_bTransparentToolbar;
54 extern bool                       g_bTransparentToolbarInOpenGLOK;
55 extern bool                       g_bopengl;
56 extern ocpnStyle::StyleManager*   g_StyleManager;
57 extern MyFrame*                   gFrame;
58 extern PlugInManager*             g_pi_manager;
59 extern bool                       g_bPermanentMOBIcon;
60 extern bool                       g_btouch;
61 extern bool                       g_bsmoothpanzoom;
62 extern OCPNPlatform               *g_Platform;
63 extern bool                       g_bmasterToolbarFull;
64 extern bool                       g_useMUI;
65 extern wxString                   g_toolbarConfig;
66 extern double                     g_plus_minus_zoom_factor;
67 //----------------------------------------------------------------------------
68 // GrabberWindow Implementation
69 //----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(GrabberWin,wxPanel)70 BEGIN_EVENT_TABLE(GrabberWin, wxPanel) EVT_MOUSE_EVENTS ( GrabberWin::MouseEvent )
71 EVT_PAINT ( GrabberWin::OnPaint )
72 END_EVENT_TABLE()
73 
74 GrabberWin::GrabberWin( wxWindow *parent, ocpnFloatingToolbarDialog *toolbar, float scale_factor, wxString icon_name, wxPoint position ):
75     wxPanel( parent, wxID_ANY, position, wxDefaultSize, wxNO_BORDER )
76 {
77     m_icon_name = icon_name;
78     m_style = g_StyleManager->GetCurrentStyle();
79     wxBitmap bitmap = m_style->GetIcon( icon_name );
80     if(scale_factor > 1.0f){
81         int new_width = bitmap.GetWidth() * scale_factor;
82         int new_height = bitmap.GetHeight() * scale_factor;
83         wxImage scaled_image = bitmap.ConvertToImage();
84         m_bitmap = wxBitmap(scaled_image.Scale(new_width, new_height, wxIMAGE_QUALITY_HIGH));
85     }
86     else
87         m_bitmap = bitmap;
88 
89     SetSize( wxSize( m_bitmap.GetWidth(), m_bitmap.GetHeight() ) );
90     SetMinSize( wxSize( m_bitmap.GetWidth(), m_bitmap.GetHeight() ) );
91 
92     m_bLeftDown = false;
93     m_bRightDown = false;
94     m_scale_factor = scale_factor;
95     m_ptoolbar = toolbar;
96     m_dragging = false;
97     Hide();
98 
99 }
100 
101 
OnPaint(wxPaintEvent & event)102 void GrabberWin::OnPaint( wxPaintEvent& event )
103 {
104     wxPaintDC dc( this );
105 
106     wxColour back_color = GetGlobalColor( _T("GREY2") );
107     SetBackgroundColour( back_color );
108     ClearBackground();
109 
110     dc.DrawBitmap( m_bitmap, 0, 0, true );
111 }
112 
SetColorScheme(ColorScheme cs)113 void GrabberWin::SetColorScheme( ColorScheme cs )
114 {
115     wxColour back_color = GetGlobalColor( _T("GREY2") );
116 
117     SetBackgroundColour( back_color );
118     ClearBackground();
119 
120     wxBitmap bitmap = m_style->GetIcon( m_icon_name) ;
121     if(m_scale_factor > 1.0f){
122         int new_width = bitmap.GetWidth() * m_scale_factor;
123         int new_height = bitmap.GetHeight() * m_scale_factor;
124         wxImage scaled_image = bitmap.ConvertToImage();
125         m_bitmap = wxBitmap(scaled_image.Scale(new_width, new_height, wxIMAGE_QUALITY_HIGH));
126     }
127     else
128         m_bitmap = bitmap;
129 }
130 
MouseEvent(wxMouseEvent & event)131 void GrabberWin::MouseEvent( wxMouseEvent& event )
132 {
133     static wxPoint s_gspt;
134     int x, y;
135 
136     event.GetPosition( &x, &y );
137 
138     wxPoint spt = ClientToScreen( wxPoint( x, y ) );
139     if( event.LeftDown() ) {
140         s_gspt = spt;
141     }
142 
143 
144 #ifndef __WXQT__
145 
146     if( event.LeftDown() ) {
147         CaptureMouse();
148     }
149 
150     if( event.LeftUp() ) {
151         if( HasCapture() ) ReleaseMouse();
152     }
153 
154 #endif
155 
156 
157     if( event.RightDown() && m_ptoolbar->GetCanToggleOrientation()){
158         if(m_ptoolbar){
159             if(!m_ptoolbar->isSubmergedToGrabber()){
160                 m_dragging = true;
161 
162                 if( !m_ptoolbar->m_bnavgrabber ){
163                     m_ptoolbar->m_bnavgrabber = true;
164                     m_ptoolbar->SetGrabber(_T("4WayMove") );
165                 }
166                 else{
167                     m_ptoolbar->m_bnavgrabber = false;
168                     m_ptoolbar->SetGrabber(_T("grabber_hi") );
169                 }
170             }
171         }
172     }
173 
174 
175 
176     if( event.Dragging() ) {
177         if(m_ptoolbar && m_ptoolbar->IsShown() /*&& m_ptoolbar->m_bnavgrabber*/){
178             wxPoint par_pos_old = m_ptoolbar->GetPosition();
179 
180             wxPoint par_pos = par_pos_old;
181             par_pos.x += spt.x - s_gspt.x;
182             par_pos.y += spt.y - s_gspt.y;
183 
184             m_ptoolbar->MoveDialogInScreenCoords( par_pos, par_pos_old );
185 
186             s_gspt = spt;
187             m_dragging = true;
188         }
189 
190     }
191 
192     if( event.LeftUp() ) {
193         if(m_ptoolbar){
194             if(m_ptoolbar->m_bnavgrabber){
195                 if(!m_dragging)
196                     m_ptoolbar->ToggleOrientation();
197             }
198             else if(!m_dragging){
199                 if(m_ptoolbar->isSubmergedToGrabber()){
200                     m_ptoolbar->SurfaceFromGrabber();
201                 }
202                 else{
203                     m_ptoolbar->SubmergeToGrabber();
204                  }
205             }
206         }
207         m_dragging = false;
208     }
209 
210 
211 #ifndef __OCPN__ANDROID__
212     gFrame->Raise();
213 #endif
214 
215 }
216 
217 class ocpnToolBarTool: public wxToolBarToolBase {
218 public:
ocpnToolBarTool(ocpnToolBarSimple * tbar,int id,const wxString & label,const wxBitmap & bmpNormal,const wxBitmap & bmpRollover,wxItemKind kind,wxObject * clientData,const wxString & shortHelp,const wxString & longHelp)219     ocpnToolBarTool( ocpnToolBarSimple *tbar, int id, const wxString& label,
220             const wxBitmap& bmpNormal, const wxBitmap& bmpRollover, wxItemKind kind,
221             wxObject *clientData, const wxString& shortHelp, const wxString& longHelp ) :
222             wxToolBarToolBase( (wxToolBarBase*) tbar, id, label, bmpNormal, bmpRollover, kind,
223                     clientData, shortHelp, longHelp )
224     {
225         m_enabled = true;
226         m_toggled = false;
227         rollover = false;
228         bitmapOK = false;
229         m_btooltip_hiviz = false;
230 
231         toolname = g_pi_manager->GetToolOwnerCommonName( id );
232         if( toolname == _T("") ) {
233             isPluginTool = false;
234             toolname = label;
235             iconName = label;
236 
237         } else {
238             isPluginTool = true;
239             pluginNormalIcon = bmpNormal;
240             pluginRolloverIcon = bmpRollover;
241         }
242     }
243 
ocpnToolBarTool(ocpnToolBarSimple * tbar,int id,const wxBitmap & bmpNormal,const wxBitmap & bmpRollover,wxItemKind kind,wxObject * clientData,const wxString & shortHelp,const wxString & longHelp)244      ocpnToolBarTool( ocpnToolBarSimple *tbar, int id,
245             const wxBitmap& bmpNormal, const wxBitmap& bmpRollover, wxItemKind kind,
246             wxObject *clientData, const wxString& shortHelp, const wxString& longHelp ) :
247             wxToolBarToolBase( (wxToolBarBase*) tbar, id, _T(""), bmpNormal, bmpRollover, kind,
248                     clientData, shortHelp, longHelp )
249     {
250         m_enabled = true;
251         m_toggled = false;
252         rollover = false;
253         m_btooltip_hiviz = false;
254         isPluginTool = false;
255 
256         m_bmpNormal = bmpNormal;
257         bitmapOK = true;
258     }
259 
SetSize(const wxSize & size)260     void SetSize( const wxSize& size )
261     {
262         m_width = size.x;
263         m_height = size.y;
264     }
265 
GetWidth() const266     wxCoord GetWidth() const
267     {
268         return m_width;
269     }
270 
GetHeight() const271     wxCoord GetHeight() const
272     {
273         return m_height;
274     }
275 
GetToolname()276     wxString GetToolname()
277     {
278         return toolname;
279     }
280 
SetIconName(wxString name)281     void SetIconName(wxString name)
282     {
283         iconName = name;
284     }
GetIconName()285     wxString GetIconName()
286     {
287         return iconName;
288     }
289 
SetTooltipHiviz(bool enable)290     void SetTooltipHiviz( bool enable){ m_btooltip_hiviz = enable; }
291 
292     wxCoord m_x;
293     wxCoord m_y;
294     wxCoord m_width;
295     wxCoord m_height;
296     wxRect trect;
297     wxString toolname;
298     wxString iconName;
299     wxBitmap pluginNormalIcon;
300     wxBitmap pluginRolloverIcon;
301     const wxBitmap* pluginToggledIcon;
302     bool firstInLine;
303     bool lastInLine;
304     bool rollover;
305     bool bitmapOK;
306     bool isPluginTool;
307     bool b_hilite;
308     bool m_btooltip_hiviz;
309     wxRect last_rect;
310     wxString pluginNormalIconSVG;
311     wxString pluginRolloverIconSVG;
312     wxString pluginToggledIconSVG;
313 };
314 
315 //---------------------------------------------------------------------------------------
316 //          ocpnFloatingToolbarDialog Implementation
317 //---------------------------------------------------------------------------------------
BEGIN_EVENT_TABLE(ocpnFloatingToolbarDialog,wxFrame)318 BEGIN_EVENT_TABLE(ocpnFloatingToolbarDialog, wxFrame)
319     EVT_MOUSE_EVENTS ( ocpnFloatingToolbarDialog::MouseEvent )
320     EVT_MENU(wxID_ANY, ocpnFloatingToolbarDialog::OnToolLeftClick)
321     EVT_TIMER ( FADE_TIMER, ocpnFloatingToolbarDialog::FadeTimerEvent )
322     EVT_TIMER ( DESTROY_TIMER, ocpnFloatingToolbarDialog::DestroyTimerEvent )
323     EVT_KEY_DOWN(ocpnFloatingToolbarDialog::OnKeyDown )
324     EVT_KEY_UP(ocpnFloatingToolbarDialog::OnKeyUp )
325     EVT_WINDOW_CREATE(ocpnFloatingToolbarDialog::OnWindowCreate)
326 END_EVENT_TABLE()
327 
328 ocpnFloatingToolbarDialog::ocpnFloatingToolbarDialog( wxWindow *parent, wxPoint position,
329                                                       long orient, float size_factor )
330 {
331     m_pparent = parent;
332     long wstyle = wxNO_BORDER | wxFRAME_NO_TASKBAR | wxFRAME_SHAPED | wxFRAME_FLOAT_ON_PARENT | wxFRAME_TOOL_WINDOW;
333 
334     m_ptoolbar = NULL;
335 
336     wxFrame::Create( parent, -1, _T(""), wxPoint( -1, -1 ), wxSize( -1, -1 ),
337             wstyle );
338 
339     m_opacity = 255;
340 
341     m_pGrabberwin = NULL; //new GrabberWin( this, this, size_factor, _T("grabber_hi") );
342     m_bGrabberEnable = true;            // default
343 
344     m_pRecoverwin = NULL;
345     m_position = position;
346     m_orient = orient;
347     m_sizefactor = size_factor;
348     m_cornerRadius = 0;
349 
350     m_bAutoHideToolbar = false;
351     m_nAutoHideToolbar = 5;
352     m_toolbar_scale_tools_shown = false;
353     m_backcolorString = _T("GREY2") ;
354     m_toolShowMask = _T("XXXXXXXXXXXXXXXX");
355     n_toolbarHideMethod = TOOLBAR_HIDE_TO_GRABBER;
356     b_canToggleOrientation = true;
357     m_enableRolloverBitmaps = true;
358     m_auxOffsetY = 0;
359 
360     m_ptoolbar = CreateNewToolbar();
361 
362     m_cs = (ColorScheme)-1;
363 
364     m_style = g_StyleManager->GetCurrentStyle();
365     SetULDockPosition(wxPoint(4,4));
366 
367     SetGeometry(false, wxRect());
368 
369 
370 // A top-level sizer
371     m_topSizer = new wxBoxSizer( wxHORIZONTAL );
372     SetSizer( m_topSizer );
373 
374     //    Set initial "Dock" parameters
375     m_dock_x = 0;
376     m_dock_y = 0;
377     m_block = false;
378 
379     m_marginsInvisible = m_style->marginsInvisible;
380 
381 //    if(m_sizefactor > 1.0 )
382  //       m_marginsInvisible = true;
383 
384     m_bnavgrabber = false;
385 
386     m_FloatingToolbarConfigMenu = NULL;
387 
388     Hide();
389 
390     m_bsubmerged = false;
391     m_bsubmergedToGrabber = false;
392 
393     m_fade_timer.SetOwner( this, FADE_TIMER );
394     if( g_bTransparentToolbar )
395         m_fade_timer.Start( 5000 );
396 
397     if( m_bAutoHideToolbar && (m_nAutoHideToolbar > 0))
398         m_fade_timer.Start( m_nAutoHideToolbar * 1000 );
399 
400     m_destroyTimer.SetOwner( this, DESTROY_TIMER );
401 
402     m_benableSubmerge = true;
403 }
404 
~ocpnFloatingToolbarDialog()405 ocpnFloatingToolbarDialog::~ocpnFloatingToolbarDialog()
406 {
407     delete m_FloatingToolbarConfigMenu;
408 
409     DestroyToolBar();
410 }
411 
AddToolItem(ToolbarItemContainer * item)412 void ocpnFloatingToolbarDialog::AddToolItem(ToolbarItemContainer *item)
413 {
414     m_Items.push_back(item);
415 }
416 
RebuildToolbar()417 int ocpnFloatingToolbarDialog::RebuildToolbar()
418 {
419     ocpnToolBarSimple *tb = GetToolbar();
420     if( !tb )
421         return 0;
422 
423     // Iterate over the array of items added,
424     // Creating the toolbar from enabled items.
425     int i_count = 0;
426     for (auto it = m_Items.cbegin(); it != m_Items.cend(); it++){
427 
428         ToolbarItemContainer *tic = *it;
429         if(!tic)
430             continue;
431 
432         bool bEnabled = _toolbarConfigMenuUtil( tic );
433 
434         if(bEnabled){
435             wxToolBarToolBase *tool = tb->AddTool(tic->m_ID, tic->m_label, tic->m_bmpNormal, tic->m_bmpDisabled, tic->m_toolKind, tic->m_tipString);
436             tic->m_tool = tool;
437 
438             //  Plugin tools may have prescribed their own SVG toolbars as file locations.
439             if(!tic->m_NormalIconSVG.IsEmpty()){
440                 tb->SetToolBitmapsSVG( tic->m_ID, tic->m_NormalIconSVG,
441                                     tic->m_RolloverIconSVG,
442                                     tic->m_ToggledIconSVG );
443             }
444         }
445 
446         i_count++;
447     }
448 
449     return i_count;
450 
451 
452 }
453 
454 
SetULDockPosition(wxPoint position)455 void ocpnFloatingToolbarDialog::SetULDockPosition(wxPoint position)
456 {
457     if(position.x >= 0)
458         m_dock_min_x = position.x;
459     if(position.y >= 0)
460         m_dock_min_y = position.y;
461 }
462 
GetToolCount()463 size_t ocpnFloatingToolbarDialog::GetToolCount()
464 {
465     if(m_ptoolbar)
466         return m_ptoolbar->GetToolsCount();
467     else
468         return 0;
469 }
470 
SetToolShowMask(wxString mask)471 void ocpnFloatingToolbarDialog::SetToolShowMask( wxString mask )
472 {
473 }
474 
SetToolShowCount(int count)475 void ocpnFloatingToolbarDialog::SetToolShowCount( int count )
476 {
477     if(m_ptoolbar)
478         m_ptoolbar->SetToolShowCount( count);
479 }
480 
GetToolShowCount(void)481 int ocpnFloatingToolbarDialog::GetToolShowCount( void )
482 {
483     if(m_ptoolbar)
484         return m_ptoolbar->GetToolShowCount();
485     else
486         return 0;
487 }
488 
SetBackGroundColorString(wxString colorRef)489 void ocpnFloatingToolbarDialog::SetBackGroundColorString( wxString colorRef )
490 {
491     m_backcolorString = colorRef;
492     SetColorScheme( m_cs );             //Causes a reload of background color
493 }
494 
OnKeyDown(wxKeyEvent & event)495 void ocpnFloatingToolbarDialog::OnKeyDown( wxKeyEvent &event )
496 {
497     event.Skip();
498 }
499 
OnKeyUp(wxKeyEvent & event)500 void ocpnFloatingToolbarDialog::OnKeyUp( wxKeyEvent &event )
501 {
502     event.Skip();
503 }
504 
CreateConfigMenu()505 void ocpnFloatingToolbarDialog::CreateConfigMenu()
506 {
507     if(m_FloatingToolbarConfigMenu)
508         delete m_FloatingToolbarConfigMenu;
509     m_FloatingToolbarConfigMenu = new wxMenu();
510 }
511 
_toolbarConfigMenuUtil(ToolbarItemContainer * tic)512 bool ocpnFloatingToolbarDialog::_toolbarConfigMenuUtil( ToolbarItemContainer *tic )
513 {
514     if(m_FloatingToolbarConfigMenu){
515         wxMenuItem* menuitem;
516 
517         if( tic->m_ID == ID_MOB && g_bPermanentMOBIcon )
518             return true;
519 
520         if( tic->m_bRequired )
521             return true;
522         if( tic->m_bPlugin )
523             return true;
524 
525         // Item ID trickery is needed because the wxCommandEvents for menu item clicked and toolbar button
526         // clicked are 100% identical, so if we use same id's we can't tell the events apart.
527 
528         int idOffset = 100;  // Hopefully no more than 100 total icons...
529         int menuItemId = tic->m_ID + idOffset;
530 
531         menuitem = m_FloatingToolbarConfigMenu->FindItem( menuItemId );
532 
533         if( menuitem ) {
534             return menuitem->IsChecked();
535         }
536 
537         menuitem = m_FloatingToolbarConfigMenu->AppendCheckItem( menuItemId, tic->m_tipString );
538         size_t n = m_FloatingToolbarConfigMenu->GetMenuItemCount();
539         menuitem->Check( m_configString.Len() >= n ? m_configString.GetChar( n-1 ) == _T('X') : true );
540         return menuitem->IsChecked();
541     }
542     else
543         return true;
544 }
545 
546 
OnWindowCreate(wxWindowCreateEvent & event)547 void ocpnFloatingToolbarDialog::OnWindowCreate( wxWindowCreateEvent& event )
548 {
549     // At least on MSW, this call leads to recursion and stack overflow.
550     //  Probably not needed any longer
551     //Realize();
552 }
553 
SetGrabber(wxString icon_name)554 void ocpnFloatingToolbarDialog::SetGrabber( wxString icon_name )
555 {
556 //    m_pGrabberwin->Destroy();
557     m_pGrabberwin = new GrabberWin( this, this, m_sizefactor, icon_name );
558     m_pGrabberwin->Hide();
559 
560     Realize();
561 
562 #ifdef __WXOSX__
563     m_pGrabberwin->Refresh();
564 #endif
565 
566 }
567 
568 
UpdateRecoveryWindow(bool b_toolbarEnable)569 void ocpnFloatingToolbarDialog::UpdateRecoveryWindow(bool b_toolbarEnable)
570 {
571     if(m_pRecoverwin ){
572         if(b_toolbarEnable){
573             m_pRecoverwin->Raise();
574             m_pRecoverwin->Refresh( false );
575         }
576         else
577             m_pRecoverwin->Hide();
578     }
579  }
580 
EnableTool(int toolid,bool enable)581 void ocpnFloatingToolbarDialog::EnableTool( int toolid, bool enable )
582 {
583     if(m_ptoolbar)
584         m_ptoolbar->EnableTool( toolid, enable);
585 }
586 
587 
SetColorScheme(ColorScheme cs)588 void ocpnFloatingToolbarDialog::SetColorScheme( ColorScheme cs )
589 {
590     m_cs = cs;
591 
592     wxColour back_color = GetGlobalColor( m_backcolorString );
593 
594     //  Set background
595     SetBackgroundColour( back_color );
596     ClearBackground();
597 
598     if( m_ptoolbar ) {
599         //  Set background
600         m_ptoolbar->SetBackgroundColour( back_color );
601         m_ptoolbar->ClearBackground();
602 
603         m_ptoolbar->SetToggledBackgroundColour( GetGlobalColor( _T("GREY1") ) );
604 
605         m_ptoolbar->SetColorScheme( cs );
606         m_ptoolbar->Refresh( true );
607     }
608 
609     if( m_pGrabberwin ){
610         m_pGrabberwin->SetColorScheme( cs );
611         m_pGrabberwin->Refresh();
612     }
613 
614     Refresh(true);
615 
616 }
617 
GetToolSize()618 wxSize ocpnFloatingToolbarDialog::GetToolSize()
619 {
620     wxSize style_tool_size;
621     if( m_ptoolbar ) {
622         style_tool_size = m_style->GetToolSize();
623 
624         style_tool_size.x *= m_sizefactor;
625         style_tool_size.y *= m_sizefactor;
626     }
627     else{
628         style_tool_size.x  = 32;
629         style_tool_size.y  = 32;
630     }
631 
632     return style_tool_size;
633 }
634 
SetGeometry(bool bAvoid,wxRect rectAvoid)635 void ocpnFloatingToolbarDialog::SetGeometry(bool bAvoid, wxRect rectAvoid)
636 {
637 
638     if( m_ptoolbar ) {
639         wxSize style_tool_size = m_style->GetToolSize();
640 
641         style_tool_size.x *= m_sizefactor;
642         style_tool_size.y *= m_sizefactor;
643 
644         m_ptoolbar->SetToolBitmapSize( style_tool_size );
645 
646         wxSize tool_size = m_ptoolbar->GetToolBitmapSize();
647         int grabber_width =  m_style->GetIcon( _T("grabber") ).GetWidth();
648 
649         int max_rows = 10;
650         int max_cols = 100;
651 
652         if(GetParent())
653         {
654 
655             int avoid_start = GetParent()->GetClientSize().x - (tool_size.x + m_style->GetToolSeparation()) * 2;  // default
656             if(bAvoid && !rectAvoid.IsEmpty()){
657                 avoid_start = GetParent()->GetClientSize().x - rectAvoid.width - 10;  // this is compass window, if shown
658             }
659 
660 
661             max_rows = (GetParent()->GetClientSize().y / ( tool_size.y + m_style->GetToolSeparation())) - 2;
662 
663             max_cols = (avoid_start - grabber_width) / ( tool_size.x + m_style->GetToolSeparation());
664             max_cols -= 1;
665 
666             if(m_orient == wxTB_VERTICAL)
667                 max_rows = wxMax( max_rows, 2);             // at least two rows
668             else
669                 max_cols = wxMax( max_cols, 2);             // at least two columns
670         }
671 
672         if( m_orient == wxTB_VERTICAL )
673             m_ptoolbar->SetMaxRowsCols(max_rows, 100);
674         else
675             m_ptoolbar->SetMaxRowsCols( 100, max_cols);
676         m_ptoolbar->SetSizeFactor(m_sizefactor);
677 
678     }
679  }
680 
RePosition()681 void ocpnFloatingToolbarDialog::RePosition()
682 {
683     if(m_block) return;
684 
685     if( m_pparent && m_ptoolbar ) {
686         wxSize cs = m_pparent->GetClientSize();
687         if( -1 == m_dock_x )
688             m_position.x = m_dock_min_x;
689         else
690             if( 1 == m_dock_x ) m_position.x = cs.x - GetSize().x;
691 
692         if( -1 == m_dock_y )
693             m_position.y = m_dock_min_y;
694         else
695             if( 1 == m_dock_y ) m_position.y = cs.y - GetSize().y;
696 
697         m_position.x = wxMin(cs.x - GetSize().x, m_position.x);
698         m_position.y = wxMin(cs.y - GetSize().y, m_position.y);
699 
700         m_position.x = wxMax(m_dock_min_x, m_position.x);
701         m_position.y = wxMax(m_dock_min_y, m_position.y);
702 
703         m_position.y += m_auxOffsetY;
704 
705         // take care of left docked instrument windows and don't blast the main toolbar on top of them, hinding instruments
706         // this positions the main toolbar directly right of the left docked instruments onto the chart
707         //        wxPoint screen_pos = m_pparent->ClientToScreen( m_position );
708         wxPoint screen_pos = gFrame->GetPrimaryCanvas()->ClientToScreen(m_position);
709 
710           //  GTK sometimes has trouble with ClientToScreen() if executed in the context of an event handler
711           //  The position of the window is calculated incorrectly if a deferred Move() has not been processed yet.
712           //  So work around this here...
713           //  Discovered with a Dashboard window left-docked, toggled on and off by toolbar tool.
714 
715           //  But this causes another problem. If a toolbar is NOT left docked, it will walk left by two pixels on each
716           //  call to Reposition().
717           //TODO
718 #ifdef __WXGTK__
719           if (m_pparent->GetParent()) {
720             wxPoint pp = m_pparent->GetPosition();
721             wxPoint ppg = m_pparent->GetParent()->GetScreenPosition();
722             wxPoint screen_pos_fix = ppg + pp + m_position;
723             screen_pos.x = screen_pos_fix.x;
724           }
725 #endif
726 
727           Move(screen_pos);
728 
729 #ifdef __WXQT__
730         Raise();
731 #endif
732 
733     }
734 }
735 
Submerge()736 void ocpnFloatingToolbarDialog::Submerge()
737 {
738     m_bsubmerged = true;
739     Hide();
740     if( m_ptoolbar ) m_ptoolbar->KillTooltip();
741 }
742 
SubmergeToGrabber()743 void ocpnFloatingToolbarDialog::SubmergeToGrabber()
744 {
745     if(!m_benableSubmerge)
746         return;
747 
748 //Submerge();
749     m_bsubmerged = true;
750     m_bsubmergedToGrabber = true;
751     Hide();
752     if( m_ptoolbar ) m_ptoolbar->KillTooltip();
753 
754     if(!m_pRecoverwin){
755         wxPoint tbPoint = GetPosition();
756         wxPoint tbPosInCanvas = m_pparent->ScreenToClient(tbPoint);
757         //tbPosInCanvas.y += 2;           // prettify
758         m_pRecoverwin = new GrabberWin( m_pparent, this, m_sizefactor, _T("grabber_ext" ), tbPosInCanvas );
759     }
760 
761     m_pRecoverwin->Show();
762     m_pRecoverwin->Raise();
763 #ifdef __WXQT__
764     wxSize s = gFrame->GetSize();
765     m_recoversize = s;
766     s.y--;
767     //gFrame->TriggerResize(s);
768     Raise();
769 #endif
770 
771     gFrame->Refresh();          // Needed for MSW OpenGL
772 }
773 
Surface()774 void ocpnFloatingToolbarDialog::Surface()
775 {
776 
777     if(m_pRecoverwin){
778         //SurfaceFromGrabber();
779         m_pRecoverwin->Show();
780         m_pRecoverwin->Raise();
781     }
782     else {
783         m_bsubmerged = false;
784         #ifdef __WXMSW__
785         Hide();
786         Move( 0, 0 );
787         #endif
788 
789         RePosition();
790         Show();
791         if( m_ptoolbar )
792             m_ptoolbar->EnableTooltips();
793 
794         #ifdef __WXQT__
795         Raise();
796         #endif
797     }
798 
799     if( m_bAutoHideToolbar && (m_nAutoHideToolbar > 0) ){
800         m_fade_timer.Start( m_nAutoHideToolbar * 1000 );
801     }
802 }
803 
CheckSurfaceRequest(wxMouseEvent & event)804 bool ocpnFloatingToolbarDialog::CheckSurfaceRequest( wxMouseEvent &event )
805 {
806     if( m_bsubmerged ){
807         if( event.LeftUp() ){
808             int x,y;
809             event.GetPosition( &x, &y );
810             if( m_pRecoverwin ){
811                 wxRect winRect = m_pRecoverwin->GetRect();
812                 if( winRect.Contains( x, y ) ){
813                     SurfaceFromGrabber();
814                     return true;
815                 }
816             }
817         }
818     }
819 
820     return false;
821 }
822 
SurfaceFromGrabber()823 void ocpnFloatingToolbarDialog::SurfaceFromGrabber()
824 {
825     m_bsubmerged = false;
826     m_bsubmergedToGrabber = false;
827 
828 #ifndef __WXOSX__
829     Hide();
830     Move( 0, 0 );
831 #endif
832 
833     if( m_ptoolbar )
834         m_ptoolbar->InvalidateBitmaps();
835 
836     RePosition();
837     Show();
838     m_ptoolbar->Refresh();              // Added to force redraw of all the tools
839 
840     if( m_ptoolbar )
841         m_ptoolbar->EnableTooltips();
842 
843     if( m_bAutoHideToolbar && (m_nAutoHideToolbar > 0) ){
844         m_fade_timer.Start( m_nAutoHideToolbar * 1000 );
845     }
846 
847 #ifdef __WXQT__
848     wxSize s = gFrame->GetSize();               // check for rotation
849     //if(m_recoversize.x == s.x)
850       //  gFrame->TriggerResize(m_recoversize);
851     Raise();
852 #endif
853     if(!m_destroyTimer.IsRunning()){
854         m_destroyGrabber = m_pRecoverwin;
855         m_pRecoverwin = NULL;
856         m_destroyTimer.Start( 5, wxTIMER_ONE_SHOT );           //  Destor the unneeded recovery grabber
857     }
858 
859 }
860 
DestroyTimerEvent(wxTimerEvent & event)861 void ocpnFloatingToolbarDialog::DestroyTimerEvent( wxTimerEvent& event )
862 {
863     delete m_destroyGrabber;
864     m_destroyGrabber = NULL;
865 
866 }
867 
isSubmergedToGrabber()868 bool ocpnFloatingToolbarDialog::isSubmergedToGrabber()
869 {
870     return (m_bsubmergedToGrabber);
871 }
872 
HideTooltip()873 void ocpnFloatingToolbarDialog::HideTooltip()
874 {
875     if( m_ptoolbar ) m_ptoolbar->HideTooltip();
876 }
877 
ShowTooltips()878 void ocpnFloatingToolbarDialog::ShowTooltips()
879 {
880     if( m_ptoolbar ) m_ptoolbar->EnableTooltips();
881 }
882 
ToggleOrientation()883 void ocpnFloatingToolbarDialog::ToggleOrientation()
884 {
885     if(!m_pGrabberwin)
886         return;
887 
888     if( m_orient == wxTB_HORIZONTAL )
889         m_orient = wxTB_VERTICAL;
890     else
891         m_orient = wxTB_HORIZONTAL;
892 
893     m_style->SetOrientation( m_orient );
894 
895     wxPoint old_screen_pos = m_pparent->ClientToScreen( m_position );
896     wxPoint grabber_point_abs = ClientToScreen( m_pGrabberwin->GetPosition() );
897 
898     DestroyToolBar();
899     CreateMyToolbar();
900     RePosition();
901     SetColorScheme(m_cs);
902     Show();
903 
904 
905     wxPoint pos_abs = grabber_point_abs;
906     pos_abs.x -= m_pGrabberwin->GetPosition().x;
907     MoveDialogInScreenCoords( pos_abs, old_screen_pos );
908 
909 
910     Show();   // this seems to be necessary on GTK to kick the sizer into gear...(FS#553)
911     Refresh(true);
912     Raise();
913 }
914 
MouseEvent(wxMouseEvent & event)915 void ocpnFloatingToolbarDialog::MouseEvent( wxMouseEvent& event )
916 {
917     if( g_bTransparentToolbar ) {
918         if( event.Entering() && ( m_opacity < 255 ) ) {
919             SetTransparent( 255 );
920             m_opacity = 255;
921         }
922 
923         m_fade_timer.Start( 5000 );           // retrigger the continuous timer
924     }
925 
926     if(m_bAutoHideToolbar && (m_nAutoHideToolbar > 0) ){
927         m_fade_timer.Start( m_nAutoHideToolbar * 1000 );
928     }
929 
930     event.Skip();
931 }
932 
FadeTimerEvent(wxTimerEvent & event)933 void ocpnFloatingToolbarDialog::FadeTimerEvent( wxTimerEvent& event )
934 {
935     if(n_toolbarHideMethod == TOOLBAR_HIDE_TO_FIRST_TOOL){
936         if(g_bmasterToolbarFull){
937             if(m_bAutoHideToolbar && (m_nAutoHideToolbar > 0) && !m_bsubmerged){
938                 wxCommandEvent event;
939                 event.SetId(ID_MASTERTOGGLE);
940                 gFrame->OnToolLeftClick(event);
941             }
942         }
943     }
944     else{
945 
946         if(m_bnavgrabber){
947             m_fade_timer.Start( 5000 );           // do nothing if nav grabber is shown
948         }
949         else{
950             if( g_bTransparentToolbar && (!g_bopengl || g_bTransparentToolbarInOpenGLOK) ){
951                 DoFade( 128 );
952                 m_fade_timer.Start( 5000 );           // retrigger the continuous timer
953             }
954 
955             if( m_bAutoHideToolbar && (m_nAutoHideToolbar > 0) && !m_bsubmerged){
956                SubmergeToGrabber();
957             }
958         }
959     }
960 }
961 
SetAutoHideTimer(int time)962 void ocpnFloatingToolbarDialog::SetAutoHideTimer(int time)
963 {
964     m_nAutoHideToolbar = time;
965     if(m_bAutoHideToolbar){
966         m_fade_timer.Stop();
967         m_fade_timer.Start( m_nAutoHideToolbar * 1000 );
968     }
969 }
970 
DoFade(int value)971 void ocpnFloatingToolbarDialog::DoFade( int value )
972 {
973     if( value != m_opacity ) SetTransparent( value );
974     m_opacity = value;
975 }
976 
RefreshFadeTimer()977 void ocpnFloatingToolbarDialog::RefreshFadeTimer()
978 {
979     SetTransparent( 255 );
980     m_opacity = 255;
981     m_fade_timer.Start( 500 );           // retrigger the continuous timer
982 
983     if(m_bAutoHideToolbar && (m_nAutoHideToolbar > 0) ){
984         m_fade_timer.Start( m_nAutoHideToolbar * 1000 );
985     }
986 
987 }
988 
SetToolShortHelp(int id,const wxString & help)989 void ocpnFloatingToolbarDialog::SetToolShortHelp( int id, const wxString& help )
990 {
991     if(m_ptoolbar)
992         m_ptoolbar->SetToolShortHelp( id, help);
993 }
994 
995 
MoveDialogInScreenCoords(wxPoint posn,wxPoint posn_old)996 void ocpnFloatingToolbarDialog::MoveDialogInScreenCoords( wxPoint posn, wxPoint posn_old )
997 {
998     wxPoint pos_in_parent = m_pparent->ScreenToClient( posn );
999     wxPoint pos_in_parent_old = m_pparent->ScreenToClient( posn_old );
1000 
1001     //    "Docking" support
1002 #define DOCK_MARGIN 40
1003 
1004     // X
1005     m_dock_x = 0;
1006     if( pos_in_parent.x < pos_in_parent_old.x )            // moving left
1007             {
1008         if( pos_in_parent.x < DOCK_MARGIN ) {
1009             pos_in_parent.x = m_dock_min_x;               // but dock position may be offset
1010             m_dock_x = -1;
1011         }
1012     } else
1013         if( pos_in_parent.x > pos_in_parent_old.x )            // moving right
1014                 {
1015             int max_right = m_pparent->GetClientSize().x - GetSize().x;
1016             if( pos_in_parent.x > ( max_right - DOCK_MARGIN ) ) {
1017                 pos_in_parent.x = max_right;
1018                 m_dock_x = 1;
1019             }
1020         }
1021 
1022     // Y
1023     m_dock_y = 0;
1024     if( pos_in_parent.y < pos_in_parent_old.y )            // moving up
1025             {
1026         if( pos_in_parent.y < DOCK_MARGIN ) {
1027             pos_in_parent.y = 0;
1028             m_dock_y = -1;
1029         }
1030     } else
1031         if( pos_in_parent.y > pos_in_parent_old.y )            // moving down
1032                 {
1033             int max_down = m_pparent->GetClientSize().y - GetSize().y;
1034             if( pos_in_parent.y > ( max_down - DOCK_MARGIN ) ) {
1035                 pos_in_parent.y = max_down;
1036                 m_dock_y = 1;
1037             }
1038         }
1039 
1040     m_position = pos_in_parent;
1041 
1042     wxPoint final_pos = m_pparent->ClientToScreen( pos_in_parent );
1043 
1044     Move( final_pos );
1045 }
1046 
Realize()1047 void ocpnFloatingToolbarDialog::Realize()
1048 {
1049     if( m_ptoolbar ) {
1050         m_ptoolbar->Realize();
1051 
1052         m_topSizer->Clear();
1053         m_topSizer->Add( m_ptoolbar );
1054 
1055         if(m_bGrabberEnable){
1056             if(!m_pGrabberwin){
1057                 m_pGrabberwin = new GrabberWin( this, this, m_sizefactor, _T("grabber_hi") );
1058                 m_pGrabberwin->Hide();
1059             }
1060 
1061             m_pGrabberwin->Show();
1062             m_topSizer->Add( m_pGrabberwin, 0, wxTOP, m_style->GetTopMargin() );
1063         }
1064 
1065         m_topSizer->Layout();
1066         Fit();
1067 
1068         //    Update "Dock" parameters
1069         if( m_position.x == 0 ) m_dock_x = -1;
1070         else
1071             if( m_position.x == m_pparent->GetClientSize().x - GetSize().x ) m_dock_x = 1;
1072 
1073         if( m_position.y == 0 ) m_dock_y = -1;
1074         else
1075             if( m_position.y == m_pparent->GetClientSize().y - GetSize().y ) m_dock_y = 1;
1076 
1077         // Now create a bitmap mask forthe frame shape.
1078 
1079         if( m_marginsInvisible ) {
1080 
1081             wxSize tool_size = m_ptoolbar->GetToolBitmapSize();
1082 
1083             //  Determine whether the tool icons are meant (by style) to join without speces between
1084             //  This will determine what type of region to draw.
1085             bool b_overlap = false;
1086 
1087             wxToolBarToolsList::compatibility_iterator node1 = m_ptoolbar->m_tools.GetFirst();
1088             if( node1 ){
1089                 wxToolBarToolsList::compatibility_iterator node2 = node1->GetNext() ;
1090                 if( node2 ){
1091                     wxToolBarToolBase *tool1 = node1->GetData();
1092                     ocpnToolBarTool *tools1 = (ocpnToolBarTool *) tool1;
1093 
1094                     wxToolBarToolBase *tool2 = node2->GetData();
1095                     ocpnToolBarTool *tools2 = (ocpnToolBarTool *) tool2;
1096 
1097                     if( (tools1->m_x + tools1->m_width) >= tools2->m_x)
1098                         b_overlap = true;
1099                 }
1100             }
1101 
1102 
1103             int toolCount = m_ptoolbar->GetVisibleToolCount();
1104 
1105             wxPoint upperLeft( m_style->GetLeftMargin(), m_style->GetTopMargin() );
1106             wxSize visibleSize;
1107             if( m_ptoolbar->IsVertical() ) {
1108                 int noTools = m_ptoolbar->GetMaxRows();
1109                 if( noTools > toolCount )
1110                     noTools = toolCount;
1111                 visibleSize.x = m_ptoolbar->GetLineCount() * ( tool_size.x + m_style->GetTopMargin() );
1112                 visibleSize.y = noTools * ( tool_size.y + m_style->GetToolSeparation() );
1113                 visibleSize.x -= m_style->GetTopMargin();
1114                 visibleSize.y -= m_style->GetToolSeparation();
1115             } else {
1116                     int noTools = m_ptoolbar->GetMaxCols();
1117                     if( noTools > toolCount )
1118                         noTools = toolCount;
1119                 visibleSize.x = noTools * ( tool_size.x + m_style->GetToolSeparation() );
1120                 visibleSize.y = m_ptoolbar->GetLineCount() * ( tool_size.y + m_style->GetTopMargin() );
1121                 visibleSize.x -= m_style->GetToolSeparation();
1122                 visibleSize.y -= m_style->GetTopMargin();
1123             }
1124 
1125             wxBitmap shape( visibleSize.x + tool_size.x, visibleSize.y + tool_size.y);          // + fluff
1126             wxMemoryDC sdc( shape );
1127             sdc.SetBackground( *wxWHITE_BRUSH );
1128             sdc.SetBrush( *wxBLACK_BRUSH );
1129             sdc.SetPen( *wxBLACK_PEN );
1130             sdc.Clear();
1131 
1132             if(b_overlap) {
1133                 int lines = m_ptoolbar->GetLineCount();
1134                 for( int i = 1; i <= lines; i++ ) {
1135                     if( m_ptoolbar->IsVertical() ) {
1136                         wxSize barsize( tool_size.x, visibleSize.y );
1137                         if( i == lines && i > 1 ) {
1138                             int toolsInLastLine = toolCount % m_ptoolbar->GetMaxRows();
1139                             if( toolsInLastLine == 0 ) toolsInLastLine = m_ptoolbar->GetMaxRows();
1140                             int emptySpace = ( m_ptoolbar->GetMaxRows() - toolsInLastLine );
1141                             barsize.y -= emptySpace
1142                             * ( tool_size.y + m_style->GetToolSeparation() );
1143                         }
1144                         if( i == lines ) {
1145                             // Also do grabber here, since it is to the right of the last line.
1146                             wxRect grabMask( upperLeft, barsize );
1147                             grabMask.width += m_style->GetIcon( _T("grabber") ).GetWidth();
1148                             grabMask.height = m_style->GetIcon( _T("grabber") ).GetHeight();
1149                             sdc.DrawRoundedRectangle( grabMask, m_style->GetToolbarCornerRadius() );
1150                         }
1151                         sdc.DrawRoundedRectangle( upperLeft, barsize,
1152                                 m_style->GetToolbarCornerRadius() );
1153                         upperLeft.x += m_style->GetTopMargin() + tool_size.x;
1154                     } else {
1155                         wxSize barsize( visibleSize.x, tool_size.y );
1156 
1157                         if( i == 1 ) {
1158                             barsize.x += m_style->GetIcon( _T("grabber") ).GetWidth();
1159                         }
1160                         if( i == lines && i > 1 ) {
1161                             int toolsInLastLine = toolCount % m_ptoolbar->GetMaxCols();
1162                             if( toolsInLastLine == 0 ) toolsInLastLine = m_ptoolbar->GetMaxCols();
1163                             int emptySpace = ( m_ptoolbar->GetMaxCols() - toolsInLastLine );
1164                             barsize.x -= emptySpace * ( tool_size.x + m_style->GetToolSeparation() );
1165                         }
1166 
1167                         sdc.DrawRoundedRectangle( upperLeft, barsize,
1168                                 m_style->GetToolbarCornerRadius() );
1169                         upperLeft.y += m_style->GetTopMargin() + tool_size.y;
1170                     }
1171                 }
1172             } //b_overlap
1173             else {
1174                 for( wxToolBarToolsList::compatibility_iterator node = m_ptoolbar->m_tools.GetFirst(); node; node = node->GetNext() ) {
1175                     wxToolBarToolBase *tool = node->GetData();
1176                     ocpnToolBarTool *tools = (ocpnToolBarTool *) tool;
1177 
1178                     sdc.DrawRoundedRectangle( tools->m_x, tools->m_y, tool_size.x, tool_size.y,
1179                                               m_style->GetToolbarCornerRadius() );
1180                 }
1181             }
1182 
1183 #ifndef __WXQT__
1184             if(shape.GetWidth() && shape.GetHeight())
1185                 SetShape( wxRegion( shape, *wxWHITE, 10 ) );
1186 #endif
1187         }
1188         else{
1189 #if !defined(__WXMAC__) && !defined(__OCPN__ANDROID__)
1190             if(m_cornerRadius) {
1191                 wxBitmap m_MaskBmp = wxBitmap( GetSize().x, GetSize().y );
1192                 wxMemoryDC sdc( m_MaskBmp );
1193                 sdc.SetBackground( *wxWHITE_BRUSH );
1194                 sdc.Clear();
1195                 sdc.SetBrush( *wxBLACK_BRUSH );
1196                 sdc.SetPen( *wxBLACK_PEN );
1197                 sdc.DrawRoundedRectangle( 0, 0, m_MaskBmp.GetWidth(), m_MaskBmp.GetHeight(), m_cornerRadius );
1198                 sdc.SelectObject( wxNullBitmap );
1199                 SetShape( wxRegion( m_MaskBmp, *wxWHITE, 0 ) );
1200             }
1201  #endif
1202 
1203         }
1204     }
1205 }
1206 
OnToolLeftClick(wxCommandEvent & event)1207 void ocpnFloatingToolbarDialog::OnToolLeftClick( wxCommandEvent& event )
1208 {
1209     // Since Dialog events don't propagate automatically, we send it explicitly
1210     // (instead of relying on event.Skip()). Send events up the window hierarchy
1211 
1212     m_pparent->GetEventHandler()->AddPendingEvent( event );
1213 #ifndef __WXQT__
1214     gFrame->Raise();
1215 #endif
1216 }
1217 
GetToolbar()1218 ocpnToolBarSimple *ocpnFloatingToolbarDialog::GetToolbar()
1219 {
1220     if( !m_ptoolbar ) {
1221         m_ptoolbar = CreateNewToolbar();
1222     }
1223 
1224     return m_ptoolbar;
1225 }
1226 
CreateNewToolbar()1227 ocpnToolBarSimple *ocpnFloatingToolbarDialog::CreateNewToolbar()
1228 {
1229     long winstyle = wxNO_BORDER | wxTB_FLAT;
1230     winstyle |= m_orient;
1231 
1232     m_ptoolbar = new ocpnToolBarSimple( this, -1, wxPoint( -1, -1 ), wxSize( -1, -1 ), winstyle );
1233 
1234     m_ptoolbar->SetBackgroundColour( GetGlobalColor( _T("GREY2") ) );
1235     m_ptoolbar->ClearBackground();
1236     m_ptoolbar->SetToggledBackgroundColour( GetGlobalColor( _T("GREY1") ) );
1237     m_ptoolbar->SetColorScheme( m_cs );
1238     m_ptoolbar->EnableRolloverBitmaps(GetEnableRolloverBitmaps());
1239 
1240     return m_ptoolbar;
1241 }
1242 
DestroyToolBar()1243 void ocpnFloatingToolbarDialog::DestroyToolBar()
1244 {
1245     g_toolbarConfig = GetToolConfigString();
1246 
1247     if( m_ptoolbar ) {
1248         m_ptoolbar->ClearTools();
1249         delete m_ptoolbar;                  //->Destroy();
1250         m_ptoolbar = NULL;
1251     }
1252 
1253     if(!m_destroyTimer.IsRunning()){
1254         m_destroyGrabber = m_pRecoverwin;
1255         m_pRecoverwin = NULL;
1256         m_destroyTimer.Start( 5, wxTIMER_ONE_SHOT );           //  Destor the unneeded recovery grabber
1257     }
1258 
1259     m_Items.clear();
1260 
1261 }
1262 
1263 #include "s52plib.h"
1264 #include "compass.h"
1265 #include "chartdb.h"
1266 
1267 extern bool     g_bAllowShowScaled;
1268 extern bool     g_bTrackActive;
1269 extern s52plib *ps52plib;
1270 
1271 
CreateMyToolbar()1272 ocpnToolBarSimple *ocpnFloatingToolbarDialog::CreateMyToolbar()
1273 {
1274     return NULL;
1275 #if 0
1276 
1277     ocpnToolBarSimple *tb = GetToolbar();
1278     if( !tb )
1279         return 0;
1280 
1281     ocpnCompass *pCompass = NULL;
1282     ChartCanvas *parentCanvas = dynamic_cast<ChartCanvas *>( GetParent() );
1283     if(parentCanvas)
1284         pCompass = parentCanvas->GetCompass();
1285 
1286     if(pCompass)
1287         SetGeometry(pCompass->IsShown(), pCompass->GetRect());
1288     else
1289         SetGeometry(false, wxRect(0,0,1,1));
1290 
1291     ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
1292 
1293     wxString tipString;
1294     wxToolBarToolBase* newtool;
1295 
1296     CheckAndAddPlugInTool( tb );
1297     tipString = wxString( _("Zoom In") ) << _T(" (+)");
1298     if( _toolbarConfigMenuUtil( ID_ZOOMIN, tipString ) )
1299         tb->AddTool( ID_ZOOMIN, _T("zoomin"),
1300             style->GetToolIcon( _T("zoomin"), TOOLICON_NORMAL ), tipString, wxITEM_NORMAL );
1301 
1302     CheckAndAddPlugInTool( tb );
1303     tipString = wxString( _("Zoom Out") ) << _T(" (-)");
1304     if( _toolbarConfigMenuUtil( ID_ZOOMOUT, tipString ) )
1305         tb->AddTool( ID_ZOOMOUT, _T("zoomout"),
1306             style->GetToolIcon( _T("zoomout"), TOOLICON_NORMAL ), tipString, wxITEM_NORMAL );
1307 
1308     CheckAndAddPlugInTool( tb );
1309     tipString = wxString( _("Shift to Larger Scale Chart") ) << _T(" (F7)");
1310     if( _toolbarConfigMenuUtil( ID_STKDN, tipString ) ) {
1311         newtool = tb->AddTool( ID_STKDN, _T("scin"),
1312                 style->GetToolIcon( _T("scin"), TOOLICON_NORMAL ), tipString, wxITEM_NORMAL );
1313         newtool->Enable( m_toolbar_scale_tools_shown );
1314     }
1315 
1316     CheckAndAddPlugInTool( tb );
1317     tipString = wxString( _("Shift to Smaller Scale Chart") ) << _T(" (F8)");
1318     if( _toolbarConfigMenuUtil( ID_STKUP, tipString ) ) {
1319         newtool = tb->AddTool( ID_STKUP, _T("scout"),
1320                 style->GetToolIcon( _T("scout"), TOOLICON_NORMAL ), tipString, wxITEM_NORMAL );
1321         newtool->Enable( m_toolbar_scale_tools_shown );
1322     }
1323 
1324     CheckAndAddPlugInTool( tb );
1325     tipString = wxString( _("Create Route") ) << _T(" (Ctrl-R)");
1326     if( _toolbarConfigMenuUtil( ID_ROUTE, tipString ) )
1327         tb->AddTool( ID_ROUTE, _T("route"),
1328             style->GetToolIcon( _T("route"), TOOLICON_NORMAL ),
1329             style->GetToolIcon( _T("route"), TOOLICON_TOGGLED ), wxITEM_CHECK, tipString );
1330 
1331     CheckAndAddPlugInTool( tb );
1332     tipString = wxString( _("Auto Follow") ) << _T(" (F2)");
1333     if( _toolbarConfigMenuUtil( ID_FOLLOW, tipString ) )
1334         tb->AddTool( ID_FOLLOW, _T("follow"),
1335             style->GetToolIcon( _T("follow"), TOOLICON_NORMAL ),
1336             style->GetToolIcon( _T("follow"), TOOLICON_TOGGLED ), wxITEM_CHECK, tipString );
1337 
1338     CheckAndAddPlugInTool( tb );
1339     tipString = _("Options");
1340     if( _toolbarConfigMenuUtil( ID_SETTINGS, tipString ) )
1341         tb->AddTool( ID_SETTINGS, _T("settings"),
1342             style->GetToolIcon( _T("settings"), TOOLICON_NORMAL ), tipString, wxITEM_NORMAL );
1343 
1344     CheckAndAddPlugInTool( tb );
1345     bool gs = false;
1346     if (ps52plib)
1347         gs = ps52plib->GetShowS57Text();
1348 
1349     if (gs)
1350         tipString = wxString( _("Hide ENC text") ) << _T(" (T)");
1351     else
1352         tipString = wxString( _("Show ENC text") ) << _T(" (T)");
1353 
1354     if( _toolbarConfigMenuUtil( ID_ENC_TEXT, tipString ) )
1355         tb->AddTool( ID_ENC_TEXT, _T("text"),
1356             style->GetToolIcon( _T("text"), TOOLICON_NORMAL ),
1357             style->GetToolIcon( _T("text"), TOOLICON_TOGGLED ), wxITEM_CHECK, tipString );
1358 
1359     m_pTBAISTool = NULL;
1360     CheckAndAddPlugInTool( tb );
1361     tipString = _("Hide AIS Targets");          // inital state is on
1362     if( _toolbarConfigMenuUtil( ID_AIS, tipString ) )
1363         m_pTBAISTool = tb->AddTool( ID_AIS, _T("AIS"), style->GetToolIcon( _T("AIS"), TOOLICON_NORMAL ),
1364                                   style->GetToolIcon( _T("AIS"), TOOLICON_DISABLED ),
1365                                   wxITEM_NORMAL, tipString );
1366 
1367     CheckAndAddPlugInTool( tb );
1368     tipString = _("Show Currents");
1369     if( _toolbarConfigMenuUtil( ID_CURRENT, tipString ) )
1370         tb->AddTool( ID_CURRENT, _T("current"),
1371             style->GetToolIcon( _T("current"), TOOLICON_NORMAL ), tipString, wxITEM_CHECK );
1372 
1373     CheckAndAddPlugInTool( tb );
1374     tipString = _("Show Tides");
1375     if( _toolbarConfigMenuUtil( ID_TIDE, tipString ) )
1376         tb->AddTool( ID_TIDE, _T("tide"),
1377             style->GetToolIcon( _T("tide"), TOOLICON_NORMAL ), tipString, wxITEM_CHECK );
1378 
1379     CheckAndAddPlugInTool( tb );
1380     tipString = _("Print Chart");
1381     if( _toolbarConfigMenuUtil( ID_PRINT, tipString ) )
1382         tb->AddTool( ID_PRINT, _T("print"),
1383             style->GetToolIcon( _T("print"), TOOLICON_NORMAL ), tipString, wxITEM_NORMAL );
1384 
1385     CheckAndAddPlugInTool( tb );
1386     tipString = _("Route & Mark Manager");
1387     if( _toolbarConfigMenuUtil( ID_ROUTEMANAGER, tipString ) )
1388         tb->AddTool( ID_ROUTEMANAGER,
1389             _T("route_manager"), style->GetToolIcon( _T("route_manager"), TOOLICON_NORMAL ),
1390             tipString, wxITEM_NORMAL );
1391 
1392     CheckAndAddPlugInTool( tb );
1393     tipString = _("Enable Tracking");
1394     if( _toolbarConfigMenuUtil( ID_TRACK, tipString ) )
1395         tb->AddTool( ID_TRACK, _T("track"),
1396             style->GetToolIcon( _T("track"), TOOLICON_NORMAL ),
1397             style->GetToolIcon( _T("track"), TOOLICON_TOGGLED ), wxITEM_CHECK, tipString );
1398 
1399     CheckAndAddPlugInTool( tb );
1400     tipString = wxString( _("Change Color Scheme") ) << _T(" (F5)");
1401     if( _toolbarConfigMenuUtil( ID_COLSCHEME, tipString ) ){
1402         tb->AddTool( ID_COLSCHEME,
1403             _T("colorscheme"), style->GetToolIcon( _T("colorscheme"), TOOLICON_NORMAL ),
1404             tipString, wxITEM_NORMAL );
1405         tb->SetToolTooltipHiViz( ID_COLSCHEME, true );  // cause the Tooltip to always be visible, whatever
1406                                                         //  the colorscheme
1407     }
1408 
1409     CheckAndAddPlugInTool( tb );
1410     tipString = _("About OpenCPN");
1411     if( _toolbarConfigMenuUtil( ID_ABOUT, tipString ) )
1412         tb->AddTool( ID_ABOUT, _T("help"),
1413             style->GetToolIcon( _T("help"), TOOLICON_NORMAL ), tipString, wxITEM_NORMAL );
1414 
1415     //      Add any PlugIn toolbar tools that request default positioning
1416     AddDefaultPositionPlugInTools( tb );
1417 
1418     //  And finally add the MOB tool
1419     tipString = wxString( _("Drop MOB Marker") ) << _(" (Ctrl-Space)");
1420     if( _toolbarConfigMenuUtil( ID_MOB, tipString ) )
1421         tb->AddTool( ID_MOB, _T("mob_btn"),
1422                      style->GetToolIcon( _T("mob_btn"), TOOLICON_NORMAL ), tipString, wxITEM_NORMAL );
1423 
1424 
1425 // Realize() the toolbar
1426     style->Unload();
1427     Realize();
1428 
1429 //      Set up the toggle states
1430 
1431     if( parentCanvas ) {
1432         //  Re-establish toggle states
1433         tb->ToggleTool( ID_CURRENT, parentCanvas->GetbShowCurrent() );
1434         tb->ToggleTool( ID_TIDE, parentCanvas->GetbShowTide() );
1435         tb->ToggleTool( ID_FOLLOW, parentCanvas->m_bFollow );
1436     }
1437 
1438     if( ( ps52plib ) ){
1439         if( ps52plib->m_bOK )
1440             tb->ToggleTool( ID_ENC_TEXT, ps52plib->GetShowS57Text() );
1441     }
1442 
1443     wxString initiconName;
1444     if( parentCanvas->GetShowAIS() ) {
1445         if (g_bAllowShowScaled){
1446             if(!parentCanvas->GetAttenAIS())
1447                 tb->SetToolShortHelp( ID_AIS, _("Attenuate less critical AIS targets") );
1448             else
1449                 tb->SetToolShortHelp( ID_AIS, _("Hide AIS Targets") );
1450         }
1451         else
1452             tb->SetToolShortHelp( ID_AIS, _("Hide AIS Targets") );
1453         initiconName = _T("AIS");
1454     }
1455     else {
1456         tb->SetToolShortHelp( ID_AIS, _("Show AIS Targets") );
1457         initiconName = _T("AIS_Disabled");
1458     }
1459     tb->SetToolNormalBitmapEx( m_pTBAISTool, initiconName );
1460     m_tblastAISiconName = initiconName;
1461 
1462     tb->ToggleTool( ID_TRACK, g_bTrackActive );
1463 
1464     //  Set PlugIn tool toggle states
1465     ArrayOfPlugInToolbarTools tool_array = g_pi_manager->GetPluginToolbarToolArray();
1466     for( unsigned int i = 0; i < tool_array.GetCount(); i++ ) {
1467         PlugInToolbarToolContainer *pttc = tool_array.Item( i );
1468         if( !pttc->b_viz )
1469             continue;
1470 
1471         if( pttc->kind == wxITEM_CHECK )
1472             tb->ToggleTool( pttc->id, pttc->b_toggle );
1473     }
1474 
1475 
1476     // TODO SetStatusBarPane( -1 );                   // don't show help on status bar
1477 
1478     return tb;
1479 #endif
1480 }
1481 
CheckAndAddPlugInTool(ocpnToolBarSimple * tb)1482 bool ocpnFloatingToolbarDialog::CheckAndAddPlugInTool( ocpnToolBarSimple *tb )
1483 {
1484     if( !g_pi_manager ) return false;
1485 
1486     // We only add plugin tools on toolbar associated with canvas #0, the primary.
1487     // Except, if in gMUI mode, we allow no plugins ever on per-canvas toolbars.
1488 
1489     ChartCanvas *parentCanvas = dynamic_cast<ChartCanvas *>( GetParent() );
1490     if(parentCanvas){
1491 
1492         if(g_useMUI){
1493             return false;
1494         }
1495         else if(!parentCanvas->IsPrimaryCanvas())
1496             return false;
1497     }
1498 
1499 
1500     bool bret = false;
1501     int n_tools = tb->GetToolsCount();
1502 
1503     //    Walk the PlugIn tool spec array, checking the requested position
1504     //    If a tool has been requested by a plugin at this position, add it
1505     ArrayOfPlugInToolbarTools tool_array = g_pi_manager->GetPluginToolbarToolArray();
1506 
1507     for( unsigned int i = 0; i < tool_array.GetCount(); i++ ) {
1508         PlugInToolbarToolContainer *pttc = tool_array.Item( i );
1509         if( pttc->position == n_tools ) {
1510             wxBitmap *ptool_bmp;
1511 
1512             switch( m_cs ){
1513                 case GLOBAL_COLOR_SCHEME_DAY:
1514                     ptool_bmp = pttc->bitmap_day;
1515                     ;
1516                     break;
1517                 case GLOBAL_COLOR_SCHEME_DUSK:
1518                     ptool_bmp = pttc->bitmap_dusk;
1519                     break;
1520                 case GLOBAL_COLOR_SCHEME_NIGHT:
1521                     ptool_bmp = pttc->bitmap_night;
1522                     break;
1523                 default:
1524                     ptool_bmp = pttc->bitmap_day;
1525                     ;
1526                     break;
1527             }
1528 
1529             wxToolBarToolBase * tool = tb->AddTool( pttc->id, wxString( pttc->label ), *( ptool_bmp ),
1530                     wxString( pttc->shortHelp ), pttc->kind );
1531 
1532             tb->SetToolBitmapsSVG( pttc->id, pttc->pluginNormalIconSVG,
1533                                    pttc->pluginRolloverIconSVG,
1534                                    pttc->pluginToggledIconSVG );
1535 
1536             bret = true;
1537         }
1538     }
1539 
1540     //    If we added a tool, call again (recursively) to allow for adding adjacent tools
1541     if( bret ) while( CheckAndAddPlugInTool( tb ) ) { /* nothing to do */
1542     }
1543 
1544     return bret;
1545 }
1546 
AddDefaultPositionPlugInTools(ocpnToolBarSimple * tb)1547 bool ocpnFloatingToolbarDialog::AddDefaultPositionPlugInTools( ocpnToolBarSimple *tb )
1548 {
1549     //We only add plugin tools on toolbar associated with canvas #0, the primary.
1550     // Except, if in gMUI mode, we allow no plugins ever on per-canvas toolbars.
1551     ChartCanvas *parentCanvas = dynamic_cast<ChartCanvas *>( GetParent() );
1552     if(parentCanvas){
1553         if(g_useMUI){
1554             return false;
1555         }
1556         if(!parentCanvas->IsPrimaryCanvas())
1557             return false;
1558     }
1559 
1560     if( !g_pi_manager ) return false;
1561 
1562     bool bret = false;
1563 
1564     //    Walk the PlugIn tool spec array, checking the requested position
1565     //    If a tool has been requested by a plugin at this position, add it
1566     ArrayOfPlugInToolbarTools tool_array = g_pi_manager->GetPluginToolbarToolArray();
1567 
1568     for( unsigned int i = 0; i < tool_array.GetCount(); i++ ) {
1569         PlugInToolbarToolContainer *pttc = tool_array.Item( i );
1570 
1571         //      Tool is currently tagged as invisible
1572         if( !pttc->b_viz )
1573             continue;
1574 
1575         if( pttc->position == -1 )                  // PlugIn has requested default positioning
1576                 {
1577             wxBitmap *ptool_bmp;
1578 
1579         switch( m_cs ){
1580                 case GLOBAL_COLOR_SCHEME_DAY:
1581                     ptool_bmp = pttc->bitmap_day;
1582                     break;
1583                 case GLOBAL_COLOR_SCHEME_DUSK:
1584                     ptool_bmp = pttc->bitmap_dusk;
1585                     break;
1586                 case GLOBAL_COLOR_SCHEME_NIGHT:
1587                     ptool_bmp = pttc->bitmap_night;
1588                     break;
1589                 default:
1590                     ptool_bmp = pttc->bitmap_day;
1591                     break;
1592             }
1593 
1594 
1595             wxToolBarToolBase * tool = tb->AddTool( pttc->id, wxString( pttc->label ), *( ptool_bmp ),
1596                                                     wxString( pttc->shortHelp ), pttc->kind );
1597 
1598             tb->SetToolBitmapsSVG( pttc->id, pttc->pluginNormalIconSVG,
1599                                    pttc->pluginRolloverIconSVG,
1600                                    pttc->pluginToggledIconSVG );
1601 
1602             bret = true;
1603         }
1604     }
1605     return bret;
1606 }
1607 
1608 
1609 
1610 
EnableRolloverBitmaps(bool bEnable)1611 void ocpnFloatingToolbarDialog::EnableRolloverBitmaps( bool bEnable )
1612 {
1613     m_enableRolloverBitmaps = bEnable;
1614     if(m_ptoolbar)
1615         m_ptoolbar->EnableRolloverBitmaps( bEnable );
1616 }
1617 
1618 
1619 
1620 
1621 
1622 
1623 
1624 
1625 
1626 
1627 //----------------------------------------------------------------------------
1628 // Toolbar Tooltip Popup Window Definition
1629 //----------------------------------------------------------------------------
1630 class ToolTipWin: public wxFrame {
1631 public:
1632     ToolTipWin( wxWindow *parent );
1633     ~ToolTipWin();
1634 
1635     void OnPaint( wxPaintEvent& event );
1636 
1637     void SetColorScheme( ColorScheme cs );
SetString(wxString & s)1638     void SetString( wxString &s )
1639     {
1640         m_string = s;
1641     }
SetPosition(wxPoint pt)1642     void SetPosition( wxPoint pt )
1643     {
1644         m_position = pt;
1645     }
1646     void SetBitmap( void );
1647 
SetHiviz(bool hiviz)1648     void SetHiviz( bool hiviz){ m_hiviz = hiviz; }
1649 
1650     wxSize GetRenderedSize( void );
1651 
1652 private:
1653 
1654     wxString m_string;
1655     wxSize m_size;
1656     wxPoint m_position;
1657     wxBitmap *m_pbm;
1658     wxColour m_back_color;
1659     wxColour m_text_color;
1660     ColorScheme m_cs ;
1661     bool m_hiviz;
1662 
1663 DECLARE_EVENT_TABLE()
1664 };
1665 //-----------------------------------------------------------------------
1666 //
1667 //    Toolbar Tooltip window implementation
1668 //
1669 //-----------------------------------------------------------------------
BEGIN_EVENT_TABLE(ToolTipWin,wxFrame)1670 BEGIN_EVENT_TABLE(ToolTipWin, wxFrame) EVT_PAINT(ToolTipWin::OnPaint)
1671 
1672 END_EVENT_TABLE()
1673 
1674 // Define a constructor
1675 ToolTipWin::ToolTipWin( wxWindow *parent ) :
1676         wxFrame( parent, wxID_ANY, _T(""), wxPoint( 0, 0 ), wxSize( 1, 1 ),
1677                 wxNO_BORDER | wxFRAME_FLOAT_ON_PARENT | wxFRAME_NO_TASKBAR )
1678 {
1679     m_pbm = NULL;
1680 
1681     m_back_color = GetGlobalColor( _T ( "UIBCK" ) );
1682     m_text_color = GetGlobalColor( _T ( "UITX1" ) );
1683 
1684     SetBackgroundStyle( wxBG_STYLE_CUSTOM );
1685     SetBackgroundColour( m_back_color );
1686     m_cs = GLOBAL_COLOR_SCHEME_RGB;
1687 
1688     Hide();
1689 }
1690 
~ToolTipWin()1691 ToolTipWin::~ToolTipWin()
1692 {
1693     delete m_pbm;
1694 }
1695 
SetColorScheme(ColorScheme cs)1696 void ToolTipWin::SetColorScheme( ColorScheme cs )
1697 {
1698     m_back_color = GetGlobalColor( _T ( "UIBCK" ) );
1699     m_text_color = FontMgr::Get().GetFontColor( _("ToolTips") );
1700     // assume black is the default
1701     if (m_text_color == *wxBLACK)
1702        m_text_color = GetGlobalColor( _T ( "UITX1" ) );
1703 
1704     m_cs = cs;
1705 }
1706 
GetRenderedSize(void)1707 wxSize ToolTipWin::GetRenderedSize( void )
1708 {
1709     int h, w;
1710     wxSize sz;
1711 
1712     wxScreenDC cdc;
1713 
1714     wxFont *plabelFont = FontMgr::Get().GetFont( _("ToolTips") );
1715     cdc.GetTextExtent( m_string, &w, &h, NULL, NULL, plabelFont );
1716 
1717     sz.x = w + 8;
1718     sz.y = h + 4;
1719 
1720     return sz;
1721 
1722 }
1723 
SetBitmap()1724 void ToolTipWin::SetBitmap()
1725 {
1726     int h, w;
1727 
1728     wxScreenDC cdc;
1729 
1730     wxFont *plabelFont = FontMgr::Get().GetFont( _("ToolTips") );
1731     cdc.GetTextExtent( m_string, &w, &h, NULL, NULL, plabelFont );
1732 
1733     m_size.x = w + 8;
1734     m_size.y = h + 4;
1735 
1736     wxMemoryDC mdc;
1737 
1738     delete m_pbm;
1739     m_pbm = new wxBitmap( m_size.x, m_size.y, -1 );
1740     mdc.SelectObject( *m_pbm );
1741 
1742     wxPen pborder( m_text_color );
1743     wxBrush bback( m_back_color );
1744     mdc.SetPen( pborder );
1745     mdc.SetBrush( bback );
1746 
1747     if(m_hiviz){
1748         if((m_cs == GLOBAL_COLOR_SCHEME_DUSK) || (m_cs == GLOBAL_COLOR_SCHEME_NIGHT)){
1749             wxBrush hv_back( wxColour(200,200,200));
1750             mdc.SetBrush( hv_back );
1751         }
1752     }
1753     mdc.DrawRectangle( 0, 0, m_size.x, m_size.y );
1754 
1755     //    Draw the text
1756     mdc.SetFont( *plabelFont );
1757     mdc.SetTextForeground( m_text_color );
1758     mdc.SetTextBackground( m_back_color );
1759 
1760     mdc.DrawText( m_string, 4, 2 );
1761 
1762     SetSize( m_position.x, m_position.y, m_size.x, m_size.y );
1763 
1764 }
1765 
OnPaint(wxPaintEvent & event)1766 void ToolTipWin::OnPaint( wxPaintEvent& event )
1767 {
1768     int width, height;
1769     GetClientSize( &width, &height );
1770     wxPaintDC dc( this );
1771 
1772     if( m_string.Len() ) {
1773         wxMemoryDC mdc;
1774         mdc.SelectObject( *m_pbm );
1775         dc.Blit( 0, 0, width, height, &mdc, 0, 0 );
1776     }
1777 }
1778 
1779 
1780 // ----------------------------------------------------------------------------
BEGIN_EVENT_TABLE(ocpnToolBarSimple,wxControl)1781 BEGIN_EVENT_TABLE(ocpnToolBarSimple, wxControl) EVT_SIZE(ocpnToolBarSimple::OnSize)
1782 EVT_PAINT(ocpnToolBarSimple::OnPaint)
1783 EVT_KILL_FOCUS(ocpnToolBarSimple::OnKillFocus)
1784 EVT_MOUSE_EVENTS(ocpnToolBarSimple::OnMouseEvent)
1785 EVT_TIMER(TOOLTIPON_TIMER, ocpnToolBarSimple::OnToolTipTimerEvent)
1786 EVT_TIMER(TOOLTIPOFF_TIMER, ocpnToolBarSimple::OnToolTipOffTimerEvent)
1787 
1788 END_EVENT_TABLE()
1789 
1790 // ============================================================================
1791 // implementation
1792 // ============================================================================
1793 
1794 // ----------------------------------------------------------------------------
1795 // tool bar tools creation
1796 // ----------------------------------------------------------------------------
1797 
1798 wxToolBarToolBase *ocpnToolBarSimple::CreateTool( int id, const wxString& label,
1799         const wxBitmap& bmpNormal, const wxBitmap& bmpDisabled, wxItemKind kind,
1800         wxObject *clientData, const wxString& shortHelp, const wxString& longHelp )
1801 {
1802     if(m_style->NativeToolIconExists(label) ){
1803         return new ocpnToolBarTool( this, id, label, bmpNormal, bmpDisabled, kind, clientData,
1804             shortHelp, longHelp );
1805     }
1806     else{
1807         wxString testToolname = g_pi_manager->GetToolOwnerCommonName( id );
1808 
1809         if( testToolname == _T("") ) {                  // Not a PlugIn tool...
1810              return new ocpnToolBarTool( this, id, bmpNormal, bmpDisabled, kind, clientData,
1811                                     shortHelp, longHelp );
1812         }
1813         else{
1814             return new ocpnToolBarTool( this, id, label, bmpNormal, bmpDisabled, kind, clientData,
1815                                         shortHelp, longHelp );
1816         }
1817     }
1818 }
1819 
1820 // ----------------------------------------------------------------------------
1821 // ocpnToolBarSimple creation
1822 // ----------------------------------------------------------------------------
1823 
Init()1824 void ocpnToolBarSimple::Init()
1825 {
1826     m_currentRowsOrColumns = 0;
1827 
1828     m_lastX = m_lastY = 0;
1829 
1830     m_maxWidth = m_maxHeight = 0;
1831 
1832     m_pressedTool = m_currentTool = -1;
1833 
1834     m_xPos = m_yPos = wxDefaultCoord;
1835 
1836     m_style = g_StyleManager->GetCurrentStyle();
1837 
1838     m_defaultWidth = 16;
1839     m_defaultHeight = 15;
1840 
1841     m_toggle_bg_color = wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE );
1842     m_toolOutlineColour.Set( _T("BLACK") );
1843     m_pToolTipWin = NULL;
1844     m_last_ro_tool = NULL;
1845 
1846     m_btoolbar_is_zooming = false;
1847     m_sizefactor = 1.0f;
1848 
1849     m_last_plugin_down_id = -1;
1850     m_leftDown = false;
1851     m_nShowTools = 0;
1852 
1853     EnableTooltips();
1854     m_tbenableRolloverBitmaps = false;
1855 
1856  }
1857 
DoAddTool(int id,const wxString & label,const wxBitmap & bitmap,const wxBitmap & bmpDisabled,wxItemKind kind,const wxString & shortHelp,const wxString & longHelp,wxObject * clientData,wxCoord xPos,wxCoord yPos)1858 wxToolBarToolBase *ocpnToolBarSimple::DoAddTool( int id, const wxString& label,
1859         const wxBitmap& bitmap, const wxBitmap& bmpDisabled, wxItemKind kind,
1860         const wxString& shortHelp, const wxString& longHelp, wxObject *clientData, wxCoord xPos,
1861         wxCoord yPos )
1862 {
1863     // rememeber the position for DoInsertTool()
1864     m_xPos = xPos;
1865     m_yPos = yPos;
1866 
1867     InvalidateBestSize();
1868     return InsertTool( GetToolsCount(), id, label, bitmap, bmpDisabled, kind, shortHelp, longHelp,
1869             clientData );
1870 
1871 }
1872 
1873 ///
1874 
AddTool(int toolid,const wxString & label,const wxBitmap & bitmap,const wxBitmap & bmpDisabled,wxItemKind kind,const wxString & shortHelp,const wxString & longHelp,wxObject * data)1875 wxToolBarToolBase *ocpnToolBarSimple::AddTool( int toolid, const wxString& label,
1876         const wxBitmap& bitmap, const wxBitmap& bmpDisabled, wxItemKind kind,
1877         const wxString& shortHelp, const wxString& longHelp, wxObject *data )
1878 {
1879     InvalidateBestSize();
1880     ocpnToolBarTool* tool = (ocpnToolBarTool*)InsertTool( GetToolsCount(), toolid, label, bitmap, bmpDisabled, kind,
1881             shortHelp, longHelp, data );
1882     return tool;
1883 }
1884 
InsertTool(size_t pos,int id,const wxString & label,const wxBitmap & bitmap,const wxBitmap & bmpDisabled,wxItemKind kind,const wxString & shortHelp,const wxString & longHelp,wxObject * clientData)1885 wxToolBarToolBase *ocpnToolBarSimple::InsertTool( size_t pos, int id, const wxString& label,
1886         const wxBitmap& bitmap, const wxBitmap& bmpDisabled, wxItemKind kind,
1887         const wxString& shortHelp, const wxString& longHelp, wxObject *clientData )
1888 {
1889     wxCHECK_MSG( pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
1890             _T("invalid position in wxToolBar::InsertTool()") );
1891 
1892     wxToolBarToolBase *tool = CreateTool( id, label, bitmap, bmpDisabled, kind, clientData,
1893             shortHelp, longHelp );
1894 
1895     if( !InsertTool( pos, tool ) ) {
1896         delete tool;
1897 
1898         return NULL;
1899     }
1900 
1901     return tool;
1902 }
1903 
InsertTool(size_t pos,wxToolBarToolBase * tool)1904 wxToolBarToolBase *ocpnToolBarSimple::InsertTool( size_t pos, wxToolBarToolBase *tool )
1905 {
1906     wxCHECK_MSG( pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
1907             _T("invalid position in wxToolBar::InsertTool()") );
1908 
1909     if( !tool || !DoInsertTool( pos, tool ) ) {
1910         return NULL;
1911     }
1912 
1913     m_tools.Insert( pos, tool );
1914     m_nShowTools++;
1915 
1916     return tool;
1917 }
1918 
DoInsertTool(size_t WXUNUSED (pos),wxToolBarToolBase * toolBase)1919 bool ocpnToolBarSimple::DoInsertTool( size_t WXUNUSED(pos), wxToolBarToolBase *toolBase )
1920 {
1921     ocpnToolBarTool *tool = (ocpnToolBarTool *) toolBase;
1922 
1923     // Check if the plugin is inserting same-named tools. Make sure they have different names,
1924     // otherwise the style manager cannot differentiate between them.
1925     if( tool->isPluginTool ) {
1926         for( unsigned int i=0; i<GetToolsCount(); i++ ) {
1927             if( tool->GetToolname() == ((ocpnToolBarTool *)m_tools.Item(i)->GetData())->GetToolname()) {
1928                 tool->toolname << _T("1");
1929             }
1930         }
1931     }
1932 
1933     tool->m_x = m_xPos;
1934     if( tool->m_x == wxDefaultCoord ) tool->m_x = m_style->GetLeftMargin();
1935 
1936     tool->m_y = m_yPos;
1937     if( tool->m_y == wxDefaultCoord ) tool->m_y = m_style->GetTopMargin();
1938 
1939     if( tool->IsButton() ) {
1940         tool->SetSize( GetToolSize() );
1941 
1942         // Calculate reasonable max size in case Layout() not called
1943         if( ( tool->m_x + tool->GetNormalBitmap().GetWidth() + m_style->GetLeftMargin() )
1944                 > m_maxWidth ) m_maxWidth = (wxCoord) ( ( tool->m_x + tool->GetWidth()
1945                 + m_style->GetLeftMargin() ) );
1946 
1947         if( ( tool->m_y + tool->GetNormalBitmap().GetHeight() + m_style->GetTopMargin() )
1948                 > m_maxHeight ) m_maxHeight = (wxCoord) ( ( tool->m_y + tool->GetHeight()
1949                 + m_style->GetTopMargin() ) );
1950     }
1951 
1952     else
1953         if( tool->IsControl() ) {
1954             tool->SetSize( tool->GetControl()->GetSize() );
1955         }
1956 
1957     tool->b_hilite = false;
1958 
1959     return true;
1960 }
1961 
DoDeleteTool(size_t WXUNUSED (pos),wxToolBarToolBase * tool)1962 bool ocpnToolBarSimple::DoDeleteTool( size_t WXUNUSED(pos), wxToolBarToolBase *tool )
1963 {
1964     // VZ: didn't test whether it works, but why not...
1965     tool->Detach();
1966 
1967     if( m_last_ro_tool == tool ) m_last_ro_tool = NULL;
1968 
1969     Refresh( false );
1970 
1971     return true;
1972 }
1973 
Create(wxWindow * parent,wxWindowID id,const wxPoint & pos,const wxSize & size,long style,const wxString & name)1974 bool ocpnToolBarSimple::Create( wxWindow *parent, wxWindowID id, const wxPoint& pos,
1975         const wxSize& size, long style, const wxString& name )
1976 {
1977     if( !wxWindow::Create( parent, id, pos, size, style, name ) ) return false;
1978 
1979     // Set it to grey (or other 3D face colour)
1980     SetBackgroundColour( wxSystemSettings::GetColour( wxSYS_COLOUR_3DFACE ) );
1981 
1982     if( GetWindowStyleFlag() & wxTB_VERTICAL ) {
1983         m_lastX = 7;
1984         m_lastY = 3;
1985 
1986         m_maxRows = 32000;      // a lot
1987         m_maxCols = 1;
1988     } else {
1989         m_lastX = 3;
1990         m_lastY = 7;
1991 
1992         m_maxRows = 1;
1993         m_maxCols = 32000;      // a lot
1994     }
1995 
1996     SetCursor( *wxSTANDARD_CURSOR );
1997 
1998     m_tooltip_timer.SetOwner( this, TOOLTIPON_TIMER );
1999     m_tooltipoff_timer.SetOwner( this, TOOLTIPOFF_TIMER );
2000     m_tooltip_off = 3000;
2001 
2002     m_tbenableRolloverBitmaps = false;
2003 
2004     return true;
2005 }
2006 
~ocpnToolBarSimple()2007 ocpnToolBarSimple::~ocpnToolBarSimple()
2008 {
2009     if( m_pToolTipWin ) {
2010         m_pToolTipWin->Destroy();
2011         m_pToolTipWin = NULL;
2012     }
2013 
2014 }
2015 
KillTooltip()2016 void ocpnToolBarSimple::KillTooltip()
2017 {
2018     m_btooltip_show = false;
2019 
2020     if( m_pToolTipWin ) {
2021         m_pToolTipWin->Hide();
2022         m_pToolTipWin->Destroy();
2023         m_pToolTipWin = NULL;
2024     }
2025     m_tooltip_timer.Stop();
2026 
2027 /*
2028     if( m_last_ro_tool ) {
2029         if( m_last_ro_tool->IsEnabled() ) {
2030             if( m_last_ro_tool->IsToggled() ) {
2031                 if( m_style->NativeToolIconExists(m_last_ro_tool->GetToolname()) ) {
2032                     m_last_ro_tool->SetNormalBitmap( m_style->GetToolIcon( m_last_ro_tool->GetToolname(), TOOLICON_TOGGLED ) );
2033                 }
2034                 else{
2035                     m_last_ro_tool->SetNormalBitmap(m_style->BuildPluginIcon( m_last_ro_tool->pluginNormalIcon, TOOLICON_TOGGLED ));
2036                 }
2037 
2038             }
2039             else {
2040                 if( m_style->NativeToolIconExists(m_last_ro_tool->GetToolname()) ) {
2041                     m_last_ro_tool->SetNormalBitmap( m_style->GetToolIcon( m_last_ro_tool->GetToolname(), TOOLICON_NORMAL ) );
2042                 }
2043                 else{
2044                     m_last_ro_tool->SetNormalBitmap(m_style->BuildPluginIcon( m_last_ro_tool->pluginNormalIcon, TOOLICON_NORMAL ));
2045                 }
2046             }
2047         }
2048     }
2049 */
2050     gFrame->Raise();
2051     gFrame->GetFocusCanvas()->TriggerDeferredFocus();
2052 
2053 }
2054 
HideTooltip()2055 void ocpnToolBarSimple::HideTooltip()
2056 {
2057     if( m_pToolTipWin ) {
2058         m_pToolTipWin->Hide();
2059     }
2060 }
2061 
SetColorScheme(ColorScheme cs)2062 void ocpnToolBarSimple::SetColorScheme( ColorScheme cs )
2063 {
2064     if( m_pToolTipWin ) {
2065         m_pToolTipWin->Destroy();
2066         m_pToolTipWin = NULL;
2067     }
2068 
2069     m_toolOutlineColour = GetGlobalColor( _T("UIBDR") );
2070 
2071     m_currentColorScheme = cs;
2072 }
2073 
Realize()2074 bool ocpnToolBarSimple::Realize()
2075 {
2076     if( IsVertical() )
2077         m_style->SetOrientation( wxTB_VERTICAL );
2078     else
2079         m_style->SetOrientation( wxTB_HORIZONTAL );
2080 
2081     wxSize toolSize = wxSize(-1, -1);
2082     int separatorSize = m_style->GetToolSeparation() * m_sizefactor;
2083     int topMargin = m_style->GetTopMargin() * m_sizefactor;
2084     int leftMargin = m_style->GetLeftMargin() * m_sizefactor;
2085 
2086     m_currentRowsOrColumns = 0;
2087     m_LineCount = 1;
2088     m_lastX = leftMargin;
2089     m_lastY = topMargin;
2090     m_maxWidth = 0;
2091     m_maxHeight = 0;
2092 
2093     ocpnToolBarTool *lastTool = NULL;
2094     bool firstNode = true;
2095     wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
2096 
2097     int iNode = 0;
2098 
2099     while( node ) {
2100 
2101         if(iNode >= m_nShowTools)
2102             break;
2103 
2104         ocpnToolBarTool *tool = (ocpnToolBarTool *) node->GetData();
2105 
2106         // Set the tool size to be the size of the first non-separator tool, usually the first one
2107         if(toolSize.x == -1){
2108             if( !tool->IsSeparator() ){
2109                 toolSize.x = tool->m_width;
2110                 toolSize.y = tool->m_height;
2111             }
2112         }
2113 
2114         tool->firstInLine = firstNode;
2115         tool->lastInLine = false;
2116         firstNode = false;
2117 
2118         tool->last_rect.width = 0;              // mark it invalid
2119 
2120         if( tool->IsSeparator() ) {
2121             if( GetWindowStyleFlag() & wxTB_HORIZONTAL ) {
2122                 if( m_currentRowsOrColumns >= m_maxCols )
2123                     m_lastY += separatorSize;
2124                 else
2125                     m_lastX += separatorSize;
2126             } else {
2127                 if( m_currentRowsOrColumns >= m_maxRows )
2128                     m_lastX += separatorSize;
2129                 else
2130                     m_lastY += separatorSize;
2131             }
2132         } else
2133             if( tool->IsButton() ) {
2134                 if( !IsVertical() ) {
2135                     if( m_currentRowsOrColumns >= m_maxCols ) {
2136                         tool->firstInLine = true;
2137                         if( lastTool && m_LineCount > 1 ) lastTool->lastInLine = true;
2138                         m_LineCount++;
2139                         m_currentRowsOrColumns = 0;
2140                         m_lastX = leftMargin;
2141                         m_lastY += toolSize.y + topMargin;
2142                     }
2143                     tool->m_x = (wxCoord) m_lastX;
2144                     tool->m_y = (wxCoord) m_lastY;
2145 
2146                     tool->trect = wxRect( tool->m_x, tool->m_y, toolSize.x, toolSize.y );
2147                     tool->trect.Inflate( separatorSize / 2, topMargin );
2148 
2149                     m_lastX += toolSize.x + separatorSize;
2150                 } else {
2151                     if( m_currentRowsOrColumns >= m_maxRows ) {
2152                         tool->firstInLine = true;
2153                         if( lastTool ) lastTool->lastInLine = true;
2154                         m_LineCount++;
2155                         m_currentRowsOrColumns = 0;
2156                         m_lastX += toolSize.x + leftMargin;
2157                         m_lastY = topMargin;
2158                     }
2159                     tool->m_x = (wxCoord) m_lastX;
2160                     tool->m_y = (wxCoord) m_lastY;
2161 
2162                     tool->trect = wxRect( tool->m_x, tool->m_y, toolSize.x, toolSize.y );
2163                     tool->trect.Inflate( (separatorSize / 2),  topMargin );
2164 
2165                     m_lastY += toolSize.y + separatorSize;
2166                 }
2167                 m_currentRowsOrColumns++;
2168             } else
2169                 if( tool->IsControl() ) {
2170                     tool->m_x = (wxCoord) ( m_lastX );
2171                     tool->m_y = (wxCoord) ( m_lastY - ( topMargin / 2 ) );
2172 
2173                     tool->trect = wxRect( tool->m_x, tool->m_y, tool->GetWidth(), tool->GetHeight() );
2174                     tool->trect.Inflate( separatorSize / 2, topMargin );
2175 
2176 
2177                     wxSize s = tool->GetControl()->GetSize();
2178                     m_lastX += s.x + separatorSize;
2179 
2180                 }
2181 
2182         if( m_lastX > m_maxWidth )
2183             m_maxWidth = m_lastX;
2184         if( m_lastY > m_maxHeight )
2185             m_maxHeight = m_lastY;
2186 
2187         lastTool = tool;
2188         node = node->GetNext();
2189         iNode++;
2190     }
2191     if( lastTool && (m_LineCount > 1 || IsVertical()) )
2192         lastTool->lastInLine = true;
2193 
2194     if( GetWindowStyleFlag() & wxTB_HORIZONTAL ){
2195         m_maxHeight += toolSize.y;
2196         m_maxHeight += m_style->GetBottomMargin();
2197     }
2198     else{
2199         m_maxWidth += toolSize.x;
2200         m_maxWidth += m_style->GetRightMargin() * m_sizefactor;
2201     }
2202 
2203     SetSize( m_maxWidth, m_maxHeight );
2204     SetMinSize( wxSize( m_maxWidth, m_maxHeight ) );
2205 
2206     return true;
2207 }
2208 
2209 // ----------------------------------------------------------------------------
2210 // event handlers
2211 // ----------------------------------------------------------------------------
2212 
OnPaint(wxPaintEvent & WXUNUSED (event))2213 void ocpnToolBarSimple::OnPaint( wxPaintEvent& WXUNUSED(event) )
2214 {
2215     wxPaintDC dc( this );
2216     PrepareDC( dc );
2217 
2218     wxRegion ru = GetUpdateRegion();
2219     wxRect upRect = ru.GetBox();
2220 
2221     static int count = 0;
2222     // Prevent reentry of OnPaint which would cause wxMemoryDC errors.
2223     if( count > 0 ) return;
2224     count++;
2225 
2226     for( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); node; node = node->GetNext() ) {
2227         wxToolBarToolBase *tool = node->GetData();
2228         ocpnToolBarTool *tools = (ocpnToolBarTool *) tool;
2229         wxRect toolRect = tools->trect;
2230 
2231         if( toolRect.Intersects( upRect ) ) {
2232 
2233             if( tool->IsButton() ) {
2234                 DrawTool( dc, tool );
2235             } else
2236                 if( tool->IsControl() ) {
2237                     if( tool->GetControl()->IsKindOf( CLASSINFO(wxStaticBitmap) ) ) {
2238                         wxStaticBitmap *psbm = (wxStaticBitmap *) tool->GetControl();
2239                         ocpnToolBarTool *toolsimp = (ocpnToolBarTool *) tool;
2240                         dc.DrawBitmap( psbm->GetBitmap(), toolsimp->m_x, toolsimp->m_y, false );
2241                     }
2242                 }
2243         }
2244     }
2245 
2246     count--;
2247 }
2248 
OnSize(wxSizeEvent & WXUNUSED (event))2249 void ocpnToolBarSimple::OnSize( wxSizeEvent& WXUNUSED(event) )
2250 {
2251     /*if( GetAutoLayout() )*/ Layout();
2252 }
2253 
OnKillFocus(wxFocusEvent & WXUNUSED (event))2254 void ocpnToolBarSimple::OnKillFocus( wxFocusEvent& WXUNUSED(event) )
2255 {
2256     OnMouseEnter( m_pressedTool = m_currentTool = -1 );
2257 }
2258 
OnToolTipTimerEvent(wxTimerEvent & event)2259 void ocpnToolBarSimple::OnToolTipTimerEvent( wxTimerEvent& event )
2260 {
2261     if( !gFrame ) //In case gFrame was already destroyed, but the toolbar still exists (Which should not happen, ever.)
2262         return;
2263 
2264     //if( !gFrame->IsActive() )
2265     //    return;
2266 
2267     if( m_btooltip_show && IsShown() && m_pToolTipWin && ( !m_pToolTipWin->IsShown() ) ) {
2268         if( m_last_ro_tool ) {
2269             wxString s = m_last_ro_tool->GetShortHelp();
2270 
2271             if( s.Len() ) {
2272                 m_pToolTipWin->SetString( s );
2273                 m_pToolTipWin->SetHiviz(m_last_ro_tool->m_btooltip_hiviz);
2274 
2275                 wxPoint pos_in_toolbar( m_last_ro_tool->m_x, m_last_ro_tool->m_y );
2276                 pos_in_toolbar.x += m_last_ro_tool->m_width + 2;
2277 
2278                 m_pToolTipWin->Move(0,0);       // workaround for gtk autocentre dialog behavior
2279 
2280                 wxPoint screenPosition = ClientToScreen( pos_in_toolbar );
2281                 wxPoint framePosition = gFrame->ScreenToClient(screenPosition);
2282                 wxSize tipSize = m_pToolTipWin->GetRenderedSize();
2283 
2284                 if( (framePosition.x + tipSize.x) > gFrame->GetSize().x)
2285                     screenPosition.x -= (tipSize.x + m_last_ro_tool->m_width + 4);
2286 
2287                 m_pToolTipWin->SetPosition( screenPosition );
2288                 m_pToolTipWin->SetBitmap();
2289                 m_pToolTipWin->Show();
2290 #ifndef __WXOSX__
2291                 gFrame->Raise();
2292 #endif
2293                 if( g_btouch )
2294                     m_tooltipoff_timer.Start(m_tooltip_off, wxTIMER_ONE_SHOT);
2295             }
2296         }
2297     }
2298 }
2299 
OnToolTipOffTimerEvent(wxTimerEvent & event)2300 void ocpnToolBarSimple::OnToolTipOffTimerEvent( wxTimerEvent& event )
2301 {
2302     HideTooltip();
2303 }
2304 
2305 
2306 int s_dragx, s_dragy;
2307 bool leftDown;
2308 
OnMouseEvent(wxMouseEvent & event)2309 void ocpnToolBarSimple::OnMouseEvent( wxMouseEvent & event )
2310 {
2311 #ifdef __OCPN__ANDROID__
2312     if(!event.IsButton())
2313         return;
2314 #endif
2315 
2316     wxCoord x, y;
2317     event.GetPosition( &x, &y );
2318     ocpnToolBarTool *tool = (ocpnToolBarTool *) FindToolForPosition( x, y );
2319 
2320 #ifndef __OCPN__ANDROID__
2321     if( event.LeftDown() ) {
2322 ///        CaptureMouse();
2323         s_dragx = x;
2324         s_dragy = y;
2325     }
2326     if( event.LeftUp() ) {
2327 ///        if( HasCapture() ) ReleaseMouse();
2328     }
2329 #endif
2330 
2331     if( tool && tool->IsButton() && IsShown() ) {
2332 
2333         if(m_btooltip_show){
2334             //    ToolTips
2335             if( NULL == m_pToolTipWin ) {
2336                 m_pToolTipWin = new ToolTipWin( gFrame/*GetParent()*/ );
2337                 m_pToolTipWin->SetColorScheme( m_currentColorScheme );
2338                 m_pToolTipWin->Hide();
2339             }
2340 
2341             if( tool != m_last_ro_tool ){
2342                 m_pToolTipWin->Hide();
2343             }
2344 
2345 #ifndef __OCPN__ANDROID__
2346             if( !m_pToolTipWin->IsShown() ) {
2347                 if(!m_tooltip_timer.IsRunning()){
2348                     m_tooltip_timer.Start( m_one_shot, wxTIMER_ONE_SHOT );
2349                 }
2350             }
2351 #endif
2352         }
2353         //    Tool Rollover highlighting
2354         if(!g_btouch && m_tbenableRolloverBitmaps){
2355             if( tool != m_last_ro_tool ) {
2356                 if( tool->IsEnabled() ) {
2357                     tool->rollover = true;
2358                 }
2359                 if( m_last_ro_tool ) {
2360                     if( m_last_ro_tool->IsEnabled() ) {
2361                         m_last_ro_tool->rollover = false;
2362                     }
2363                 }
2364                 tool->bitmapOK = false;
2365                 m_last_ro_tool = tool;
2366 
2367                 Refresh( false );
2368             }
2369         }
2370     } else {
2371         //    Tooltips
2372         if( m_pToolTipWin && m_pToolTipWin->IsShown() ){
2373             m_pToolTipWin->Hide();
2374             KillTooltip();
2375             m_btooltip_show = true;
2376 
2377         }
2378 
2379         //    Remove Highlighting
2380         if( m_last_ro_tool && m_tbenableRolloverBitmaps) {
2381             if( m_last_ro_tool->IsEnabled() ) {
2382                 m_last_ro_tool->rollover = false;
2383                 m_last_ro_tool->bitmapOK = false;
2384             }
2385             Refresh( false );
2386         }
2387     }
2388 
2389     m_last_ro_tool = tool;
2390 
2391     // allow smooth zooming while toolbutton is held down
2392     if(g_bsmoothpanzoom && !g_btouch) {
2393         ChartCanvas *pcc = NULL;
2394         ocpnFloatingToolbarDialog *parent = wxDynamicCast(GetParent(), ocpnFloatingToolbarDialog);
2395         if(parent)
2396             pcc = wxDynamicCast(parent->GetParent(), ChartCanvas);
2397 
2398 
2399         if(event.LeftUp() && m_btoolbar_is_zooming) {
2400             if(pcc){
2401                 pcc->StopMovement();
2402                 m_btoolbar_is_zooming = false;
2403             }
2404             return;
2405         }
2406 
2407         if( event.LeftDown() && tool && (tool->GetId() == ID_ZOOMIN || tool->GetId() == ID_ZOOMOUT) ) {
2408             if(pcc){
2409                 pcc->ZoomCanvas( tool->GetId() == ID_ZOOMIN ? g_plus_minus_zoom_factor : 1.0 / g_plus_minus_zoom_factor, false, false );
2410                 m_btoolbar_is_zooming = true;
2411             }
2412             return;
2413         }
2414     }
2415 
2416     if( !tool ) {
2417         if( m_currentTool > -1 ) {
2418             if( event.LeftIsDown() ) SpringUpButton( m_currentTool );
2419             m_currentTool = -1;
2420             OnMouseEnter( -1 );
2421         }
2422 
2423         wxMouseEvent *pev = (wxMouseEvent *) event.Clone();
2424         GetParent()->GetEventHandler()->AddPendingEvent( *pev );
2425         wxDELETE( pev );
2426 
2427         return;
2428     }
2429 
2430     if (tool->GetId() == ID_MASTERTOGGLE) {
2431         static wxPoint s_pos_m_old;
2432         static bool s_drag;
2433 
2434         wxPoint pos_m = ClientToScreen(wxPoint(x, y));
2435         if (event.LeftDown()) {
2436             s_pos_m_old = pos_m;
2437 
2438         }
2439 
2440         if (event.Dragging()) {
2441             s_drag = true;
2442             wxPoint pos_old = GetScreenPosition();
2443             wxPoint pos_new = pos_old;
2444 
2445             pos_new.x += pos_m.x - s_pos_m_old.x;
2446             pos_new.y += pos_m.y - s_pos_m_old.y;
2447 
2448             ocpnFloatingToolbarDialog * parentFloatingToolBar = dynamic_cast<ocpnFloatingToolbarDialog*>(GetParent());
2449             parentFloatingToolBar->MoveDialogInScreenCoords(pos_new, pos_old);
2450             s_pos_m_old = pos_m;
2451             return;
2452         }
2453 
2454         if (event.LeftUp() && s_drag) {
2455             s_drag = false;
2456             return;
2457         }
2458     }
2459 
2460     if( !event.IsButton() ) {
2461         if( tool->GetId() != m_currentTool ) {
2462             // If the left button is kept down and moved over buttons,
2463             // press those buttons.
2464             if( event.LeftIsDown() && tool->IsEnabled() ) {
2465                 SpringUpButton( m_currentTool );
2466 
2467                 if( tool->CanBeToggled() ) {
2468                     tool->Toggle();
2469                 }
2470 
2471                 DrawTool( tool );
2472             }
2473 
2474             m_currentTool = tool->GetId();
2475             OnMouseEnter( m_currentTool );
2476         }
2477 
2478         wxMouseEvent *pev = (wxMouseEvent *) event.Clone();
2479         GetParent()->GetEventHandler()->AddPendingEvent( *pev );
2480         wxDELETE( pev );
2481 
2482         return;
2483     }
2484 
2485     // Left button pressed.
2486     if( event.LeftIsDown() )
2487         m_leftDown = true;                      // trigger on
2488 
2489     if( event.LeftDown() && tool->IsEnabled() ) {
2490         if( tool->CanBeToggled() ) {
2491             tool->Toggle();
2492             tool->bitmapOK = false;
2493 
2494         }
2495 
2496         DrawTool( tool );
2497 
2498         //        Look for PlugIn tools
2499         //        If found, make the callback.
2500         if( g_pi_manager ) {
2501             ArrayOfPlugInToolbarTools tool_array = g_pi_manager->GetPluginToolbarToolArray();
2502             for( unsigned int i = 0; i < tool_array.GetCount(); i++ ) {
2503                 PlugInToolbarToolContainer *pttc = tool_array[i];
2504                 if( tool->GetId() == pttc->id ) {
2505                     opencpn_plugin_113 *ppi = dynamic_cast<opencpn_plugin_113 *>(pttc->m_pplugin);
2506                     if( ppi ) {
2507                         ppi->OnToolbarToolDownCallback( pttc->id );
2508                         m_last_plugin_down_id = pttc->id;
2509                     }
2510                 }
2511             }
2512         }
2513     } else
2514         if( event.RightDown() ) {
2515             OnRightClick( tool->GetId(), x, y );
2516         }
2517 
2518     // Left Button Released.  Only this action confirms selection.
2519     // If the button is enabled and it is not a toggle tool and it is
2520     // in the pressed state, then raise the button and call OnLeftClick.
2521     //
2522     // Unfortunately, some touch screen drivers do not send "LeftIsDown" events.
2523     // Nor do they report "LeftIsDown" in any state.
2524     // c.f rPI "official" 7" panel.
2525 
2526     // So, for this logic, assume in touch mode that the m_leftDown flag may not be set,
2527     // and process the left-up event anyway.
2528     if( event.LeftUp() && tool->IsEnabled() && (m_leftDown || g_btouch) ) {
2529         // Pass the OnLeftClick event to tool
2530         if( !OnLeftClick( tool->GetId(), tool->IsToggled() ) && tool->CanBeToggled() ) {
2531             // If it was a toggle, and OnLeftClick says No Toggle allowed,
2532             // then change it back
2533             tool->Toggle();
2534             tool->bitmapOK = false;
2535         }
2536 
2537         DoPluginToolUp();
2538         m_leftDown = false;
2539     }
2540 
2541     wxMouseEvent *pev = (wxMouseEvent *) event.Clone();
2542     GetParent()->GetEventHandler()->AddPendingEvent( *pev );
2543     wxDELETE( pev );
2544     event.Skip();
2545 }
2546 
2547 // ----------------------------------------------------------------------------
2548 // drawing
2549 // ----------------------------------------------------------------------------
2550 
DrawTool(wxToolBarToolBase * tool)2551 void ocpnToolBarSimple::DrawTool( wxToolBarToolBase *tool )
2552 {
2553     wxClientDC dc( this );
2554     DrawTool( dc, tool );
2555 }
2556 
2557 // NB! The current DrawTool code assumes that plugin tools are never disabled
2558 // when they are present on the toolbar, since disabled plugins are removed.
2559 
DrawTool(wxDC & dc,wxToolBarToolBase * toolBase)2560 void ocpnToolBarSimple::DrawTool( wxDC& dc, wxToolBarToolBase *toolBase )
2561 {
2562     ocpnToolBarTool *tool = (ocpnToolBarTool *) toolBase;
2563     PrepareDC( dc );
2564 
2565     wxPoint drawAt( tool->m_x, tool->m_y );
2566     wxBitmap bmp = wxNullBitmap;
2567 
2568     bool bNeedClear = !tool->bitmapOK;
2569 
2570     if( tool->bitmapOK ) {
2571         if( tool->IsEnabled() ) {
2572             bmp = tool->GetNormalBitmap();
2573             if( !bmp.IsOk() ){
2574                 bmp = m_style->GetToolIcon( tool->GetToolname(), TOOLICON_NORMAL, tool->rollover,
2575                                             tool->m_width, tool->m_height );
2576                 tool->SetNormalBitmap( bmp );
2577                 tool->bitmapOK = true;
2578             }
2579         } else {
2580             bmp = tool->GetDisabledBitmap();
2581             if( !bmp.IsOk() ){
2582                 bmp = m_style->GetToolIcon( tool->GetToolname(), TOOLICON_DISABLED, false,
2583                                             tool->m_width, tool->m_height );
2584                 tool->SetDisabledBitmap( bmp );
2585                 tool->bitmapOK = true;
2586             }
2587         }
2588     } else {
2589         if ( tool->isPluginTool ) {
2590             int toggleFlag = tool->IsToggled()?TOOLICON_TOGGLED:TOOLICON_NORMAL;
2591 
2592             // First try getting the icon from an SVG definition.
2593             // If it is not found, try to see if it is available in the style
2594             // If not there, we build a new icon from the style BG and the (default) plugin icon.
2595 
2596             wxString svgFile = tool->pluginNormalIconSVG;
2597             if( toggleFlag ) {
2598                 if(tool->pluginToggledIconSVG.Length())
2599                     svgFile = tool->pluginToggledIconSVG;
2600             }
2601             if( tool->rollover ) {
2602                 if(tool->pluginRolloverIconSVG.Length())
2603                     svgFile = tool->pluginRolloverIconSVG;
2604             }
2605 
2606             if(!svgFile.IsEmpty()){         // try SVG
2607 #ifdef ocpnUSE_SVG
2608 #ifndef __OCPN__ANDROID__
2609                 if( wxFileExists( svgFile ) ){
2610                     wxSVGDocument svgDoc;
2611                     if( svgDoc.Load(svgFile) ){
2612                         bool square = (tool->m_width == tool->m_height);
2613                         bmp = wxBitmap( svgDoc.Render( tool->m_width, tool->m_height, NULL, !square, true ) );
2614                         bmp = m_style->BuildPluginIcon( bmp, toggleFlag, m_sizefactor );
2615                     }
2616                     else
2617                         bmp = m_style->BuildPluginIcon( tool->pluginNormalIcon, TOOLICON_NORMAL );
2618                 }
2619 #else
2620                 bmp = loadAndroidSVG( svgFile,tool->m_width, tool->m_height );
2621                 bmp = m_style->BuildPluginIcon( bmp, TOOLICON_NORMAL );
2622 #endif
2623 
2624 #endif
2625             }
2626 
2627             if( !bmp.IsOk() || bmp.IsNull() ) {
2628                 if( m_style->NativeToolIconExists(tool->GetToolname()) ) {
2629                     bmp = m_style->GetToolIcon( tool->GetToolname(), toggleFlag, tool->rollover, tool->m_width, tool->m_height );
2630                 } else {
2631                     bmp = wxNullBitmap;
2632                 }
2633 
2634                 if( bmp.IsNull() ) {     // Tool icon not found
2635                     if( tool->rollover ) {
2636                         bmp = m_style->BuildPluginIcon( tool->pluginRolloverIcon, toggleFlag );
2637                         if( !bmp.IsOk() ) {
2638                             bmp = m_style->BuildPluginIcon( tool->pluginNormalIcon, toggleFlag );
2639                         }
2640                     }
2641                     else {
2642                         bmp = m_style->BuildPluginIcon( tool->pluginNormalIcon, toggleFlag );
2643                     }
2644                     if( fabs(m_sizefactor - 1.0) > 0.01) {
2645                         if(tool->m_width && tool->m_height) {
2646                             wxImage scaled_image = bmp.ConvertToImage();
2647                             bmp = wxBitmap(scaled_image.Scale(tool->m_width, tool->m_height, wxIMAGE_QUALITY_HIGH));
2648                         }
2649                     }
2650                 }
2651             }
2652             tool->SetNormalBitmap( bmp );
2653             tool->bitmapOK = true;
2654         } else { // Not a plugin tool
2655             bmp = tool->GetNormalBitmap();
2656             if( tool->IsEnabled() ) {
2657                 if( tool->IsToggled() ){
2658                     if(!tool->bitmapOK){
2659                         if(m_style->NativeToolIconExists(tool->GetToolname())){
2660                             bmp = m_style->GetToolIcon( tool->GetToolname(), TOOLICON_TOGGLED, tool->rollover,
2661                                                 tool->m_width, tool->m_height );
2662                             tool->SetNormalBitmap( bmp );
2663                         }
2664                     }
2665                  }
2666 
2667                 else{
2668                     if(!tool->bitmapOK){
2669                         if(m_style->NativeToolIconExists(tool->GetToolname())){
2670                             bmp = m_style->GetToolIcon( tool->GetIconName(), TOOLICON_NORMAL, tool->rollover,
2671                                                 tool->m_width, tool->m_height );
2672                             tool->SetNormalBitmap( bmp );
2673                         }
2674                     }
2675                 }
2676 
2677                 tool->bitmapOK = true;
2678             } else {
2679                 bmp = m_style->GetToolIcon( tool->GetToolname(), TOOLICON_DISABLED, false,
2680                                             tool->m_width, tool->m_height );
2681                 tool->SetDisabledBitmap( bmp );
2682                 tool->bitmapOK = true;
2683             }
2684         }
2685     }
2686 
2687     if( tool->firstInLine ) {
2688         m_style->DrawToolbarLineStart( bmp, m_sizefactor );
2689     }
2690     if( tool->lastInLine ) {
2691         m_style->DrawToolbarLineEnd( bmp, m_sizefactor );
2692     }
2693 
2694     if( bmp.GetWidth() != m_style->GetToolSize().x
2695             || bmp.GetHeight() != m_style->GetToolSize().y ) {
2696 //        drawAt.x -= ( bmp.GetWidth() - m_style->GetToolSize().x ) / 2;
2697 //        drawAt.y -= ( bmp.GetHeight() - m_style->GetToolSize().y ) / 2;
2698     }
2699 
2700     //      Clear the last drawn tool if necessary
2701     if( (tool->last_rect.width && (tool->last_rect.x != drawAt.x || tool->last_rect.y != drawAt.y)) || bNeedClear )
2702     {
2703         wxBrush bb(GetGlobalColor( _T("GREY3") ));
2704         dc.SetBrush(bb);
2705         dc.SetPen( *wxTRANSPARENT_PEN );
2706         dc.DrawRectangle(tool->last_rect.x, tool->last_rect.y, tool->last_rect.width, tool->last_rect.height);
2707     }
2708 
2709     //  could cache this in the tool...
2710     //  A bit of a hack here.  We only scale tools if they are to be magnified globally
2711     if(0/*m_sizefactor > 1.0*/ )
2712     {
2713         wxImage scaled_image = bmp.ConvertToImage();
2714         wxBitmap sbmp = wxBitmap(scaled_image.Scale(tool->m_width, tool->m_height, wxIMAGE_QUALITY_HIGH));
2715         dc.DrawBitmap( sbmp, drawAt );
2716         tool->last_rect = wxRect(drawAt.x, drawAt.y, sbmp.GetWidth(), sbmp.GetHeight());
2717 
2718     }
2719     else
2720     {
2721         dc.DrawBitmap( bmp, drawAt );
2722         tool->last_rect = wxRect(drawAt.x, drawAt.y, bmp.GetWidth(), bmp.GetHeight());
2723     }
2724 
2725 }
2726 
2727 // ----------------------------------------------------------------------------
2728 // toolbar geometry
2729 // ----------------------------------------------------------------------------
2730 
FindToolForPosition(wxCoord x,wxCoord y)2731 wxToolBarToolBase *ocpnToolBarSimple::FindToolForPosition( wxCoord x, wxCoord y )
2732 {
2733     wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
2734     while( node ) {
2735         ocpnToolBarTool *tool = (ocpnToolBarTool *) node->GetData();
2736         if( ( x >= tool->m_x ) && ( y >= tool->m_y ) && ( x < ( tool->m_x + tool->GetWidth() ) )
2737                 && ( y < ( tool->m_y + tool->GetHeight() ) ) ) {
2738             return tool;
2739         }
2740 
2741         node = node->GetNext();
2742     }
2743 
2744     return (wxToolBarToolBase *) NULL;
2745 }
2746 
InvalidateBitmaps()2747 void ocpnToolBarSimple::InvalidateBitmaps()
2748 {
2749     wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
2750     while( node ) {
2751         ocpnToolBarTool *tool = (ocpnToolBarTool *) node->GetData();
2752         tool->bitmapOK = false;
2753         node = node->GetNext();
2754     }
2755 }
2756 
GetToolRect(int tool_id)2757 wxRect ocpnToolBarSimple::GetToolRect( int tool_id )
2758 {
2759     wxRect rect;
2760     wxToolBarToolBase *tool = FindById( tool_id );
2761     if( tool ) {
2762         ocpnToolBarTool *otool = (ocpnToolBarTool *) tool;
2763         if( otool ) rect = otool->trect;
2764     }
2765 
2766     return rect;
2767 }
2768 
2769 // ----------------------------------------------------------------------------
2770 // tool state change handlers
2771 // ----------------------------------------------------------------------------
2772 
DoEnableTool(wxToolBarToolBase * tool,bool WXUNUSED (enable))2773 void ocpnToolBarSimple::DoEnableTool( wxToolBarToolBase *tool, bool WXUNUSED(enable) )
2774 {
2775     ocpnToolBarTool *t = (ocpnToolBarTool *) tool;
2776     t->bitmapOK = false;
2777     DrawTool( tool );
2778 }
2779 
DoToggleTool(wxToolBarToolBase * tool,bool WXUNUSED (toggle))2780 void ocpnToolBarSimple::DoToggleTool( wxToolBarToolBase *tool, bool WXUNUSED(toggle) )
2781 {
2782     ocpnToolBarTool *t = (ocpnToolBarTool *) tool;
2783     t->bitmapOK = false;
2784     DrawTool( tool );
2785 }
2786 
2787 // Okay, so we've left the tool we're in ... we must check if the tool we're
2788 // leaving was a 'sprung push button' and if so, spring it back to the up
2789 // state.
SpringUpButton(int id)2790 void ocpnToolBarSimple::SpringUpButton( int id )
2791 {
2792     wxToolBarToolBase *tool = FindById( id );
2793 
2794     if( tool && tool->CanBeToggled() ) {
2795         if( tool->IsToggled() ) tool->Toggle();
2796 
2797         DrawTool( tool );
2798     }
2799 }
2800 
2801 // ----------------------------------------------------------------------------
2802 // scrolling implementation
2803 // ----------------------------------------------------------------------------
2804 
GetToolShortHelp(int id) const2805 wxString ocpnToolBarSimple::GetToolShortHelp( int id ) const
2806 {
2807     wxToolBarToolBase *tool = FindById( id );
2808     wxCHECK_MSG( tool, wxEmptyString, _T("no such tool") );
2809 
2810     return tool->GetShortHelp();
2811 }
2812 
GetToolLongHelp(int id) const2813 wxString ocpnToolBarSimple::GetToolLongHelp( int id ) const
2814 {
2815     wxToolBarToolBase *tool = FindById( id );
2816     wxCHECK_MSG( tool, wxEmptyString, _T("no such tool") );
2817 
2818     return tool->GetLongHelp();
2819 }
2820 
SetToolShortHelp(int id,const wxString & help)2821 void ocpnToolBarSimple::SetToolShortHelp( int id, const wxString& help )
2822 {
2823     wxToolBarToolBase *tool = FindById( id );
2824     if( tool ) {
2825         (void) tool->SetShortHelp( help );
2826     }
2827 }
2828 
SetToolLongHelp(int id,const wxString & help)2829 void ocpnToolBarSimple::SetToolLongHelp( int id, const wxString& help )
2830 {
2831     wxToolBarToolBase *tool = FindById( id );
2832     if( tool ) {
2833         (void) tool->SetLongHelp( help );
2834     }
2835 }
2836 
GetToolPos(int id) const2837 int ocpnToolBarSimple::GetToolPos( int id ) const
2838 {
2839     size_t pos = 0;
2840     wxToolBarToolsList::compatibility_iterator node;
2841 
2842     for( node = m_tools.GetFirst(); node; node = node->GetNext() ) {
2843         if( node->GetData()->GetId() == id ) return pos;
2844 
2845         pos++;
2846     }
2847 
2848     return wxNOT_FOUND;
2849 }
GetToolState(int id) const2850 bool ocpnToolBarSimple::GetToolState( int id ) const
2851 {
2852     wxToolBarToolBase *tool = FindById( id );
2853     wxCHECK_MSG( tool, false, _T("no such tool") );
2854 
2855     return tool->IsToggled();
2856 }
2857 
GetToolEnabled(int id) const2858 bool ocpnToolBarSimple::GetToolEnabled( int id ) const
2859 {
2860     wxToolBarToolBase *tool = FindById( id );
2861     wxCHECK_MSG( tool, false, _T("no such tool") );
2862 
2863     return tool->IsEnabled();
2864 }
2865 
ToggleTool(int id,bool toggle)2866 void ocpnToolBarSimple::ToggleTool( int id, bool toggle )
2867 {
2868     wxToolBarToolBase *tool = FindById( id );
2869 
2870     if( tool && tool->CanBeToggled() && tool->Toggle( toggle ) ) {
2871         DoToggleTool( tool, toggle );
2872         Refresh();
2873     }
2874 }
2875 
GetToolClientData(int id) const2876 wxObject *ocpnToolBarSimple::GetToolClientData( int id ) const
2877 {
2878     wxToolBarToolBase *tool = FindById( id );
2879     return tool ? tool->GetClientData() : (wxObject *) NULL;
2880 }
2881 
SetToolClientData(int id,wxObject * clientData)2882 void ocpnToolBarSimple::SetToolClientData( int id, wxObject *clientData )
2883 {
2884     wxToolBarToolBase *tool = FindById( id );
2885 
2886     wxCHECK_RET( tool, _T("no such tool in wxToolBar::SetToolClientData") );
2887 
2888     tool->SetClientData( clientData );
2889 }
2890 
EnableTool(int id,bool enable)2891 void ocpnToolBarSimple::EnableTool( int id, bool enable )
2892 {
2893     wxToolBarToolBase *tool = FindById( id );
2894     if( tool ) {
2895         if( tool->Enable( enable ) ) {
2896             DoEnableTool( tool, enable );
2897         }
2898     }
2899 
2900     ocpnFloatingToolbarDialog *parent = wxDynamicCast(GetParent(), ocpnFloatingToolbarDialog);
2901     if(parent && parent->m_FloatingToolbarConfigMenu){
2902         wxMenuItem* configItem = parent->m_FloatingToolbarConfigMenu->FindItem( id );
2903         if(configItem)
2904             configItem->Check( true );
2905     }
2906 }
2907 
SetToolTooltipHiViz(int id,bool b_hiviz)2908 void ocpnToolBarSimple::SetToolTooltipHiViz( int id, bool b_hiviz )
2909 {
2910     ocpnToolBarTool *tool = (ocpnToolBarTool*)FindById( id );
2911     if( tool ) {
2912         tool->SetTooltipHiviz( b_hiviz );
2913     }
2914 }
2915 
2916 
ClearTools()2917 void ocpnToolBarSimple::ClearTools()
2918 {
2919     while( GetToolsCount() ) {
2920         DeleteToolByPos( 0 );
2921     }
2922 }
2923 
GetVisibleToolCount()2924 int ocpnToolBarSimple::GetVisibleToolCount()
2925 {
2926     int counter = 0;
2927     wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
2928     while( node ) {
2929         ocpnToolBarTool *tool = (ocpnToolBarTool *) node->GetData();
2930         counter++;
2931         node = node->GetNext();
2932     }
2933     return counter;
2934 }
2935 
DeleteToolByPos(size_t pos)2936 bool ocpnToolBarSimple::DeleteToolByPos( size_t pos )
2937 {
2938     wxCHECK_MSG( pos < GetToolsCount(), false,
2939             _T("invalid position in wxToolBar::DeleteToolByPos()") );
2940 
2941     wxToolBarToolsList::compatibility_iterator node = m_tools.Item(pos);
2942 
2943     if( !DoDeleteTool( pos, node->GetData() ) ) {
2944         return false;
2945     }
2946 
2947     delete node->GetData();
2948     m_tools.Erase( node );
2949 
2950     return true;
2951 }
2952 
DeleteTool(int id)2953 bool ocpnToolBarSimple::DeleteTool( int id )
2954 {
2955     size_t pos = 0;
2956     wxToolBarToolsList::compatibility_iterator node;
2957     for( node = m_tools.GetFirst(); node; node = node->GetNext() ) {
2958         if( node->GetData()->GetId() == id ) break;
2959 
2960         pos++;
2961     }
2962 
2963     if( !node || !DoDeleteTool( pos, node->GetData() ) ) {
2964         return false;
2965     }
2966 
2967     delete node->GetData();
2968     m_tools.Erase( node );
2969 
2970     return true;
2971 }
2972 
AddSeparator()2973 wxToolBarToolBase *ocpnToolBarSimple::AddSeparator()
2974 {
2975     return InsertSeparator( GetToolsCount() );
2976 }
2977 
InsertSeparator(size_t pos)2978 wxToolBarToolBase *ocpnToolBarSimple::InsertSeparator( size_t pos )
2979 {
2980     wxCHECK_MSG( pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
2981             _T("invalid position in wxToolBar::InsertSeparator()") );
2982 
2983     wxToolBarToolBase *tool = CreateTool( wxID_SEPARATOR, wxEmptyString, wxNullBitmap, wxNullBitmap,
2984             wxITEM_SEPARATOR, (wxObject *) NULL, wxEmptyString, wxEmptyString );
2985 
2986     if( !tool || !DoInsertTool( pos, tool ) ) {
2987         delete tool;
2988 
2989         return NULL;
2990     }
2991 
2992     m_tools.Insert( pos, tool );
2993     m_nShowTools++;
2994 
2995     return tool;
2996 }
2997 
RemoveTool(int id)2998 wxToolBarToolBase *ocpnToolBarSimple::RemoveTool( int id )
2999 {
3000     size_t pos = 0;
3001     wxToolBarToolsList::compatibility_iterator node;
3002     for( node = m_tools.GetFirst(); node; node = node->GetNext() ) {
3003         if( node->GetData()->GetId() == id ) break;
3004 
3005         pos++;
3006     }
3007 
3008     if( !node ) {
3009         // don't give any error messages - sometimes we might call RemoveTool()
3010         // without knowing whether the tool is or not in the toolbar
3011         return (wxToolBarToolBase *) NULL;
3012     }
3013 
3014     wxToolBarToolBase *tool = node->GetData();
3015     if( !DoDeleteTool( pos, tool ) ) {
3016         return (wxToolBarToolBase *) NULL;
3017     }
3018 
3019     m_tools.Erase( node );
3020 
3021     return tool;
3022 }
3023 
3024 
FindControl(int id)3025 wxControl *ocpnToolBarSimple::FindControl( int id )
3026 {
3027     for( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); node;
3028             node = node->GetNext() ) {
3029         const wxToolBarToolBase * const tool = node->GetData();
3030         if( tool->IsControl() ) {
3031             wxControl * const control = tool->GetControl();
3032 
3033             if( !control ) {
3034                 wxFAIL_MSG( _T("NULL control in toolbar?") );
3035             } else
3036                 if( control->GetId() == id ) {
3037                     // found
3038                     return control;
3039                 }
3040         }
3041     }
3042 
3043     return NULL;
3044 }
3045 
FindById(int id) const3046 wxToolBarToolBase *ocpnToolBarSimple::FindById( int id ) const
3047 {
3048     wxToolBarToolBase *tool = (wxToolBarToolBase *) NULL;
3049 
3050     for( wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); node;
3051             node = node->GetNext() ) {
3052         tool = node->GetData();
3053         if( tool->GetId() == id ) {
3054             // found
3055             break;
3056         }
3057 
3058         tool = NULL;
3059     }
3060 
3061     return tool;
3062 }
3063 
3064 // ----------------------------------------------------------------------------
3065 // event processing
3066 // ----------------------------------------------------------------------------
3067 
3068 // Only allow toggle if returns true
OnLeftClick(int id,bool toggleDown)3069 bool ocpnToolBarSimple::OnLeftClick( int id, bool toggleDown )
3070 {
3071     wxCommandEvent event( wxEVT_COMMAND_TOOL_CLICKED, id );
3072     event.SetEventObject( this );
3073 
3074     // we use SetInt() to make wxCommandEvent::IsChecked() return toggleDown
3075     event.SetInt( (int) toggleDown );
3076 
3077     // and SetExtraLong() for backwards compatibility
3078     event.SetExtraLong( (long) toggleDown );
3079 
3080     // Send events to this toolbar instead (and thence up the window hierarchy)
3081     GetEventHandler()->ProcessEvent( event );
3082 
3083     return true;
3084 }
3085 
3086 // Call when right button down.
OnRightClick(int id,long WXUNUSED (x),long WXUNUSED (y))3087 void ocpnToolBarSimple::OnRightClick( int id, long WXUNUSED(x), long WXUNUSED(y) )
3088 {
3089     HideTooltip();
3090 
3091     ocpnFloatingToolbarDialog *parent = wxDynamicCast(GetParent(), ocpnFloatingToolbarDialog);
3092     if(parent){
3093         if(parent->m_FloatingToolbarConfigMenu){
3094             ToolbarChoicesDialog *dlg = new ToolbarChoicesDialog(NULL, GetParent(), -1, _T("OpenCPN"), wxDefaultPosition, wxSize(100,100));
3095             int rc = dlg->ShowModal();
3096             delete dlg;
3097 
3098             if(rc == wxID_OK){
3099                 wxCommandEvent event( wxEVT_COMMAND_TOOL_RCLICKED, id );
3100                 event.SetEventObject( this );
3101                 event.SetInt( id );
3102 
3103                 gFrame->GetEventHandler()->AddPendingEvent( event );
3104             }
3105         }
3106     }
3107 }
3108 
3109 // Called when the mouse cursor enters a tool bitmap (no button pressed).
3110 // Argument is wxID_ANY if mouse is exiting the toolbar.
3111 // Note that for this event, the id of the window is used,
3112 // and the integer parameter of wxCommandEvent is used to retrieve
3113 // the tool id.
OnMouseEnter(int id)3114 void ocpnToolBarSimple::OnMouseEnter( int id )
3115 {
3116     wxCommandEvent event( wxEVT_COMMAND_TOOL_ENTER, GetId() );
3117     event.SetEventObject( this );
3118     event.SetInt( id );
3119 
3120     wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
3121     if( frame ) {
3122         wxString help;
3123         wxToolBarToolBase* tool = id == wxID_ANY ? (wxToolBarToolBase*) NULL : FindById( id );
3124         if( tool ) help = tool->GetLongHelp();
3125         frame->DoGiveHelp( help, id != wxID_ANY );
3126     }
3127 
3128     (void) GetEventHandler()->ProcessEvent( event );
3129 
3130     DoPluginToolUp();
3131 }
3132 
DoPluginToolUp()3133 void ocpnToolBarSimple::DoPluginToolUp()
3134 {
3135     //        Look for PlugIn tools
3136     //        If found, make the callback.
3137     if( !g_pi_manager)
3138         return;
3139 
3140     ArrayOfPlugInToolbarTools tool_array = g_pi_manager->GetPluginToolbarToolArray();
3141     for( unsigned int i = 0; i < tool_array.GetCount(); i++ ) {
3142         PlugInToolbarToolContainer *pttc = tool_array[i];
3143         if( m_last_plugin_down_id == pttc->id ) {
3144             opencpn_plugin_113 *ppi = dynamic_cast<opencpn_plugin_113 *>(pttc->m_pplugin);
3145             if( ppi )
3146                 ppi->OnToolbarToolUpCallback( pttc->id );
3147         }
3148     }
3149 
3150     m_last_plugin_down_id = -1;
3151 }
3152 
SetToolNormalBitmapEx(wxToolBarToolBase * tool,const wxString & iconName)3153 void ocpnToolBarSimple::SetToolNormalBitmapEx(wxToolBarToolBase *tool, const wxString & iconName)
3154 {
3155     if( tool ) {
3156         ocpnToolBarTool *otool = (ocpnToolBarTool *) tool;
3157         if(otool){
3158             ocpnStyle::Style *style = g_StyleManager->GetCurrentStyle();
3159 
3160             wxBitmap bmp = style->GetToolIcon( iconName, TOOLICON_NORMAL, false,
3161                                         otool->m_width, otool->m_height );
3162             tool->SetNormalBitmap( bmp );
3163             otool->SetIconName( iconName );
3164         }
3165     }
3166 }
3167 
SetToolNormalBitmapSVG(wxToolBarToolBase * tool,wxString fileSVG)3168 void ocpnToolBarSimple::SetToolNormalBitmapSVG(wxToolBarToolBase *tool, wxString fileSVG)
3169 {
3170     if( tool ) {
3171         ocpnToolBarTool *otool = (ocpnToolBarTool *) tool;
3172         if(otool){
3173             otool->pluginNormalIconSVG = fileSVG;
3174         }
3175     }
3176 }
3177 
3178 
SetToolBitmaps(int id,wxBitmap * bmp,wxBitmap * bmpRollover)3179 void ocpnToolBarSimple::SetToolBitmaps( int id, wxBitmap *bmp, wxBitmap *bmpRollover )
3180 {
3181     ocpnToolBarTool *tool = (ocpnToolBarTool*)FindById( id );
3182     if( tool ) {
3183         if(tool->isPluginTool){
3184             tool->pluginNormalIcon = *bmp;
3185             tool->pluginRolloverIcon = *bmpRollover;
3186             tool->bitmapOK = false;
3187         }
3188         else{
3189             tool->SetNormalBitmap( *bmp );
3190             tool->bitmapOK = true;
3191         }
3192     }
3193 }
3194 
SetToolBitmapsSVG(int id,wxString fileSVGNormal,wxString fileSVGRollover,wxString fileSVGToggled)3195 void ocpnToolBarSimple::SetToolBitmapsSVG( int id, wxString fileSVGNormal, wxString fileSVGRollover, wxString fileSVGToggled )
3196 {
3197     ocpnToolBarTool *tool = (ocpnToolBarTool*)FindById( id );
3198     if( tool ) {
3199         tool->pluginNormalIconSVG = fileSVGNormal;
3200         tool->pluginRolloverIconSVG = fileSVGRollover;
3201         tool->pluginToggledIconSVG = fileSVGToggled;
3202         tool->bitmapOK = false;
3203     }
3204 }
3205 
3206 
3207 //-------------------------------------------------------------------------------------
3208 
ToolbarMOBDialog(wxWindow * parent)3209 ToolbarMOBDialog::ToolbarMOBDialog( wxWindow* parent )
3210        : wxDialog( parent, wxID_ANY, _("OpenCPN Alert"), wxDefaultPosition, wxSize(250, 230) )
3211 {
3212     wxBoxSizer* topSizer = new wxBoxSizer( wxVERTICAL );
3213 
3214     wxBoxSizer* sizer = new wxBoxSizer( wxVERTICAL );
3215     topSizer->Add( sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5 );
3216 
3217     choices.push_back( new wxRadioButton( this, 0,  _("No, I don't want to hide it."),
3218             wxDefaultPosition, wxDefaultSize, wxRB_GROUP ) );
3219 
3220     choices.push_back( new wxRadioButton( this, 1, _("No, and permanently remove the option to hide it."),
3221             wxDefaultPosition) );
3222 
3223     choices.push_back( new wxRadioButton( this, 2, _("Yes, hide it."),
3224             wxDefaultPosition) );
3225 
3226     wxStdDialogButtonSizer* buttonSizer = CreateStdDialogButtonSizer( wxOK | wxCANCEL );
3227 
3228 
3229     wxStaticText* textCtrl = new wxStaticText( this, wxID_ANY, _("The Man Over Board button could be an important safety feature.\nAre you sure you want to hide it?") );
3230 
3231     sizer->Add( textCtrl, 0, wxEXPAND | wxALL, 5 );
3232     sizer->Add( choices[0], 0, wxEXPAND | wxALL, 5 );
3233     sizer->Add( choices[1], 0, wxEXPAND | wxALL, 5 );
3234     sizer->Add( choices[2], 0, wxEXPAND | wxALL, 5 );
3235     sizer->Add( buttonSizer, 0, wxEXPAND | wxTOP, 5 );
3236 
3237     topSizer->SetSizeHints(this);
3238     SetSizer( topSizer );
3239 }
3240 
GetSelection()3241 int ToolbarMOBDialog::GetSelection() {
3242     for( unsigned int i=0; i<choices.size(); i++ ) {
3243         if( choices[i]->GetValue() ) return choices[i]->GetId();
3244     }
3245     return 0;
3246 }
3247 
3248 
3249 
3250 
IMPLEMENT_DYNAMIC_CLASS(ToolbarChoicesDialog,wxDialog)3251 IMPLEMENT_DYNAMIC_CLASS( ToolbarChoicesDialog, wxDialog )
3252 /*!
3253  * ToolbarChoicesDialog event table definition
3254  */
3255 BEGIN_EVENT_TABLE( ToolbarChoicesDialog, wxDialog )
3256 END_EVENT_TABLE()
3257 
3258  /*!
3259   * ToolbarChoicesDialog constructors
3260   */
3261 
3262  ToolbarChoicesDialog::ToolbarChoicesDialog()
3263  {
3264  }
3265 
ToolbarChoicesDialog(wxWindow * parent,wxWindow * sponsor,wxWindowID id,const wxString & caption,const wxPoint & pos,const wxSize & size,long style)3266  ToolbarChoicesDialog::ToolbarChoicesDialog( wxWindow* parent, wxWindow *sponsor, wxWindowID id, const wxString& caption,
3267                                          const wxPoint& pos, const wxSize& size, long style )
3268  {
3269 
3270      long wstyle = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER;
3271      wxDialog::Create( parent, id, caption, pos, size, wstyle );
3272 
3273      m_configMenu = NULL;
3274      m_ToolbarDialogAncestor = wxDynamicCast(sponsor, ocpnFloatingToolbarDialog);
3275      if(m_ToolbarDialogAncestor)
3276          m_configMenu = m_ToolbarDialogAncestor->m_FloatingToolbarConfigMenu;
3277 
3278 
3279      CreateControls();
3280      GetSizer()->Fit( this );
3281 
3282      RecalculateSize();
3283 
3284  }
3285 
~ToolbarChoicesDialog()3286  ToolbarChoicesDialog::~ToolbarChoicesDialog()
3287  {
3288  }
3289 
3290  /*!
3291   * Control creation for ToolbarChoicesDialog
3292   */
3293 
CreateControls()3294  void ToolbarChoicesDialog::CreateControls()
3295 {
3296 
3297 
3298     wxBoxSizer* itemBoxSizer1 = new wxBoxSizer( wxVERTICAL );
3299     SetSizer( itemBoxSizer1 );
3300 
3301     wxScrolledWindow *itemDialog1 = new wxScrolledWindow( this, wxID_ANY,
3302                                       wxDefaultPosition, wxSize(-1, -1), wxHSCROLL | wxVSCROLL);
3303     itemDialog1->SetScrollRate(2, 2);
3304 
3305 #ifdef __OCPN__ANDROID__
3306 
3307     //  Set Dialog Font by custom crafted Qt Stylesheet.
3308     wxFont *qFont = GetOCPNScaledFont(_("Dialog"));
3309 
3310     wxString wqs = getFontQtStylesheet(qFont);
3311     wxCharBuffer sbuf = wqs.ToUTF8();
3312     QString qsb = QString(sbuf.data());
3313 
3314     QString qsbq = getQtStyleSheet();           // basic scrollbars, etc
3315 
3316     this->GetHandle()->setStyleSheet( qsb + qsbq );      // Concatenated style sheets
3317 
3318 #endif
3319     itemBoxSizer1->Add( itemDialog1, 2, wxEXPAND | wxALL, 0 );
3320 
3321     wxBoxSizer* itemBoxSizer2 = new wxBoxSizer( wxVERTICAL );
3322     itemDialog1->SetSizer( itemBoxSizer2 );
3323 
3324     wxStaticBox* itemStaticBoxSizer3Static = new wxStaticBox( itemDialog1, wxID_ANY,
3325                                                               _("Choose Toolbar Icons")  );
3326     wxStaticBoxSizer* itemStaticBoxSizer3 = new wxStaticBoxSizer( itemStaticBoxSizer3Static, wxVERTICAL );
3327     itemBoxSizer2->Add( itemStaticBoxSizer3, 0, wxEXPAND | wxALL, 5 );
3328 
3329     int nitems = 0;
3330     int max_width = -1;
3331     if(m_configMenu){
3332         nitems = m_configMenu->GetMenuItemCount();
3333 
3334         cboxes.clear();
3335         for (int i=0 ; i < nitems ; i++){
3336             if ( i + ID_ZOOMIN == ID_MOB && g_bPermanentMOBIcon )
3337                 continue;
3338             wxMenuItem *item = m_configMenu->FindItemByPosition( i );
3339 
3340             wxString label = item->GetItemLabel();
3341             int l = label.Len();
3342             max_width = wxMax(max_width, l);
3343 
3344             wxString windowName = _T("");
3345             if(item->GetId() == ID_MOB + 100)
3346                 windowName = _T("MOBCheck");
3347 
3348             wxCheckBox *cb = new wxCheckBox(itemDialog1, -1, label, wxDefaultPosition, wxDefaultSize, 0, wxDefaultValidator, windowName);
3349 //            wxCheckBox *cb = new wxCheckBox(itemDialog1, -1, label);
3350             itemStaticBoxSizer3->Add(cb, 0, wxALL | wxEXPAND, 2);
3351             cb->SetValue(item->IsChecked());
3352 
3353             cboxes.push_back(cb);
3354         }
3355     }
3356 
3357     itemBoxSizer1->SetMinSize( (max_width + 20) * GetCharWidth()  , (nitems + 4) * GetCharHeight() * 2);
3358 
3359     wxBoxSizer* itemBoxSizerBottom = new wxBoxSizer( wxHORIZONTAL );
3360     itemBoxSizer1->Add( itemBoxSizerBottom, 0, wxALL | wxEXPAND, 5 );
3361 
3362     wxBoxSizer* itemBoxSizerAux = new wxBoxSizer( wxHORIZONTAL );
3363     itemBoxSizerBottom->Add( itemBoxSizerAux, 1, wxALL, 3 );
3364 
3365     wxBoxSizer* itemBoxSizer16 = new wxBoxSizer( wxHORIZONTAL );
3366     itemBoxSizerBottom->Add( itemBoxSizer16, 0, wxALL, 3 );
3367 
3368     m_CancelButton = new wxButton( this, -1, _("Cancel"), wxDefaultPosition,
3369             wxDefaultSize, 0 );
3370     itemBoxSizer16->Add( m_CancelButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1 );
3371 
3372     m_OKButton = new wxButton( this, -1, _("OK"), wxDefaultPosition,
3373             wxDefaultSize, 0 );
3374     itemBoxSizer16->Add( m_OKButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
3375     m_OKButton->SetDefault();
3376 
3377     m_CancelButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ToolbarChoicesDialog::OnCancelClick ), NULL, this );
3378     m_OKButton->Connect( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEventHandler( ToolbarChoicesDialog::OnOkClick ), NULL, this );
3379 
3380     SetColorScheme( (ColorScheme) 0 );
3381 
3382 }
3383 
3384 
3385 
3386 
3387 
3388 
SetColorScheme(ColorScheme cs)3389  void ToolbarChoicesDialog::SetColorScheme( ColorScheme cs )
3390  {
3391      DimeControl( this );
3392  }
3393 
3394 
OnCancelClick(wxCommandEvent & event)3395  void ToolbarChoicesDialog::OnCancelClick( wxCommandEvent& event )
3396  {
3397      EndModal(wxID_CANCEL);
3398  }
3399 
OnOkClick(wxCommandEvent & event)3400  void ToolbarChoicesDialog::OnOkClick( wxCommandEvent& event )
3401  {
3402      unsigned int ncheck = 0;
3403 
3404      wxString toolbarConfigSave = m_ToolbarDialogAncestor->GetToolConfigString();
3405      wxString new_toolbarConfig = toolbarConfigSave;
3406 
3407      for(unsigned int i=0 ; i < cboxes.size() ; i++){
3408          wxCheckBox *cb = cboxes[i];
3409          wxString cbName = cb->GetName();               // Special flag passed into checkbox ctor to find the "MOB" item
3410          if ( cbName.IsSameAs(_T("MOBCheck")) && !cb->IsChecked( ) ) {
3411              // Ask if really want to disable MOB button
3412              ToolbarMOBDialog mdlg( this );
3413              int dialog_ret = mdlg.ShowModal( );
3414              int answer = mdlg.GetSelection( );
3415              if ( dialog_ret == wxID_OK ) {
3416                  if ( answer == 1 ) {
3417                      g_bPermanentMOBIcon = true;
3418                      cb->SetValue( true );
3419                  }
3420                  else if ( answer == 0 ) {
3421                      cb->SetValue( true );
3422                  }
3423              }
3424              else { // wxID_CANCEL
3425                  new_toolbarConfig = toolbarConfigSave;
3426                  return;
3427              }
3428          }
3429          if(m_configMenu){
3430              wxMenuItem *item = m_configMenu->FindItemByPosition( i );
3431              if( new_toolbarConfig.Len() > i ) {
3432                  new_toolbarConfig.SetChar( i, cb->IsChecked( ) ? _T( 'X' ) : _T( '.' ) );
3433              } else {
3434                  new_toolbarConfig.Append( cb->IsChecked( ) ? _T( 'X' ) : _T( '.' ) );
3435              }
3436              item->Check( cb->IsChecked() );
3437              if(cb->IsChecked())
3438                  ncheck++;
3439          }
3440      }
3441 
3442 #if 0
3443      //  We always must have one Tool enabled.  Make it the Options tool....
3444      if( 0 == ncheck){
3445          new_toolbarConfig.SetChar( ID_SETTINGS -ID_ZOOMIN , _T('X') );
3446 
3447          int idOffset = ID_PLUGIN_BASE - ID_ZOOMIN + 100;
3448 
3449          if(m_configMenu){
3450              wxMenuItem *item = m_configMenu->FindItem(ID_SETTINGS + idOffset);
3451              if(item)
3452                 item->Check( true );
3453          }
3454      }
3455 #endif
3456      m_ToolbarDialogAncestor->SetToolConfigString( new_toolbarConfig );
3457 
3458      EndModal(wxID_OK);
3459  }
3460 
RecalculateSize(void)3461  void ToolbarChoicesDialog::RecalculateSize( void )
3462  {
3463      wxSize esize = GetSize();
3464 
3465      if(GetParent()){
3466         wxSize dsize = GetParent()->GetClientSize();
3467         esize.y = wxMin(esize.y, dsize.y - (4 * GetCharHeight()));
3468         esize.x = wxMin(esize.x, dsize.x - (2 * GetCharHeight()));
3469         SetSize(esize);
3470         Centre();
3471 
3472      }
3473      else{
3474         wxSize fsize =  g_Platform->getDisplaySize();
3475         fsize.y = wxMin(esize.y, fsize.y - (4 * GetCharHeight()));
3476         fsize.x = wxMin(esize.x, fsize.x - (2 * GetCharHeight()));
3477         SetSize(fsize);
3478         CentreOnScreen();
3479 #ifdef __OCPN__ANDROID__
3480         Move(GetPosition().x, 10);
3481 #endif
3482      }
3483  }
3484 
3485 
3486