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