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