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