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