OpenCPN Partial API docs
toolbar.cpp
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 "model/ais_state_vars.h"
36 #include "model/ocpn_types.h"
37 #include "navutil.h"
38 #include "styles.h"
39 #include "toolbar.h"
40 #include "pluginmanager.h"
41 #include "FontMgr.h"
42 #include "OCPNPlatform.h"
43 #include "chcanv.h"
44 #include "gui_lib.h"
45 #include "svg_utils.h"
46 #include "model/idents.h"
47 #include "ocpn_frame.h"
48 
49 #ifdef __OCPN__ANDROID__
50 #include "androidUTIL.h"
51 #endif
52 
53 #ifdef ocpnUSE_GL
54 #include "glChartCanvas.h"
55 #endif
56 
57 extern bool g_bTransparentToolbar;
58 extern bool g_bTransparentToolbarInOpenGLOK;
59 extern bool g_bopengl;
60 extern ocpnStyle::StyleManager *g_StyleManager;
61 extern MyFrame *gFrame;
62 extern PlugInManager *g_pi_manager;
63 extern bool g_bPermanentMOBIcon;
64 extern bool g_bsmoothpanzoom;
65 extern OCPNPlatform *g_Platform;
66 extern bool g_bmasterToolbarFull;
67 extern bool g_useMUI;
68 extern wxString g_toolbarConfig;
69 extern double g_plus_minus_zoom_factor;
70 extern int g_maintoolbar_x;
71 extern int g_maintoolbar_y;
72 
73 #ifdef ocpnUSE_GL
74 extern GLenum g_texture_rectangle_format;
75 #endif
76 
77 
78 class ocpnToolBarTool : public wxToolBarToolBase {
79 public:
80  ocpnToolBarTool(ocpnToolBarSimple *tbar, int id, const wxString &label,
81  const wxBitmap &bmpNormal, const wxBitmap &bmpRollover,
82  wxItemKind kind, wxObject *clientData,
83  const wxString &shortHelp, const wxString &longHelp)
84  : wxToolBarToolBase((wxToolBarBase *)tbar, id, label, bmpNormal,
85  bmpRollover, kind, clientData, shortHelp, longHelp) {
86  m_enabled = true;
87  m_toggled = false;
88  rollover = false;
89  bitmapOK = false;
90  m_btooltip_hiviz = false;
91 
92  toolname = g_pi_manager->GetToolOwnerCommonName(id);
93  if (toolname == _T("")) {
94  isPluginTool = false;
95  toolname = label;
96  iconName = label;
97 
98  } else {
99  isPluginTool = true;
100  pluginNormalIcon = bmpNormal;
101  pluginRolloverIcon = bmpRollover;
102  }
103  }
104 
105  ocpnToolBarTool(ocpnToolBarSimple *tbar, int id, const wxBitmap &bmpNormal,
106  const wxBitmap &bmpRollover, wxItemKind kind,
107  wxObject *clientData, const wxString &shortHelp,
108  const wxString &longHelp)
109  : wxToolBarToolBase((wxToolBarBase *)tbar, id, _T(""), bmpNormal,
110  bmpRollover, kind, clientData, shortHelp, longHelp) {
111  m_enabled = true;
112  m_toggled = false;
113  rollover = false;
114  m_btooltip_hiviz = false;
115  isPluginTool = false;
116 
117  m_bmpNormal = bmpNormal;
118  bitmapOK = true;
119  }
120 
121  void SetSize(const wxSize &size) {
122  m_width = size.x;
123  m_height = size.y;
124  }
125 
126  wxCoord GetWidth() const { return m_width; }
127 
128  wxCoord GetHeight() const { return m_height; }
129 
130  wxString GetToolname() { return toolname; }
131 
132  void SetIconName(wxString name) { iconName = name; }
133  wxString GetIconName() { return iconName; }
134 
135  void SetTooltipHiviz(bool enable) { m_btooltip_hiviz = enable; }
136 
137  wxCoord m_x;
138  wxCoord m_y;
139  wxCoord m_width;
140  wxCoord m_height;
141  wxRect trect;
142  wxString toolname;
143  wxString iconName;
144  wxBitmap pluginNormalIcon;
145  wxBitmap pluginRolloverIcon;
146  const wxBitmap *pluginToggledIcon;
147  bool firstInLine;
148  bool lastInLine;
149  bool rollover;
150  bool bitmapOK;
151  bool isPluginTool;
152  bool b_hilite;
153  bool m_btooltip_hiviz;
154  wxRect last_rect;
155  wxString pluginNormalIconSVG;
156  wxString pluginRolloverIconSVG;
157  wxString pluginToggledIconSVG;
158  wxBitmap m_activeBitmap;
159 };
160 
161 //---------------------------------------------------------------------------------------
162 // ocpnFloatingToolbarDialog Implementation
163 //---------------------------------------------------------------------------------------
164 
165 ocpnFloatingToolbarDialog::ocpnFloatingToolbarDialog(wxWindow *parent,
166  wxPoint position,
167  long orient,
168  float size_factor) {
169  m_pparent = parent;
170  m_ptoolbar = NULL;
171 
172  m_opacity = 255;
173  m_position = position;
174  m_orient = orient;
175  m_sizefactor = size_factor;
176  m_cornerRadius = 0;
177 
178  m_bAutoHideToolbar = false;
179  m_nAutoHideToolbar = 5;
180  m_toolbar_scale_tools_shown = false;
181  m_backcolorString = _T("GREY3");
182  m_toolShowMask = _T("XXXXXXXXXXXXXXXX");
183  n_toolbarHideMethod = TOOLBAR_HIDE_TO_GRABBER;
184  b_canToggleOrientation = true;
185  m_enableRolloverBitmaps = true;
186  m_auxOffsetY = 0;
187 
188  m_ptoolbar = CreateNewToolbar();
189  if (m_ptoolbar)
190  m_ptoolbar->SetBackgroundColour(GetGlobalColor("GREY3"));
191  m_cs = (ColorScheme)-1;
192 
193  m_style = g_StyleManager->GetCurrentStyle();
194  SetULDockPosition(wxPoint(4, 4));
195 
196  SetGeometry(false, wxRect());
197 
198  // Set initial "Dock" parameters
199  m_dock_x = 0;
200  m_dock_y = 0;
201  m_block = false;
202 
203  m_texture = 0;
204 
205  m_marginsInvisible = m_style->marginsInvisible;
206 
207 
208  m_FloatingToolbarConfigMenu = NULL;
209 
210  m_fade_timer.SetOwner(this);
211  this->Connect( wxEVT_TIMER, wxTimerEventHandler( ocpnFloatingToolbarDialog::FadeTimerEvent ), NULL, this );
212 
213  if (m_bAutoHideToolbar && (m_nAutoHideToolbar > 0))
214  m_fade_timer.Start(m_nAutoHideToolbar * 1000);
215 
216  m_bsubmerged = false;
217  m_benableSubmerge = true;
218 }
219 
220 ocpnFloatingToolbarDialog::~ocpnFloatingToolbarDialog() {
221  delete m_FloatingToolbarConfigMenu;
222 
223  DestroyToolBar();
224 }
225 
226 void ocpnFloatingToolbarDialog::FadeTimerEvent(wxTimerEvent &event) {
227  if (n_toolbarHideMethod == TOOLBAR_HIDE_TO_FIRST_TOOL) {
228  if (g_bmasterToolbarFull) {
229  if (m_bAutoHideToolbar && (m_nAutoHideToolbar > 0) /*&& !m_bsubmerged*/ ) {
230 
231  // Double check the mouse position
232  wxPoint mp = gFrame->GetPrimaryCanvas()->ScreenToClient(::wxGetMousePosition());
233  // in the toolbar?
234  wxRect r = GetToolbarRect();
235  if (r.Contains(mp))
236  return;
237 
238  wxCommandEvent event;
239  event.SetId(ID_MASTERTOGGLE);
240  gFrame->OnToolLeftClick(event);
241  }
242  }
243  }
244 }
245 
246 void ocpnFloatingToolbarDialog::AddToolItem(ToolbarItemContainer *item) {
247  m_Items.push_back(item);
248 }
249 
250 int ocpnFloatingToolbarDialog::RebuildToolbar() {
251  ocpnToolBarSimple *tb = GetToolbar();
252  if (!tb) return 0;
253 
254  // Iterate over the array of items added,
255  // Creating the toolbar from enabled items.
256  int i_count = 0;
257  for (auto it = m_Items.cbegin(); it != m_Items.cend(); it++) {
258  ToolbarItemContainer *tic = *it;
259  if (!tic) continue;
260 
261  bool bEnabled = _toolbarConfigMenuUtil(tic);
262 
263  if (bEnabled) {
264  wxToolBarToolBase *tool =
265  tb->AddTool(tic->m_ID, tic->m_label, tic->m_bmpNormal,
266  tic->m_bmpDisabled, tic->m_toolKind, tic->m_tipString);
267  tic->m_tool = tool;
268 
269  // Plugin tools may have prescribed their own SVG toolbars as file
270  // locations.
271  if (!tic->m_NormalIconSVG.IsEmpty()) {
272  tb->SetToolBitmapsSVG(tic->m_ID, tic->m_NormalIconSVG,
273  tic->m_RolloverIconSVG, tic->m_ToggledIconSVG);
274  }
275  }
276 
277  i_count++;
278  }
279 
280  return i_count;
281 }
282 
283 void ocpnFloatingToolbarDialog::SetULDockPosition(wxPoint position) {
284  if (position.x >= 0) m_dock_min_x = position.x;
285  if (position.y >= 0) m_dock_min_y = position.y;
286 }
287 
288 size_t ocpnFloatingToolbarDialog::GetToolCount() {
289  if (m_ptoolbar)
290  return m_ptoolbar->GetToolsCount();
291  else
292  return 0;
293 }
294 
295 void ocpnFloatingToolbarDialog::SetToolShowMask(wxString mask) {}
296 
297 void ocpnFloatingToolbarDialog::SetToolShowCount(int count) {
298  if (m_ptoolbar) {
299  m_ptoolbar->SetToolShowCount(count);
300  m_ptoolbar->SetDirty(true);
301  }
302 }
303 
304 int ocpnFloatingToolbarDialog::GetToolShowCount(void) {
305  if (m_ptoolbar)
306  return m_ptoolbar->GetToolShowCount();
307  else
308  return 0;
309 }
310 
311 void ocpnFloatingToolbarDialog::SetBackGroundColorString(wxString colorRef) {
312  m_backcolorString = colorRef;
313  SetColorScheme(m_cs); // Causes a reload of background color
314 }
315 
316 void ocpnFloatingToolbarDialog::OnKeyDown(wxKeyEvent &event) { event.Skip(); }
317 
318 void ocpnFloatingToolbarDialog::OnKeyUp(wxKeyEvent &event) { event.Skip(); }
319 
320 void ocpnFloatingToolbarDialog::CreateConfigMenu() {
321  if (m_FloatingToolbarConfigMenu) delete m_FloatingToolbarConfigMenu;
322  m_FloatingToolbarConfigMenu = new wxMenu();
323 }
324 
325 bool ocpnFloatingToolbarDialog::_toolbarConfigMenuUtil(
326  ToolbarItemContainer *tic) {
327  if (m_FloatingToolbarConfigMenu) {
328  wxMenuItem *menuitem;
329 
330  if (tic->m_ID == ID_MOB && g_bPermanentMOBIcon) return true;
331 
332  if (tic->m_bRequired) return true;
333  if (tic->m_bPlugin) return true;
334 
335  // Item ID trickery is needed because the wxCommandEvents for menu item
336  // clicked and toolbar button clicked are 100% identical, so if we use same
337  // id's we can't tell the events apart.
338 
339  int idOffset = 100; // Hopefully no more than 100 total icons...
340  int menuItemId = tic->m_ID + idOffset;
341 
342  menuitem = m_FloatingToolbarConfigMenu->FindItem(menuItemId);
343 
344  if (menuitem) {
345  return menuitem->IsChecked();
346  }
347 
348  menuitem = m_FloatingToolbarConfigMenu->AppendCheckItem(menuItemId,
349  tic->m_tipString);
350  size_t n = m_FloatingToolbarConfigMenu->GetMenuItemCount();
351  menuitem->Check(m_configString.Len() >= n
352  ? m_configString.GetChar(n - 1) == _T('X')
353  : true);
354  return menuitem->IsChecked();
355  } else
356  return true;
357 }
358 
359 
360 void ocpnFloatingToolbarDialog::EnableTool(int toolid, bool enable) {
361  if (m_ptoolbar) m_ptoolbar->EnableTool(toolid, enable);
362 }
363 
364 void ocpnFloatingToolbarDialog::SetColorScheme(ColorScheme cs) {
365  m_cs = cs;
366  wxColour back_color = GetGlobalColor(m_backcolorString);
367 
368  if (m_ptoolbar) {
369  m_ptoolbar->SetToggledBackgroundColour(GetGlobalColor(_T("GREY1")));
370  m_ptoolbar->SetColorScheme(cs);
371  }
372 }
373 
374 wxSize ocpnFloatingToolbarDialog::GetToolSize() {
375  wxSize style_tool_size;
376  if (m_ptoolbar) {
377  style_tool_size = m_style->GetToolSize();
378 
379  style_tool_size.x *= m_sizefactor;
380  style_tool_size.y *= m_sizefactor;
381  } else {
382  style_tool_size.x = 32;
383  style_tool_size.y = 32;
384  }
385 
386  return style_tool_size;
387 }
388 
389 void ocpnFloatingToolbarDialog::SetGeometry(bool bAvoid, wxRect rectAvoid) {
390  if (m_ptoolbar) {
391  wxSize style_tool_size = m_style->GetToolSize();
392 
393  style_tool_size.x *= m_sizefactor;
394  style_tool_size.y *= m_sizefactor;
395 
396  m_ptoolbar->SetToolBitmapSize(style_tool_size);
397 
398  wxSize tool_size = m_ptoolbar->GetToolBitmapSize();
399  int grabber_width = m_style->GetIcon(_T("grabber")).GetWidth();
400 
401  int max_rows = 10;
402  int max_cols = 100;
403 
404  if (m_pparent) {
405  int avoid_start =
406  m_pparent->GetClientSize().x -
407  (tool_size.x + m_style->GetToolSeparation()) * 2; // default
408  if (bAvoid && !rectAvoid.IsEmpty()) {
409  avoid_start = m_pparent->GetClientSize().x - rectAvoid.width -
410  10; // this is compass window, if shown
411  }
412 
413  max_rows = (m_pparent->GetClientSize().y /
414  (tool_size.y + m_style->GetToolSeparation())) -
415  2;
416 
417  max_cols = (avoid_start - grabber_width) /
418  (tool_size.x + m_style->GetToolSeparation());
419  max_cols -= 1;
420 
421  if (m_orient == wxTB_VERTICAL)
422  max_rows = wxMax(max_rows, 2); // at least two rows
423  else
424  max_cols = wxMax(max_cols, 2); // at least two columns
425  }
426 
427  if (m_orient == wxTB_VERTICAL)
428  m_ptoolbar->SetMaxRowsCols(max_rows, 100);
429  else
430  m_ptoolbar->SetMaxRowsCols(100, max_cols);
431  m_ptoolbar->SetSizeFactor(m_sizefactor);
432  }
433 }
434 
435 
436 void ocpnFloatingToolbarDialog::SetDefaultPosition() {
437  if (m_block) return;
438 
439  if (m_pparent && m_ptoolbar) {
440  wxSize cs = m_pparent->GetClientSize();
441  if (-1 == m_dock_x)
442  m_position.x = m_dock_min_x;
443  else if (1 == m_dock_x)
444  m_position.x = cs.x - m_ptoolbar->m_maxWidth;
445 
446  if (-1 == m_dock_y)
447  m_position.y = m_dock_min_y;
448  else if (1 == m_dock_y)
449  m_position.y = cs.y - m_ptoolbar->m_maxHeight;
450 
451  m_position.x = wxMin(cs.x - m_ptoolbar->m_maxWidth, m_position.x);
452  m_position.y = wxMin(cs.y - m_ptoolbar->m_maxHeight, m_position.y);
453 
454  m_position.x = wxMax(m_dock_min_x, m_position.x);
455  m_position.y = wxMax(m_dock_min_y, m_position.y);
456 
457  m_position.y += m_auxOffsetY;
458 
459  g_maintoolbar_x = m_position.x;
460  g_maintoolbar_y = m_position.y;
461 
462  // take care of left docked instrument windows and don't blast the main
463  // toolbar on top of them, hinding instruments this positions the main
464  // toolbar directly right of the left docked instruments onto the chart
465  // wxPoint screen_pos = m_pparent->ClientToScreen( m_position );
466  //wxPoint screen_pos = gFrame->GetPrimaryCanvas()->ClientToScreen(m_position);
467 
468  // GTK sometimes has trouble with ClientToScreen() if executed in the
469  // context of an event handler The position of the window is calculated
470  // incorrectly if a deferred Move() has not been processed yet. So work
471  // around this here... Discovered with a Dashboard window left-docked,
472  // toggled on and off by toolbar tool.
473 
474  // But this causes another problem. If a toolbar is NOT left docked, it
475  // will walk left by two pixels on each call to Reposition().
476  // TODO
477 
478  }
479 }
480 
481 void ocpnFloatingToolbarDialog::Submerge() {
482  m_bsubmerged = true;
483  //Hide();
484  if (m_ptoolbar) m_ptoolbar->KillTooltip();
485 }
486 
487 
488 
489 void ocpnFloatingToolbarDialog::HideTooltip() {
490 #ifndef __OCPN__ANDROID__
491  if (m_ptoolbar) m_ptoolbar->HideTooltip();
492 #endif
493 }
494 
495 void ocpnFloatingToolbarDialog::ShowTooltips() {
496 #ifndef __OCPN__ANDROID__
497  if (m_ptoolbar) m_ptoolbar->EnableTooltips();
498 #endif
499 }
500 
501 void ocpnFloatingToolbarDialog::ToggleOrientation() {}
502 
503 wxRect ocpnFloatingToolbarDialog::GetToolbarRect() {
504  return wxRect(m_position.x, m_position.y,
505  m_ptoolbar->m_maxWidth, m_ptoolbar->m_maxHeight);
506 }
507 
508 wxSize ocpnFloatingToolbarDialog::GetToolbarSize() {
509  return wxSize(m_ptoolbar->m_maxWidth, m_ptoolbar->m_maxHeight);
510 }
511 
512 wxPoint ocpnFloatingToolbarDialog::GetToolbarPosition() {
513  return wxPoint(m_position.x, m_position.y);
514 }
515 
516 bool ocpnFloatingToolbarDialog::MouseEvent(wxMouseEvent &event) {
517  if (m_ptoolbar){
518  bool bproc = m_ptoolbar->OnMouseEvent(event, m_position);
519  if (bproc)
520  m_ptoolbar->CreateBitmap();
521  return bproc;
522  }
523  else
524  return false;
525 }
526 
527 void ocpnFloatingToolbarDialog::RefreshToolbar() {
528  if (m_ptoolbar){
529  if (m_ptoolbar->IsDirty()) {
530  Realize();
531  gFrame->GetPrimaryCanvas()->Refresh();
532  }
533  }
534 }
535 
536 
537 void ocpnFloatingToolbarDialog::SetAutoHideTimer(int time) {
538  m_nAutoHideToolbar = time;
539  if (m_bAutoHideToolbar) {
540  m_fade_timer.Stop();
541  m_fade_timer.Start(m_nAutoHideToolbar * 1000);
542  }
543 }
544 
545 void ocpnFloatingToolbarDialog::RefreshFadeTimer() {
546  if (m_bAutoHideToolbar && (m_nAutoHideToolbar > 0)) {
547  m_fade_timer.Start(m_nAutoHideToolbar * 1000);
548  }
549 }
550 
551 void ocpnFloatingToolbarDialog::SetToolShortHelp(int id, const wxString &help) {
552  if (m_ptoolbar) m_ptoolbar->SetToolShortHelp(id, help);
553 }
554 
555 
556 void ocpnFloatingToolbarDialog::Realize() {
557  if (m_ptoolbar) {
558  m_ptoolbar->Realize();
559  m_ptoolbar->CreateBitmap();
560  m_toolbar_image.Destroy();
561  }
562 }
563 
564 void ocpnFloatingToolbarDialog::DrawDC(ocpnDC &dc, double displayScale) {
565  if (m_ptoolbar) {
566  m_ptoolbar->CreateBitmap();
567  if (m_ptoolbar->GetBitmap().IsOk()) {
568  dc.DrawBitmap(m_ptoolbar->GetBitmap(), m_position.x, m_position.y, false);
569  m_ptoolbar->SetDirty(false);
570  }
571  }
572 }
573 
574 void ocpnFloatingToolbarDialog::DrawGL(ocpnDC &gldc, double displayScale) {
575 #ifdef ocpnUSE_GL
576  if (!m_ptoolbar)
577  return;
578 
579  wxColour backColor = GetGlobalColor("GREY3");
580  gldc.SetBrush(wxBrush(backColor));
581  gldc.SetPen(wxPen(backColor));
582 
583  wxRect r = GetToolbarRect();
584  int m_end_margin = wxMin(GetToolSize().x, GetToolSize().y) / 8;
585 
586  if (m_orient == wxHORIZONTAL)
587  gldc.DrawRoundedRectangle((r.x - m_end_margin/2)*displayScale,
588  (r.y-1)*displayScale,
589  (r.width + m_end_margin)*displayScale,
590  (r.height+2)*displayScale,
591  (m_end_margin * 1)*displayScale);
592  else
593  gldc.DrawRoundedRectangle((r.x-1)*displayScale,
594  (r.y- m_end_margin/2)*displayScale,
595  (r.width + 2)*displayScale,
596  (r.height + m_end_margin)*displayScale,
597  (m_end_margin * 1.5)*displayScale);
598 
599 
600  int width = GetToolbarSize().x;
601  int height = GetToolbarSize().y;
602 
603  m_ptoolbar->CreateBitmap(displayScale);
604 
605  // Make a GL texture
606  if (!m_texture) {
607  glGenTextures(1, &m_texture);
608 
609  glBindTexture(g_texture_rectangle_format, m_texture);
610  glTexParameterf(g_texture_rectangle_format, GL_TEXTURE_MIN_FILTER,
611  GL_NEAREST);
612  glTexParameteri(g_texture_rectangle_format, GL_TEXTURE_MAG_FILTER,
613  GL_NEAREST);
614  glTexParameteri(g_texture_rectangle_format, GL_TEXTURE_WRAP_S,
615  GL_CLAMP_TO_EDGE);
616  glTexParameteri(g_texture_rectangle_format, GL_TEXTURE_WRAP_T,
617  GL_CLAMP_TO_EDGE);
618  } else {
619  glBindTexture(g_texture_rectangle_format, m_texture);
620  }
621 
622  if (!m_toolbar_image.IsOk()) {
623  // fill texture data
624  m_toolbar_image = m_ptoolbar->GetBitmap().ConvertToImage();
625 
626  unsigned char *d = m_toolbar_image.GetData();
627  unsigned char *e = new unsigned char[4 * width * height];
628  for (int y = 0; y < height; y++)
629  for (int x = 0; x < width; x++) {
630  int i = y * width + x;
631  memcpy(e + 4 * i, d + 3 * i, 3);
632  e[4 * i + 3] = 255; // d[3*i + 2] == 255 ? 0:255; //255 - d[3 * i + 2];
633  }
634  glTexImage2D(g_texture_rectangle_format, 0, GL_RGBA, width, height, 0,
635  GL_RGBA, GL_UNSIGNED_BYTE, e);
636  delete[] e;
637  glDisable(g_texture_rectangle_format);
638  glDisable(GL_BLEND);
639  }
640 
641  // Render the texture
642  if (m_texture) {
643  glEnable(g_texture_rectangle_format);
644  glBindTexture(g_texture_rectangle_format, m_texture);
645  glEnable(GL_BLEND);
646 
647  int x0 = GetToolbarPosition().x, x1 = x0 + width;
648  int y0 = GetToolbarPosition().y - 0, y1 = y0 + height;
649  x0 *= displayScale; x1 *= displayScale;
650  y0 *= displayScale; y1 *= displayScale;
651 
652  float tx, ty;
653  if (GL_TEXTURE_RECTANGLE_ARB == g_texture_rectangle_format)
654  tx = width, ty = height;
655  else
656  tx = ty = 1;
657 
658  float coords[8];
659  float uv[8];
660 
661  // normal uv
662  uv[0] = 0;
663  uv[1] = 0;
664  uv[2] = tx;
665  uv[3] = 0;
666  uv[4] = tx;
667  uv[5] = ty;
668  uv[6] = 0;
669  uv[7] = ty;
670 
671  // pixels
672  coords[0] = x0;
673  coords[1] = y0;
674  coords[2] = x1;
675  coords[3] = y0;
676  coords[4] = x1;
677  coords[5] = y1;
678  coords[6] = x0;
679  coords[7] = y1;
680 
681  auto canvas = gFrame->GetPrimaryCanvas();
682  canvas->GetglCanvas()->RenderTextures(gldc, coords, uv, 4,
683  canvas->GetpVP());
684 
685  glDisable(g_texture_rectangle_format);
686  glBindTexture(g_texture_rectangle_format, 0);
687  glDisable(GL_BLEND);
688  }
689 #endif
690 
691  return;
692 }
693 
694 void ocpnFloatingToolbarDialog::OnToolLeftClick(wxCommandEvent &event) {
695  // Since Dialog events don't propagate automatically, we send it explicitly
696  // (instead of relying on event.Skip()). Send events up the window hierarchy
697 
698  m_pparent->GetEventHandler()->AddPendingEvent(event);
699 #ifndef __WXQT__
700  gFrame->Raise();
701 #endif
702 }
703 
704 ocpnToolBarSimple *ocpnFloatingToolbarDialog::GetToolbar() {
705  if (!m_ptoolbar) {
706  m_ptoolbar = CreateNewToolbar();
707  }
708 
709  return m_ptoolbar;
710 }
711 
712 ocpnToolBarSimple *ocpnFloatingToolbarDialog::CreateNewToolbar() {
713  long winstyle = wxNO_BORDER | wxTB_FLAT;
714  winstyle |= m_orient;
715 
716  m_ptoolbar = new ocpnToolBarSimple(this, -1, wxPoint(-1, -1), wxSize(-1, -1),
717  winstyle, m_orient);
718 
719  //m_ptoolbar->SetBackgroundColour(GetGlobalColor(_T("GREY2")));
720  //m_ptoolbar->ClearBackground();
721  m_ptoolbar->SetToggledBackgroundColour(GetGlobalColor(_T("GREY1")));
722  m_ptoolbar->SetColorScheme(m_cs);
723  m_ptoolbar->EnableRolloverBitmaps(GetEnableRolloverBitmaps());
724 
725  return m_ptoolbar;
726 }
727 
728 void ocpnFloatingToolbarDialog::DestroyToolBar() {
729  g_toolbarConfig = GetToolConfigString();
730 
731  if (m_ptoolbar) {
732  m_ptoolbar->ClearTools();
733  delete m_ptoolbar; //->Destroy();
734  m_ptoolbar = NULL;
735  }
736 
737  for (auto it = m_Items.cbegin(); it != m_Items.cend(); it++) {
738  delete *it;
739  }
740  m_Items.clear();
741 }
742 
743 #include "s52plib.h"
744 #include "compass.h"
745 #include "chartdb.h"
746 
747 extern bool g_bTrackActive;
748 extern s52plib *ps52plib;
749 
750 
751 bool ocpnFloatingToolbarDialog::CheckAndAddPlugInTool(ocpnToolBarSimple *tb) {
752  if (!g_pi_manager) return false;
753 
754  bool bret = false;
755  int n_tools = tb->GetToolsCount();
756 
757  // Walk the PlugIn tool spec array, checking the requested position
758  // If a tool has been requested by a plugin at this position, add it
759  ArrayOfPlugInToolbarTools tool_array =
760  g_pi_manager->GetPluginToolbarToolArray();
761 
762  for (unsigned int i = 0; i < tool_array.GetCount(); i++) {
763  PlugInToolbarToolContainer *pttc = tool_array.Item(i);
764  if (pttc->position == n_tools) {
765  wxBitmap *ptool_bmp;
766 
767  switch (m_cs) {
768  case GLOBAL_COLOR_SCHEME_DAY:
769  ptool_bmp = pttc->bitmap_day;
770  ;
771  break;
772  case GLOBAL_COLOR_SCHEME_DUSK:
773  ptool_bmp = pttc->bitmap_dusk;
774  break;
775  case GLOBAL_COLOR_SCHEME_NIGHT:
776  ptool_bmp = pttc->bitmap_night;
777  break;
778  default:
779  ptool_bmp = pttc->bitmap_day;
780  ;
781  break;
782  }
783 
784  wxToolBarToolBase *tool =
785  tb->AddTool(pttc->id, wxString(pttc->label), *(ptool_bmp),
786  wxString(pttc->shortHelp), pttc->kind);
787 
788  tb->SetToolBitmapsSVG(pttc->id, pttc->pluginNormalIconSVG,
789  pttc->pluginRolloverIconSVG,
790  pttc->pluginToggledIconSVG);
791 
792  bret = true;
793  }
794  }
795 
796  // If we added a tool, call again (recursively) to allow for adding
797  // adjacent tools
798  if (bret)
799  while (CheckAndAddPlugInTool(tb)) { /* nothing to do */
800  }
801 
802  return bret;
803 }
804 
805 
806 void ocpnFloatingToolbarDialog::EnableRolloverBitmaps(bool bEnable) {
807  m_enableRolloverBitmaps = bEnable;
808  if (m_ptoolbar) m_ptoolbar->EnableRolloverBitmaps(bEnable);
809 }
810 
811 //----------------------------------------------------------------------------
812 // Toolbar Tooltip Popup Window Definition
813 //----------------------------------------------------------------------------
814 class ToolTipWin : public wxFrame {
815 public:
816  ToolTipWin(wxWindow *parent);
817  ~ToolTipWin();
818 
819  void OnPaint(wxPaintEvent &event);
820 
821  void SetColorScheme(ColorScheme cs);
822  void SetString(wxString &s) { m_string = s; }
823  void SetPosition(wxPoint pt) { m_position = pt; }
824  void SetBitmap(void);
825 
826  void SetHiviz(bool hiviz) { m_hiviz = hiviz; }
827 
828  wxSize GetRenderedSize(void);
829 
830 private:
831  wxString m_string;
832  wxSize m_size;
833  wxPoint m_position;
834  wxBitmap *m_pbm;
835  wxColour m_back_color;
836  wxColour m_text_color;
837  ColorScheme m_cs;
838  bool m_hiviz;
839 
840  DECLARE_EVENT_TABLE()
841 };
842 //-----------------------------------------------------------------------
843 //
844 // Toolbar Tooltip window implementation
845 //
846 //-----------------------------------------------------------------------
847 BEGIN_EVENT_TABLE(ToolTipWin, wxFrame)
848 EVT_PAINT(ToolTipWin::OnPaint)
849 
850 END_EVENT_TABLE()
851 
852 // Define a constructor
853 ToolTipWin::ToolTipWin(wxWindow *parent)
854  : wxFrame(parent, wxID_ANY, _T(""), wxPoint(0, 0), wxSize(1, 1),
855  wxNO_BORDER | wxFRAME_FLOAT_ON_PARENT | wxFRAME_NO_TASKBAR) {
856  m_pbm = NULL;
857 
858  m_back_color = GetDimedColor(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
859  m_text_color = GetDimedColor(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
860 
861  SetBackgroundStyle(wxBG_STYLE_CUSTOM);
862  SetBackgroundColour(m_back_color);
863  m_cs = GLOBAL_COLOR_SCHEME_RGB;
864 
865  Hide();
866 }
867 
868 ToolTipWin::~ToolTipWin() { delete m_pbm; }
869 
870 void ToolTipWin::SetColorScheme(ColorScheme cs) {
871  m_back_color = GetDimedColor(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW));
872  m_text_color = GetDimedColor(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
873 
874 #ifndef __WXOSX__
875  m_text_color = GetDimedColor(FontMgr::Get().GetFontColor(_("ToolTips")));
876 #endif
877 
878  m_cs = cs;
879 }
880 
881 wxSize ToolTipWin::GetRenderedSize(void) {
882  int h, w;
883  wxSize sz;
884 
885  wxScreenDC cdc;
886 
887  wxFont *plabelFont = FontMgr::Get().GetFont(_("ToolTips"));
888  cdc.GetTextExtent(m_string, &w, &h, NULL, NULL, plabelFont);
889 
890  sz.x = w + 8;
891  sz.y = h + 4;
892 
893  return sz;
894 }
895 
896 void ToolTipWin::SetBitmap() {
897  int h, w;
898 
899  wxScreenDC cdc;
900  double scaler = g_Platform->GetDisplayDIPMult(this);
901 
902  wxFont *plabelFont = FontMgr::Get().GetFont(_("ToolTips"));
903  wxFont sFont = plabelFont->Scaled(1.0 / scaler);
904 
905  cdc.GetTextExtent(m_string, &w, &h, NULL, NULL, &sFont);
906 
907  m_size.x = w + GetCharWidth() * 2;
908  m_size.y = h + GetCharHeight() / 2;
909 
910  m_size.x *= scaler;
911  m_size.y *= scaler;
912 
913  wxMemoryDC mdc;
914 
915  delete m_pbm;
916  m_pbm = new wxBitmap(m_size.x, m_size.y, -1);
917  mdc.SelectObject(*m_pbm);
918 
919  wxPen pborder(m_text_color);
920  wxBrush bback(m_back_color);
921  mdc.SetPen(pborder);
922  mdc.SetBrush(bback);
923 
924  if (m_hiviz) {
925  if ((m_cs == GLOBAL_COLOR_SCHEME_DUSK) ||
926  (m_cs == GLOBAL_COLOR_SCHEME_NIGHT)) {
927  wxBrush hv_back(wxColour(200, 200, 200));
928  mdc.SetBrush(hv_back);
929  }
930  }
931  mdc.DrawRectangle(0, 0, m_size.x, m_size.y);
932 
933  // Draw the text
934  mdc.SetFont(sFont);
935  mdc.SetTextForeground(m_text_color);
936  mdc.SetTextBackground(m_back_color);
937 
938  int offx = GetCharWidth();
939  int offy = GetCharHeight()/4;
940  offx *= scaler;
941  offy *= scaler;
942  mdc.DrawText(m_string, offx, offy);
943 
944  SetClientSize(m_size.x, m_size.y);
945  SetSize(m_position.x, m_position.y, m_size.x, m_size.y);
946 }
947 
948 void ToolTipWin::OnPaint(wxPaintEvent &event) {
949  int width, height;
950  GetClientSize(&width, &height);
951  wxPaintDC dc(this);
952 
953  if (m_string.Len()) {
954  wxMemoryDC mdc;
955  mdc.SelectObject(*m_pbm);
956  dc.Blit(0, 0, width, height, &mdc, 0, 0);
957  }
958 }
959 
960 // ----------------------------------------------------------------------------
961 
962 // ============================================================================
963 // implementation
964 // ============================================================================
965 // ----------------------------------------------------------------------------
966 BEGIN_EVENT_TABLE(ocpnToolBarSimple, wxEvtHandler)
967 EVT_TIMER(TOOLTIPON_TIMER, ocpnToolBarSimple::OnToolTipTimerEvent)
968 EVT_TIMER(TOOLTIPOFF_TIMER, ocpnToolBarSimple::OnToolTipOffTimerEvent)
969 END_EVENT_TABLE()
970 
971 // ----------------------------------------------------------------------------
972 // tool bar tools creation
973 // ----------------------------------------------------------------------------
974 
975 wxToolBarToolBase *ocpnToolBarSimple::CreateTool(
976  int id, const wxString &label, const wxBitmap &bmpNormal,
977  const wxBitmap &bmpDisabled, wxItemKind kind, wxObject *clientData,
978  const wxString &shortHelp, const wxString &longHelp) {
979  if (m_style->NativeToolIconExists(label)) {
980  return new ocpnToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind,
981  clientData, shortHelp, longHelp);
982  } else {
983  wxString testToolname = g_pi_manager->GetToolOwnerCommonName(id);
984 
985  if (testToolname == _T("")) { // Not a PlugIn tool...
986  return new ocpnToolBarTool(this, id, bmpNormal, bmpDisabled, kind,
987  clientData, shortHelp, longHelp);
988  } else {
989  return new ocpnToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind,
990  clientData, shortHelp, longHelp);
991  }
992  }
993 }
994 
995 // ----------------------------------------------------------------------------
996 // ocpnToolBarSimple creation
997 // ----------------------------------------------------------------------------
998 
999 void ocpnToolBarSimple::Init() {
1000  m_currentRowsOrColumns = 0;
1001 
1002  m_lastX = m_lastY = 0;
1003 
1004  m_maxWidth = m_maxHeight = 0;
1005 
1006  m_pressedTool = m_currentTool = -1;
1007 
1008  m_xPos = m_yPos = wxDefaultCoord;
1009 
1010  m_style = g_StyleManager->GetCurrentStyle();
1011 
1012  m_defaultWidth = 16;
1013  m_defaultHeight = 15;
1014 
1015  m_toggle_bg_color = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
1016  m_toolOutlineColour.Set(_T("BLACK"));
1017  m_pToolTipWin = NULL;
1018  m_last_ro_tool = NULL;
1019 
1020  m_btoolbar_is_zooming = false;
1021  m_sizefactor = 1.0f;
1022 
1023  m_last_plugin_down_id = -1;
1024  m_leftDown = false;
1025  m_nShowTools = 0;
1026  m_btooltip_show = false;
1027 #ifndef __OCPN__ANDROID__
1028  EnableTooltips();
1029 #endif
1030  m_tbenableRolloverBitmaps = false;
1031 }
1032 
1033 wxToolBarToolBase *ocpnToolBarSimple::DoAddTool(
1034  int id, const wxString &label, const wxBitmap &bitmap,
1035  const wxBitmap &bmpDisabled, wxItemKind kind, const wxString &shortHelp,
1036  const wxString &longHelp, wxObject *clientData, wxCoord xPos,
1037  wxCoord yPos) {
1038  // rememeber the position for DoInsertTool()
1039  m_xPos = xPos;
1040  m_yPos = yPos;
1041 
1042  //InvalidateBestSize();
1043  return InsertTool(GetToolsCount(), id, label, bitmap, bmpDisabled, kind,
1044  shortHelp, longHelp, clientData);
1045 }
1046 
1048 
1049 wxToolBarToolBase *ocpnToolBarSimple::AddTool(
1050  int toolid, const wxString &label, const wxBitmap &bitmap,
1051  const wxBitmap &bmpDisabled, wxItemKind kind, const wxString &shortHelp,
1052  const wxString &longHelp, wxObject *data) {
1053  //InvalidateBestSize();
1054  ocpnToolBarTool *tool = (ocpnToolBarTool *)InsertTool(
1055  GetToolsCount(), toolid, label, bitmap, bmpDisabled, kind, shortHelp,
1056  longHelp, data);
1057  return tool;
1058 }
1059 
1060 wxToolBarToolBase *ocpnToolBarSimple::InsertTool(
1061  size_t pos, int id, const wxString &label, const wxBitmap &bitmap,
1062  const wxBitmap &bmpDisabled, wxItemKind kind, const wxString &shortHelp,
1063  const wxString &longHelp, wxObject *clientData) {
1064  wxCHECK_MSG(pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
1065  _T("invalid position in wxToolBar::InsertTool()"));
1066 
1067  wxToolBarToolBase *tool = CreateTool(id, label, bitmap, bmpDisabled, kind,
1068  clientData, shortHelp, longHelp);
1069 
1070  if (!InsertTool(pos, tool)) {
1071  delete tool;
1072 
1073  return NULL;
1074  }
1075 
1076  return tool;
1077 }
1078 
1079 wxToolBarToolBase *ocpnToolBarSimple::InsertTool(size_t pos,
1080  wxToolBarToolBase *tool) {
1081  wxCHECK_MSG(pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
1082  _T("invalid position in wxToolBar::InsertTool()"));
1083 
1084  if (!tool || !DoInsertTool(pos, tool)) {
1085  return NULL;
1086  }
1087 
1088  m_tools.Insert(pos, tool);
1089  m_nShowTools++;
1090 
1091  return tool;
1092 }
1093 
1094 bool ocpnToolBarSimple::DoInsertTool(size_t WXUNUSED(pos),
1095  wxToolBarToolBase *toolBase) {
1096  ocpnToolBarTool *tool = (ocpnToolBarTool *)toolBase;
1097 
1098  // Check if the plugin is inserting same-named tools. Make sure they have
1099  // different names, otherwise the style manager cannot differentiate between
1100  // them.
1101  if (tool->isPluginTool) {
1102  for (unsigned int i = 0; i < GetToolsCount(); i++) {
1103  if (tool->GetToolname() ==
1104  ((ocpnToolBarTool *)m_tools.Item(i)->GetData())->GetToolname()) {
1105  tool->toolname << _T("1");
1106  }
1107  }
1108  }
1109 
1110  tool->m_x = m_xPos;
1111  if (tool->m_x == wxDefaultCoord) tool->m_x = m_style->GetLeftMargin();
1112 
1113  tool->m_y = m_yPos;
1114  if (tool->m_y == wxDefaultCoord) tool->m_y = m_style->GetTopMargin();
1115 
1116  if (tool->IsButton()) {
1117  tool->SetSize(GetToolSize());
1118 
1119  // Calculate reasonable max size in case Layout() not called
1120  if ((tool->m_x + tool->GetNormalBitmap().GetWidth() +
1121  m_style->GetLeftMargin()) > m_maxWidth)
1122  m_maxWidth =
1123  (wxCoord)((tool->m_x + tool->GetWidth() + m_style->GetLeftMargin()));
1124 
1125  if ((tool->m_y + tool->GetNormalBitmap().GetHeight() +
1126  m_style->GetTopMargin()) > m_maxHeight)
1127  m_maxHeight =
1128  (wxCoord)((tool->m_y + tool->GetHeight() + m_style->GetTopMargin()));
1129  }
1130 
1131  else if (tool->IsControl()) {
1132  tool->SetSize(tool->GetControl()->GetSize());
1133  }
1134 
1135  tool->b_hilite = false;
1136 
1137  return true;
1138 }
1139 
1140 bool ocpnToolBarSimple::DoDeleteTool(size_t WXUNUSED(pos),
1141  wxToolBarToolBase *tool) {
1142  // VZ: didn't test whether it works, but why not...
1143  tool->Detach();
1144 
1145  if (m_last_ro_tool == tool) m_last_ro_tool = NULL;
1146 
1147  //Refresh(false);
1148 
1149  return true;
1150 }
1151 
1152 bool ocpnToolBarSimple::Create(ocpnFloatingToolbarDialog *parent, wxWindowID id,
1153  const wxPoint &pos, const wxSize &size,
1154  long style, int orient) {
1155 
1156  m_parentContainer = parent;
1157  m_orient = orient;
1158 
1159  if (IsVertical()) {
1160  m_lastX = 7;
1161  m_lastY = 3;
1162 
1163  m_maxRows = 32000; // a lot
1164  m_maxCols = 1;
1165  } else {
1166  m_lastX = 3;
1167  m_lastY = 7;
1168 
1169  m_maxRows = 1;
1170  m_maxCols = 32000; // a lot
1171  }
1172 
1173  //SetCursor(*wxSTANDARD_CURSOR);
1174 
1175  m_tooltip_timer.SetOwner(this, TOOLTIPON_TIMER);
1176  m_tooltipoff_timer.SetOwner(this, TOOLTIPOFF_TIMER);
1177  m_tooltip_off = 3000;
1178 
1179  m_tbenableRolloverBitmaps = false;
1180 
1181  return true;
1182 }
1183 
1184 ocpnToolBarSimple::~ocpnToolBarSimple() {
1185  if (m_pToolTipWin) {
1186  m_pToolTipWin->Destroy();
1187  m_pToolTipWin = NULL;
1188  }
1189 }
1190 
1191 void ocpnToolBarSimple::EnableTooltips() {
1192 #ifndef __OCPN__ANDROID__
1193  m_btooltip_show = true;
1194 #endif
1195 }
1196 
1197 void ocpnToolBarSimple::DisableTooltips() {
1198 #ifndef __OCPN__ANDROID__
1199  ocpnToolBarSimple::m_btooltip_show = false;
1200 #endif
1201 }
1202 
1203 void ocpnToolBarSimple::KillTooltip() {
1204  m_btooltip_show = false;
1205 
1206  if (m_pToolTipWin) {
1207  m_pToolTipWin->Hide();
1208  m_pToolTipWin->Destroy();
1209  m_pToolTipWin = NULL;
1210  }
1211  m_tooltip_timer.Stop();
1212 
1213  gFrame->Raise();
1214  gFrame->GetFocusCanvas()->TriggerDeferredFocus();
1215 }
1216 
1217 void ocpnToolBarSimple::HideTooltip() {
1218 #ifndef __OCPN__ANDROID__
1219  if (m_pToolTipWin) {
1220  m_pToolTipWin->Hide();
1221  }
1222 #endif
1223 }
1224 
1225 void ocpnToolBarSimple::SetColorScheme(ColorScheme cs) {
1226 #ifndef __OCPN__ANDROID__
1227  if (m_pToolTipWin) {
1228  m_pToolTipWin->Destroy();
1229  m_pToolTipWin = NULL;
1230  }
1231 #endif
1232  m_toolOutlineColour = GetGlobalColor(_T("UIBDR"));
1233 
1234  m_currentColorScheme = cs;
1235 }
1236 
1237 bool ocpnToolBarSimple::Realize() {
1238  if (IsVertical())
1239  m_style->SetOrientation(wxTB_VERTICAL);
1240  else
1241  m_style->SetOrientation(wxTB_HORIZONTAL);
1242 
1243  wxSize toolSize = wxSize(-1, -1);
1244  int separatorSize = m_style->GetToolSeparation() * m_sizefactor;
1245  int topMargin = m_style->GetTopMargin() * m_sizefactor;
1246  int leftMargin = m_style->GetLeftMargin() * m_sizefactor;
1247 
1248  m_currentRowsOrColumns = 0;
1249  m_LineCount = 1;
1250  m_lastX = leftMargin;
1251  m_lastY = topMargin;
1252  m_maxWidth = 0;
1253  m_maxHeight = 0;
1254 
1255  ocpnToolBarTool *lastTool = NULL;
1256  bool firstNode = true;
1257  wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1258 
1259  int iNode = 0;
1260 
1261  while (node) {
1262  if (iNode >= m_nShowTools) break;
1263 
1264  ocpnToolBarTool *tool = (ocpnToolBarTool *)node->GetData();
1265 
1266  // Set the tool size to be the size of the first non-separator tool, usually
1267  // the first one
1268  if (toolSize.x == -1) {
1269  if (!tool->IsSeparator()) {
1270  toolSize.x = tool->m_width;
1271  toolSize.y = tool->m_height;
1272  }
1273  }
1274 
1275  tool->firstInLine = firstNode;
1276  tool->lastInLine = false;
1277  firstNode = false;
1278 
1279  tool->last_rect.width = 0; // mark it invalid
1280 
1281  if (tool->IsSeparator()) {
1282  //if (GetWindowStyleFlag() & wxTB_HORIZONTAL) {
1283  //if (m_currentRowsOrColumns >= m_maxCols)
1284  //m_lastY += separatorSize;
1285  //else
1286  // m_lastX += separatorSize;
1287  //}
1288  //else
1289  {
1290  if (m_currentRowsOrColumns >= m_maxRows)
1291  m_lastX += separatorSize;
1292  else
1293  m_lastY += separatorSize;
1294  }
1295  } else if (tool->IsButton()) {
1296  if (!IsVertical()) {
1297  if (m_currentRowsOrColumns >= m_maxCols) {
1298  tool->firstInLine = true;
1299  if (lastTool && m_LineCount > 1) lastTool->lastInLine = true;
1300  m_LineCount++;
1301  m_currentRowsOrColumns = 0;
1302  m_lastX = leftMargin;
1303  m_lastY += toolSize.y + topMargin;
1304  }
1305  tool->m_x = (wxCoord)m_lastX;
1306  tool->m_y = (wxCoord)m_lastY;
1307 
1308  tool->trect = wxRect(tool->m_x, tool->m_y, toolSize.x, toolSize.y);
1309  tool->trect.Inflate(separatorSize / 2, topMargin);
1310 
1311  m_lastX += toolSize.x + separatorSize;
1312  } else {
1313  if (m_currentRowsOrColumns >= m_maxRows) {
1314  tool->firstInLine = true;
1315  if (lastTool) lastTool->lastInLine = true;
1316  m_LineCount++;
1317  m_currentRowsOrColumns = 0;
1318  m_lastX += toolSize.x + leftMargin;
1319  m_lastY = topMargin;
1320  }
1321  tool->m_x = (wxCoord)m_lastX;
1322  tool->m_y = (wxCoord)m_lastY;
1323 
1324  tool->trect = wxRect(tool->m_x, tool->m_y, toolSize.x, toolSize.y);
1325  tool->trect.Inflate((separatorSize / 2), topMargin);
1326 
1327  m_lastY += toolSize.y + separatorSize;
1328  }
1329  m_currentRowsOrColumns++;
1330  }
1331  //else
1332  //if (tool->IsControl()) {
1333  //tool->m_x = (wxCoord)(m_lastX);
1334  //tool->m_y = (wxCoord)(m_lastY - (topMargin / 2));
1335 
1336  //tool->trect =
1337  // wxRect(tool->m_x, tool->m_y, tool->GetWidth(), tool->GetHeight());
1338  //tool->trect.Inflate(separatorSize / 2, topMargin);
1339 
1340  //wxSize s = tool->GetControl()->GetSize();
1341  //m_lastX += s.x + separatorSize;
1342  //}
1343 
1344  if (m_lastX > m_maxWidth) m_maxWidth = m_lastX;
1345  if (m_lastY > m_maxHeight) m_maxHeight = m_lastY;
1346 
1347  lastTool = tool;
1348  node = node->GetNext();
1349  iNode++;
1350  }
1351  if (lastTool && (m_LineCount > 1 || IsVertical()))
1352  lastTool->lastInLine = true;
1353 
1354  if (!IsVertical()) {
1355  m_maxHeight += toolSize.y;
1356  m_maxHeight += m_style->GetBottomMargin();
1357  } else {
1358  m_maxWidth += toolSize.x;
1359  m_maxWidth += m_style->GetRightMargin() * m_sizefactor;
1360  }
1361 
1362  m_bitmap = wxNullBitmap;
1363 
1364  return true;
1365 }
1366 
1367 wxBitmap &ocpnToolBarSimple::CreateBitmap(double display_scale) {
1368  if (m_bitmap.IsOk())
1369  return m_bitmap;
1370 
1371  //Make the bitmap
1372  int width = m_maxWidth;
1373  int height = m_maxHeight;
1374 
1375  wxMemoryDC mdc;
1376  wxBitmap bm(width, height);
1377  mdc.SelectObject(bm);
1378  mdc.SetBackground(wxBrush( GetBackgroundColour()));
1379  mdc.Clear();
1380 
1381  // In a loop, draw the tools
1382  for (wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1383  node; node = node->GetNext()) {
1384  wxToolBarToolBase *tool = node->GetData();
1385  ocpnToolBarTool *tools = (ocpnToolBarTool *)tool;
1386  wxRect toolRect = tools->trect;
1387  CreateToolBitmap(tool);
1388 
1389  if (tools->m_activeBitmap.IsOk()) {
1390  mdc.DrawBitmap(tools->m_activeBitmap, tools->m_x, tools->m_y, false);
1391  }
1392  int yyp = 5;
1393  }
1394 
1395  mdc.SelectObject(wxNullBitmap);
1396 
1397  m_bitmap = bm;
1398  return m_bitmap;
1399 }
1400 
1401 
1402 
1403 void ocpnToolBarSimple::OnToolTipTimerEvent(wxTimerEvent &event) {
1404  if (!gFrame) // In case gFrame was already destroyed, but the toolbar still
1405  // exists (Which should not happen, ever.)
1406  return;
1407 
1408  if (m_btooltip_show /*&& IsShown()*/ && m_pToolTipWin &&
1409  (!m_pToolTipWin->IsShown())) {
1410  if (m_last_ro_tool) {
1411  wxString s = m_last_ro_tool->GetShortHelp();
1412 
1413  if (s.Len()) {
1414  m_pToolTipWin->SetString(s);
1415  m_pToolTipWin->SetHiviz(m_last_ro_tool->m_btooltip_hiviz);
1416 
1417  wxPoint pos_in_toolbar(m_last_ro_tool->m_x, m_last_ro_tool->m_y);
1418  pos_in_toolbar.x += m_last_ro_tool->m_width + 2;
1419 
1420  m_pToolTipWin->Move(
1421  0, 0); // workaround for gtk autocentre dialog behavior
1422 
1423  wxPoint screenPosition = gFrame->GetPrimaryCanvas()->ClientToScreen(pos_in_toolbar);
1424  wxSize tipSize = m_pToolTipWin->GetRenderedSize();
1425 
1426  m_pToolTipWin->SetPosition(screenPosition);
1427  m_pToolTipWin->SetBitmap();
1428  m_pToolTipWin->Show();
1429 #ifndef __WXOSX__
1430  gFrame->Raise();
1431 #endif
1432 
1433 #ifndef __OCPN__ANDROID__
1434  if (g_btouch) m_tooltipoff_timer.Start(m_tooltip_off, wxTIMER_ONE_SHOT);
1435 #endif
1436  }
1437  }
1438  }
1439 }
1440 
1441 void ocpnToolBarSimple::OnToolTipOffTimerEvent(wxTimerEvent &event) {
1442  HideTooltip();
1443 }
1444 
1445 
1446 bool ocpnToolBarSimple::OnMouseEvent(wxMouseEvent &event, wxPoint &position) {
1447 #ifdef __OCPN__ANDROID__
1448  if (!event.IsButton()) return false;
1449 #endif
1450 
1451  wxCoord x, y;
1452  event.GetPosition(&x, &y);
1453 
1454  // in the toolbar?
1455  wxRect r = wxRect(position, wxSize( m_maxWidth, m_maxHeight));
1456  if (!r.Contains(x,y)) {
1457  HideTooltip();
1458  return false;
1459  }
1460 
1461  m_parentContainer->RefreshFadeTimer();
1462 
1463  ocpnToolBarTool *tool = (ocpnToolBarTool *)FindToolForPosition(x - position.x,
1464  y - position.y);
1465  if (tool == NULL) {
1466  m_tooltipoff_timer.Start(m_tooltip_off, wxTIMER_ONE_SHOT);
1467  return true;
1468  }
1469  else
1470  m_tooltipoff_timer.Stop();
1471 
1472 
1473  // tooltips
1474  if (tool && tool->IsButton() /*&& IsShown()*/) {
1475  if (m_btooltip_show) {
1476  // ToolTips
1477  if (NULL == m_pToolTipWin) {
1478  m_pToolTipWin = new ToolTipWin(gFrame /*GetParent()*/);
1479  m_pToolTipWin->SetColorScheme(m_currentColorScheme);
1480  m_pToolTipWin->Hide();
1481  }
1482 
1483  if (tool != m_last_ro_tool) {
1484  m_pToolTipWin->Hide();
1485  }
1486 
1487 #ifndef __OCPN__ANDROID__
1488  if (!m_pToolTipWin->IsShown()) {
1489  if (!m_tooltip_timer.IsRunning()) {
1490  m_tooltip_timer.Start(m_one_shot, wxTIMER_ONE_SHOT);
1491  }
1492  }
1493 #endif
1494  }
1495  }
1496 
1497  m_last_ro_tool = tool;
1498 
1499  // Left button pressed.
1500  if (event.LeftIsDown()) m_leftDown = true; // trigger on
1501 
1502  if (event.LeftDown() && tool->IsEnabled()) {
1503  if (tool->CanBeToggled()) {
1504  tool->Toggle();
1505  tool->bitmapOK = false;
1506  SetDirty(true);
1507  m_bitmap = wxNullBitmap;
1508  }
1509 
1510  // Look for PlugIn tools
1511  // If found, make the callback.
1512  if (g_pi_manager) {
1513  ArrayOfPlugInToolbarTools tool_array =
1514  g_pi_manager->GetPluginToolbarToolArray();
1515  for (unsigned int i = 0; i < tool_array.GetCount(); i++) {
1516  PlugInToolbarToolContainer *pttc = tool_array[i];
1517  if (tool->GetId() == pttc->id) {
1518  opencpn_plugin_113 *ppi =
1519  dynamic_cast<opencpn_plugin_113 *>(pttc->m_pplugin);
1520  if (ppi) {
1521  ppi->OnToolbarToolDownCallback(pttc->id);
1522  m_last_plugin_down_id = pttc->id;
1523  }
1524  }
1525  }
1526  }
1527  } else if (event.RightDown()) {
1528  OnRightClick(tool->GetId(), x, y);
1529  }
1530 
1531  // Left Button Released. Only this action confirms selection.
1532  // If the button is enabled and it is not a toggle tool and it is
1533  // in the pressed state, then raise the button and call OnLeftClick.
1534  //
1535  // Unfortunately, some touch screen drivers do not send "LeftIsDown" events.
1536  // Nor do they report "LeftIsDown" in any state.
1537  // c.f rPI "official" 7" panel.
1538 
1539  // So, for this logic, assume in touch mode that the m_leftDown flag may not
1540  // be set, and process the left-up event anyway.
1541  if (event.LeftUp() && tool->IsEnabled() && (m_leftDown || g_btouch)) {
1542  // Pass the OnLeftClick event to tool
1543  if (!OnLeftClick(tool->GetId(), tool->IsToggled()) &&
1544  tool->CanBeToggled()) {
1545  // If it was a toggle, and OnLeftClick says No Toggle allowed,
1546  // then change it back
1547  tool->Toggle();
1548  tool->bitmapOK = false;
1549  }
1550 
1551  DoPluginToolUp();
1552  m_leftDown = false;
1553  return true;
1554  }
1555 
1556  return true;
1557 }
1558 
1559 // ----------------------------------------------------------------------------
1560 // drawing
1561 // ----------------------------------------------------------------------------
1562 
1563 void ocpnToolBarSimple::CreateToolBitmap(wxToolBarToolBase *toolBase) {
1564  ocpnToolBarTool *tool = (ocpnToolBarTool *)toolBase;
1565 
1566  wxBitmap bmp = wxNullBitmap;
1567 
1568  bool bNeedClear = !tool->bitmapOK;
1569 
1570  if (tool->bitmapOK) {
1571  if (tool->IsEnabled()) {
1572  bmp = tool->GetNormalBitmap();
1573  if (!bmp.IsOk()) {
1574  bmp =
1575  m_style->GetToolIcon(tool->GetToolname(), TOOLICON_NORMAL,
1576  tool->rollover, tool->m_width, tool->m_height);
1577  tool->SetNormalBitmap(bmp);
1578  tool->bitmapOK = true;
1579  }
1580  } else {
1581  bmp = tool->GetDisabledBitmap();
1582  if (!bmp.IsOk()) {
1583  bmp = m_style->GetToolIcon(tool->GetToolname(), TOOLICON_DISABLED,
1584  false, tool->m_width, tool->m_height);
1585  tool->SetDisabledBitmap(bmp);
1586  tool->bitmapOK = true;
1587  }
1588  }
1589  } else {
1590  if (tool->isPluginTool) {
1591  int toggleFlag = tool->IsToggled() ? TOOLICON_TOGGLED : TOOLICON_NORMAL;
1592 
1593  // First try getting the icon from an SVG definition.
1594  // If it is not found, try to see if it is available in the style
1595  // If not there, we build a new icon from the style BG and the (default)
1596  // plugin icon.
1597 
1598  wxString svgFile = tool->pluginNormalIconSVG;
1599  if (toggleFlag) {
1600  if (tool->pluginToggledIconSVG.Length())
1601  svgFile = tool->pluginToggledIconSVG;
1602  }
1603  if (tool->rollover) {
1604  if (tool->pluginRolloverIconSVG.Length())
1605  svgFile = tool->pluginRolloverIconSVG;
1606  }
1607 
1608  if (!svgFile.IsEmpty()) { // try SVG
1609 #ifdef ocpnUSE_SVG
1610  bmp = LoadSVG(svgFile, tool->m_width, tool->m_height);
1611  if (bmp.IsOk()) {
1612  bmp = m_style->BuildPluginIcon(bmp, toggleFlag, m_sizefactor);
1613  } else
1614  bmp =
1615  m_style->BuildPluginIcon(tool->pluginNormalIcon, TOOLICON_NORMAL);
1616 #endif
1617  }
1618 
1619  if (!bmp.IsOk() || bmp.IsNull()) {
1620  if (m_style->NativeToolIconExists(tool->GetToolname())) {
1621  bmp = m_style->GetToolIcon(tool->GetToolname(), toggleFlag,
1622  tool->rollover, tool->m_width,
1623  tool->m_height);
1624  } else {
1625  bmp = wxNullBitmap;
1626  }
1627 
1628  if (bmp.IsNull()) { // Tool icon not found in style definition
1629  //bmp = m_style->BuildPluginIcon(tool->pluginNormalIcon, toggleFlag);
1630  bmp = tool->pluginNormalIcon;
1631  if (fabs(m_sizefactor - 1.0) > 0.01) {
1632  if (tool->m_width && tool->m_height) {
1633  wxImage scaled_image = bmp.ConvertToImage();
1634  bmp = wxBitmap(scaled_image.Scale(tool->m_width, tool->m_height,
1635  wxIMAGE_QUALITY_HIGH));
1636  }
1637  }
1638  }
1639  }
1640  tool->SetNormalBitmap(bmp);
1641  tool->bitmapOK = true;
1642  } else { // Not a plugin tool
1643  bmp = tool->GetNormalBitmap();
1644  if (tool->IsEnabled()) {
1645  if (tool->IsToggled()) {
1646  if (!tool->bitmapOK) {
1647  if (m_style->NativeToolIconExists(tool->GetToolname())) {
1648  bmp = m_style->GetToolIcon(tool->GetToolname(), TOOLICON_TOGGLED,
1649  tool->rollover, tool->m_width,
1650  tool->m_height);
1651  tool->SetNormalBitmap(bmp);
1652  }
1653  }
1654  }
1655 
1656  else {
1657  if (!tool->bitmapOK) {
1658  if (m_style->NativeToolIconExists(tool->GetToolname())) {
1659  bmp = m_style->GetToolIcon(tool->GetIconName(), TOOLICON_NORMAL,
1660  tool->rollover, tool->m_width,
1661  tool->m_height);
1662  tool->SetNormalBitmap(bmp);
1663  }
1664  }
1665  }
1666 
1667  tool->bitmapOK = true;
1668  } else {
1669  bmp = m_style->GetToolIcon(tool->GetToolname(), TOOLICON_DISABLED,
1670  false, tool->m_width, tool->m_height);
1671  tool->SetDisabledBitmap(bmp);
1672  tool->bitmapOK = true;
1673  }
1674  }
1675  }
1676  tool->m_activeBitmap = bmp;
1677 }
1678 
1679 
1680 
1681 
1682 
1683 
1684 // NB! The current DrawTool code assumes that plugin tools are never disabled
1685 // when they are present on the toolbar, since disabled plugins are removed.
1686 
1687 void ocpnToolBarSimple::DrawTool(wxDC &dc, wxToolBarToolBase *toolBase) {
1688  ocpnToolBarTool *tool = (ocpnToolBarTool *)toolBase;
1689  //PrepareDC(dc);
1690 
1691  wxPoint drawAt(tool->m_x, tool->m_y);
1692  wxBitmap bmp = wxNullBitmap;
1693 
1694  bool bNeedClear = !tool->bitmapOK;
1695 
1696  if (tool->bitmapOK) {
1697  if (tool->IsEnabled()) {
1698  bmp = tool->GetNormalBitmap();
1699  if (!bmp.IsOk()) {
1700  bmp =
1701  m_style->GetToolIcon(tool->GetToolname(), TOOLICON_NORMAL,
1702  tool->rollover, tool->m_width, tool->m_height);
1703  tool->SetNormalBitmap(bmp);
1704  tool->bitmapOK = true;
1705  }
1706  } else {
1707  bmp = tool->GetDisabledBitmap();
1708  if (!bmp.IsOk()) {
1709  bmp = m_style->GetToolIcon(tool->GetToolname(), TOOLICON_DISABLED,
1710  false, tool->m_width, tool->m_height);
1711  tool->SetDisabledBitmap(bmp);
1712  tool->bitmapOK = true;
1713  }
1714  }
1715  } else {
1716  if (tool->isPluginTool) {
1717  int toggleFlag = tool->IsToggled() ? TOOLICON_TOGGLED : TOOLICON_NORMAL;
1718 
1719  // First try getting the icon from an SVG definition.
1720  // If it is not found, try to see if it is available in the style
1721  // If not there, we build a new icon from the style BG and the (default)
1722  // plugin icon.
1723 
1724  wxString svgFile = tool->pluginNormalIconSVG;
1725  if (toggleFlag) {
1726  if (tool->pluginToggledIconSVG.Length())
1727  svgFile = tool->pluginToggledIconSVG;
1728  }
1729  if (tool->rollover) {
1730  if (tool->pluginRolloverIconSVG.Length())
1731  svgFile = tool->pluginRolloverIconSVG;
1732  }
1733 
1734  if (!svgFile.IsEmpty()) { // try SVG
1735 #ifdef ocpnUSE_SVG
1736  bmp = LoadSVG(svgFile, tool->m_width, tool->m_height);
1737  if (bmp.IsOk()) {
1738  bmp = m_style->BuildPluginIcon(bmp, toggleFlag, m_sizefactor);
1739  } else
1740  bmp =
1741  m_style->BuildPluginIcon(tool->pluginNormalIcon, TOOLICON_NORMAL);
1742 #endif
1743  }
1744 
1745  if (!bmp.IsOk() || bmp.IsNull()) {
1746  if (m_style->NativeToolIconExists(tool->GetToolname())) {
1747  bmp = m_style->GetToolIcon(tool->GetToolname(), toggleFlag,
1748  tool->rollover, tool->m_width,
1749  tool->m_height);
1750  } else {
1751  bmp = wxNullBitmap;
1752  }
1753 
1754  if (bmp.IsNull()) { // Tool icon not found
1755  if (tool->rollover) {
1756  bmp =
1757  m_style->BuildPluginIcon(tool->pluginRolloverIcon, toggleFlag);
1758  if (!bmp.IsOk()) {
1759  bmp =
1760  m_style->BuildPluginIcon(tool->pluginNormalIcon, toggleFlag);
1761  }
1762  } else {
1763  bmp = m_style->BuildPluginIcon(tool->pluginNormalIcon, toggleFlag);
1764  }
1765  if (fabs(m_sizefactor - 1.0) > 0.01) {
1766  if (tool->m_width && tool->m_height) {
1767  wxImage scaled_image = bmp.ConvertToImage();
1768  bmp = wxBitmap(scaled_image.Scale(tool->m_width, tool->m_height,
1769  wxIMAGE_QUALITY_HIGH));
1770  }
1771  }
1772  }
1773  }
1774  tool->SetNormalBitmap(bmp);
1775  tool->bitmapOK = true;
1776  } else { // Not a plugin tool
1777  bmp = tool->GetNormalBitmap();
1778  if (tool->IsEnabled()) {
1779  if (tool->IsToggled()) {
1780  if (!tool->bitmapOK) {
1781  if (m_style->NativeToolIconExists(tool->GetToolname())) {
1782  bmp = m_style->GetToolIcon(tool->GetToolname(), TOOLICON_TOGGLED,
1783  tool->rollover, tool->m_width,
1784  tool->m_height);
1785  tool->SetNormalBitmap(bmp);
1786  }
1787  }
1788  }
1789 
1790  else {
1791  if (!tool->bitmapOK) {
1792  if (m_style->NativeToolIconExists(tool->GetToolname())) {
1793  bmp = m_style->GetToolIcon(tool->GetIconName(), TOOLICON_NORMAL,
1794  tool->rollover, tool->m_width,
1795  tool->m_height);
1796  tool->SetNormalBitmap(bmp);
1797  }
1798  }
1799  }
1800 
1801  tool->bitmapOK = true;
1802  } else {
1803  bmp = m_style->GetToolIcon(tool->GetToolname(), TOOLICON_DISABLED,
1804  false, tool->m_width, tool->m_height);
1805  tool->SetDisabledBitmap(bmp);
1806  tool->bitmapOK = true;
1807  }
1808  }
1809  }
1810 
1811  if (tool->firstInLine) {
1812  m_style->DrawToolbarLineStart(bmp, m_sizefactor);
1813  }
1814  if (tool->lastInLine) {
1815  m_style->DrawToolbarLineEnd(bmp, m_sizefactor);
1816  }
1817 
1818  if (bmp.GetWidth() != m_style->GetToolSize().x ||
1819  bmp.GetHeight() != m_style->GetToolSize().y) {
1820  // drawAt.x -= ( bmp.GetWidth() - m_style->GetToolSize().x ) / 2;
1821  // drawAt.y -= ( bmp.GetHeight() - m_style->GetToolSize().y ) / 2;
1822  }
1823 
1824  // Clear the last drawn tool if necessary
1825  if ((tool->last_rect.width &&
1826  (tool->last_rect.x != drawAt.x || tool->last_rect.y != drawAt.y)) ||
1827  bNeedClear) {
1828  wxBrush bb(GetGlobalColor(_T("GREY3")));
1829  dc.SetBrush(bb);
1830  dc.SetPen(*wxTRANSPARENT_PEN);
1831  dc.DrawRectangle(tool->last_rect.x, tool->last_rect.y,
1832  tool->last_rect.width, tool->last_rect.height);
1833  }
1834 
1835  // could cache this in the tool...
1836  // A bit of a hack here. We only scale tools if they are to be magnified
1837  // globally
1838  if (0 /*m_sizefactor > 1.0*/) {
1839  wxImage scaled_image = bmp.ConvertToImage();
1840  wxBitmap sbmp = wxBitmap(scaled_image.Scale(tool->m_width, tool->m_height,
1841  wxIMAGE_QUALITY_HIGH));
1842  dc.DrawBitmap(sbmp, drawAt);
1843  tool->last_rect =
1844  wxRect(drawAt.x, drawAt.y, sbmp.GetWidth(), sbmp.GetHeight());
1845 
1846  } else {
1847  dc.DrawBitmap(bmp, drawAt);
1848  tool->last_rect =
1849  wxRect(drawAt.x, drawAt.y, bmp.GetWidth(), bmp.GetHeight());
1850  }
1851 }
1852 
1853 // ----------------------------------------------------------------------------
1854 // toolbar geometry
1855 // ----------------------------------------------------------------------------
1856 
1857 wxToolBarToolBase *ocpnToolBarSimple::FindToolForPosition(wxCoord x,
1858  wxCoord y) {
1859  wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1860  while (node) {
1861  ocpnToolBarTool *tool = (ocpnToolBarTool *)node->GetData();
1862  if ((x >= tool->m_x) && (y >= tool->m_y) &&
1863  (x < (tool->m_x + tool->GetWidth())) &&
1864  (y < (tool->m_y + tool->GetHeight()))) {
1865  return tool;
1866  }
1867 
1868  node = node->GetNext();
1869  }
1870 
1871  return (wxToolBarToolBase *)NULL;
1872 }
1873 
1874 void ocpnToolBarSimple::InvalidateBitmaps() {
1875  wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1876  while (node) {
1877  ocpnToolBarTool *tool = (ocpnToolBarTool *)node->GetData();
1878  tool->bitmapOK = false;
1879  node = node->GetNext();
1880  }
1881  m_bitmap = wxNullBitmap;
1882 }
1883 
1884 wxRect ocpnToolBarSimple::GetToolRect(int tool_id) {
1885  wxRect rect;
1886  wxToolBarToolBase *tool = FindById(tool_id);
1887  if (tool) {
1888  ocpnToolBarTool *otool = (ocpnToolBarTool *)tool;
1889  if (otool) rect = otool->trect;
1890  }
1891 
1892  return rect;
1893 }
1894 
1895 // ----------------------------------------------------------------------------
1896 // tool state change handlers
1897 // ----------------------------------------------------------------------------
1898 
1899 void ocpnToolBarSimple::DoEnableTool(wxToolBarToolBase *tool,
1900  bool WXUNUSED(enable)) {
1901  ocpnToolBarTool *t = (ocpnToolBarTool *)tool;
1902  t->bitmapOK = false;
1903 }
1904 
1905 void ocpnToolBarSimple::DoToggleTool(wxToolBarToolBase *tool,
1906  bool WXUNUSED(toggle)) {
1907  ocpnToolBarTool *t = (ocpnToolBarTool *)tool;
1908  t->bitmapOK = false;
1909  SetDirty(true);
1910 }
1911 
1912 
1913 // ----------------------------------------------------------------------------
1914 // scrolling implementation
1915 // ----------------------------------------------------------------------------
1916 
1917 wxString ocpnToolBarSimple::GetToolShortHelp(int id) const {
1918  wxToolBarToolBase *tool = FindById(id);
1919  wxCHECK_MSG(tool, wxEmptyString, _T("no such tool"));
1920 
1921  return tool->GetShortHelp();
1922 }
1923 
1924 wxString ocpnToolBarSimple::GetToolLongHelp(int id) const {
1925  wxToolBarToolBase *tool = FindById(id);
1926  wxCHECK_MSG(tool, wxEmptyString, _T("no such tool"));
1927 
1928  return tool->GetLongHelp();
1929 }
1930 
1931 void ocpnToolBarSimple::SetToolShortHelp(int id, const wxString &help) {
1932  wxToolBarToolBase *tool = FindById(id);
1933  if (tool) {
1934  (void)tool->SetShortHelp(help);
1935  }
1936 }
1937 
1938 void ocpnToolBarSimple::SetToolLongHelp(int id, const wxString &help) {
1939  wxToolBarToolBase *tool = FindById(id);
1940  if (tool) {
1941  (void)tool->SetLongHelp(help);
1942  }
1943 }
1944 
1945 int ocpnToolBarSimple::GetToolPos(int id) const {
1946  size_t pos = 0;
1947  wxToolBarToolsList::compatibility_iterator node;
1948 
1949  for (node = m_tools.GetFirst(); node; node = node->GetNext()) {
1950  if (node->GetData()->GetId() == id) return pos;
1951 
1952  pos++;
1953  }
1954 
1955  return wxNOT_FOUND;
1956 }
1957 bool ocpnToolBarSimple::GetToolState(int id) const {
1958  wxToolBarToolBase *tool = FindById(id);
1959  wxCHECK_MSG(tool, false, _T("no such tool"));
1960 
1961  return tool->IsToggled();
1962 }
1963 
1964 bool ocpnToolBarSimple::GetToolEnabled(int id) const {
1965  wxToolBarToolBase *tool = FindById(id);
1966  wxCHECK_MSG(tool, false, _T("no such tool"));
1967 
1968  return tool->IsEnabled();
1969 }
1970 
1971 void ocpnToolBarSimple::ToggleTool(int id, bool toggle) {
1972  wxToolBarToolBase *tool = FindById(id);
1973 
1974  if (tool && tool->CanBeToggled() && tool->Toggle(toggle)) {
1975  DoToggleTool(tool, toggle);
1976  InvalidateBitmaps();
1977  gFrame->GetPrimaryCanvas()->Refresh(true);
1978  }
1979 }
1980 
1981 wxObject *ocpnToolBarSimple::GetToolClientData(int id) const {
1982  wxToolBarToolBase *tool = FindById(id);
1983  return tool ? tool->GetClientData() : (wxObject *)NULL;
1984 }
1985 
1986 void ocpnToolBarSimple::SetToolClientData(int id, wxObject *clientData) {
1987  wxToolBarToolBase *tool = FindById(id);
1988 
1989  wxCHECK_RET(tool, _T("no such tool in wxToolBar::SetToolClientData"));
1990 
1991  tool->SetClientData(clientData);
1992 }
1993 
1994 void ocpnToolBarSimple::EnableTool(int id, bool enable) {
1995  wxToolBarToolBase *tool = FindById(id);
1996  if (tool) {
1997  if (tool->Enable(enable)) {
1998  DoEnableTool(tool, enable);
1999  }
2000  }
2001 
2002  ocpnFloatingToolbarDialog *parent = m_parentContainer;
2003  if (parent && parent->m_FloatingToolbarConfigMenu) {
2004  wxMenuItem *configItem = parent->m_FloatingToolbarConfigMenu->FindItem(id);
2005  if (configItem) configItem->Check(true);
2006  }
2007 }
2008 
2009 void ocpnToolBarSimple::SetToolTooltipHiViz(int id, bool b_hiviz) {
2010  ocpnToolBarTool *tool = (ocpnToolBarTool *)FindById(id);
2011  if (tool) {
2012  tool->SetTooltipHiviz(b_hiviz);
2013  }
2014 }
2015 
2016 void ocpnToolBarSimple::ClearTools() {
2017  while (GetToolsCount()) {
2018  DeleteToolByPos(0);
2019  }
2020 }
2021 
2022 int ocpnToolBarSimple::GetVisibleToolCount() {
2023  int counter = 0;
2024  wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
2025  while (node) {
2026  ocpnToolBarTool *tool = (ocpnToolBarTool *)node->GetData();
2027  counter++;
2028  node = node->GetNext();
2029  }
2030  return counter;
2031 }
2032 
2033 bool ocpnToolBarSimple::DeleteToolByPos(size_t pos) {
2034  wxCHECK_MSG(pos < GetToolsCount(), false,
2035  _T("invalid position in wxToolBar::DeleteToolByPos()"));
2036 
2037  wxToolBarToolsList::compatibility_iterator node = m_tools.Item(pos);
2038 
2039  if (!DoDeleteTool(pos, node->GetData())) {
2040  return false;
2041  }
2042 
2043  delete node->GetData();
2044  m_tools.Erase(node);
2045 
2046  return true;
2047 }
2048 
2049 bool ocpnToolBarSimple::DeleteTool(int id) {
2050  size_t pos = 0;
2051  wxToolBarToolsList::compatibility_iterator node;
2052  for (node = m_tools.GetFirst(); node; node = node->GetNext()) {
2053  if (node->GetData()->GetId() == id) break;
2054 
2055  pos++;
2056  }
2057 
2058  if (!node || !DoDeleteTool(pos, node->GetData())) {
2059  return false;
2060  }
2061 
2062  delete node->GetData();
2063  m_tools.Erase(node);
2064 
2065  return true;
2066 }
2067 
2068 wxToolBarToolBase *ocpnToolBarSimple::AddSeparator() {
2069  return InsertSeparator(GetToolsCount());
2070 }
2071 
2072 wxToolBarToolBase *ocpnToolBarSimple::InsertSeparator(size_t pos) {
2073  wxCHECK_MSG(pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
2074  _T("invalid position in wxToolBar::InsertSeparator()"));
2075 
2076  wxToolBarToolBase *tool = CreateTool(
2077  wxID_SEPARATOR, wxEmptyString, wxNullBitmap, wxNullBitmap,
2078  wxITEM_SEPARATOR, (wxObject *)NULL, wxEmptyString, wxEmptyString);
2079 
2080  if (!tool || !DoInsertTool(pos, tool)) {
2081  delete tool;
2082 
2083  return NULL;
2084  }
2085 
2086  m_tools.Insert(pos, tool);
2087  m_nShowTools++;
2088 
2089  return tool;
2090 }
2091 
2092 wxToolBarToolBase *ocpnToolBarSimple::RemoveTool(int id) {
2093  size_t pos = 0;
2094  wxToolBarToolsList::compatibility_iterator node;
2095  for (node = m_tools.GetFirst(); node; node = node->GetNext()) {
2096  if (node->GetData()->GetId() == id) break;
2097 
2098  pos++;
2099  }
2100 
2101  if (!node) {
2102  // don't give any error messages - sometimes we might call RemoveTool()
2103  // without knowing whether the tool is or not in the toolbar
2104  return (wxToolBarToolBase *)NULL;
2105  }
2106 
2107  wxToolBarToolBase *tool = node->GetData();
2108  if (!DoDeleteTool(pos, tool)) {
2109  return (wxToolBarToolBase *)NULL;
2110  }
2111 
2112  m_tools.Erase(node);
2113 
2114  return tool;
2115 }
2116 
2117 wxControl *ocpnToolBarSimple::FindControl(int id) {
2118  for (wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
2119  node; node = node->GetNext()) {
2120  const wxToolBarToolBase *const tool = node->GetData();
2121  if (tool->IsControl()) {
2122  wxControl *const control = tool->GetControl();
2123 
2124  if (!control) {
2125  wxFAIL_MSG(_T("NULL control in toolbar?"));
2126  } else if (control->GetId() == id) {
2127  // found
2128  return control;
2129  }
2130  }
2131  }
2132 
2133  return NULL;
2134 }
2135 
2136 wxToolBarToolBase *ocpnToolBarSimple::FindById(int id) const {
2137  wxToolBarToolBase *tool = (wxToolBarToolBase *)NULL;
2138 
2139  for (wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
2140  node; node = node->GetNext()) {
2141  tool = node->GetData();
2142  if (tool->GetId() == id) {
2143  // found
2144  break;
2145  }
2146 
2147  tool = NULL;
2148  }
2149 
2150  return tool;
2151 }
2152 
2153 // ----------------------------------------------------------------------------
2154 // event processing
2155 // ----------------------------------------------------------------------------
2156 
2157 // Only allow toggle if returns true
2158 
2159 bool ocpnToolBarSimple::OnLeftClick(int id, bool toggleDown) {
2160  wxCommandEvent event(wxEVT_COMMAND_TOOL_CLICKED, id);
2161  //event.SetEventObject(this);
2162 
2163  // we use SetInt() to make wxCommandEvent::IsChecked() return toggleDown
2164  event.SetInt((int)toggleDown);
2165 
2166  // and SetExtraLong() for backwards compatibility
2167  event.SetExtraLong((long)toggleDown);
2168 
2169  gFrame->GetEventHandler()->AddPendingEvent(event);
2170 
2171  return true;
2172 }
2173 
2174 // Call when right button down.
2175 void ocpnToolBarSimple::OnRightClick(int id, long WXUNUSED(x),
2176  long WXUNUSED(y)) {
2177  HideTooltip();
2178 
2179  if (m_parentContainer) {
2180  if (m_parentContainer->m_FloatingToolbarConfigMenu) {
2181  ToolbarChoicesDialog *dlg =
2182  new ToolbarChoicesDialog(NULL, m_parentContainer, -1, _T("OpenCPN"),
2183  wxDefaultPosition, wxSize(100, 100));
2184  int rc = dlg->ShowModal();
2185  delete dlg;
2186 
2187  if (rc == wxID_OK) {
2188  wxCommandEvent event(wxEVT_COMMAND_TOOL_RCLICKED, id);
2189  event.SetEventObject(this);
2190  event.SetInt(id);
2191 
2192  gFrame->GetEventHandler()->AddPendingEvent(event);
2193  }
2194  }
2195  }
2196 }
2197 
2198 
2199 void ocpnToolBarSimple::DoPluginToolUp() {
2200  // Look for PlugIn tools
2201  // If found, make the callback.
2202  if (!g_pi_manager) return;
2203 
2204  ArrayOfPlugInToolbarTools tool_array =
2205  g_pi_manager->GetPluginToolbarToolArray();
2206  for (unsigned int i = 0; i < tool_array.GetCount(); i++) {
2207  PlugInToolbarToolContainer *pttc = tool_array[i];
2208  if (m_last_plugin_down_id == pttc->id) {
2209  opencpn_plugin_113 *ppi =
2210  dynamic_cast<opencpn_plugin_113 *>(pttc->m_pplugin);
2211  if (ppi) ppi->OnToolbarToolUpCallback(pttc->id);
2212  }
2213  }
2214 
2215  m_last_plugin_down_id = -1;
2216 }
2217 
2218 void ocpnToolBarSimple::SetToolNormalBitmapEx(wxToolBarToolBase *tool,
2219  const wxString &iconName) {
2220  if (tool) {
2221  ocpnToolBarTool *otool = (ocpnToolBarTool *)tool;
2222  if (otool) {
2223  ocpnStyle::Style *style = g_StyleManager->GetCurrentStyle();
2224 
2225  wxBitmap bmp = style->GetToolIcon(iconName, TOOLICON_NORMAL, false,
2226  otool->m_width, otool->m_height);
2227  tool->SetNormalBitmap(bmp);
2228  otool->SetIconName(iconName);
2229  }
2230  }
2231 }
2232 
2233 void ocpnToolBarSimple::SetToolNormalBitmapSVG(wxToolBarToolBase *tool,
2234  wxString fileSVG) {
2235  if (tool) {
2236  ocpnToolBarTool *otool = (ocpnToolBarTool *)tool;
2237  if (otool) {
2238  otool->pluginNormalIconSVG = fileSVG;
2239  }
2240  }
2241 }
2242 
2243 void ocpnToolBarSimple::SetToolBitmaps(int id, wxBitmap *bmp,
2244  wxBitmap *bmpRollover) {
2245  ocpnToolBarTool *tool = (ocpnToolBarTool *)FindById(id);
2246  if (tool) {
2247  if (tool->isPluginTool) {
2248  if (bmp->GetWidth() != tool->GetWidth()) {
2249  if (bmp->IsOk()) {
2250  wxImage ibmp = bmp->ConvertToImage();
2251  ibmp.Rescale(tool->GetWidth(), tool->GetHeight(),
2252  wxIMAGE_QUALITY_HIGH);
2253  wxBitmap sbmp = wxBitmap(ibmp);
2254  tool->pluginNormalIcon = sbmp;
2255  }
2256  } else {
2257  tool->pluginNormalIcon = *bmp;
2258  }
2259 
2260  if (bmpRollover->GetWidth() != tool->GetWidth()) {
2261  if (bmpRollover->IsOk()) {
2262  wxImage ibmp = bmpRollover->ConvertToImage();
2263  ibmp.Rescale(tool->GetWidth(), tool->GetHeight(),
2264  wxIMAGE_QUALITY_HIGH);
2265  wxBitmap sbmp = wxBitmap(ibmp);
2266  tool->pluginRolloverIcon = sbmp;
2267  }
2268  } else {
2269  tool->pluginRolloverIcon = *bmpRollover;
2270  }
2271  tool->bitmapOK = false;
2272 
2273  } else {
2274  tool->SetNormalBitmap(*bmp);
2275  tool->bitmapOK = true;
2276  }
2277  InvalidateBitmaps();
2278  }
2279 }
2280 
2281 void ocpnToolBarSimple::SetToolBitmapsSVG(int id, wxString fileSVGNormal,
2282  wxString fileSVGRollover,
2283  wxString fileSVGToggled) {
2284  ocpnToolBarTool *tool = (ocpnToolBarTool *)FindById(id);
2285  if (tool) {
2286  tool->pluginNormalIconSVG = fileSVGNormal;
2287  tool->pluginRolloverIconSVG = fileSVGRollover;
2288  tool->pluginToggledIconSVG = fileSVGToggled;
2289  tool->bitmapOK = false;
2290  InvalidateBitmaps();
2291  }
2292 }
2293 
2294 //-------------------------------------------------------------------------------------
2295 
2296 ToolbarMOBDialog::ToolbarMOBDialog(wxWindow *parent)
2297  : wxDialog(parent, wxID_ANY, _("OpenCPN Alert"), wxDefaultPosition,
2298  wxSize(250, 230)) {
2299  wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
2300 
2301  wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
2302  topSizer->Add(sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
2303 
2304  choices.push_back(
2305  new wxRadioButton(this, 0, _("No, I don't want to hide it."),
2306  wxDefaultPosition, wxDefaultSize, wxRB_GROUP));
2307 
2308  choices.push_back(new wxRadioButton(
2309  this, 1, _("No, and permanently remove the option to hide it."),
2310  wxDefaultPosition));
2311 
2312  choices.push_back(
2313  new wxRadioButton(this, 2, _("Yes, hide it."), wxDefaultPosition));
2314 
2315  wxStdDialogButtonSizer *buttonSizer =
2316  CreateStdDialogButtonSizer(wxOK | wxCANCEL);
2317 
2318  wxStaticText *textCtrl =
2319  new wxStaticText(this, wxID_ANY,
2320  _("The Man Over Board button could be an important "
2321  "safety feature.\nAre you sure you want to hide it?"));
2322 
2323  sizer->Add(textCtrl, 0, wxEXPAND | wxALL, 5);
2324  sizer->Add(choices[0], 0, wxEXPAND | wxALL, 5);
2325  sizer->Add(choices[1], 0, wxEXPAND | wxALL, 5);
2326  sizer->Add(choices[2], 0, wxEXPAND | wxALL, 5);
2327  sizer->Add(buttonSizer, 0, wxEXPAND | wxTOP, 5);
2328 
2329  topSizer->SetSizeHints(this);
2330  SetSizer(topSizer);
2331 }
2332 
2333 int ToolbarMOBDialog::GetSelection() {
2334  for (unsigned int i = 0; i < choices.size(); i++) {
2335  if (choices[i]->GetValue()) return choices[i]->GetId();
2336  }
2337  return 0;
2338 }
2339 
2340 IMPLEMENT_DYNAMIC_CLASS(ToolbarChoicesDialog, wxDialog)
2344 BEGIN_EVENT_TABLE(ToolbarChoicesDialog, wxDialog)
2345 END_EVENT_TABLE()
2346 
2347 
2352 
2354  wxWindowID id,
2355  const wxString &caption,
2356  const wxPoint &pos,
2357  const wxSize &size, long style) {
2358  long wstyle = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER;
2359  wxDialog::Create(parent, id, caption, pos, size, wstyle);
2360 
2361  m_configMenu = NULL;
2362  m_ToolbarDialogAncestor = sponsor;
2363 
2364  if (m_ToolbarDialogAncestor)
2365  m_configMenu = m_ToolbarDialogAncestor->m_FloatingToolbarConfigMenu;
2366 
2367  CreateControls();
2368  GetSizer()->Fit(this);
2369 
2370  RecalculateSize();
2371 }
2372 
2373 ToolbarChoicesDialog::~ToolbarChoicesDialog() {}
2374 
2380  wxBoxSizer *itemBoxSizer1 = new wxBoxSizer(wxVERTICAL);
2381  SetSizer(itemBoxSizer1);
2382 
2383  wxScrolledWindow *itemDialog1 = new wxScrolledWindow(
2384  this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1), wxHSCROLL | wxVSCROLL);
2385  itemDialog1->SetScrollRate(2, 2);
2386 
2387 #ifdef __OCPN__ANDROID__
2388 
2389  // Set Dialog Font by custom crafted Qt Stylesheet.
2390  wxFont *qFont = GetOCPNScaledFont(_("Dialog"));
2391 
2392  wxString wqs = getFontQtStylesheet(qFont);
2393  wxCharBuffer sbuf = wqs.ToUTF8();
2394  QString qsb = QString(sbuf.data());
2395 
2396  QString qsbq = getQtStyleSheet(); // basic scrollbars, etc
2397 
2398  this->GetHandle()->setStyleSheet(qsb + qsbq); // Concatenated style sheets
2399 
2400 #endif
2401  itemBoxSizer1->Add(itemDialog1, 2, wxEXPAND | wxALL, 0);
2402 
2403  wxBoxSizer *itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
2404  itemDialog1->SetSizer(itemBoxSizer2);
2405 
2406  wxStaticBox *itemStaticBoxSizer3Static =
2407  new wxStaticBox(itemDialog1, wxID_ANY, _("Choose Toolbar Icons"));
2408  wxStaticBoxSizer *itemStaticBoxSizer3 =
2409  new wxStaticBoxSizer(itemStaticBoxSizer3Static, wxVERTICAL);
2410  itemBoxSizer2->Add(itemStaticBoxSizer3, 0, wxEXPAND | wxALL, 5);
2411 
2412  int nitems = 0;
2413  int max_width = -1;
2414  if (m_configMenu) {
2415  nitems = m_configMenu->GetMenuItemCount();
2416 
2417  cboxes.clear();
2418  for (int i = 0; i < nitems; i++) {
2419  if (i + ID_ZOOMIN == ID_MOB && g_bPermanentMOBIcon) continue;
2420  wxMenuItem *item = m_configMenu->FindItemByPosition(i);
2421 
2422  wxString label = item->GetItemLabel();
2423  int l = label.Len();
2424  max_width = wxMax(max_width, l);
2425 
2426  wxString windowName = _T("");
2427  if (item->GetId() == ID_MOB + 100) windowName = _T("MOBCheck");
2428 
2429  wxCheckBox *cb =
2430  new wxCheckBox(itemDialog1, -1, label, wxDefaultPosition,
2431  wxDefaultSize, 0, wxDefaultValidator, windowName);
2432  // wxCheckBox *cb = new wxCheckBox(itemDialog1, -1, label);
2433  itemStaticBoxSizer3->Add(cb, 0, wxALL | wxEXPAND, 2);
2434  cb->SetValue(item->IsChecked());
2435 
2436  cboxes.push_back(cb);
2437  }
2438  }
2439 
2440  itemBoxSizer1->SetMinSize((max_width + 20) * GetCharWidth(),
2441  (nitems + 4) * GetCharHeight() * 2);
2442 
2443  wxBoxSizer *itemBoxSizerBottom = new wxBoxSizer(wxHORIZONTAL);
2444  itemBoxSizer1->Add(itemBoxSizerBottom, 0, wxALL | wxEXPAND, 5);
2445 
2446  wxBoxSizer *itemBoxSizerAux = new wxBoxSizer(wxHORIZONTAL);
2447  itemBoxSizerBottom->Add(itemBoxSizerAux, 1, wxALL, 3);
2448 
2449  wxBoxSizer *itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL);
2450  itemBoxSizerBottom->Add(itemBoxSizer16, 0, wxALL, 3);
2451 
2452  m_CancelButton =
2453  new wxButton(this, -1, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0);
2454  itemBoxSizer16->Add(m_CancelButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
2455 
2456  m_OKButton =
2457  new wxButton(this, -1, _("OK"), wxDefaultPosition, wxDefaultSize, 0);
2458  itemBoxSizer16->Add(m_OKButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
2459  m_OKButton->SetDefault();
2460 
2461  m_CancelButton->Connect(
2462  wxEVT_COMMAND_BUTTON_CLICKED,
2463  wxCommandEventHandler(ToolbarChoicesDialog::OnCancelClick), NULL, this);
2464  m_OKButton->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2465  wxCommandEventHandler(ToolbarChoicesDialog::OnOkClick),
2466  NULL, this);
2467 
2468  SetColorScheme((ColorScheme)0);
2469 }
2470 
2471 void ToolbarChoicesDialog::SetColorScheme(ColorScheme cs) { DimeControl(this); }
2472 
2473 void ToolbarChoicesDialog::OnCancelClick(wxCommandEvent &event) {
2474  EndModal(wxID_CANCEL);
2475 }
2476 
2477 void ToolbarChoicesDialog::OnOkClick(wxCommandEvent &event) {
2478  unsigned int ncheck = 0;
2479 
2480  wxString toolbarConfigSave = m_ToolbarDialogAncestor->GetToolConfigString();
2481  wxString new_toolbarConfig = toolbarConfigSave;
2482 
2483  for (unsigned int i = 0; i < cboxes.size(); i++) {
2484  wxCheckBox *cb = cboxes[i];
2485  wxString cbName = cb->GetName(); // Special flag passed into checkbox ctor
2486  // to find the "MOB" item
2487  if (cbName.IsSameAs(_T("MOBCheck")) && !cb->IsChecked()) {
2488  // Ask if really want to disable MOB button
2489  ToolbarMOBDialog mdlg(this);
2490  int dialog_ret = mdlg.ShowModal();
2491  int answer = mdlg.GetSelection();
2492  if (dialog_ret == wxID_OK) {
2493  if (answer == 1) {
2494  g_bPermanentMOBIcon = true;
2495  cb->SetValue(true);
2496  } else if (answer == 0) {
2497  cb->SetValue(true);
2498  }
2499  } else { // wxID_CANCEL
2500  new_toolbarConfig = toolbarConfigSave;
2501  return;
2502  }
2503  }
2504  if (m_configMenu) {
2505  wxMenuItem *item = m_configMenu->FindItemByPosition(i);
2506  if (new_toolbarConfig.Len() > i) {
2507  new_toolbarConfig.SetChar(i, cb->IsChecked() ? _T('X') : _T('.'));
2508  } else {
2509  new_toolbarConfig.Append(cb->IsChecked() ? _T('X') : _T('.'));
2510  }
2511  item->Check(cb->IsChecked());
2512  if (cb->IsChecked()) ncheck++;
2513  }
2514  }
2515 
2516 #if 0
2517  // We always must have one Tool enabled. Make it the Options tool....
2518  if( 0 == ncheck){
2519  new_toolbarConfig.SetChar( ID_SETTINGS -ID_ZOOMIN , _T('X') );
2520 
2521  int idOffset = ID_PLUGIN_BASE - ID_ZOOMIN + 100;
2522 
2523  if(m_configMenu){
2524  wxMenuItem *item = m_configMenu->FindItem(ID_SETTINGS + idOffset);
2525  if(item)
2526  item->Check( true );
2527  }
2528  }
2529 #endif
2530  m_ToolbarDialogAncestor->SetToolConfigString(new_toolbarConfig);
2531 
2532  EndModal(wxID_OK);
2533 }
2534 
2535 void ToolbarChoicesDialog::RecalculateSize(void) {
2536  wxSize esize = GetSize();
2537 
2538  if (GetParent()) {
2539  wxSize dsize = GetParent()->GetClientSize();
2540  esize.y = wxMin(esize.y, dsize.y - (4 * GetCharHeight()));
2541  esize.x = wxMin(esize.x, dsize.x - (2 * GetCharHeight()));
2542  SetSize(esize);
2543  Centre();
2544 
2545  } else {
2546  wxSize fsize = g_Platform->getDisplaySize();
2547  fsize.y = wxMin(esize.y, fsize.y - (4 * GetCharHeight()));
2548  fsize.x = wxMin(esize.x, fsize.x - (2 * GetCharHeight()));
2549  SetSize(fsize);
2550  CentreOnScreen();
2551 #ifdef __OCPN__ANDROID__
2552  Move(GetPosition().x, 10);
2553 #endif
2554  }
2555 }
Global state for AIS decoder.
ToolbarChoicesDialog()
Constructors.
Definition: toolbar.cpp:2351
Definition: ocpndc.h:58
General purpose GUI support.