OpenCPN Partial API docs
Loading...
Searching...
No Matches
compasswin.cpp
1/******************************************************************************
2 *
3 * Project: OpenCPN
4 * Purpose: OpenCPN Main wxWidgets Program
5 * Author: David Register
6 *
7 ***************************************************************************
8 * Copyright (C) 2010 by David S. Register *
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
24 ***************************************************************************
25 *
26 */
27#include "wx/wxprec.h"
28#ifndef WX_PRECOMP
29#include "wx/wx.h"
30#endif // precompiled headers
31#include "ocpn_types.h"
32#include "compasswin.h"
33#include "comm_vars.h"
34#include "chcanv.h"
35#include "styles.h"
36#include "wx28compat.h"
37
38BEGIN_EVENT_TABLE(ocpnFloatingCompassWindow, wxWindow)
39EVT_PAINT(ocpnFloatingCompassWindow::OnPaint)
40 EVT_LEFT_DOWN(ocpnFloatingCompassWindow::MouseEvent) END_EVENT_TABLE()
41
42 extern ocpnStyle::StyleManager* g_StyleManager;
43extern bool bGPSValid;
44extern bool g_bCourseUp;
45extern bool g_bskew_comp;
46extern MyFrame* gFrame;
47
48ocpnFloatingCompassWindow::ocpnFloatingCompassWindow(wxWindow* parent) {
49 m_pparent = parent;
50 long wstyle = wxNO_BORDER | wxFRAME_NO_TASKBAR | wxFRAME_SHAPED;
51#ifdef __WXMAC__
52 wstyle |= wxSTAY_ON_TOP;
53#endif
54 wxDialog::Create(parent, -1, _T(""), wxPoint(0, 0), wxSize(-1, -1), wstyle);
55
56 ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
57 _img_compass = style->GetIcon(_T("CompassRose"));
58 _img_gpsRed = style->GetIcon(_T("gpsRed"));
59
60 m_rose_angle = -999; // force a refresh when first used
61
62 m_pStatBoxToolStaticBmp = NULL;
63
64 m_scale = 1.0;
65 SetSize(m_scale *
66 ((_img_compass.GetWidth() + _img_gpsRed.GetWidth()) +
67 style->GetCompassLeftMargin() * 2 + style->GetToolSeparation()),
68 m_scale * (_img_compass.GetHeight() + style->GetCompassTopMargin() +
69 style->GetCompassBottomMargin()));
70
71 m_xoffset = style->GetCompassXOffset();
72 m_yoffset = style->GetCompassYOffset();
73}
74
75ocpnFloatingCompassWindow::~ocpnFloatingCompassWindow() {
76 delete m_pStatBoxToolStaticBmp;
77}
78
79void ocpnFloatingCompassWindow::OnPaint(wxPaintEvent& event) {
80 int width, height;
81 GetClientSize(&width, &height);
82 wxPaintDC dc(this);
83
84 dc.DrawBitmap(m_StatBmp, 0, 0, false);
85}
86
87void ocpnFloatingCompassWindow::MouseEvent(wxMouseEvent& event) {
88 gFrame->ToggleCourseUp();
89}
90
91void ocpnFloatingCompassWindow::SetColorScheme(ColorScheme cs) {
92 wxColour back_color = GetGlobalColor(_T("GREY2"));
93
94 // Set background
95 SetBackgroundColour(back_color);
96 ClearBackground();
97
98 UpdateStatus(true);
99}
100
101void ocpnFloatingCompassWindow::UpdateStatus(bool bnew) {
102 if (bnew) m_lastgpsIconName.Clear(); // force an update to occur
103
104 wxBitmap statbmp = CreateBmp(bnew);
105 if (statbmp.IsOk()) m_StatBmp = statbmp;
106
107 Show();
108 Refresh(false);
109}
110
111void ocpnFloatingCompassWindow::SetScaleFactor(float factor) {
112 // qDebug() << m_scale << factor;
113 ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
114
115 if (factor > 0.1)
116 m_scale = factor;
117 else
118 m_scale = 1.0;
119
120 SetSize(m_scale *
121 ((_img_compass.GetWidth() + _img_gpsRed.GetWidth()) +
122 style->GetCompassLeftMargin() * 2 + style->GetToolSeparation()),
123 m_scale * (_img_compass.GetHeight() + style->GetCompassTopMargin() +
124 style->GetCompassBottomMargin()));
125}
126
127wxBitmap ocpnFloatingCompassWindow::CreateBmp(bool newColorScheme) {
128 wxString gpsIconName;
129 ocpnStyle::Style* style = g_StyleManager->GetCurrentStyle();
130
131 // In order to draw a horizontal compass window when the toolbar is vertical,
132 // we need to save away the sizes and backgrounds for the two icons.
133
134 static wxBitmap compassBg, gpsBg;
135 static wxSize toolsize;
136 static int topmargin, leftmargin, radius;
137
138 if (!compassBg.IsOk() || newColorScheme) {
139 int orient = style->GetOrientation();
140 style->SetOrientation(wxTB_HORIZONTAL);
141 if (style->HasBackground()) {
142 compassBg = style->GetNormalBG();
143 style->DrawToolbarLineStart(compassBg);
144 compassBg = style->SetBitmapBrightness(compassBg);
145 gpsBg = style->GetNormalBG();
146 style->DrawToolbarLineEnd(gpsBg);
147 gpsBg = style->SetBitmapBrightness(gpsBg);
148
149 if (fabs(m_scale - 1.0) > 0.1) {
150 wxImage bg_img = compassBg.ConvertToImage();
151 bg_img.Rescale(compassBg.GetWidth() * m_scale,
152 compassBg.GetHeight() * m_scale, wxIMAGE_QUALITY_NORMAL);
153 compassBg = wxBitmap(bg_img);
154
155 bg_img = gpsBg.ConvertToImage();
156 bg_img.Rescale(gpsBg.GetWidth() * m_scale, gpsBg.GetHeight() * m_scale,
157 wxIMAGE_QUALITY_NORMAL);
158 gpsBg = wxBitmap(bg_img);
159 }
160 }
161
162 leftmargin = style->GetCompassLeftMargin();
163 topmargin = style->GetCompassTopMargin();
164 toolsize = style->GetToolSize();
165 toolsize.x *= 2;
166 radius = style->GetCompassCornerRadius();
167
168 if (orient) style->SetOrientation(wxTB_VERTICAL);
169 }
170
171 bool b_need_refresh = false;
172
173 if (bGPSValid) {
174 if (g_bSatValid) {
175 gpsIconName = _T("gps3Bar");
176 if (g_SatsInView <= 8) gpsIconName = _T("gps2Bar");
177 if (g_SatsInView <= 4) gpsIconName = _T("gps1Bar");
178 if (g_SatsInView < 0) gpsIconName = _T("gpsGry");
179
180 } else
181 gpsIconName = _T("gpsGrn");
182 } else
183 gpsIconName = _T("gpsRed");
184
185 if (m_lastgpsIconName != gpsIconName) b_need_refresh = true;
186
187 double rose_angle = -999.;
188
189 if ((fabs(cc1->GetVPRotation()) > .01) || (fabs(cc1->GetVPSkew()) > .01)) {
190 rose_angle = -cc1->GetVPRotation();
191
192 if (!g_bCourseUp && !g_bskew_comp) rose_angle -= cc1->GetVPSkew();
193
194 } else
195 rose_angle = 0.;
196
197 if (fabs(m_rose_angle - rose_angle) > .1) b_need_refresh = true;
198
199 if (b_need_refresh) {
200 wxBitmap StatBmp;
201
202 StatBmp.Create(
203 m_scale *
204 ((_img_compass.GetWidth() + _img_gpsRed.GetWidth()) +
205 style->GetCompassLeftMargin() * 2 + style->GetToolSeparation()),
206 m_scale * (_img_compass.GetHeight() + style->GetCompassTopMargin() +
207 style->GetCompassBottomMargin()));
208
209 if (StatBmp.IsOk()) {
210 wxMemoryDC mdc;
211 mdc.SelectObject(StatBmp);
212 mdc.SetBackground(
213 wxBrush(GetGlobalColor(_T("GREY2")), wxBRUSHSTYLE_SOLID));
214 mdc.Clear();
215
216 mdc.SetPen(wxPen(GetGlobalColor(_T("UITX1")), 1));
217 mdc.SetBrush(
218 wxBrush(GetGlobalColor(_T("UITX1")), wxBRUSHSTYLE_TRANSPARENT));
219
220 mdc.DrawRoundedRectangle(0, 0, StatBmp.GetWidth(), StatBmp.GetHeight(),
221 m_scale * style->GetCompassCornerRadius());
222
223 wxPoint offset(style->GetCompassLeftMargin(),
224 style->GetCompassTopMargin());
225
226 wxBitmap iconBm;
227
228 // Build Compass Rose, rotated...
229 wxBitmap BMPRose;
230 wxPoint after_rotate;
231
232 if (g_bCourseUp)
233 BMPRose = style->GetIcon(_T("CompassRose"));
234 else
235 BMPRose = style->GetIcon(_T("CompassRoseBlue"));
236
237 if ((fabs(cc1->GetVPRotation()) > .01) ||
238 (fabs(cc1->GetVPSkew()) > .01) || (fabs(m_scale - 1.0) > 0.1)) {
239 int width = BMPRose.GetWidth() * m_scale;
240 int height = BMPRose.GetHeight() * m_scale;
241
242 wxImage rose_img = BMPRose.ConvertToImage();
243
244 if (fabs(m_scale - 1.0) > 0.1)
245 rose_img.Rescale(width, height, wxIMAGE_QUALITY_NORMAL);
246
247 if (fabs(rose_angle) > 0.01) {
248 wxPoint rot_ctr(width / 2, height / 2);
249 wxImage rot_image =
250 rose_img.Rotate(rose_angle, rot_ctr, true, &after_rotate);
251 BMPRose = wxBitmap(rot_image).GetSubBitmap(
252 wxRect(-after_rotate.x, -after_rotate.y, width, height));
253 } else
254 BMPRose = wxBitmap(rose_img);
255 }
256
257 if (style->HasBackground()) {
258 iconBm = MergeBitmaps(compassBg, BMPRose, wxSize(0, 0));
259 } else {
260 iconBm = BMPRose;
261 }
262
263 mdc.DrawBitmap(iconBm, offset);
264 offset.x += iconBm.GetWidth();
265
266 m_rose_angle = rose_angle;
267
268 // GPS Icon
269 wxBitmap gicon = style->GetIcon(gpsIconName);
270 if (fabs(m_scale - 1.0) > 0.1) {
271 int width = gicon.GetWidth() * m_scale;
272 int height = gicon.GetHeight() * m_scale;
273
274 wxImage gps_img = gicon.ConvertToImage();
275 gps_img.Rescale(width, height, wxIMAGE_QUALITY_NORMAL);
276 gicon = wxBitmap(gps_img);
277 }
278
279 if (style->HasBackground()) {
280 iconBm = MergeBitmaps(gpsBg, gicon, wxSize(0, 0));
281 } else {
282 iconBm = gicon;
283 }
284 mdc.DrawBitmap(iconBm, offset);
285 mdc.SelectObject(wxNullBitmap);
286 m_lastgpsIconName = gpsIconName;
287 }
288
289#if !defined(__WXMAC__) && !defined(__OCPN__ANDROID__)
290 if (style->marginsInvisible) {
291 m_MaskBmp = wxBitmap(StatBmp.GetWidth(), StatBmp.GetHeight());
292 wxMemoryDC sdc(m_MaskBmp);
293 sdc.SetBackground(*wxWHITE_BRUSH);
294 sdc.Clear();
295 sdc.SetBrush(*wxBLACK_BRUSH);
296 sdc.SetPen(*wxBLACK_PEN);
297 sdc.DrawRoundedRectangle(wxPoint(leftmargin, topmargin), toolsize,
298 radius);
299 sdc.SelectObject(wxNullBitmap);
300 SetShape(wxRegion(m_MaskBmp, *wxWHITE, 0));
301 } else if (radius) {
302 m_MaskBmp = wxBitmap(GetSize().x, GetSize().y);
303 wxMemoryDC sdc(m_MaskBmp);
304 sdc.SetBackground(*wxWHITE_BRUSH);
305 sdc.Clear();
306 sdc.SetBrush(*wxBLACK_BRUSH);
307 sdc.SetPen(*wxBLACK_PEN);
308 sdc.DrawRoundedRectangle(0, 0, m_MaskBmp.GetWidth(),
309 m_MaskBmp.GetHeight(), radius);
310 sdc.SelectObject(wxNullBitmap);
311 SetShape(wxRegion(m_MaskBmp, *wxWHITE, 0));
312 }
313#endif
314
315 return StatBmp;
316 }
317
318 else
319 return wxNullBitmap;
320}