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#if defined(__OCPN__ANDROID__)
32#include <GLES2/gl2.h>
33#elif defined(__WXQT__) || defined(__WXGTK__)
34#include <GL/glew.h>
35#endif
36
37#include "ocpndc.h"
38#include "RolloverWin.h"
39#include "timers.h"
40#include "navutil.h"
41#include "FontMgr.h"
42#include "ocpn_plugin.h"
43#include "color_handler.h"
44#include "ocpn_frame.h"
45#include "OCPNPlatform.h"
46
47#ifdef ocpnUSE_GL
48#include "glChartCanvas.h"
49#include "chcanv.h"
50#endif
51
52extern bool g_bopengl;
53#ifdef ocpnUSE_GL
54extern GLenum g_texture_rectangle_format;
55#endif
56extern MyFrame *gFrame;
57extern BasePlatform *g_BasePlatform;
58
59BEGIN_EVENT_TABLE(RolloverWin, wxWindow)
60EVT_PAINT(RolloverWin::OnPaint) EVT_TIMER(ROLLOVER_TIMER, RolloverWin::OnTimer)
61 EVT_MOUSE_EVENTS(RolloverWin::OnMouseEvent)
62
63 END_EVENT_TABLE()
64
65 // Define a constructor
66 RolloverWin::RolloverWin(wxWindow *parent, int timeout, bool maincanvas)
67 : wxWindow(parent, wxID_ANY, wxPoint(0, 0), wxSize(1, 1), wxNO_BORDER),
68 m_bmaincanvas(maincanvas) {
69 m_pbm = NULL;
70
71 m_timer_timeout.SetOwner(this, ROLLOVER_TIMER);
72 m_timeout_sec = timeout;
73 m_mmouse_propogate = 0;
74 isActive = false;
75 m_plabelFont = NULL;
76 m_texture = 0;
77 Hide();
78}
79
80RolloverWin::~RolloverWin() {
81 delete m_pbm;
82 glDeleteTextures(1, &m_texture);
83}
84void RolloverWin::OnTimer(wxTimerEvent &event) {
85 if (IsActive()) {
86 Hide();
87 GetParent()->Refresh(true);
88 IsActive(false);
89 }
90}
91
92void RolloverWin::OnMouseEvent(wxMouseEvent &event) {
93 // If directed, send mouse events up the window family tree,
94 // until some parent window does NOT call event.Skip()
95 if (m_mmouse_propogate) {
96 event.ResumePropagation(m_mmouse_propogate);
97 event.Skip();
98 }
99}
100
101void RolloverWin::SetBitmap(int rollover) {
102 wxMemoryDC mdc;
103 delete m_pbm;
104 m_pbm = new wxBitmap(m_size.x, m_size.y);
105 mdc.SelectObject(*m_pbm);
106
107 mdc.SetBackground(wxBrush(GetGlobalColor(_T ( "YELO1" ))));
108 mdc.Clear();
109#ifdef ocpnUSE_GL
110 bool usegl = g_bopengl && g_texture_rectangle_format;
111#else
112 bool usegl = false;
113#endif
114
115 if (!usegl) {
116 if (m_bmaincanvas) {
117 wxDC *cdc = new wxScreenDC();
118 int cpx = 0, cpy = 0;
119 GetParent()->ClientToScreen(&cpx, &cpy);
120 mdc.Blit(0, 0, m_size.x, m_size.y, cdc, m_position.x + cpx,
121 m_position.y + cpy);
122 delete cdc;
123 }
124 }
125
126 ocpnDC dc(mdc);
127
128 wxString text;
129 double radius = 6.0;
130 switch (rollover) {
131 case AIS_ROLLOVER:
132 text = _("AISRollover");
133 break;
134 case TC_ROLLOVER:
135 text = _("TideCurrentGraphRollover"), radius = 0;
136 break;
137 default:
138 case LEG_ROLLOVER:
139 text = _("RouteLegInfoRollover");
140 break;
141 }
142
143 if (m_bmaincanvas)
144 AlphaBlending(dc, 0, 0, m_size.x, m_size.y, radius,
145 GetGlobalColor(_T ( "YELO1" )), 172);
146
147 mdc.SetTextForeground(FontMgr::Get().GetFontColor(text));
148
149#ifdef __WXOSX__
150 mdc.SetTextForeground(wxColour(0,0,0));
151#endif
152
153 if (m_plabelFont && m_plabelFont->IsOk()) {
154 // Draw the text
155 mdc.SetFont(*m_plabelFont);
156
157 mdc.DrawLabel(m_string, wxRect(0, 0, m_size.x, m_size.y),
158 wxALIGN_CENTRE_HORIZONTAL | wxALIGN_CENTRE_VERTICAL);
159 }
160
161 mdc.SelectObject(wxNullBitmap);
162
163 SetSize(m_position.x, m_position.y, m_size.x, m_size.y);
164
165#ifdef ocpnUSE_GL
166 if (usegl) {
167 if (!m_texture) {
168 glGenTextures(1, &m_texture);
169
170 glBindTexture(g_texture_rectangle_format, m_texture);
171 glTexParameterf(g_texture_rectangle_format, GL_TEXTURE_MIN_FILTER,
172 GL_NEAREST);
173 glTexParameteri(g_texture_rectangle_format, GL_TEXTURE_MAG_FILTER,
174 GL_NEAREST);
175 glTexParameteri(g_texture_rectangle_format, GL_TEXTURE_WRAP_S,
176 GL_CLAMP_TO_EDGE);
177 glTexParameteri(g_texture_rectangle_format, GL_TEXTURE_WRAP_T,
178 GL_CLAMP_TO_EDGE);
179
180 } else
181 glBindTexture(g_texture_rectangle_format, m_texture);
182
183 wxString msg;
184 msg.Printf(_T("Render texture %d"), m_texture);
185 wxLogMessage(msg);
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 ChartCanvas *pCanvas = wxDynamicCast(GetParent(), ChartCanvas);
264 if (pCanvas)
265 pCanvas->GetglCanvas()->RenderTextures(dc, coords, uv, 4, pCanvas->GetpVP());
266
267 glDisable(g_texture_rectangle_format);
268 glDisable(GL_BLEND);
269 } else {
270#ifdef __WXOSX__
271 // Support MacBook Retina display
272 if(g_bopengl){
273 double scale = m_parent->GetContentScaleFactor();
274 if(scale > 1){
275 wxImage image = m_pbm->ConvertToImage();
276 image.Rescale( image.GetWidth() * scale, image.GetHeight() * scale);
277 wxBitmap bmp( image );
278 dc.DrawBitmap(bmp, m_position.x, m_position.y, false);
279 }
280 else
281 dc.DrawBitmap(*m_pbm, m_position.x, m_position.y, false);
282 }
283 else
284 dc.DrawBitmap(*m_pbm, m_position.x, m_position.y, false);
285#else
286 dc.DrawBitmap(*m_pbm, m_position.x, m_position.y, false);
287#endif
288 }
289
290#else
291 dc.DrawBitmap(*m_pbm, m_position.x, m_position.y, false);
292#endif
293}
294
295void RolloverWin::SetBestPosition(int x, int y, int off_x, int off_y,
296 int rollover, wxSize parent_size) {
297 int h, w;
298
299 wxFont *dFont;
300 switch (rollover) {
301 case AIS_ROLLOVER:
302 dFont = FontMgr::Get().GetFont(_("AISRollover"));
303 break;
304
305 case TC_ROLLOVER:
306 dFont = FontMgr::Get().GetFont(_("TideCurrentGraphRollover"));
307 break;
308
309 default:
310 case LEG_ROLLOVER:
311 dFont = FontMgr::Get().GetFont(_("RouteLegInfoRollover"));
312 break;
313 }
314
315 int font_size = wxMax(8, 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
341 m_size.x = w + sizeM.x;
342 m_size.y = h + sizeM.y;
343
344 m_size *= 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}
Definition: ocpndc.h:55
Definition: Quilt.cpp:864