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 case GLOBAL_COLOR_SCHEME_DAY_HICON:
748 ptool_bmp = pttc->bitmap_day;
749 ;
750 break;
751 case GLOBAL_COLOR_SCHEME_DUSK:
752 case GLOBAL_COLOR_SCHEME_NIGHT_HICON:
753 ptool_bmp = pttc->bitmap_dusk;
754 break;
755 case GLOBAL_COLOR_SCHEME_NIGHT:
756 ptool_bmp = pttc->bitmap_night;
757 break;
758 default:
759 ptool_bmp = pttc->bitmap_day;
760 ;
761 break;
762 }
763
764 wxToolBarToolBase *tool =
765 tb->AddTool(pttc->id, wxString(pttc->label), *(ptool_bmp),
766 wxString(pttc->shortHelp), pttc->kind);
767
768 tb->SetToolBitmapsSVG(pttc->id, pttc->pluginNormalIconSVG,
769 pttc->pluginRolloverIconSVG,
770 pttc->pluginToggledIconSVG);
771
772 bret = true;
773 }
774 }
775
776 // If we added a tool, call again (recursively) to allow for adding
777 // adjacent tools
778 if (bret)
779 while (CheckAndAddPlugInTool(tb)) { /* nothing to do */
780 }
781
782 return bret;
783}
784
785void ocpnFloatingToolbarDialog::EnableRolloverBitmaps(bool bEnable) {
786 m_enableRolloverBitmaps = bEnable;
787 if (m_ptoolbar) m_ptoolbar->EnableRolloverBitmaps(bEnable);
788}
789
790// ----------------------------------------------------------------------------
791
792// ============================================================================
793// implementation
794// ============================================================================
795// ----------------------------------------------------------------------------
796BEGIN_EVENT_TABLE(ocpnToolBarSimple, wxEvtHandler)
797EVT_TIMER(TOOLTIPON_TIMER, ocpnToolBarSimple::OnToolTipTimerEvent)
798EVT_TIMER(TOOLTIPOFF_TIMER, ocpnToolBarSimple::OnToolTipOffTimerEvent)
799END_EVENT_TABLE()
800
801// ----------------------------------------------------------------------------
802// tool bar tools creation
803// ----------------------------------------------------------------------------
804
805wxToolBarToolBase *ocpnToolBarSimple::CreateTool(
806 int id, const wxString &label, const wxBitmap &bmpNormal,
807 const wxBitmap &bmpDisabled, wxItemKind kind, wxObject *clientData,
808 const wxString &shortHelp, const wxString &longHelp) {
809 if (m_style->NativeToolIconExists(label)) {
810 return new ocpnToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind,
811 clientData, shortHelp, longHelp);
812 } else {
813 wxString testToolname = g_pi_manager->GetToolOwnerCommonName(id);
814
815 if (testToolname == "") { // Not a PlugIn tool...
816 return new ocpnToolBarTool(this, id, bmpNormal, bmpDisabled, kind,
817 clientData, shortHelp, longHelp);
818 } else {
819 return new ocpnToolBarTool(this, id, label, bmpNormal, bmpDisabled, kind,
820 clientData, shortHelp, longHelp);
821 }
822 }
823}
824
825// ----------------------------------------------------------------------------
826// ocpnToolBarSimple creation
827// ----------------------------------------------------------------------------
828
829void ocpnToolBarSimple::Init() {
830 m_currentRowsOrColumns = 0;
831
832 m_lastX = m_lastY = 0;
833
834 m_maxWidth = m_maxHeight = 0;
835
836 m_pressedTool = m_currentTool = -1;
837
838 m_xPos = m_yPos = wxDefaultCoord;
839
840 m_style = g_StyleManager->GetCurrentStyle();
841
842 m_defaultWidth = 16;
843 m_defaultHeight = 15;
844
845 m_toggle_bg_color = wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE);
846 m_toolOutlineColour.Set("BLACK");
847 m_last_ro_tool = NULL;
848
849 m_btoolbar_is_zooming = false;
850 m_sizefactor = 1.0f;
851
852 m_last_plugin_down_id = -1;
853 m_leftDown = false;
854 m_nShowTools = 0;
855 DisableTooltips();
856#ifndef __ANDROID__
857 EnableTooltips();
858#endif
859 m_tbenableRolloverBitmaps = false;
860}
861
862wxToolBarToolBase *ocpnToolBarSimple::DoAddTool(
863 int id, const wxString &label, const wxBitmap &bitmap,
864 const wxBitmap &bmpDisabled, wxItemKind kind, const wxString &shortHelp,
865 const wxString &longHelp, wxObject *clientData, wxCoord xPos,
866 wxCoord yPos) {
867 // rememeber the position for DoInsertTool()
868 m_xPos = xPos;
869 m_yPos = yPos;
870
871 // InvalidateBestSize();
872 return InsertTool(GetToolsCount(), id, label, bitmap, bmpDisabled, kind,
873 shortHelp, longHelp, clientData);
874}
875
877
878wxToolBarToolBase *ocpnToolBarSimple::AddTool(
879 int toolid, const wxString &label, const wxBitmap &bitmap,
880 const wxBitmap &bmpDisabled, wxItemKind kind, const wxString &shortHelp,
881 const wxString &longHelp, wxObject *data) {
882 // InvalidateBestSize();
883 ocpnToolBarTool *tool = (ocpnToolBarTool *)InsertTool(
884 GetToolsCount(), toolid, label, bitmap, bmpDisabled, kind, shortHelp,
885 longHelp, data);
886 return tool;
887}
888
889wxToolBarToolBase *ocpnToolBarSimple::InsertTool(
890 size_t pos, int id, const wxString &label, const wxBitmap &bitmap,
891 const wxBitmap &bmpDisabled, wxItemKind kind, const wxString &shortHelp,
892 const wxString &longHelp, wxObject *clientData) {
893 wxCHECK_MSG(pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
894 "invalid position in wxToolBar::InsertTool()");
895
896 wxToolBarToolBase *tool = CreateTool(id, label, bitmap, bmpDisabled, kind,
897 clientData, shortHelp, longHelp);
898
899 if (!InsertTool(pos, tool)) {
900 delete tool;
901
902 return NULL;
903 }
904
905 return tool;
906}
907
908wxToolBarToolBase *ocpnToolBarSimple::InsertTool(size_t pos,
909 wxToolBarToolBase *tool) {
910 wxCHECK_MSG(pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
911 "invalid position in wxToolBar::InsertTool()");
912
913 if (!tool || !DoInsertTool(pos, tool)) {
914 return NULL;
915 }
916
917 m_tools.Insert(pos, tool);
918 m_nShowTools++;
919
920 return tool;
921}
922
923bool ocpnToolBarSimple::DoInsertTool(size_t WXUNUSED(pos),
924 wxToolBarToolBase *toolBase) {
925 ocpnToolBarTool *tool = (ocpnToolBarTool *)toolBase;
926
927 // Check if the plugin is inserting same-named tools. Make sure they have
928 // different names, otherwise the style manager cannot differentiate between
929 // them.
930 if (tool->isPluginTool) {
931 for (unsigned int i = 0; i < GetToolsCount(); i++) {
932 if (tool->GetToolname() ==
933 ((ocpnToolBarTool *)m_tools.Item(i)->GetData())->GetToolname()) {
934 tool->toolname << "1";
935 }
936 }
937 }
938
939 tool->m_x = m_xPos;
940 if (tool->m_x == wxDefaultCoord) tool->m_x = m_style->GetLeftMargin();
941
942 tool->m_y = m_yPos;
943 if (tool->m_y == wxDefaultCoord) tool->m_y = m_style->GetTopMargin();
944
945 if (tool->IsButton()) {
946 tool->SetSize(GetToolSize());
947
948 // Calculate reasonable max size in case Layout() not called
949 if ((tool->m_x + tool->GetNormalBitmap().GetWidth() +
950 m_style->GetLeftMargin()) > m_maxWidth)
951 m_maxWidth =
952 (wxCoord)((tool->m_x + tool->GetWidth() + m_style->GetLeftMargin()));
953
954 if ((tool->m_y + tool->GetNormalBitmap().GetHeight() +
955 m_style->GetTopMargin()) > m_maxHeight)
956 m_maxHeight =
957 (wxCoord)((tool->m_y + tool->GetHeight() + m_style->GetTopMargin()));
958 }
959
960 else if (tool->IsControl()) {
961 tool->SetSize(tool->GetControl()->GetSize());
962 }
963
964 tool->b_hilite = false;
965
966 return true;
967}
968
969bool ocpnToolBarSimple::DoDeleteTool(size_t WXUNUSED(pos),
970 wxToolBarToolBase *tool) {
971 // VZ: didn't test whether it works, but why not...
972 tool->Detach();
973
974 if (m_last_ro_tool == tool) m_last_ro_tool = NULL;
975
976 // Refresh(false);
977
978 return true;
979}
980
981bool ocpnToolBarSimple::Create(ocpnFloatingToolbarDialog *parent, wxWindowID id,
982 const wxPoint &pos, const wxSize &size,
983 long style, int orient) {
984 m_parentContainer = parent;
985 m_orient = orient;
986
987 if (IsVertical()) {
988 m_lastX = 7;
989 m_lastY = 3;
990
991 m_maxRows = 32000; // a lot
992 m_maxCols = 1;
993 } else {
994 m_lastX = 3;
995 m_lastY = 7;
996
997 m_maxRows = 1;
998 m_maxCols = 32000; // a lot
999 }
1000
1001 // SetCursor(*wxSTANDARD_CURSOR);
1002
1003 m_tooltip_timer.SetOwner(this, TOOLTIPON_TIMER);
1004 m_tooltipoff_timer.SetOwner(this, TOOLTIPOFF_TIMER);
1005 m_tooltip_off = 3000;
1006
1007 m_tbenableRolloverBitmaps = false;
1008
1009 return true;
1010}
1011
1012ocpnToolBarSimple::~ocpnToolBarSimple() {}
1013
1014void ocpnToolBarSimple::EnableTooltips() {
1015#ifndef __ANDROID__
1016 m_btooltip_show = true;
1017#endif
1018}
1019
1020bool ocpnToolBarSimple::DisableTooltips() {
1021#ifndef __ANDROID__
1022 bool ret = ocpnToolBarSimple::m_btooltip_show;
1023 ocpnToolBarSimple::m_btooltip_show = false;
1024 return ret;
1025#else
1026 return true;
1027#endif
1028}
1029
1030void ocpnToolBarSimple::KillTooltip() {
1031 DisableTooltips();
1032
1034 m_tooltip_timer.Stop();
1035
1036 wxTheApp->GetTopWindow()->Raise();
1037 top_frame::Get()->GetAbstractFocusCanvas()->TriggerDeferredFocus();
1038}
1039
1040void ocpnToolBarSimple::HideTooltip() {
1041#ifndef __ANDROID__
1043#endif
1044}
1045
1046void ocpnToolBarSimple::SetColorScheme(ColorScheme cs) {
1047#ifndef __ANDROID__
1049#endif
1050 m_toolOutlineColour = GetGlobalColor("UIBDR");
1051
1052 m_currentColorScheme = cs;
1053}
1054
1055bool ocpnToolBarSimple::Realize() {
1056 if (IsVertical())
1057 m_style->SetOrientation(wxTB_VERTICAL);
1058 else
1059 m_style->SetOrientation(wxTB_HORIZONTAL);
1060
1061 wxSize toolSize = wxSize(-1, -1);
1062 int separatorSize = m_style->GetToolSeparation() * m_sizefactor;
1063 int topMargin = m_style->GetTopMargin() * m_sizefactor;
1064 int leftMargin = m_style->GetLeftMargin() * m_sizefactor;
1065
1066 m_currentRowsOrColumns = 0;
1067 m_LineCount = 1;
1068 m_lastX = leftMargin;
1069 m_lastY = topMargin;
1070 m_maxWidth = 0;
1071 m_maxHeight = 0;
1072
1073 ocpnToolBarTool *lastTool = NULL;
1074 bool firstNode = true;
1075 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1076
1077 int iNode = 0;
1078
1079 while (node) {
1080 if (iNode >= m_nShowTools) break;
1081
1082 ocpnToolBarTool *tool = (ocpnToolBarTool *)node->GetData();
1083
1084 // Set the tool size to be the size of the first non-separator tool, usually
1085 // the first one
1086 if (toolSize.x == -1) {
1087 if (!tool->IsSeparator()) {
1088 toolSize.x = tool->m_width;
1089 toolSize.y = tool->m_height;
1090 }
1091 }
1092
1093 tool->firstInLine = firstNode;
1094 tool->lastInLine = false;
1095 firstNode = false;
1096
1097 tool->last_rect.width = 0; // mark it invalid
1098
1099 if (tool->IsSeparator()) {
1100 // if (GetWindowStyleFlag() & wxTB_HORIZONTAL) {
1101 // if (m_currentRowsOrColumns >= m_maxCols)
1102 // m_lastY += separatorSize;
1103 // else
1104 // m_lastX += separatorSize;
1105 //}
1106 // else
1107 {
1108 if (m_currentRowsOrColumns >= m_maxRows)
1109 m_lastX += separatorSize;
1110 else
1111 m_lastY += separatorSize;
1112 }
1113 } else if (tool->IsButton()) {
1114 if (!IsVertical()) {
1115 if (m_currentRowsOrColumns >= m_maxCols) {
1116 tool->firstInLine = true;
1117 if (lastTool && m_LineCount > 1) lastTool->lastInLine = true;
1118 m_LineCount++;
1119 m_currentRowsOrColumns = 0;
1120 m_lastX = leftMargin;
1121 m_lastY += toolSize.y + topMargin;
1122 }
1123 tool->m_x = (wxCoord)m_lastX;
1124 tool->m_y = (wxCoord)m_lastY;
1125
1126 tool->trect = wxRect(tool->m_x, tool->m_y, toolSize.x, toolSize.y);
1127 tool->trect.Inflate(separatorSize / 2, topMargin);
1128
1129 m_lastX += toolSize.x + separatorSize;
1130 } else {
1131 if (m_currentRowsOrColumns >= m_maxRows) {
1132 tool->firstInLine = true;
1133 if (lastTool) lastTool->lastInLine = true;
1134 m_LineCount++;
1135 m_currentRowsOrColumns = 0;
1136 m_lastX += toolSize.x + leftMargin;
1137 m_lastY = topMargin;
1138 }
1139 tool->m_x = (wxCoord)m_lastX;
1140 tool->m_y = (wxCoord)m_lastY;
1141
1142 tool->trect = wxRect(tool->m_x, tool->m_y, toolSize.x, toolSize.y);
1143 tool->trect.Inflate((separatorSize / 2), topMargin);
1144
1145 m_lastY += toolSize.y + separatorSize;
1146 }
1147 m_currentRowsOrColumns++;
1148 }
1149 // else
1150 // if (tool->IsControl()) {
1151 // tool->m_x = (wxCoord)(m_lastX);
1152 // tool->m_y = (wxCoord)(m_lastY - (topMargin / 2));
1153
1154 // tool->trect =
1155 // wxRect(tool->m_x, tool->m_y, tool->GetWidth(), tool->GetHeight());
1156 // tool->trect.Inflate(separatorSize / 2, topMargin);
1157
1158 // wxSize s = tool->GetControl()->GetSize();
1159 // m_lastX += s.x + separatorSize;
1160 //}
1161
1162 if (m_lastX > m_maxWidth) m_maxWidth = m_lastX;
1163 if (m_lastY > m_maxHeight) m_maxHeight = m_lastY;
1164
1165 lastTool = tool;
1166 node = node->GetNext();
1167 iNode++;
1168 }
1169 if (lastTool && (m_LineCount > 1 || IsVertical()))
1170 lastTool->lastInLine = true;
1171
1172 if (!IsVertical()) {
1173 m_maxHeight += toolSize.y;
1174 m_maxHeight += m_style->GetBottomMargin();
1175 } else {
1176 m_maxWidth += toolSize.x;
1177 m_maxWidth += m_style->GetRightMargin() * m_sizefactor;
1178 }
1179
1180 m_bitmap = wxNullBitmap;
1181
1182 return true;
1183}
1184
1185wxBitmap &ocpnToolBarSimple::CreateBitmap(double display_scale) {
1186 if (m_bitmap.IsOk()) return m_bitmap;
1187
1188 // Make the bitmap
1189 int width = m_maxWidth;
1190 int height = m_maxHeight;
1191
1192 wxMemoryDC mdc;
1193 wxBitmap bm(width, height);
1194 mdc.SelectObject(bm);
1195 mdc.SetBackground(wxBrush(GetBackgroundColour()));
1196 mdc.Clear();
1197
1198 // In a loop, draw the tools
1199 for (wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1200 node; node = node->GetNext()) {
1201 wxToolBarToolBase *tool = node->GetData();
1202 ocpnToolBarTool *tools = (ocpnToolBarTool *)tool;
1203 wxRect toolRect = tools->trect;
1204 CreateToolBitmap(tool);
1205
1206 if (tools->m_activeBitmap.IsOk()) {
1207 mdc.DrawBitmap(tools->m_activeBitmap, tools->m_x, tools->m_y, false);
1208 }
1209 int yyp = 5;
1210 }
1211
1212 mdc.SelectObject(wxNullBitmap);
1213
1214 m_bitmap = bm;
1215 return m_bitmap;
1216}
1217
1218void ocpnToolBarSimple::OnToolTipTimerEvent(wxTimerEvent &event) {
1219 if (!top_frame::Get()) // In case gFrame was already destroyed, but the
1220 // toolbar still exists (Which should not happen,
1221 // ever.)
1222 return;
1223
1224 if (m_btooltip_show /*&& IsShown()*/) {
1225 if (m_last_ro_tool) {
1226 wxString s = m_last_ro_tool->GetShortHelp();
1227
1228 if (s.Len()) {
1229 // Calculate tooltip position relative to the tool
1230 wxPoint pos_in_toolbar(m_last_ro_tool->m_x, m_last_ro_tool->m_y);
1231 pos_in_toolbar.x += m_last_ro_tool->m_width + 2;
1232
1233 wxPoint screenPosition =
1234 top_frame::Get()->GetAbstractPrimaryCanvas()->ClientToScreen(
1235 pos_in_toolbar);
1236
1237 // Show tooltip using new system
1239 top_frame::Get()->GetAbstractPrimaryCanvas()->GetWindow(), s,
1240 screenPosition, m_last_ro_tool->m_btooltip_hiviz);
1241
1242#ifndef __WXOSX__
1243 wxTheApp->GetTopWindow()->Raise();
1244#endif
1245
1246#ifndef __ANDROID__
1247 if (g_btouch) m_tooltipoff_timer.Start(m_tooltip_off, wxTIMER_ONE_SHOT);
1248#endif
1249 }
1250 }
1251 }
1252}
1253
1254void ocpnToolBarSimple::OnToolTipOffTimerEvent(wxTimerEvent &event) {
1255 HideTooltip();
1256}
1257
1258bool ocpnToolBarSimple::OnMouseEvent(wxMouseEvent &event, wxPoint &position) {
1259 wxCoord x, y;
1260 event.GetPosition(&x, &y);
1261
1262 // in the toolbar?
1263 wxRect r = wxRect(position, wxSize(m_maxWidth, m_maxHeight));
1264 if (!r.Contains(x, y)) {
1265 HideTooltip();
1266 return false;
1267 }
1268
1269 m_parentContainer->RefreshFadeTimer();
1270
1271 ocpnToolBarTool *tool =
1272 (ocpnToolBarTool *)FindToolForPosition(x - position.x, y - position.y);
1273 if (tool == NULL) {
1274 m_tooltipoff_timer.Start(m_tooltip_off, wxTIMER_ONE_SHOT);
1275 return true;
1276 } else
1277 m_tooltipoff_timer.Stop();
1278
1279 // tooltips
1280 if (tool && tool->IsButton() /*&& IsShown()*/) {
1281 if (m_btooltip_show) {
1282 if (tool != m_last_ro_tool) {
1284 }
1285
1286#ifndef __ANDROID__
1287 if (!TooltipManager::Get().IsShown()) {
1288 if (!m_tooltip_timer.IsRunning()) {
1289 m_tooltip_timer.Start(m_one_shot, wxTIMER_ONE_SHOT);
1290 }
1291 }
1292#endif
1293 }
1294 }
1295
1296 m_last_ro_tool = tool;
1297
1298 // Left button pressed.
1299 if (event.LeftIsDown()) m_leftDown = true; // trigger on
1300
1301 if (event.LeftDown() && tool->IsEnabled()) {
1302 if (tool->CanBeToggled()) {
1303 tool->Toggle();
1304 tool->bitmapOK = false;
1305 SetDirty(true);
1306 m_bitmap = wxNullBitmap;
1307 }
1308
1309 // Look for PlugIn tools
1310 // If found, make the callback.
1311 if (g_pi_manager) {
1312 ArrayOfPlugInToolbarTools tool_array =
1313 g_pi_manager->GetPluginToolbarToolArray();
1314 for (unsigned int i = 0; i < tool_array.GetCount(); i++) {
1315 PlugInToolbarToolContainer *pttc = tool_array[i];
1316 if (tool->GetId() == pttc->id) {
1317 opencpn_plugin_113 *ppi =
1318 dynamic_cast<opencpn_plugin_113 *>(pttc->m_pplugin);
1319 if (ppi) {
1320 ppi->OnToolbarToolDownCallback(pttc->id);
1321 m_last_plugin_down_id = pttc->id;
1322 }
1323 }
1324 }
1325 }
1326 } else if (event.RightDown()) {
1327 OnRightClick(tool->GetId(), x, y);
1328 }
1329
1330 // Left Button Released. Only this action confirms selection.
1331 // If the button is enabled and it is not a toggle tool and it is
1332 // in the pressed state, then raise the button and call OnLeftClick.
1333 //
1334 // Unfortunately, some touch screen drivers do not send "LeftIsDown" events.
1335 // Nor do they report "LeftIsDown" in any state.
1336 // c.f rPI "official" 7" panel.
1337
1338 // So, for this logic, assume in touch mode that the m_leftDown flag may not
1339 // be set, and process the left-up event anyway.
1340 if (event.LeftUp() && tool->IsEnabled() && (m_leftDown || g_btouch)) {
1341 // Pass the OnLeftClick event to tool
1342 if (!OnLeftClick(tool->GetId(), tool->IsToggled()) &&
1343 tool->CanBeToggled()) {
1344 // If it was a toggle, and OnLeftClick says No Toggle allowed,
1345 // then change it back
1346 tool->Toggle();
1347 tool->bitmapOK = false;
1348 }
1349
1350 DoPluginToolUp();
1351 m_leftDown = false;
1352 return true;
1353 }
1354
1355 return true;
1356}
1357
1358// ----------------------------------------------------------------------------
1359// drawing
1360// ----------------------------------------------------------------------------
1361
1362void ocpnToolBarSimple::CreateToolBitmap(wxToolBarToolBase *toolBase) {
1363 ocpnToolBarTool *tool = (ocpnToolBarTool *)toolBase;
1364
1365 wxBitmap bmp = wxNullBitmap;
1366
1367 bool bNeedClear = !tool->bitmapOK;
1368
1369 if (tool->bitmapOK) {
1370 if (tool->IsEnabled()) {
1371 bmp = tool->GetNormalBitmap();
1372 if (!bmp.IsOk()) {
1373 bmp =
1374 m_style->GetToolIcon(tool->GetToolname(), TOOLICON_NORMAL,
1375 tool->rollover, tool->m_width, tool->m_height);
1376 tool->SetNormalBitmap(bmp);
1377 tool->bitmapOK = true;
1378 }
1379 } else {
1380 bmp = tool->GetDisabledBitmap();
1381 if (!bmp.IsOk()) {
1382 bmp = m_style->GetToolIcon(tool->GetToolname(), TOOLICON_DISABLED,
1383 false, tool->m_width, tool->m_height);
1384 tool->SetDisabledBitmap(bmp);
1385 tool->bitmapOK = true;
1386 }
1387 }
1388 } else {
1389 if (tool->isPluginTool) {
1390 int toggleFlag = tool->IsToggled() ? TOOLICON_TOGGLED : TOOLICON_NORMAL;
1391
1392 // First try getting the icon from an SVG definition.
1393 // If it is not found, try to see if it is available in the style
1394 // If not there, we build a new icon from the style BG and the (default)
1395 // plugin icon.
1396
1397 wxString svgFile = tool->pluginNormalIconSVG;
1398 if (toggleFlag) {
1399 if (tool->pluginToggledIconSVG.Length())
1400 svgFile = tool->pluginToggledIconSVG;
1401 }
1402 if (tool->rollover) {
1403 if (tool->pluginRolloverIconSVG.Length())
1404 svgFile = tool->pluginRolloverIconSVG;
1405 }
1406
1407 if (!svgFile.IsEmpty()) { // try SVG
1408#ifdef ocpnUSE_SVG
1409 bmp = LoadSVG(svgFile, tool->m_width, tool->m_height);
1410 if (bmp.IsOk()) {
1411 bmp = m_style->BuildPluginIcon(bmp, toggleFlag, m_sizefactor);
1412 } else
1413 bmp =
1414 m_style->BuildPluginIcon(tool->pluginNormalIcon, TOOLICON_NORMAL);
1415#endif
1416 }
1417
1418 if (!bmp.IsOk() || bmp.IsNull()) {
1419 if (m_style->NativeToolIconExists(tool->GetToolname())) {
1420 bmp = m_style->GetToolIcon(tool->GetToolname(), toggleFlag,
1421 tool->rollover, tool->m_width,
1422 tool->m_height);
1423 } else {
1424 bmp = wxNullBitmap;
1425 }
1426
1427 if (bmp.IsNull()) { // Tool icon not found in style definition
1428 // bmp = m_style->BuildPluginIcon(tool->pluginNormalIcon, toggleFlag);
1429 bmp = tool->pluginNormalIcon;
1430 if (fabs(m_sizefactor - 1.0) > 0.01) {
1431 if (tool->m_width && tool->m_height) {
1432 wxImage scaled_image = bmp.ConvertToImage();
1433 bmp = wxBitmap(scaled_image.Scale(tool->m_width, tool->m_height,
1434 wxIMAGE_QUALITY_HIGH));
1435 }
1436 }
1437 }
1438 }
1439 tool->SetNormalBitmap(bmp);
1440 tool->bitmapOK = true;
1441 } else { // Not a plugin tool
1442 bmp = tool->GetNormalBitmap();
1443 if (tool->IsEnabled()) {
1444 if (tool->IsToggled()) {
1445 if (!tool->bitmapOK) {
1446 if (m_style->NativeToolIconExists(tool->GetToolname())) {
1447 bmp = m_style->GetToolIcon(tool->GetToolname(), TOOLICON_TOGGLED,
1448 tool->rollover, tool->m_width,
1449 tool->m_height);
1450 tool->SetNormalBitmap(bmp);
1451 }
1452 }
1453 }
1454
1455 else {
1456 if (!tool->bitmapOK) {
1457 if (m_style->NativeToolIconExists(tool->GetToolname())) {
1458 bmp = m_style->GetToolIcon(tool->GetIconName(), TOOLICON_NORMAL,
1459 tool->rollover, tool->m_width,
1460 tool->m_height);
1461 tool->SetNormalBitmap(bmp);
1462 }
1463 }
1464 }
1465
1466 tool->bitmapOK = true;
1467 } else {
1468 bmp = m_style->GetToolIcon(tool->GetToolname(), TOOLICON_DISABLED,
1469 false, tool->m_width, tool->m_height);
1470 tool->SetDisabledBitmap(bmp);
1471 tool->bitmapOK = true;
1472 }
1473 }
1474 }
1475 tool->m_activeBitmap = bmp;
1476}
1477
1478// NB! The current DrawTool code assumes that plugin tools are never disabled
1479// when they are present on the toolbar, since disabled plugins are removed.
1480
1481void ocpnToolBarSimple::DrawTool(wxDC &dc, wxToolBarToolBase *toolBase) {
1482 ocpnToolBarTool *tool = (ocpnToolBarTool *)toolBase;
1483 // PrepareDC(dc);
1484
1485 wxPoint drawAt(tool->m_x, tool->m_y);
1486 wxBitmap bmp = wxNullBitmap;
1487
1488 bool bNeedClear = !tool->bitmapOK;
1489
1490 if (tool->bitmapOK) {
1491 if (tool->IsEnabled()) {
1492 bmp = tool->GetNormalBitmap();
1493 if (!bmp.IsOk()) {
1494 bmp =
1495 m_style->GetToolIcon(tool->GetToolname(), TOOLICON_NORMAL,
1496 tool->rollover, tool->m_width, tool->m_height);
1497 tool->SetNormalBitmap(bmp);
1498 tool->bitmapOK = true;
1499 }
1500 } else {
1501 bmp = tool->GetDisabledBitmap();
1502 if (!bmp.IsOk()) {
1503 bmp = m_style->GetToolIcon(tool->GetToolname(), TOOLICON_DISABLED,
1504 false, tool->m_width, tool->m_height);
1505 tool->SetDisabledBitmap(bmp);
1506 tool->bitmapOK = true;
1507 }
1508 }
1509 } else {
1510 if (tool->isPluginTool) {
1511 int toggleFlag = tool->IsToggled() ? TOOLICON_TOGGLED : TOOLICON_NORMAL;
1512
1513 // First try getting the icon from an SVG definition.
1514 // If it is not found, try to see if it is available in the style
1515 // If not there, we build a new icon from the style BG and the (default)
1516 // plugin icon.
1517
1518 wxString svgFile = tool->pluginNormalIconSVG;
1519 if (toggleFlag) {
1520 if (tool->pluginToggledIconSVG.Length())
1521 svgFile = tool->pluginToggledIconSVG;
1522 }
1523 if (tool->rollover) {
1524 if (tool->pluginRolloverIconSVG.Length())
1525 svgFile = tool->pluginRolloverIconSVG;
1526 }
1527
1528 if (!svgFile.IsEmpty()) { // try SVG
1529#ifdef ocpnUSE_SVG
1530 bmp = LoadSVG(svgFile, tool->m_width, tool->m_height);
1531 if (bmp.IsOk()) {
1532 bmp = m_style->BuildPluginIcon(bmp, toggleFlag, m_sizefactor);
1533 } else
1534 bmp =
1535 m_style->BuildPluginIcon(tool->pluginNormalIcon, TOOLICON_NORMAL);
1536#endif
1537 }
1538
1539 if (!bmp.IsOk() || bmp.IsNull()) {
1540 if (m_style->NativeToolIconExists(tool->GetToolname())) {
1541 bmp = m_style->GetToolIcon(tool->GetToolname(), toggleFlag,
1542 tool->rollover, tool->m_width,
1543 tool->m_height);
1544 } else {
1545 bmp = wxNullBitmap;
1546 }
1547
1548 if (bmp.IsNull()) { // Tool icon not found
1549 if (tool->rollover) {
1550 bmp =
1551 m_style->BuildPluginIcon(tool->pluginRolloverIcon, toggleFlag);
1552 if (!bmp.IsOk()) {
1553 bmp =
1554 m_style->BuildPluginIcon(tool->pluginNormalIcon, toggleFlag);
1555 }
1556 } else {
1557 bmp = m_style->BuildPluginIcon(tool->pluginNormalIcon, toggleFlag);
1558 }
1559 if (fabs(m_sizefactor - 1.0) > 0.01) {
1560 if (tool->m_width && tool->m_height) {
1561 wxImage scaled_image = bmp.ConvertToImage();
1562 bmp = wxBitmap(scaled_image.Scale(tool->m_width, tool->m_height,
1563 wxIMAGE_QUALITY_HIGH));
1564 }
1565 }
1566 }
1567 }
1568 tool->SetNormalBitmap(bmp);
1569 tool->bitmapOK = true;
1570 } else { // Not a plugin tool
1571 bmp = tool->GetNormalBitmap();
1572 if (tool->IsEnabled()) {
1573 if (tool->IsToggled()) {
1574 if (!tool->bitmapOK) {
1575 if (m_style->NativeToolIconExists(tool->GetToolname())) {
1576 bmp = m_style->GetToolIcon(tool->GetToolname(), TOOLICON_TOGGLED,
1577 tool->rollover, tool->m_width,
1578 tool->m_height);
1579 tool->SetNormalBitmap(bmp);
1580 }
1581 }
1582 }
1583
1584 else {
1585 if (!tool->bitmapOK) {
1586 if (m_style->NativeToolIconExists(tool->GetToolname())) {
1587 bmp = m_style->GetToolIcon(tool->GetIconName(), TOOLICON_NORMAL,
1588 tool->rollover, tool->m_width,
1589 tool->m_height);
1590 tool->SetNormalBitmap(bmp);
1591 }
1592 }
1593 }
1594
1595 tool->bitmapOK = true;
1596 } else {
1597 bmp = m_style->GetToolIcon(tool->GetToolname(), TOOLICON_DISABLED,
1598 false, tool->m_width, tool->m_height);
1599 tool->SetDisabledBitmap(bmp);
1600 tool->bitmapOK = true;
1601 }
1602 }
1603 }
1604
1605 if (tool->firstInLine) {
1606 m_style->DrawToolbarLineStart(bmp, m_sizefactor);
1607 }
1608 if (tool->lastInLine) {
1609 m_style->DrawToolbarLineEnd(bmp, m_sizefactor);
1610 }
1611
1612 if (bmp.GetWidth() != m_style->GetToolSize().x ||
1613 bmp.GetHeight() != m_style->GetToolSize().y) {
1614 // drawAt.x -= ( bmp.GetWidth() - m_style->GetToolSize().x ) / 2;
1615 // drawAt.y -= ( bmp.GetHeight() - m_style->GetToolSize().y ) / 2;
1616 }
1617
1618 // Clear the last drawn tool if necessary
1619 if ((tool->last_rect.width &&
1620 (tool->last_rect.x != drawAt.x || tool->last_rect.y != drawAt.y)) ||
1621 bNeedClear) {
1622 wxBrush bb(GetGlobalColor("GREY3"));
1623 dc.SetBrush(bb);
1624 dc.SetPen(*wxTRANSPARENT_PEN);
1625 dc.DrawRectangle(tool->last_rect.x, tool->last_rect.y,
1626 tool->last_rect.width, tool->last_rect.height);
1627 }
1628
1629 // could cache this in the tool...
1630 // A bit of a hack here. We only scale tools if they are to be magnified
1631 // globally
1632 if (0 /*m_sizefactor > 1.0*/) {
1633 wxImage scaled_image = bmp.ConvertToImage();
1634 wxBitmap sbmp = wxBitmap(scaled_image.Scale(tool->m_width, tool->m_height,
1635 wxIMAGE_QUALITY_HIGH));
1636 dc.DrawBitmap(sbmp, drawAt);
1637 tool->last_rect =
1638 wxRect(drawAt.x, drawAt.y, sbmp.GetWidth(), sbmp.GetHeight());
1639
1640 } else {
1641 dc.DrawBitmap(bmp, drawAt);
1642 tool->last_rect =
1643 wxRect(drawAt.x, drawAt.y, bmp.GetWidth(), bmp.GetHeight());
1644 }
1645}
1646
1647// ----------------------------------------------------------------------------
1648// toolbar geometry
1649// ----------------------------------------------------------------------------
1650
1651wxToolBarToolBase *ocpnToolBarSimple::FindToolForPosition(wxCoord x,
1652 wxCoord y) {
1653 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1654 while (node) {
1655 ocpnToolBarTool *tool = (ocpnToolBarTool *)node->GetData();
1656 if ((x >= tool->m_x) && (y >= tool->m_y) &&
1657 (x < (tool->m_x + tool->GetWidth())) &&
1658 (y < (tool->m_y + tool->GetHeight()))) {
1659 return tool;
1660 }
1661
1662 node = node->GetNext();
1663 }
1664
1665 return (wxToolBarToolBase *)NULL;
1666}
1667
1668void ocpnToolBarSimple::InvalidateBitmaps() {
1669 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1670 while (node) {
1671 ocpnToolBarTool *tool = (ocpnToolBarTool *)node->GetData();
1672 tool->bitmapOK = false;
1673 node = node->GetNext();
1674 }
1675 m_bitmap = wxNullBitmap;
1676}
1677
1678wxRect ocpnToolBarSimple::GetToolRect(int tool_id) {
1679 wxRect rect;
1680 wxToolBarToolBase *tool = FindById(tool_id);
1681 if (tool) {
1682 ocpnToolBarTool *otool = (ocpnToolBarTool *)tool;
1683 if (otool) rect = otool->trect;
1684 }
1685
1686 return rect;
1687}
1688
1689// ----------------------------------------------------------------------------
1690// tool state change handlers
1691// ----------------------------------------------------------------------------
1692
1693void ocpnToolBarSimple::DoEnableTool(wxToolBarToolBase *tool,
1694 bool WXUNUSED(enable)) {
1695 ocpnToolBarTool *t = (ocpnToolBarTool *)tool;
1696 t->bitmapOK = false;
1697}
1698
1699void ocpnToolBarSimple::DoToggleTool(wxToolBarToolBase *tool,
1700 bool WXUNUSED(toggle)) {
1701 ocpnToolBarTool *t = (ocpnToolBarTool *)tool;
1702 t->bitmapOK = false;
1703 SetDirty(true);
1704}
1705
1706// ----------------------------------------------------------------------------
1707// scrolling implementation
1708// ----------------------------------------------------------------------------
1709
1710wxString ocpnToolBarSimple::GetToolShortHelp(int id) const {
1711 wxToolBarToolBase *tool = FindById(id);
1712 wxCHECK_MSG(tool, "", "no such tool");
1713
1714 return tool->GetShortHelp();
1715}
1716
1717wxString ocpnToolBarSimple::GetToolLongHelp(int id) const {
1718 wxToolBarToolBase *tool = FindById(id);
1719 wxCHECK_MSG(tool, "", "no such tool");
1720
1721 return tool->GetLongHelp();
1722}
1723
1724void ocpnToolBarSimple::SetToolShortHelp(int id, const wxString &help) {
1725 wxToolBarToolBase *tool = FindById(id);
1726 if (tool) {
1727 (void)tool->SetShortHelp(help);
1728 }
1729}
1730
1731void ocpnToolBarSimple::SetToolLongHelp(int id, const wxString &help) {
1732 wxToolBarToolBase *tool = FindById(id);
1733 if (tool) {
1734 (void)tool->SetLongHelp(help);
1735 }
1736}
1737
1738int ocpnToolBarSimple::GetToolPos(int id) const {
1739 size_t pos = 0;
1740 wxToolBarToolsList::compatibility_iterator node;
1741
1742 for (node = m_tools.GetFirst(); node; node = node->GetNext()) {
1743 if (node->GetData()->GetId() == id) return pos;
1744
1745 pos++;
1746 }
1747
1748 return wxNOT_FOUND;
1749}
1750bool ocpnToolBarSimple::GetToolState(int id) const {
1751 wxToolBarToolBase *tool = FindById(id);
1752 wxCHECK_MSG(tool, false, "no such tool");
1753
1754 return tool->IsToggled();
1755}
1756
1757bool ocpnToolBarSimple::GetToolEnabled(int id) const {
1758 wxToolBarToolBase *tool = FindById(id);
1759 wxCHECK_MSG(tool, false, "no such tool");
1760
1761 return tool->IsEnabled();
1762}
1763
1764void ocpnToolBarSimple::ToggleTool(int id, bool toggle) {
1765 wxToolBarToolBase *tool = FindById(id);
1766
1767 if (tool && tool->CanBeToggled() && tool->Toggle(toggle)) {
1768 DoToggleTool(tool, toggle);
1769 InvalidateBitmaps();
1770 top_frame::Get()->GetAbstractPrimaryCanvas()->Refresh(true);
1771 }
1772}
1773
1774wxObject *ocpnToolBarSimple::GetToolClientData(int id) const {
1775 wxToolBarToolBase *tool = FindById(id);
1776 return tool ? tool->GetClientData() : (wxObject *)NULL;
1777}
1778
1779void ocpnToolBarSimple::SetToolClientData(int id, wxObject *clientData) {
1780 wxToolBarToolBase *tool = FindById(id);
1781
1782 wxCHECK_RET(tool, "no such tool in wxToolBar::SetToolClientData");
1783
1784 tool->SetClientData(clientData);
1785}
1786
1787void ocpnToolBarSimple::EnableTool(int id, bool enable) {
1788 wxToolBarToolBase *tool = FindById(id);
1789 if (tool) {
1790 if (tool->Enable(enable)) {
1791 DoEnableTool(tool, enable);
1792 }
1793 }
1794
1795 ocpnFloatingToolbarDialog *parent = m_parentContainer;
1796 if (parent && parent->m_FloatingToolbarConfigMenu) {
1797 wxMenuItem *configItem = parent->m_FloatingToolbarConfigMenu->FindItem(id);
1798 if (configItem) configItem->Check(true);
1799 }
1800}
1801
1802void ocpnToolBarSimple::SetToolTooltipHiViz(int id, bool b_hiviz) {
1803 ocpnToolBarTool *tool = (ocpnToolBarTool *)FindById(id);
1804 if (tool) {
1805 tool->SetTooltipHiviz(b_hiviz);
1806 }
1807}
1808
1809void ocpnToolBarSimple::ClearTools() {
1810 while (GetToolsCount()) {
1811 DeleteToolByPos(0);
1812 }
1813}
1814
1815int ocpnToolBarSimple::GetVisibleToolCount() {
1816 int counter = 0;
1817 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1818 while (node) {
1819 ocpnToolBarTool *tool = (ocpnToolBarTool *)node->GetData();
1820 counter++;
1821 node = node->GetNext();
1822 }
1823 return counter;
1824}
1825
1826bool ocpnToolBarSimple::DeleteToolByPos(size_t pos) {
1827 wxCHECK_MSG(pos < GetToolsCount(), false,
1828 "invalid position in wxToolBar::DeleteToolByPos()");
1829
1830 wxToolBarToolsList::compatibility_iterator node = m_tools.Item(pos);
1831
1832 if (!DoDeleteTool(pos, node->GetData())) {
1833 return false;
1834 }
1835
1836 delete node->GetData();
1837 m_tools.Erase(node);
1838
1839 return true;
1840}
1841
1842bool ocpnToolBarSimple::DeleteTool(int id) {
1843 size_t pos = 0;
1844 wxToolBarToolsList::compatibility_iterator node;
1845 for (node = m_tools.GetFirst(); node; node = node->GetNext()) {
1846 if (node->GetData()->GetId() == id) break;
1847
1848 pos++;
1849 }
1850
1851 if (!node || !DoDeleteTool(pos, node->GetData())) {
1852 return false;
1853 }
1854
1855 delete node->GetData();
1856 m_tools.Erase(node);
1857
1858 return true;
1859}
1860
1861wxToolBarToolBase *ocpnToolBarSimple::AddSeparator() {
1862 return InsertSeparator(GetToolsCount());
1863}
1864
1865wxToolBarToolBase *ocpnToolBarSimple::InsertSeparator(size_t pos) {
1866 wxCHECK_MSG(pos <= GetToolsCount(), (wxToolBarToolBase *)NULL,
1867 "invalid position in wxToolBar::InsertSeparator()");
1868
1869 wxToolBarToolBase *tool =
1870 CreateTool(wxID_SEPARATOR, "", wxNullBitmap, wxNullBitmap,
1871 wxITEM_SEPARATOR, (wxObject *)NULL, "", "");
1872
1873 if (!tool || !DoInsertTool(pos, tool)) {
1874 delete tool;
1875
1876 return NULL;
1877 }
1878
1879 m_tools.Insert(pos, tool);
1880 m_nShowTools++;
1881
1882 return tool;
1883}
1884
1885wxToolBarToolBase *ocpnToolBarSimple::RemoveTool(int id) {
1886 size_t pos = 0;
1887 wxToolBarToolsList::compatibility_iterator node;
1888 for (node = m_tools.GetFirst(); node; node = node->GetNext()) {
1889 if (node->GetData()->GetId() == id) break;
1890
1891 pos++;
1892 }
1893
1894 if (!node) {
1895 // don't give any error messages - sometimes we might call RemoveTool()
1896 // without knowing whether the tool is or not in the toolbar
1897 return (wxToolBarToolBase *)NULL;
1898 }
1899
1900 wxToolBarToolBase *tool = node->GetData();
1901 if (!DoDeleteTool(pos, tool)) {
1902 return (wxToolBarToolBase *)NULL;
1903 }
1904
1905 m_tools.Erase(node);
1906
1907 return tool;
1908}
1909
1910wxControl *ocpnToolBarSimple::FindControl(int id) {
1911 for (wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1912 node; node = node->GetNext()) {
1913 const wxToolBarToolBase *const tool = node->GetData();
1914 if (tool->IsControl()) {
1915 wxControl *const control = tool->GetControl();
1916
1917 if (!control) {
1918 wxFAIL_MSG("NULL control in toolbar?");
1919 } else if (control->GetId() == id) {
1920 // found
1921 return control;
1922 }
1923 }
1924 }
1925
1926 return NULL;
1927}
1928
1929wxToolBarToolBase *ocpnToolBarSimple::FindById(int id) const {
1930 wxToolBarToolBase *tool = (wxToolBarToolBase *)NULL;
1931
1932 for (wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1933 node; node = node->GetNext()) {
1934 tool = node->GetData();
1935 if (tool->GetId() == id) {
1936 // found
1937 break;
1938 }
1939
1940 tool = NULL;
1941 }
1942
1943 return tool;
1944}
1945
1946// ----------------------------------------------------------------------------
1947// event processing
1948// ----------------------------------------------------------------------------
1949
1950// Only allow toggle if returns true
1951
1952bool ocpnToolBarSimple::OnLeftClick(int id, bool toggleDown) {
1953 wxCommandEvent event(wxEVT_COMMAND_TOOL_CLICKED, id);
1954 // event.SetEventObject(this);
1955
1956 // we use SetInt() to make wxCommandEvent::IsChecked() return toggleDown
1957 event.SetInt((int)toggleDown);
1958
1959 // and SetExtraLong() for backwards compatibility
1960 event.SetExtraLong((long)toggleDown);
1961
1962 top_frame::Get()->GetEventHandler()->AddPendingEvent(event);
1963
1964 return true;
1965}
1966
1967// Call when right button down.
1968void ocpnToolBarSimple::OnRightClick(int id, long WXUNUSED(x),
1969 long WXUNUSED(y)) {
1970 HideTooltip();
1971
1972 if (m_parentContainer) {
1973 if (m_parentContainer->m_FloatingToolbarConfigMenu) {
1975 new ToolbarChoicesDialog(NULL, m_parentContainer, -1, "OpenCPN",
1976 wxDefaultPosition, wxSize(100, 100));
1977 int rc = dlg->ShowModal();
1978 delete dlg;
1979
1980 if (rc == wxID_OK) {
1981 wxCommandEvent event(wxEVT_COMMAND_TOOL_RCLICKED, id);
1982 event.SetEventObject(this);
1983 event.SetInt(id);
1984
1985 top_frame::Get()->GetEventHandler()->AddPendingEvent(event);
1986 }
1987 }
1988 }
1989}
1990
1991void ocpnToolBarSimple::DoPluginToolUp() {
1992 // Look for PlugIn tools
1993 // If found, make the callback.
1994 if (!g_pi_manager) return;
1995
1996 ArrayOfPlugInToolbarTools tool_array =
1997 g_pi_manager->GetPluginToolbarToolArray();
1998 for (unsigned int i = 0; i < tool_array.GetCount(); i++) {
1999 PlugInToolbarToolContainer *pttc = tool_array[i];
2000 if (m_last_plugin_down_id == pttc->id) {
2001 opencpn_plugin_113 *ppi =
2002 dynamic_cast<opencpn_plugin_113 *>(pttc->m_pplugin);
2003 if (ppi) ppi->OnToolbarToolUpCallback(pttc->id);
2004 }
2005 }
2006
2007 m_last_plugin_down_id = -1;
2008}
2009
2010void ocpnToolBarSimple::SetToolNormalBitmapEx(wxToolBarToolBase *tool,
2011 const wxString &iconName) {
2012 if (tool) {
2013 ocpnToolBarTool *otool = (ocpnToolBarTool *)tool;
2014 if (otool) {
2015 ocpnStyle::Style *style = g_StyleManager->GetCurrentStyle();
2016
2017 wxBitmap bmp = style->GetToolIcon(iconName, TOOLICON_NORMAL, false,
2018 otool->m_width, otool->m_height);
2019 tool->SetNormalBitmap(bmp);
2020 otool->SetIconName(iconName);
2021 }
2022 }
2023}
2024
2025void ocpnToolBarSimple::SetToolNormalBitmapSVG(wxToolBarToolBase *tool,
2026 wxString fileSVG) {
2027 if (tool) {
2028 ocpnToolBarTool *otool = (ocpnToolBarTool *)tool;
2029 if (otool) {
2030 otool->pluginNormalIconSVG = fileSVG;
2031 }
2032 }
2033}
2034
2035void ocpnToolBarSimple::SetToolBitmaps(int id, wxBitmap *bmp,
2036 wxBitmap *bmpRollover) {
2037 ocpnToolBarTool *tool = (ocpnToolBarTool *)FindById(id);
2038 if (tool) {
2039 if (tool->isPluginTool) {
2040 if (bmp->GetWidth() != tool->GetWidth()) {
2041 if (bmp->IsOk()) {
2042 wxImage ibmp = bmp->ConvertToImage();
2043 ibmp.Rescale(tool->GetWidth(), tool->GetHeight(),
2044 wxIMAGE_QUALITY_HIGH);
2045 wxBitmap sbmp = wxBitmap(ibmp);
2046 tool->pluginNormalIcon = sbmp;
2047 }
2048 } else {
2049 tool->pluginNormalIcon = *bmp;
2050 }
2051
2052 if (bmpRollover->GetWidth() != tool->GetWidth()) {
2053 if (bmpRollover->IsOk()) {
2054 wxImage ibmp = bmpRollover->ConvertToImage();
2055 ibmp.Rescale(tool->GetWidth(), tool->GetHeight(),
2056 wxIMAGE_QUALITY_HIGH);
2057 wxBitmap sbmp = wxBitmap(ibmp);
2058 tool->pluginRolloverIcon = sbmp;
2059 }
2060 } else {
2061 tool->pluginRolloverIcon = *bmpRollover;
2062 }
2063 tool->bitmapOK = false;
2064
2065 } else {
2066 tool->SetNormalBitmap(*bmp);
2067 tool->bitmapOK = true;
2068 }
2069 InvalidateBitmaps();
2070 }
2071}
2072
2073void ocpnToolBarSimple::SetToolBitmapsSVG(int id, wxString fileSVGNormal,
2074 wxString fileSVGRollover,
2075 wxString fileSVGToggled) {
2076 ocpnToolBarTool *tool = (ocpnToolBarTool *)FindById(id);
2077 if (tool) {
2078 tool->pluginNormalIconSVG = fileSVGNormal;
2079 tool->pluginRolloverIconSVG = fileSVGRollover;
2080 tool->pluginToggledIconSVG = fileSVGToggled;
2081 tool->bitmapOK = false;
2082 InvalidateBitmaps();
2083 }
2084}
2085
2086//-------------------------------------------------------------------------------------
2087
2088ToolbarMOBDialog::ToolbarMOBDialog(wxWindow *parent)
2089 : wxDialog(parent, wxID_ANY, _("OpenCPN Alert"), wxDefaultPosition,
2090 wxSize(250, 230)) {
2091 wxBoxSizer *topSizer = new wxBoxSizer(wxVERTICAL);
2092
2093 wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
2094 topSizer->Add(sizer, 0, wxALIGN_CENTER_HORIZONTAL | wxALL, 5);
2095
2096 choices.push_back(
2097 new wxRadioButton(this, 0, _("No, I don't want to hide it."),
2098 wxDefaultPosition, wxDefaultSize, wxRB_GROUP));
2099
2100 choices.push_back(new wxRadioButton(
2101 this, 1, _("No, and permanently remove the option to hide it."),
2102 wxDefaultPosition));
2103
2104 choices.push_back(
2105 new wxRadioButton(this, 2, _("Yes, hide it."), wxDefaultPosition));
2106
2107 wxStdDialogButtonSizer *buttonSizer =
2108 CreateStdDialogButtonSizer(wxOK | wxCANCEL);
2109
2110 wxStaticText *textCtrl =
2111 new wxStaticText(this, wxID_ANY,
2112 _("The Man Over Board button could be an important "
2113 "safety feature.\nAre you sure you want to hide it?"));
2114
2115 sizer->Add(textCtrl, 0, wxEXPAND | wxALL, 5);
2116 sizer->Add(choices[0], 0, wxEXPAND | wxALL, 5);
2117 sizer->Add(choices[1], 0, wxEXPAND | wxALL, 5);
2118 sizer->Add(choices[2], 0, wxEXPAND | wxALL, 5);
2119 sizer->Add(buttonSizer, 0, wxEXPAND | wxTOP, 5);
2120
2121 topSizer->SetSizeHints(this);
2122 SetSizer(topSizer);
2123}
2124
2125int ToolbarMOBDialog::GetSelection() {
2126 for (unsigned int i = 0; i < choices.size(); i++) {
2127 if (choices[i]->GetValue()) return choices[i]->GetId();
2128 }
2129 return 0;
2130}
2131
2135BEGIN_EVENT_TABLE(ToolbarChoicesDialog, wxDialog)
2136END_EVENT_TABLE()
2137
2138
2143
2146 wxWindowID id,
2147 const wxString &caption,
2148 const wxPoint &pos,
2149 const wxSize &size, long style) {
2150 long wstyle = wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER;
2151 wxDialog::Create(parent, id, caption, pos, size, wstyle);
2152
2153 m_configMenu = NULL;
2154 m_ToolbarDialogAncestor = sponsor;
2155
2156 if (m_ToolbarDialogAncestor)
2157 m_configMenu = m_ToolbarDialogAncestor->m_FloatingToolbarConfigMenu;
2158
2160 GetSizer()->Fit(this);
2161
2162 RecalculateSize();
2163}
2164
2165ToolbarChoicesDialog::~ToolbarChoicesDialog() {}
2166
2172 wxBoxSizer *itemBoxSizer1 = new wxBoxSizer(wxVERTICAL);
2173 SetSizer(itemBoxSizer1);
2174
2175 wxScrolledWindow *itemDialog1 = new wxScrolledWindow(
2176 this, wxID_ANY, wxDefaultPosition, wxSize(-1, -1), wxHSCROLL | wxVSCROLL);
2177 itemDialog1->SetScrollRate(2, 2);
2178
2179#ifdef __ANDROID__
2180
2181 // Set Dialog Font by custom crafted Qt Stylesheet.
2182 wxFont *qFont = GetOCPNScaledFont(_("Dialog"));
2183
2184 wxString wqs = getFontQtStylesheet(qFont);
2185 wxCharBuffer sbuf = wqs.ToUTF8();
2186 QString qsb = QString(sbuf.data());
2187
2188 QString qsbq = getQtStyleSheet(); // basic scrollbars, etc
2189
2190 this->GetHandle()->setStyleSheet(qsb + qsbq); // Concatenated style sheets
2191
2192#endif
2193 itemBoxSizer1->Add(itemDialog1, 2, wxEXPAND | wxALL, 0);
2194
2195 wxBoxSizer *itemBoxSizer2 = new wxBoxSizer(wxVERTICAL);
2196 itemDialog1->SetSizer(itemBoxSizer2);
2197
2198 wxStaticBox *itemStaticBoxSizer3Static =
2199 new wxStaticBox(itemDialog1, wxID_ANY, _("Choose Toolbar Icons"));
2200 wxStaticBoxSizer *itemStaticBoxSizer3 =
2201 new wxStaticBoxSizer(itemStaticBoxSizer3Static, wxVERTICAL);
2202 itemBoxSizer2->Add(itemStaticBoxSizer3, 0, wxEXPAND | wxALL, 5);
2203
2204 int nitems = 0;
2205 int max_width = -1;
2206 if (m_configMenu) {
2207 nitems = m_configMenu->GetMenuItemCount();
2208
2209 cboxes.clear();
2210 for (int i = 0; i < nitems; i++) {
2211 if (i + ID_ZOOMIN == ID_MOB && g_bPermanentMOBIcon) continue;
2212 wxMenuItem *item = m_configMenu->FindItemByPosition(i);
2213
2214 wxString label = item->GetItemLabel();
2215 int l = label.Len();
2216 max_width = wxMax(max_width, l);
2217
2218 wxString windowName = "";
2219 if (item->GetId() == ID_MOB + 100) windowName = "MOBCheck";
2220
2221 wxCheckBox *cb =
2222 new wxCheckBox(itemDialog1, -1, label, wxDefaultPosition,
2223 wxDefaultSize, 0, wxDefaultValidator, windowName);
2224 // wxCheckBox *cb = new wxCheckBox(itemDialog1, -1, label);
2225 itemStaticBoxSizer3->Add(cb, 0, wxALL | wxEXPAND, 2);
2226 cb->SetValue(item->IsChecked());
2227
2228 cboxes.push_back(cb);
2229 }
2230 }
2231
2232 itemBoxSizer1->SetMinSize((max_width + 20) * GetCharWidth(),
2233 (nitems + 4) * GetCharHeight() * 2);
2234
2235 wxBoxSizer *itemBoxSizerBottom = new wxBoxSizer(wxHORIZONTAL);
2236 itemBoxSizer1->Add(itemBoxSizerBottom, 0, wxALL | wxEXPAND, 5);
2237
2238 wxBoxSizer *itemBoxSizerAux = new wxBoxSizer(wxHORIZONTAL);
2239 itemBoxSizerBottom->Add(itemBoxSizerAux, 1, wxALL, 3);
2240
2241 wxBoxSizer *itemBoxSizer16 = new wxBoxSizer(wxHORIZONTAL);
2242 itemBoxSizerBottom->Add(itemBoxSizer16, 0, wxALL, 3);
2243
2244 m_CancelButton =
2245 new wxButton(this, -1, _("Cancel"), wxDefaultPosition, wxDefaultSize, 0);
2246 itemBoxSizer16->Add(m_CancelButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
2247
2248 m_OKButton =
2249 new wxButton(this, -1, _("OK"), wxDefaultPosition, wxDefaultSize, 0);
2250 itemBoxSizer16->Add(m_OKButton, 0, wxALIGN_CENTER_VERTICAL | wxALL, 1);
2251 m_OKButton->SetDefault();
2252
2253 m_CancelButton->Connect(
2254 wxEVT_COMMAND_BUTTON_CLICKED,
2255 wxCommandEventHandler(ToolbarChoicesDialog::OnCancelClick), NULL, this);
2256 m_OKButton->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
2257 wxCommandEventHandler(ToolbarChoicesDialog::OnOkClick),
2258 NULL, this);
2259
2260 SetColorScheme((ColorScheme)0);
2261}
2262
2263void ToolbarChoicesDialog::SetColorScheme(ColorScheme cs) { DimeControl(this); }
2264
2265void ToolbarChoicesDialog::OnCancelClick(wxCommandEvent &event) {
2266 EndModal(wxID_CANCEL);
2267}
2268
2269void ToolbarChoicesDialog::OnOkClick(wxCommandEvent &event) {
2270 unsigned int ncheck = 0;
2271
2272 wxString toolbarConfigSave = m_ToolbarDialogAncestor->GetToolConfigString();
2273 wxString new_toolbarConfig = toolbarConfigSave;
2274
2275 for (unsigned int i = 0; i < cboxes.size(); i++) {
2276 wxCheckBox *cb = cboxes[i];
2277 wxString cbName = cb->GetName(); // Special flag passed into checkbox ctor
2278 // to find the "MOB" item
2279 if (cbName.IsSameAs("MOBCheck") && !cb->IsChecked()) {
2280 // Ask if really want to disable MOB button
2281 ToolbarMOBDialog mdlg(this);
2282 int dialog_ret = mdlg.ShowModal();
2283 int answer = mdlg.GetSelection();
2284 if (dialog_ret == wxID_OK) {
2285 if (answer == 1) {
2286 g_bPermanentMOBIcon = true;
2287 cb->SetValue(true);
2288 } else if (answer == 0) {
2289 cb->SetValue(true);
2290 }
2291 } else { // wxID_CANCEL
2292 new_toolbarConfig = toolbarConfigSave;
2293 return;
2294 }
2295 }
2296 if (m_configMenu) {
2297 wxMenuItem *item = m_configMenu->FindItemByPosition(i);
2298 if (new_toolbarConfig.Len() > i) {
2299 new_toolbarConfig.SetChar(i, cb->IsChecked() ? 'X' : '.');
2300 } else {
2301 new_toolbarConfig.Append(cb->IsChecked() ? 'X' : '.');
2302 }
2303 item->Check(cb->IsChecked());
2304 if (cb->IsChecked()) ncheck++;
2305 }
2306 }
2307
2308#if 0
2309 // We always must have one Tool enabled. Make it the Options tool....
2310 if( 0 == ncheck){
2311 new_toolbarConfig.SetChar( ID_SETTINGS -ID_ZOOMIN , 'X' );
2312
2313 int idOffset = ID_PLUGIN_BASE - ID_ZOOMIN + 100;
2314
2315 if(m_configMenu){
2316 wxMenuItem *item = m_configMenu->FindItem(ID_SETTINGS + idOffset);
2317 if(item)
2318 item->Check( true );
2319 }
2320 }
2321#endif
2322 m_ToolbarDialogAncestor->SetToolConfigString(new_toolbarConfig);
2323
2324 EndModal(wxID_OK);
2325}
2326
2327void ToolbarChoicesDialog::RecalculateSize() {
2328 wxSize esize = GetSize();
2329
2330 if (GetParent()) {
2331 wxSize dsize = GetParent()->GetClientSize();
2332 esize.y = wxMin(esize.y, dsize.y - (4 * GetCharHeight()));
2333 esize.x = wxMin(esize.x, dsize.x - (2 * GetCharHeight()));
2334 SetSize(esize);
2335 Centre();
2336
2337 } else {
2338 wxSize fsize = g_Platform->getDisplaySize();
2339 fsize.y = wxMin(esize.y, fsize.y - (4 * GetCharHeight()));
2340 fsize.x = wxMin(esize.x, fsize.x - (2 * GetCharHeight()));
2341 SetSize(fsize);
2342 CentreOnScreen();
2343#ifdef __ANDROID__
2344 Move(GetPosition().x, 10);
2345#endif
2346 }
2347}
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:2142
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.