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