OpenCPN Partial API docs
iENCToolbar.cpp
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 "chcanv.h"
38 #include "s52s57.h"
39 #include "s52plib.h"
40 #include "pluginmanager.h"
41 #include "OCPNPlatform.h"
42 #include "chcanv.h"
43 #include "svg_utils.h"
44 #include "ocpn_frame.h"
45 
46 extern s52plib *ps52plib;
47 extern MyFrame *gFrame;
48 extern OCPNPlatform *g_Platform;
49 
50 //---------------------------------------------------------------------------------------
51 // iENCToolbar Implementation
52 //---------------------------------------------------------------------------------------
53 
54 iENCToolbar::iENCToolbar(wxWindow *parent, wxPoint position, long orient,
55  float size_factor)
56  : ocpnFloatingToolbarDialog(parent, position, orient, size_factor) {
57  LoadToolBitmaps();
58 
59  wxSize a = m_bmMinimum.GetSize();
60  m_ptoolbar->SetToolBitmapSize(a);
61 
62  m_pbmScratch = new wxBitmap(a.x, a.y);
63 
64  m_bmTemplate = m_bmRMinus;
65 
66  m_toolDensity =
67  m_ptoolbar->AddTool(ID_DENSITY, _T("Density"), m_bmMinimum, m_bmMinimum);
68  m_ptoolbar->AddTool(ID_RPLUS, _T("RangePlus"), m_bmRPlus, m_bmRPlus);
69  m_ptoolbar->AddTool(ID_RMINUS, _T("RangeMinus"), m_bmRMinus, m_bmRMinus);
70 
71  SetCanToggleOrientation(false);
72  EnableRolloverBitmaps(false);
73  DisableTooltips();
74 
75  m_nDensity = 0;
76  SetDensityToolBitmap(m_nDensity);
77  m_range = 0;
78 
79  m_ptoolbar->SetBackgroundColour(GetGlobalColor("DILG0"));
80 
81  // Realize() the toolbar
82  Realize();
83  SetDefaultPosition();
84 
85  m_state_timer.SetOwner(this, STATE_TIMER);
86  m_state_timer.Start(100, wxTIMER_CONTINUOUS);
87  this->Connect( wxEVT_TIMER, wxTimerEventHandler( iENCToolbar::StateTimerEvent ), NULL, this );
88 }
89 
90 iENCToolbar::~iENCToolbar() {}
91 
92 void iENCToolbar::SetColorScheme(ColorScheme cs) {
93  m_nDensity = -1;
94  m_ptoolbar->SetBackgroundColour(GetGlobalColor("DILG0"));
95  SetRangeToolBitmap();
96  ocpnFloatingToolbarDialog::SetColorScheme(cs);
97  m_ptoolbar->InvalidateBitmaps();
98  RefreshToolbar();
99  m_range = 0;
100 }
101 
102 void iENCToolbar::LoadToolBitmaps() {
103  wxString svgDir = g_Platform->GetSharedDataDir() + _T("uidata") +
104  wxFileName::GetPathSeparator();
105 
106  int w = 96;
107  int h = 32;
108 
109  if (::wxFileExists(svgDir + _T("iENC_All.svg"))) {
110  m_bmAll = LoadSVG(svgDir + _T("iENC_All.svg"), w, h);
111  m_bmMinimum = LoadSVG(svgDir + _T("iENC_Minimum.svg"), w, h);
112  m_bmStandard = LoadSVG(svgDir + _T("iENC_Standard.svg"), w, h);
113  m_bmUStd = LoadSVG(svgDir + _T("iENC_UserStd.svg"), w, h);
114  m_bmRPlus = LoadSVG(svgDir + _T("iENC_RPlus.svg"), w, h);
115  m_bmRMinus = LoadSVG(svgDir + _T("iENC_RMinus.svg"), w, h);
116  } else {
117  wxLogMessage(_T("Cannot find iENC icons at: ") + svgDir);
118 
119  m_bmMinimum = wxBitmap(96, 32);
120  m_bmStandard = wxBitmap(96, 32);
121  m_bmAll = wxBitmap(96, 32);
122  m_bmUStd = wxBitmap(96, 32);
123  m_bmRPlus = wxBitmap(96, 32);
124  m_bmRMinus = wxBitmap(96, 32);
125  }
126 }
127 
128 void iENCToolbar::OnToolLeftClick(wxCommandEvent &event) {
129  int itemId = event.GetId();
130 
131  ChartCanvas *cc = gFrame->GetPrimaryCanvas();
132 
133  enum _DisCat nset = STANDARD;
134  double range;
135 
136  switch (itemId) {
137  case ID_DENSITY:
138 
139  if (++m_nDensity > 3) m_nDensity = 0;
140 
141  SetDensityToolBitmap(m_nDensity);
142 
143  switch (m_nDensity) {
144  case 0:
145  nset = DISPLAYBASE;
146  break;
147  case 1:
148  nset = STANDARD;
149  break;
150  case 2:
151  nset = OTHER;
152  break;
153  case 3:
154  nset = MARINERS_STANDARD;
155  break;
156  default:
157  nset = STANDARD;
158  break;
159  }
160 
161  gFrame->SetENCDisplayCategory(cc, nset);
162 
163  break;
164 
165  case ID_RMINUS:
166  range = cc->GetCanvasRangeMeters();
167  range = wxRound(range * 10) / 10.;
168 
169  if (range > 8000.) cc->SetCanvasRangeMeters(8000.);
170  if (range > 4000.)
171  cc->SetCanvasRangeMeters(4000.);
172  else if (range > 2000.)
173  cc->SetCanvasRangeMeters(2000.);
174  else if (range > 1600.)
175  cc->SetCanvasRangeMeters(1600.);
176  else if (range > 1200.)
177  cc->SetCanvasRangeMeters(1200.);
178  else if (range > 800.)
179  cc->SetCanvasRangeMeters(800.);
180  else if (range > 500.)
181  cc->SetCanvasRangeMeters(500.);
182  else if (range > 300.)
183  cc->SetCanvasRangeMeters(300.);
184 
185  break;
186 
187  case ID_RPLUS:
188  range = cc->GetCanvasRangeMeters();
189  range = wxRound(range * 10) / 10.;
190 
191  if (range < 300.)
192  cc->SetCanvasRangeMeters(300.);
193  else if (range < 500.)
194  cc->SetCanvasRangeMeters(500.);
195  else if (range < 800.)
196  cc->SetCanvasRangeMeters(800.);
197  else if (range < 1200.)
198  cc->SetCanvasRangeMeters(1200.);
199  else if (range < 1600.)
200  cc->SetCanvasRangeMeters(1600.);
201  else if (range < 2000.)
202  cc->SetCanvasRangeMeters(2000.);
203  else if (range < 4000.)
204  cc->SetCanvasRangeMeters(4000.);
205  else if (range < 8000.)
206  cc->SetCanvasRangeMeters(8000.);
207 
208  break;
209 
210  default:
211  break;
212  }
213  m_ptoolbar->InvalidateBitmaps();
214  RefreshToolbar();
215 
216 }
217 
218 void iENCToolbar::SetDensityToolBitmap(int nDensity) {
219  int toolID = m_toolDensity->GetId();
220 
221  if (nDensity == 0)
222  m_ptoolbar->SetToolBitmaps(ID_DENSITY, &m_bmMinimum, &m_bmMinimum);
223  else if (nDensity == 1)
224  m_ptoolbar->SetToolBitmaps(ID_DENSITY, &m_bmStandard, &m_bmStandard);
225  else if (nDensity == 2)
226  m_ptoolbar->SetToolBitmaps(ID_DENSITY, &m_bmAll, &m_bmAll);
227  else if (nDensity == 3)
228  m_ptoolbar->SetToolBitmaps(ID_DENSITY, &m_bmUStd, &m_bmUStd);
229 }
230 
231 void iENCToolbar::SetRangeToolBitmap() {
232  wxMemoryDC dc;
233  dc.SelectObject(*m_pbmScratch);
234  dc.SetBackground(wxBrush(GetGlobalColor("DILG0")));
235  dc.Clear();
236  dc.DrawBitmap(m_bmRMinus, wxPoint(0, 0));
237 
238  // Render the range as text onto the template
239  m_rangeFont = wxTheFontList->FindOrCreateFont(
240  12, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL, wxFONTWEIGHT_NORMAL);
241 
242  wxString range_string;
243  range_string.Printf(_T("%4.0fm"), m_range);
244 
245  dc.SetFont(*m_rangeFont);
246 
247  // Select a font that will fit into the allow space.
248  bool good = false;
249  int target_points = 12;
250  while (!good && (target_points > 4)) {
251  int width, height;
252  dc.GetTextExtent(range_string, &width, &height);
253  if (width < 50) {
254  good = true;
255  break;
256  } else {
257  target_points--;
258  m_rangeFont = wxTheFontList->FindOrCreateFont(
259  target_points, wxFONTFAMILY_MODERN, wxFONTSTYLE_NORMAL,
260  wxFONTWEIGHT_NORMAL);
261  dc.SetFont(*m_rangeFont);
262  }
263  }
264 
265  dc.SetTextForeground(*wxBLACK);
266  dc.SetBackgroundMode(wxTRANSPARENT);
267 
268  dc.DrawText(range_string, 42, 8);
269 
270  dc.SelectObject(wxNullBitmap);
271 
272  m_ptoolbar->SetToolBitmaps(ID_RMINUS, m_pbmScratch, m_pbmScratch);
273 
274 }
275 
276 void iENCToolbar::StateTimerEvent(wxTimerEvent &event) {
277  ChartCanvas *cc = gFrame->GetPrimaryCanvas();
278  if (!cc) return;
279 
280  bool bRefresh = false;
281  // Keep the Density tool in sync
282  if (ps52plib) {
283  int nset = 1;
284 
285  switch (gFrame->GetPrimaryCanvas()->GetENCDisplayCategory()) {
286  case (DISPLAYBASE):
287  nset = 0;
288  break;
289  case (STANDARD):
290  nset = 1;
291  break;
292  case (OTHER):
293  nset = 2;
294  break;
295  case (MARINERS_STANDARD):
296  nset = 3;
297  break;
298  default:
299  nset = 1;
300  break;
301  }
302 
303  if (nset != m_nDensity) {
304  if (nset < 3) {
305  m_nDensity = nset;
306  SetDensityToolBitmap(m_nDensity);
307 
308  bRefresh = true;
309  }
310  }
311  }
312 
313  // Keep the Range annunciator updated
314 
315  if (cc) {
316  double range = cc->GetCanvasRangeMeters();
317 
318  if (range != m_range) {
319  m_range = range;
320  SetRangeToolBitmap();
321  bRefresh = true;
322  }
323  }
324  if (bRefresh) {
325  RebuildToolbar();
326  m_ptoolbar->InvalidateBitmaps();
327  RefreshToolbar();
328  }
329 
330  // Restore runtime timer frequency after startup
331  m_state_timer.Start(500, wxTIMER_CONTINUOUS);
332 
333 }