OpenCPN Partial API docs
Loading...
Searching...
No Matches
rollover_win.cpp
Go to the documentation of this file.
1/**************************************************************************
2 * Copyright (C) 2013 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 "gl_headers.h"
25
26#include <wx/wxprec.h>
27
28#include <wx/bitmap.h>
29#include <wx/dcmemory.h>
30#include <wx/dcscreen.h>
31
32#include "model/base_platform.h"
33#include "model/config_vars.h"
34#include "model/gui_vars.h"
35
36#include "ocpndc.h"
37#include "rollover_win.h"
38#include "timers.h"
39#include "navutil.h"
40#include "font_mgr.h"
41#include "ocpn_plugin.h"
42#include "color_handler.h"
43#include "ocpn_platform.h"
44
45#ifdef ocpnUSE_GL
46#include "gl_chart_canvas.h"
47#include "chcanv.h"
48#endif
49
50#ifdef ocpnUSE_GL
51extern GLenum g_texture_rectangle_format;
52#endif
53
54BEGIN_EVENT_TABLE(RolloverWin, wxWindow)
55EVT_PAINT(RolloverWin::OnPaint)
56EVT_TIMER(ROLLOVER_TIMER, RolloverWin::OnTimer)
57EVT_MOUSE_EVENTS(RolloverWin::OnMouseEvent)
58
59END_EVENT_TABLE()
60
61// Define a constructor
62RolloverWin::RolloverWin(wxWindow *parent, int timeout, bool maincanvas)
63 : wxWindow(parent, wxID_ANY, wxPoint(0, 0), wxSize(1, 1), wxNO_BORDER),
64 m_bmaincanvas(maincanvas) {
65 m_pbm = NULL;
66
67 m_timer_timeout.SetOwner(this, ROLLOVER_TIMER);
68 m_timeout_sec = timeout;
69 m_mmouse_propogate = 0;
70 isActive = false;
71 m_plabelFont = NULL;
72 m_texture = 0;
73 Hide();
74}
75
76RolloverWin::~RolloverWin() {
77 delete m_pbm;
78#ifdef ocpnUSE_GL
79 if (g_bopengl) glDeleteTextures(1, &m_texture);
80#endif
81}
82void RolloverWin::OnTimer(wxTimerEvent &event) {
83 if (IsActive()) {
84 Hide();
85 GetParent()->Refresh(true);
86 IsActive(false);
87 }
88}
89
90void RolloverWin::OnMouseEvent(wxMouseEvent &event) {
91 // If directed, send mouse events up the window family tree,
92 // until some parent window does NOT call event.Skip()
93 if (m_mmouse_propogate) {
94 event.ResumePropagation(m_mmouse_propogate);
95 event.Skip();
96 }
97}
98
99void RolloverWin::SetBitmap(int rollover) {
100 wxMemoryDC mdc;
101 delete m_pbm;
102 m_pbm = new wxBitmap(m_size.x, m_size.y);
103 mdc.SelectObject(*m_pbm);
104
105 mdc.SetBackground(wxBrush(GetGlobalColor("YELO1")));
106 mdc.Clear();
107#ifdef ocpnUSE_GL
108 bool usegl = g_bopengl && g_texture_rectangle_format;
109#else
110 bool usegl = false;
111#endif
112
113 if (!usegl) {
114 if (m_bmaincanvas) {
115 wxDC *cdc = new wxScreenDC();
116 int cpx = 0, cpy = 0;
117 GetParent()->ClientToScreen(&cpx, &cpy);
118 mdc.Blit(0, 0, m_size.x, m_size.y, cdc, m_position.x + cpx,
119 m_position.y + cpy);
120 delete cdc;
121 }
122 }
123
124 ocpnDC dc(mdc);
125
126 wxString text;
127 double radius = 6.0;
128 switch (rollover) {
129 case AIS_ROLLOVER:
130 text = _("AISRollover");
131 break;
132 case TC_ROLLOVER:
133 text = _("TideCurrentGraphRollover"), radius = 0;
134 break;
135 default:
136 case LEG_ROLLOVER:
137 text = _("RouteLegInfoRollover");
138 break;
139 }
140
141 if (m_bmaincanvas)
142 AlphaBlending(dc, 0, 0, m_size.x, m_size.y, radius, GetGlobalColor("YELO1"),
143 172);
144
145 mdc.SetTextForeground(FontMgr::Get().GetFontColor(text));
146
147#ifdef __WXOSX__
148 mdc.SetTextForeground(wxColour(0, 0, 0));
149#endif
150
151 if (m_plabelFont && m_plabelFont->IsOk()) {
152 // Draw the text
153 mdc.SetFont(*m_plabelFont);
154
155 mdc.DrawLabel(m_string, wxRect(0, 0, m_size.x, m_size.y),
156 wxALIGN_CENTRE_HORIZONTAL | wxALIGN_CENTRE_VERTICAL);
157 }
158
159 mdc.SelectObject(wxNullBitmap);
160
161 SetSize(m_position.x, m_position.y, m_size.x, m_size.y);
162
163#ifdef ocpnUSE_GL
164 if (usegl) {
165 if (!m_texture) {
166 glGenTextures(1, &m_texture);
167
168 glBindTexture(g_texture_rectangle_format, m_texture);
169 glTexParameterf(g_texture_rectangle_format, GL_TEXTURE_MIN_FILTER,
170 GL_NEAREST);
171 glTexParameteri(g_texture_rectangle_format, GL_TEXTURE_MAG_FILTER,
172 GL_NEAREST);
173 glTexParameteri(g_texture_rectangle_format, GL_TEXTURE_WRAP_S,
174 GL_CLAMP_TO_EDGE);
175 glTexParameteri(g_texture_rectangle_format, GL_TEXTURE_WRAP_T,
176 GL_CLAMP_TO_EDGE);
177
178 } else
179 glBindTexture(g_texture_rectangle_format, m_texture);
180
181 // make texture data
182 wxImage image = m_pbm->ConvertToImage();
183
184 unsigned char *d = image.GetData();
185 unsigned char *e = new unsigned char[4 * m_size.x * m_size.y];
186 for (int y = 0; y < m_size.y; y++)
187 for (int x = 0; x < m_size.x; x++) {
188 int i = y * m_size.x + x;
189 memcpy(e + 4 * i, d + 3 * i, 3);
190 e[4 * i + 3] = 255 - d[3 * i + 2];
191 }
192 glTexImage2D(g_texture_rectangle_format, 0, GL_RGBA, m_size.x, m_size.y, 0,
193 GL_RGBA, GL_UNSIGNED_BYTE, e);
194 delete[] e;
195 glDisable(g_texture_rectangle_format);
196 glDisable(GL_BLEND);
197 }
198#endif
199
200 // Retrigger the auto timeout
201 if (m_timeout_sec > 0) {
202 m_timer_timeout.Start(m_timeout_sec * 1000, wxTIMER_ONE_SHOT);
203 }
204}
205
206void RolloverWin::OnPaint(wxPaintEvent &event) {
207 int width, height;
208 GetClientSize(&width, &height);
209 wxPaintDC dc(this);
210
211 if (m_string.Len()) {
212 wxMemoryDC mdc;
213 mdc.SelectObject(*m_pbm);
214 dc.Blit(0, 0, width, height, &mdc, 0, 0);
215 }
216}
217
218void RolloverWin::Draw(ocpnDC &dc) {
219 if (!IsActive()) return;
220#ifdef ocpnUSE_GL
221 if (g_bopengl && m_texture) {
222 glEnable(g_texture_rectangle_format);
223 glBindTexture(g_texture_rectangle_format, m_texture);
224 glEnable(GL_BLEND);
225
226 int x0 = m_position.x, x1 = x0 + m_size.x;
227 int y0 = m_position.y, y1 = y0 + m_size.y;
228 float tx, ty;
229 if (GL_TEXTURE_RECTANGLE_ARB == g_texture_rectangle_format)
230 tx = m_size.x, ty = m_size.y;
231 else
232 tx = ty = 1;
233
234 float coords[8];
235 float uv[8];
236
237 // normal uv
238 uv[0] = 0;
239 uv[1] = 0;
240 uv[2] = tx;
241 uv[3] = 0;
242 uv[4] = tx;
243 uv[5] = ty;
244 uv[6] = 0;
245 uv[7] = ty;
246
247 // pixels
248 coords[0] = x0;
249 coords[1] = y0;
250 coords[2] = x1;
251 coords[3] = y0;
252 coords[4] = x1;
253 coords[5] = y1;
254 coords[6] = x0;
255 coords[7] = y1;
256
257 auto pCanvas = dynamic_cast<ChartCanvas *>(GetParent());
258 if (pCanvas)
259 pCanvas->GetglCanvas()->RenderTextures(dc, coords, uv, 4,
260 pCanvas->GetpVP());
261
262 glDisable(g_texture_rectangle_format);
263 glDisable(GL_BLEND);
264 } else {
265#ifdef __WXOSX__
266 // Support MacBook Retina display
267 if (g_bopengl) {
268 double scale = m_parent->GetContentScaleFactor();
269 if (scale > 1) {
270 wxImage image = m_pbm->ConvertToImage();
271 image.Rescale(image.GetWidth() * scale, image.GetHeight() * scale);
272 wxBitmap bmp(image);
273 dc.DrawBitmap(bmp, m_position.x, m_position.y, false);
274 } else
275 dc.DrawBitmap(*m_pbm, m_position.x, m_position.y, false);
276 } else
277 dc.DrawBitmap(*m_pbm, m_position.x, m_position.y, false);
278#else
279 dc.DrawBitmap(*m_pbm, m_position.x, m_position.y, false);
280#endif
281 }
282
283#else
284 dc.DrawBitmap(*m_pbm, m_position.x, m_position.y, false);
285#endif
286}
287
288void RolloverWin::SetBestPosition(int x, int y, int off_x, int off_y,
289 int rollover, wxSize parent_size) {
290 int h, w;
291
292 wxFont *dFont;
293 switch (rollover) {
294 case AIS_ROLLOVER:
295 dFont = FontMgr::Get().GetFont(_("AISRollover"));
296 break;
297
298 case TC_ROLLOVER:
299 dFont = FontMgr::Get().GetFont(_("TideCurrentGraphRollover"));
300 break;
301
302 default:
303 case LEG_ROLLOVER:
304 dFont = FontMgr::Get().GetFont(_("RouteLegInfoRollover"));
305 break;
306 }
307
308 int font_size =
309 wxMax(8 * g_current_monitor_dip_px_ratio, dFont->GetPointSize());
310 font_size /= OCPN_GetWinDIPScaleFactor();
311
312 m_plabelFont = FontMgr::Get().FindOrCreateFont(
313 font_size, dFont->GetFamily(), dFont->GetStyle(), dFont->GetWeight(),
314 false, dFont->GetFaceName());
315
316 wxSize sizeM;
317 if (m_plabelFont && m_plabelFont->IsOk()) {
318#ifdef __WXMAC__
319 wxScreenDC sdc;
320 sdc.SetFont(*m_plabelFont);
321 sdc.GetMultiLineTextExtent(m_string, &w, &h, NULL, m_plabelFont);
322 sizeM = sdc.GetTextExtent("M");
323#else
324 wxClientDC cdc(GetParent());
325 cdc.SetFont(*m_plabelFont);
326 cdc.GetMultiLineTextExtent(m_string, &w, &h, NULL, m_plabelFont);
327 sizeM = cdc.GetTextExtent("M");
328#endif
329 } else {
330 w = 10;
331 h = 10;
332 }
333
334 m_size.x = w + sizeM.x;
335 m_size.y = h + sizeM.y;
336
337 m_size *=
338 OCPN_GetWinDIPScaleFactor(); // g_BasePlatform->GetDisplayDPIMult(this);
339
340 int xp, yp;
341 if ((x + off_x + m_size.x) > parent_size.x) {
342 xp = x - (off_x / 2) - m_size.x;
343 xp = wxMax(0, xp);
344 } else
345 xp = x + off_x;
346
347 if ((y + off_y + m_size.y) > parent_size.y) {
348 yp = y - (off_y / 2) - m_size.y;
349 } else
350 yp = y + off_y;
351
352 SetPosition(wxPoint(xp, yp));
353}
Basic platform specific support utilities without GUI deps.
Generic Chart canvas base.
ChartCanvas - Main chart display and interaction component.
Definition chcanv.h:173
wxFont * FindOrCreateFont(int point_size, wxFontFamily family, wxFontStyle style, wxFontWeight weight, bool underline=false, const wxString &facename=wxEmptyString, wxFontEncoding encoding=wxFONTENCODING_DEFAULT)
Creates or finds a matching font in the font cache.
Definition font_mgr.cpp:442
wxFont * GetFont(const wxString &TextElement, int requested_font_size=0)
Get a font object for a UI element.
Definition font_mgr.cpp:193
Device context class that can use either wxDC or OpenGL for drawing.
Definition ocpndc.h:60
Global color handling by name.
Global variables stored in configuration file.
Font list manager.
OpenGL chart rendering canvas.
Platform independent GL includes.
double g_current_monitor_dip_px_ratio
ratio to convert between DIP and physical pixels.
Definition gui_vars.cpp:69
Miscellaneous globals primarely used by gui layer, not persisted in configuration file.
Utility functions.
OpenCPN Platform specific support utilities.
PlugIn Object Definition/API.
double OCPN_GetWinDIPScaleFactor()
Gets Windows-specific DPI scaling factor.
Layer to use wxDC or opengl.
Timer identification constants.