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