OpenCPN Partial API docs
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 
54 extern bool g_bopengl;
55 #ifdef ocpnUSE_GL
56 extern GLenum g_texture_rectangle_format;
57 #endif
58 extern MyFrame *gFrame;
59 extern BasePlatform *g_BasePlatform;
60 
61 BEGIN_EVENT_TABLE(RolloverWin, wxWindow)
62 EVT_PAINT(RolloverWin::OnPaint) EVT_TIMER(ROLLOVER_TIMER, RolloverWin::OnTimer)
63  EVT_MOUSE_EVENTS(RolloverWin::OnMouseEvent)
64 
65  END_EVENT_TABLE()
66 
67  // Define a constructor
68  RolloverWin::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 
82 RolloverWin::~RolloverWin() {
83  delete m_pbm;
84 #ifdef ocpnUSE_GL
85  if (g_bopengl)
86  glDeleteTextures(1, &m_texture);
87 #endif
88 }
89 void RolloverWin::OnTimer(wxTimerEvent &event) {
90  if (IsActive()) {
91  Hide();
92  GetParent()->Refresh(true);
93  IsActive(false);
94  }
95 }
96 
97 void RolloverWin::OnMouseEvent(wxMouseEvent &event) {
98  // If directed, send mouse events up the window family tree,
99  // until some parent window does NOT call event.Skip()
100  if (m_mmouse_propogate) {
101  event.ResumePropagation(m_mmouse_propogate);
102  event.Skip();
103  }
104 }
105 
106 void RolloverWin::SetBitmap(int rollover) {
107  wxMemoryDC mdc;
108  delete m_pbm;
109  m_pbm = new wxBitmap(m_size.x, m_size.y);
110  mdc.SelectObject(*m_pbm);
111 
112  mdc.SetBackground(wxBrush(GetGlobalColor(_T ( "YELO1" ))));
113  mdc.Clear();
114 #ifdef ocpnUSE_GL
115  bool usegl = g_bopengl && g_texture_rectangle_format;
116 #else
117  bool usegl = false;
118 #endif
119 
120  if (!usegl) {
121  if (m_bmaincanvas) {
122  wxDC *cdc = new wxScreenDC();
123  int cpx = 0, cpy = 0;
124  GetParent()->ClientToScreen(&cpx, &cpy);
125  mdc.Blit(0, 0, m_size.x, m_size.y, cdc, m_position.x + cpx,
126  m_position.y + cpy);
127  delete cdc;
128  }
129  }
130 
131  ocpnDC dc(mdc);
132 
133  wxString text;
134  double radius = 6.0;
135  switch (rollover) {
136  case AIS_ROLLOVER:
137  text = _("AISRollover");
138  break;
139  case TC_ROLLOVER:
140  text = _("TideCurrentGraphRollover"), radius = 0;
141  break;
142  default:
143  case LEG_ROLLOVER:
144  text = _("RouteLegInfoRollover");
145  break;
146  }
147 
148  if (m_bmaincanvas)
149  AlphaBlending(dc, 0, 0, m_size.x, m_size.y, radius,
150  GetGlobalColor(_T ( "YELO1" )), 172);
151 
152  mdc.SetTextForeground(FontMgr::Get().GetFontColor(text));
153 
154 #ifdef __WXOSX__
155  mdc.SetTextForeground(wxColour(0,0,0));
156 #endif
157 
158  if (m_plabelFont && m_plabelFont->IsOk()) {
159  // Draw the text
160  mdc.SetFont(*m_plabelFont);
161 
162  mdc.DrawLabel(m_string, wxRect(0, 0, m_size.x, m_size.y),
163  wxALIGN_CENTRE_HORIZONTAL | wxALIGN_CENTRE_VERTICAL);
164  }
165 
166  mdc.SelectObject(wxNullBitmap);
167 
168  SetSize(m_position.x, m_position.y, m_size.x, m_size.y);
169 
170 #ifdef ocpnUSE_GL
171  if (usegl) {
172  if (!m_texture) {
173  glGenTextures(1, &m_texture);
174 
175  glBindTexture(g_texture_rectangle_format, m_texture);
176  glTexParameterf(g_texture_rectangle_format, GL_TEXTURE_MIN_FILTER,
177  GL_NEAREST);
178  glTexParameteri(g_texture_rectangle_format, GL_TEXTURE_MAG_FILTER,
179  GL_NEAREST);
180  glTexParameteri(g_texture_rectangle_format, GL_TEXTURE_WRAP_S,
181  GL_CLAMP_TO_EDGE);
182  glTexParameteri(g_texture_rectangle_format, GL_TEXTURE_WRAP_T,
183  GL_CLAMP_TO_EDGE);
184 
185  } else
186  glBindTexture(g_texture_rectangle_format, m_texture);
187 
188  // make texture data
189  wxImage image = m_pbm->ConvertToImage();
190 
191  unsigned char *d = image.GetData();
192  unsigned char *e = new unsigned char[4 * m_size.x * m_size.y];
193  for (int y = 0; y < m_size.y; y++)
194  for (int x = 0; x < m_size.x; x++) {
195  int i = y * m_size.x + x;
196  memcpy(e + 4 * i, d + 3 * i, 3);
197  e[4 * i + 3] = 255 - d[3 * i + 2];
198  }
199  glTexImage2D(g_texture_rectangle_format, 0, GL_RGBA, m_size.x, m_size.y, 0,
200  GL_RGBA, GL_UNSIGNED_BYTE, e);
201  delete[] e;
202  glDisable(g_texture_rectangle_format);
203  glDisable(GL_BLEND);
204  }
205 #endif
206 
207  // Retrigger the auto timeout
208  if (m_timeout_sec > 0) {
209  m_timer_timeout.Start(m_timeout_sec * 1000, wxTIMER_ONE_SHOT);
210  }
211 }
212 
213 void RolloverWin::OnPaint(wxPaintEvent &event) {
214  int width, height;
215  GetClientSize(&width, &height);
216  wxPaintDC dc(this);
217 
218  if (m_string.Len()) {
219  wxMemoryDC mdc;
220  mdc.SelectObject(*m_pbm);
221  dc.Blit(0, 0, width, height, &mdc, 0, 0);
222  }
223 }
224 
225 void RolloverWin::Draw(ocpnDC &dc) {
226  if (!IsActive()) return;
227 #ifdef ocpnUSE_GL
228  if (g_bopengl && m_texture) {
229  glEnable(g_texture_rectangle_format);
230  glBindTexture(g_texture_rectangle_format, m_texture);
231  glEnable(GL_BLEND);
232 
233  int x0 = m_position.x, x1 = x0 + m_size.x;
234  int y0 = m_position.y, y1 = y0 + m_size.y;
235  float tx, ty;
236  if (GL_TEXTURE_RECTANGLE_ARB == g_texture_rectangle_format)
237  tx = m_size.x, ty = m_size.y;
238  else
239  tx = ty = 1;
240 
241  float coords[8];
242  float uv[8];
243 
244  // normal uv
245  uv[0] = 0;
246  uv[1] = 0;
247  uv[2] = tx;
248  uv[3] = 0;
249  uv[4] = tx;
250  uv[5] = ty;
251  uv[6] = 0;
252  uv[7] = ty;
253 
254  // pixels
255  coords[0] = x0;
256  coords[1] = y0;
257  coords[2] = x1;
258  coords[3] = y0;
259  coords[4] = x1;
260  coords[5] = y1;
261  coords[6] = x0;
262  coords[7] = y1;
263 
264  ChartCanvas *pCanvas = wxDynamicCast(GetParent(), ChartCanvas);
265  if (pCanvas)
266  pCanvas->GetglCanvas()->RenderTextures(dc, coords, uv, 4, 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  }
281  else
282  dc.DrawBitmap(*m_pbm, m_position.x, m_position.y, false);
283  }
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 
296 void 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 = wxMax(8 * g_current_monitor_dip_px_ratio, dFont->GetPointSize());
317  font_size /= OCPN_GetWinDIPScaleFactor();
318 
319  m_plabelFont = FontMgr::Get().FindOrCreateFont(
320  font_size, dFont->GetFamily(), dFont->GetStyle(), dFont->GetWeight(),
321  false, dFont->GetFaceName());
322 
323  wxSize sizeM;
324  if (m_plabelFont && m_plabelFont->IsOk()) {
325 #ifdef __WXMAC__
326  wxScreenDC sdc;
327  sdc.SetFont(*m_plabelFont);
328  sdc.GetMultiLineTextExtent(m_string, &w, &h, NULL, m_plabelFont);
329  sizeM = sdc.GetTextExtent("M");
330 #else
331  wxClientDC cdc(GetParent());
332  cdc.SetFont(*m_plabelFont);
333  cdc.GetMultiLineTextExtent(m_string, &w, &h, NULL, m_plabelFont);
334  sizeM = cdc.GetTextExtent("M");
335 #endif
336  } else {
337  w = 10;
338  h = 10;
339  }
340 
341 
342  m_size.x = w + sizeM.x;
343  m_size.y = h + sizeM.y;
344 
345  m_size *= OCPN_GetWinDIPScaleFactor(); //g_BasePlatform->GetDisplayDPIMult(this);
346 
347  int xp, yp;
348  if ((x + off_x + m_size.x) > parent_size.x) {
349  xp = x - (off_x / 2) - m_size.x;
350  xp = wxMax(0, xp);
351  } else
352  xp = x + off_x;
353 
354  if ((y + off_y + m_size.y) > parent_size.y) {
355  yp = y - (off_y / 2) - m_size.y;
356  } else
357  yp = y + off_y;
358 
359  SetPosition(wxPoint(xp, yp));
360 }
Definition: ocpndc.h:58
Definition: Quilt.cpp:867