1 /***************************************************************************
2  *
3  * Project:  OpenCPN
4  * Purpose:  OpenCPN iENCToolbar
5  * Author:   David Register
6  *
7  ***************************************************************************
8  *   Copyright (C) 2017 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 "config.h"
27 
28 #include "wx/wxprec.h"
29 
30 #ifndef  WX_PRECOMP
31 #include "wx/wx.h"
32 #endif
33 
34 #include "toolbar.h"
35 #include "iENCToolbar.h"
36 
37 #include "chart1.h"
38 #include "chcanv.h"
39 #include "s52s57.h"
40 #include "s52plib.h"
41 #include "pluginmanager.h"
42 #include "OCPNPlatform.h"
43 #include "chcanv.h"
44 
45 extern s52plib *ps52plib;
46 extern MyFrame * gFrame;
47 extern OCPNPlatform *g_Platform;
48 
49 
50 extern wxImage LoadSVGIcon( wxString filename, int width, int height );
51 
52 //---------------------------------------------------------------------------------------
53 //          iENCToolbar Implementation
54 //---------------------------------------------------------------------------------------
BEGIN_EVENT_TABLE(iENCToolbar,ocpnFloatingToolbarDialog)55 BEGIN_EVENT_TABLE(iENCToolbar, ocpnFloatingToolbarDialog)
56     EVT_MENU(wxID_ANY, iENCToolbar::OnToolLeftClick)
57     EVT_TIMER ( STATE_TIMER, iENCToolbar::StateTimerEvent )
58     EVT_MOUSE_EVENTS ( iENCToolbar::MouseEvent )
59 END_EVENT_TABLE()
60 
61 iENCToolbar::iENCToolbar( wxWindow *parent, wxPoint position, long orient, float size_factor ):
62         ocpnFloatingToolbarDialog( parent, position, orient, size_factor)
63 {
64 
65     LoadToolBitmaps();
66 
67     wxSize a = m_bmMinimum.GetSize();
68     m_ptoolbar->SetToolBitmapSize( a );
69 
70     m_pbmScratch = new wxBitmap(a.x, a.y);
71 
72     m_bmTemplate = m_bmRMinus;
73 
74     m_toolDensity = m_ptoolbar->AddTool( ID_DENSITY, _T("Density"), m_bmMinimum, m_bmMinimum );
75     m_ptoolbar->AddTool( ID_RPLUS, _T("RangePlus"), m_bmRPlus, m_bmRPlus );
76     m_ptoolbar->AddTool( ID_RMINUS, _T("RangeMinus"), m_bmRMinus, m_bmRMinus );
77 
78 
79     SetCanToggleOrientation( false );
80     EnableRolloverBitmaps( false );
81     DisableTooltips();
82     SetGrabberEnable( false );
83 
84     m_nDensity = 0;
85     SetDensityToolBitmap(m_nDensity);
86 
87     // Realize() the toolbar
88     Realize();
89     Hide();
90 
91     RePosition();
92     Show(true);
93 
94     m_state_timer.SetOwner( this, STATE_TIMER );
95     m_state_timer.Start( 500, wxTIMER_CONTINUOUS );
96 
97 
98 }
99 
~iENCToolbar()100 iENCToolbar::~iENCToolbar()
101 {
102 
103 }
104 
MouseEvent(wxMouseEvent & event)105 void iENCToolbar::MouseEvent( wxMouseEvent& event )
106 {
107     if( event.IsButton() )
108         gFrame->Raise();
109 }
110 
111 
SetColorScheme(ColorScheme cs)112 void iENCToolbar::SetColorScheme( ColorScheme cs )
113 {
114     m_range = 0;                // Forcw a redraw of tools
115     m_nDensity = -1;
116 
117     ocpnFloatingToolbarDialog::SetColorScheme( cs );
118 }
119 
120 
LoadToolBitmaps()121 void iENCToolbar::LoadToolBitmaps()
122 {
123     wxString svgDir = g_Platform->GetSharedDataDir() + _T("uidata") + wxFileName::GetPathSeparator() ;
124 
125     int w = 96;
126     int h = 32;
127 
128     if(::wxFileExists( svgDir + _T("iENC_All.svg"))){
129         wxImage img = LoadSVGIcon( svgDir + _T("iENC_All.svg"), w, h );
130         m_bmAll = wxBitmap(img);
131         img = LoadSVGIcon( svgDir + _T("iENC_Minimum.svg"), w, h );
132         m_bmMinimum = wxBitmap(img);
133         img = LoadSVGIcon( svgDir + _T("iENC_Standard.svg"), w, h );
134         m_bmStandard = wxBitmap(img);
135         img = LoadSVGIcon( svgDir + _T("iENC_UserStd.svg"), w, h );
136         m_bmUStd = wxBitmap(img);
137 
138         img = LoadSVGIcon( svgDir + _T("iENC_RPlus.svg"), w, h );
139         m_bmRPlus = wxBitmap(img);
140         img = LoadSVGIcon( svgDir + _T("iENC_RMinus.svg"), w, h );
141         m_bmRMinus = wxBitmap(img);
142 
143     }
144     else{
145         wxLogMessage(_T("Cannot find iENC icons at: ") + svgDir);
146 
147         m_bmMinimum = wxBitmap( 96, 32);
148         m_bmStandard = wxBitmap( 96, 32);;
149         m_bmAll = wxBitmap( 96, 32);
150         m_bmUStd = wxBitmap( 96, 32);
151 
152         m_bmRPlus = wxBitmap( 96, 32);
153         m_bmRMinus = wxBitmap( 96, 32);
154     }
155 
156 }
157 
158 
159 
OnToolLeftClick(wxCommandEvent & event)160 void iENCToolbar::OnToolLeftClick( wxCommandEvent& event )
161 {
162     int itemId = event.GetId();
163 
164     ChartCanvas *cc = gFrame->GetPrimaryCanvas();
165 
166     enum _DisCat nset = STANDARD;
167     double range;
168 
169     switch(itemId){
170         case ID_DENSITY:
171 
172             if(++m_nDensity > 3)
173                 m_nDensity = 0;
174 
175             SetDensityToolBitmap(m_nDensity);
176             m_ptoolbar->Refresh();
177 
178 
179             switch(m_nDensity){
180                 case 0:
181                     nset = DISPLAYBASE;
182                     break;
183                 case 1:
184                     nset = STANDARD;
185                     break;
186                 case 2:
187                     nset = OTHER;
188                     break;
189                 case 3:
190                     nset = MARINERS_STANDARD;
191                     break;
192                 default:
193                     nset = STANDARD;
194                     break;
195             }
196 
197             gFrame->SetENCDisplayCategory( cc, nset );
198 
199             break;
200 
201         case ID_RMINUS:
202             range = cc->GetCanvasRangeMeters();
203             range = wxRound(range * 10) / 10.;
204 
205             if(range > 8000.)
206                 cc->SetCanvasRangeMeters(8000.);
207             if(range > 4000.)
208                 cc->SetCanvasRangeMeters(4000.);
209             else if(range > 2000.)
210                 cc->SetCanvasRangeMeters(2000.);
211             else if(range > 1600.)
212                 cc->SetCanvasRangeMeters(1600.);
213             else if(range > 1200.)
214                 cc->SetCanvasRangeMeters(1200.);
215             else if(range > 800.)
216                 cc->SetCanvasRangeMeters(800.);
217             else if(range > 500.)
218                 cc->SetCanvasRangeMeters(500.);
219             else if(range > 300.)
220                 cc->SetCanvasRangeMeters(300.);
221 
222             break;
223 
224         case ID_RPLUS:
225             range = cc->GetCanvasRangeMeters();
226             range = wxRound(range * 10) / 10.;
227 
228             if(range < 300.)
229                 cc->SetCanvasRangeMeters(300.);
230             else if(range < 500.)
231                 cc->SetCanvasRangeMeters(500.);
232             else if(range < 800.)
233                 cc->SetCanvasRangeMeters(800.);
234             else if(range < 1200.)
235                 cc->SetCanvasRangeMeters(1200.);
236             else if(range < 1600.)
237                 cc->SetCanvasRangeMeters(1600.);
238             else if(range < 2000.)
239                 cc->SetCanvasRangeMeters(2000.);
240             else if(range < 4000.)
241                 cc->SetCanvasRangeMeters(4000.);
242             else if(range < 8000.)
243                 cc->SetCanvasRangeMeters(8000.);
244 
245             break;
246 
247         default:
248             break;
249     }
250 
251 }
252 
253 
254 
SetDensityToolBitmap(int nDensity)255 void iENCToolbar::SetDensityToolBitmap( int nDensity)
256 {
257     int toolID = m_toolDensity->GetId();
258 
259     if(nDensity == 0)
260         m_ptoolbar->SetToolBitmaps( ID_DENSITY, &m_bmMinimum, &m_bmMinimum );
261     else if(nDensity == 1)
262         m_ptoolbar->SetToolBitmaps( ID_DENSITY, &m_bmStandard, &m_bmStandard );
263     else if(nDensity == 2)
264         m_ptoolbar->SetToolBitmaps( ID_DENSITY, &m_bmAll, &m_bmAll );
265     else if(nDensity == 3)
266         m_ptoolbar->SetToolBitmaps( ID_DENSITY, &m_bmUStd, &m_bmUStd );
267 
268 }
269 
270 
StateTimerEvent(wxTimerEvent & event)271 void iENCToolbar::StateTimerEvent( wxTimerEvent& event )
272 {
273     ChartCanvas *cc = gFrame->GetPrimaryCanvas();
274     if(!cc)
275         return;
276 
277     //  Keep the Density tool in sync
278     if(ps52plib){
279         int nset = 1;
280 
281         switch (gFrame->GetPrimaryCanvas()->GetENCDisplayCategory()) {
282             case (DISPLAYBASE):
283                 nset = 0;
284                 break;
285             case (STANDARD):
286                 nset = 1;
287                 break;
288             case (OTHER):
289                 nset = 2;
290                 break;
291             case (MARINERS_STANDARD):
292                 nset = 3;
293                 break;
294             default:
295                 nset = 1;
296                 break;
297         }
298 
299         if( nset != m_nDensity){
300             if(nset < 3){
301                 m_nDensity = nset;
302                 SetDensityToolBitmap( m_nDensity );
303 
304                 m_ptoolbar->Refresh();
305             }
306         }
307     }
308 
309     // Keep the Range annunciator updated
310 
311     if(cc){
312         double range = cc->GetCanvasRangeMeters();
313 
314         if(range != m_range){
315             m_range = range;
316 
317 
318 #if 0
319             // This DOES NOT WORK on Mac
320             //  None of it....
321 
322 //            wxImage image = m_bmRMinus.ConvertToImage();
323 //            wxBitmap bmTemplate(image);
324 
325             // Get the template bitmap
326             wxBitmap bmTemplate = m_bmRMinus;
327 
328             wxMask *mask = new wxMask(bmTemplate, wxColour(wxTRANSPARENT));
329             bmTemplate.SetMask(mask);
330 
331             wxMemoryDC dct(bmTemplate);
332 
333             //  Make a deep copy by Blit
334             wxMemoryDC dc;
335             dc.SelectObject(*m_pbmScratch);
336             dc.SetBackground(wxBrush(GetGlobalColor(_T("GREY2"))));
337             dc.Clear();
338 
339             dc.Blit(0, 0, m_pbmScratch->GetWidth(), m_pbmScratch->GetHeight(), &dct, 0, 0, wxCOPY, true);
340 
341             dct.SelectObject(wxNullBitmap);
342 #else
343             wxMemoryDC dc;
344             dc.SelectObject(*m_pbmScratch);
345             dc.SetBackground(wxBrush(GetGlobalColor(_T("GREY2"))));
346             dc.Clear();
347             dc.DrawBitmap(m_bmRMinus, wxPoint(0,0));
348 #endif
349             //  Render the range as text onto the template
350             m_rangeFont = wxTheFontList->FindOrCreateFont( 12, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL );
351 
352             wxString range_string;
353             range_string.Printf(_T("%4.0fm"), range);
354 
355             dc.SetFont( *m_rangeFont );
356 
357             //  Select a font that will fit into the allow space.
358             bool good = false;
359             int target_points = 12;
360             while(!good && (target_points > 4)){
361                 int width, height;
362                 dc.GetTextExtent( range_string, &width, &height);
363                 if(width < 50){
364                     good = true;
365                     break;
366                 }
367                 else{
368                     target_points--;
369                     m_rangeFont = wxTheFontList->FindOrCreateFont( target_points, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL );
370                     dc.SetFont( *m_rangeFont );
371                 }
372             }
373 
374             dc.SetTextForeground(*wxBLACK);
375             dc.SetBackgroundMode(wxTRANSPARENT);
376 
377 
378             dc.DrawText(range_string, 42, 8);
379 
380             dc.SelectObject(wxNullBitmap);
381 
382             m_ptoolbar->SetToolBitmaps( ID_RMINUS, m_pbmScratch, m_pbmScratch );
383 
384             m_ptoolbar->Refresh();
385         }
386     }
387 }
388