1 /******************************************************************************
2  * $Id: gps.cpp, v1.0 2010/08/26 SethDart Exp $
3  *
4  * Project:  OpenCPN
5  * Purpose:  Dashboard Plugin
6  * Author:   Jean-Eudes Onfray
7  *
8  ***************************************************************************
9  *   Copyright (C) 2010 by David S. Register   *
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  *   This program is distributed in the hope that it will be useful,       *
17  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
18  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
19  *   GNU General Public License for more details.                          *
20  *                                                                         *
21  *   You should have received a copy of the GNU General Public License     *
22  *   along with this program; if not, write to the                         *
23  *   Free Software Foundation, Inc.,                                       *
24  *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,  USA.             *
25  ***************************************************************************
26  */
27 
28 #include "gps.h"
29 #include "wx28compat.h"
30 
31 // For compilers that support precompilation, includes "wx/wx.h".
32 #include <wx/wxprec.h>
33 
34 #ifdef __BORLANDC__
35     #pragma hdrstop
36 #endif
37 
38 // for all others, include the necessary headers (this file is usually all you
39 // need because it includes almost all "standard" wxWidgets headers)
40 #ifndef WX_PRECOMP
41     #include <wx/wx.h>
42 #endif
43 
44 // Required deg2rad
45 #include "dial.h"
46 
DashboardInstrument_GPS(wxWindow * parent,wxWindowID id,wxString title)47 DashboardInstrument_GPS::DashboardInstrument_GPS( wxWindow *parent, wxWindowID id, wxString title) :
48       DashboardInstrument(parent, id, title, OCPN_DBP_STC_GPS)
49 {
50       m_cx = 35;
51       m_cy = 57;
52       m_radius = 35;
53 
54       m_SatCount = 0;
55       for (int idx = 0; idx < 12; idx++)
56       {
57             m_SatInfo[idx].SatNumber = 0;
58             m_SatInfo[idx].ElevationDegrees = 0;
59             m_SatInfo[idx].AzimuthDegreesTrue = 0;
60             m_SatInfo[idx].SignalToNoiseRatio = 0;
61       }
62 }
63 
GetSize(int orient,wxSize hint)64 wxSize DashboardInstrument_GPS::GetSize( int orient, wxSize hint )
65 {
66       wxClientDC dc(this);
67       int w;
68       dc.GetTextExtent(m_title, &w, &m_TitleHeight, 0, 0, g_pFontTitle);
69       if( orient == wxHORIZONTAL ) {
70           m_cx = DefaultWidth/2;
71           return wxSize( DefaultWidth, wxMax(hint.y, m_TitleHeight+140) );
72       } else {
73           w = wxMax(hint.x, DefaultWidth);
74           m_cx = w/2;
75           return wxSize( w, m_TitleHeight+140 );
76       }
77 }
78 
SetSatInfo(int cnt,int seq,SAT_INFO sats[4])79 void DashboardInstrument_GPS::SetSatInfo(int cnt, int seq, SAT_INFO sats[4])
80 {
81       m_SatCount = cnt;
82       // Some GPS receivers may emit more than 12 sats info
83       if (seq < 1 || seq > 3)
84             return;
85 
86       int lidx = (seq-1)*4;
87       for (int idx = 0; idx < 4; idx++)
88       {
89             m_SatInfo[lidx+idx].SatNumber = sats[idx].SatNumber;
90             m_SatInfo[lidx+idx].ElevationDegrees = sats[idx].ElevationDegrees;
91             m_SatInfo[lidx+idx].AzimuthDegreesTrue = sats[idx].AzimuthDegreesTrue;
92             m_SatInfo[lidx+idx].SignalToNoiseRatio = sats[idx].SignalToNoiseRatio;
93       }
94 }
95 
Draw(wxGCDC * dc)96 void DashboardInstrument_GPS::Draw(wxGCDC* dc)
97 {
98       DrawFrame(dc);
99       DrawBackground(dc);
100       DrawForeground(dc);
101 }
102 
DrawFrame(wxGCDC * dc)103 void DashboardInstrument_GPS::DrawFrame(wxGCDC* dc)
104 {
105       wxSize size = GetClientSize();
106       wxColour cb;
107 
108       GetGlobalColor(_T("DASHB"), &cb);
109       dc->SetTextBackground(cb);
110       dc->SetBackgroundMode(wxSOLID);
111 
112       wxColour cl;
113       GetGlobalColor(_T("DASHL"), &cl);
114       dc->SetTextForeground(cl);
115       dc->SetBrush(*wxTRANSPARENT_BRUSH);
116 
117       wxPen pen;
118       pen.SetStyle(wxPENSTYLE_SOLID);
119       wxColour cf;
120       GetGlobalColor(_T("DASHF"), &cf);
121       pen.SetColour(cf);
122       pen.SetWidth(1);
123       dc->SetPen(pen);
124 
125       dc->DrawCircle(m_cx, m_cy, m_radius);
126 
127       dc->SetFont(*g_pFontSmall);
128 
129       wxScreenDC sdc;
130       int height, width;
131       sdc.GetTextExtent(_T("W"), &width, &height, NULL, NULL, g_pFontSmall);
132 
133       wxBitmap tbm( width, height, -1 );
134       wxMemoryDC tdc( tbm );
135       tdc.SetBackground( cb );
136       tdc.SetTextForeground( cl );
137       tdc.SetTextBackground(cb);
138       tdc.SetBackgroundMode(wxSOLID);
139       tdc.SetFont(*g_pFontSmall );
140 
141         tdc.Clear();
142         tdc.DrawText(_("N"), 0,0);
143         dc->Blit(m_cx-3, m_cy-m_radius-6, width, height, &tdc, 0, 0);
144 
145         tdc.Clear();
146         tdc.DrawText(_("E"), 0,0);
147         dc->Blit(m_cx+m_radius-4, m_cy-5, width, height, &tdc, 0, 0);
148 
149         tdc.Clear();
150         tdc.DrawText(_("S"), 0,0);
151         dc->Blit(m_cx-3, m_cy+m_radius-6, width, height, &tdc, 0, 0);
152 
153         tdc.Clear();
154         tdc.DrawText(_("W"), 0,0);
155         dc->Blit(m_cx-m_radius-4, m_cy-5, width, height, &tdc, 0, 0);
156 
157       tdc.SelectObject( wxNullBitmap );
158 
159 
160       dc->SetBackgroundMode(wxTRANSPARENT);
161 
162       dc->DrawLine(3, 100, size.x-3, 100);
163       dc->DrawLine(3, 140, size.x-3, 140);
164 
165       pen.SetStyle(wxPENSTYLE_DOT);
166       dc->SetPen(pen);
167       dc->DrawCircle(m_cx, m_cy, m_radius * sin(deg2rad(45)));
168       dc->DrawCircle(m_cx, m_cy, m_radius * sin(deg2rad(20)));
169 
170       //        wxSHORT_DASH is not supported on GTK, and it destroys the pen.
171 #ifndef __WXGTK__
172       pen.SetStyle(wxPENSTYLE_SHORT_DASH);
173       dc->SetPen(pen);
174 #endif
175       dc->DrawLine(3, 110, size.x-3, 110);
176       dc->DrawLine(3, 120, size.x-3, 120);
177       dc->DrawLine(3, 130, size.x-3, 130);
178 }
179 
DrawBackground(wxGCDC * dc)180 void DashboardInstrument_GPS::DrawBackground(wxGCDC* dc)
181 {
182       // Draw SatID
183 
184       wxScreenDC sdc;
185       int height, width;
186       sdc.GetTextExtent(_T("W"), &width, &height, NULL, NULL, g_pFontSmall);
187 
188       wxColour cl;
189       wxBitmap tbm( dc->GetSize().x, height, -1 );
190       wxMemoryDC tdc( tbm );
191       wxColour c2;
192       GetGlobalColor( _T("DASHB"), &c2 );
193       tdc.SetBackground( c2 );
194       tdc.Clear();
195 
196       tdc.SetFont(*g_pFontSmall );
197       GetGlobalColor( _T("DASHF"), &cl );
198       tdc.SetTextForeground( cl );
199 
200       for (int idx = 0; idx < 12; idx++)
201       {
202             if (m_SatInfo[idx].SatNumber)
203                   tdc.DrawText(wxString::Format(_T("%02d"), m_SatInfo[idx].SatNumber), idx*16+5, 0);
204       }
205 
206       tdc.SelectObject( wxNullBitmap );
207       dc->DrawBitmap(tbm, 0, 142, false);
208 
209 }
210 
DrawForeground(wxGCDC * dc)211 void DashboardInstrument_GPS::DrawForeground( wxGCDC* dc )
212 {
213     wxColour cl;
214     GetGlobalColor( _T("DASHL"), &cl );
215     wxBrush brush( cl );
216     dc->SetBrush( brush );
217     dc->SetPen( *wxTRANSPARENT_PEN);
218     dc->SetTextBackground( cl );
219 
220     wxColor cf;
221     GetGlobalColor( _T("DASHF"), &cf );
222     dc->SetTextForeground( cf );
223     dc->SetBackgroundMode( wxSOLID );
224 
225     wxColour cb;
226     GetGlobalColor( _T("DASHB"), &cb );
227 
228     for( int idx = 0; idx < 12; idx++ ) {
229         if( m_SatInfo[idx].SignalToNoiseRatio ) {
230             int h = m_SatInfo[idx].SignalToNoiseRatio * 0.4;
231             dc->DrawRectangle( idx * 16 + 5, 140 - h, 13, h );
232         }
233     }
234 
235     wxString label;
236     for( int idx = 0; idx < 12; idx++ ) {
237         if( m_SatInfo[idx].SignalToNoiseRatio ) {
238             label.Printf( _T("%02d"), m_SatInfo[idx].SatNumber );
239             int width, height;
240             wxScreenDC sdc;
241             sdc.GetTextExtent( label, &width, &height, 0, 0, g_pFontSmall );
242 
243             wxBitmap tbm( width, height, -1 );
244             wxMemoryDC tdc( tbm );
245             tdc.SetBackground( cb );
246             tdc.Clear();
247 
248             tdc.SetFont(*g_pFontSmall );
249             tdc.SetTextForeground( cf );
250             tdc.SetBackgroundMode( wxSOLID );
251             tdc.SetTextBackground( cl );
252 
253             tdc.DrawText( label, 0, 0 );
254             tdc.SelectObject( wxNullBitmap );
255 
256             int posx = m_cx + m_radius * cos( deg2rad( m_SatInfo[idx].AzimuthDegreesTrue - ANGLE_OFFSET ) )
257                             * sin( deg2rad( ANGLE_OFFSET - m_SatInfo[idx].ElevationDegrees ) ) - width / 2;
258             int posy = m_cy + m_radius * sin( deg2rad( m_SatInfo[idx].AzimuthDegreesTrue - ANGLE_OFFSET ) )
259                             * sin( deg2rad( ANGLE_OFFSET - m_SatInfo[idx].ElevationDegrees ) ) - height / 2;
260              dc->DrawBitmap( tbm, posx, posy, false );
261         }
262     }
263 
264 }
265 
266