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