📄 satellitecontrol.cpp
字号:
/*
* Roadnav
* SatelliteControl.cpp
*
* Copyright (c) 2004 - 2006 Richard L. Lynch <rllynch@users.sourceforge.net>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of version 2 of the GNU General Public License
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
//////////////////////////////////////////////////////////////////////////////
/// \file
///
/// Contains the SatelliteControl class - a control that graphically shows the
/// detected satellites.
///
//////////////////////////////////////////////////////////////////////////////
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef _MSC_VER
#pragma warning(disable: 4786)
#endif
#include <wx/wx.h>
#ifdef HAVE_MATH_H
#include <math.h>
#endif
#include "SatelliteControl.h"
#include "libroadnav/Constants.h"
#include "libroadnav/wxAntiAliasedDC.h"
//////////////////////////////////////////////////////////////////////////////
///
/// SatelliteControl events
///
//////////////////////////////////////////////////////////////////////////////
BEGIN_EVENT_TABLE(SatelliteControl, wxControl)
EVT_PAINT(SatelliteControl::OnPaint)
EVT_ERASE_BACKGROUND(SatelliteControl::OnEraseBackground)
EVT_COMMAND(0, wxEVT_SAFE_REFRESH, SatelliteControl::OnSafeRefresh)
END_EVENT_TABLE()
IMPLEMENT_DYNAMIC_CLASS(SatelliteControl, wxControl);
using namespace std;
//////////////////////////////////////////////////////////////////////////////
///
/// \brief Satellite control constructor
///
//////////////////////////////////////////////////////////////////////////////
SatelliteControl::SatelliteControl()
{
}
//////////////////////////////////////////////////////////////////////////////
///
/// \brief Satellite control constructor
///
//////////////////////////////////////////////////////////////////////////////
SatelliteControl::SatelliteControl(wxWindow* parent, wxWindowID id, wxPoint pt, wxSize sz)
{
Create(parent, id, pt, wxSize(200, 200), wxNO_BORDER | wxFULL_REPAINT_ON_RESIZE);
SetMinSize(wxSize(100, 100));
}
//////////////////////////////////////////////////////////////////////////////
///
/// \brief Control needs to be repainted.
///
//////////////////////////////////////////////////////////////////////////////
void SatelliteControl::OnPaint(wxPaintEvent& event)
{
wxPaintDC realdc(this);
wxAntiAliasedDC<wxMemoryDC> dc;
int iWidth;
int iHeight;
int iRadius;
wxPoint ptCenter;
int iCircle;
vector<SSatelliteInfo>::iterator iSatellite;
wxBitmap bmpEmpty(1, 1);
GetSize(&iWidth, &iHeight);
if (iWidth > iHeight)
iRadius = iHeight / 2;
else
iRadius = iWidth / 2;
int iOuterMargin = iRadius / 10;
iRadius -= iOuterMargin;
ptCenter.x = iWidth / 2;
ptCenter.y = iHeight / 2;
wxBitmap bmpDC(iWidth, iHeight);
wxBrush brWindowBackground(GetBackgroundColour(), wxSOLID);
wxPen penForeground(GetForegroundColour());
wxPen penBackground(GetBackgroundColour());
dc.SelectObject(bmpDC);
dc.SetBackground(brWindowBackground);
// fill in background
dc.SetBrush(brWindowBackground);
dc.SetPen(penBackground);
dc.DrawRectangle(0, 0, iWidth, iHeight);
dc.SetPen(penForeground);
// circles
dc.SetBrush(*wxTRANSPARENT_BRUSH);
for (iCircle = 1; iCircle < 4; iCircle++)
dc.DrawCircle(ptCenter, iRadius * iCircle / 3);
// satellites
dc.SetFont(*wxNORMAL_FONT);
dc.SetTextForeground(GetForegroundColour());
for (iSatellite = m_vSatellites.begin(); iSatellite != m_vSatellites.end(); iSatellite++)
{
wxPoint ptSat;
wxString strText;
wxCoord iTextWidth;
wxCoord iTextHeight;
float fGreen;
float fBackground;
wxColour clrBackground;
fGreen = (*iSatellite).m_fSNR / 100.0;
wxASSERT(fGreen >= 0);
wxASSERT(fGreen <= 1);
if (fGreen < 0)
fGreen = 0;
if (fGreen > 1)
fGreen = 1;
fBackground = 1 - fGreen;
clrBackground.Set(
(int) (fBackground * GetBackgroundColour().Red()),
(int) (192 * fGreen + GetBackgroundColour().Green () * fBackground),
(int) (fBackground * GetBackgroundColour().Blue())
);
wxBrush brRectBackground( clrBackground,
wxSOLID);
int iTextMargin = 4;
ptSat = ptCenter;
ptSat.x += (int) (sin((*iSatellite).m_fAzimuth * 2.0 * PI / 360.0) * (90 - (*iSatellite).m_fElevation) / 90.0 * iRadius);
ptSat.y += (int) (-1 * cos((*iSatellite).m_fAzimuth * 2.0 * PI / 360.0) * (90 - (*iSatellite).m_fElevation) / 90.0 * iRadius);
strText = wxString::Format(wxT("%d"), (*iSatellite).m_iID);
dc.GetTextExtent(strText, &iTextWidth, &iTextHeight);
dc.SetBrush(brRectBackground);
dc.SetBackground(clrBackground);
dc.DrawRectangle( ptSat.x - iTextMargin,
ptSat.y - iTextMargin,
iTextWidth + iTextMargin * 2,
iTextHeight + iTextMargin * 2);
dc.DrawText(strText, ptSat);
}
// paint
dc.SelectObject(bmpEmpty);
realdc.DrawBitmap(bmpDC, 0, 0);
}
//////////////////////////////////////////////////////////////////////////////
///
/// \brief New GPS coordinates are available - record them.
///
/// Parent is responsible for invalidating the control.
///
//////////////////////////////////////////////////////////////////////////////
bool SatelliteControl::OnGPSUpdate(wxGPSEvent evGPS)
{
bool bChanged;
bChanged = false;
if (m_vSatellites.size() == evGPS.m_vSatellites.size())
{
unsigned int i;
for (i = 0; i < m_vSatellites.size() && !bChanged; i++)
{
if (m_vSatellites[i].m_iID != evGPS.m_vSatellites[i].m_iID)
bChanged = true;
if (fabs(m_vSatellites[i].m_fAzimuth - evGPS.m_vSatellites[i].m_fAzimuth) > 3)
bChanged = true;
if (fabs(m_vSatellites[i].m_fElevation - evGPS.m_vSatellites[i].m_fElevation) > 3)
bChanged = true;
if (fabs(m_vSatellites[i].m_fSNR - evGPS.m_vSatellites[i].m_fSNR) > 3)
bChanged = true;
}
}
else
{
bChanged = true;
}
if (bChanged)
{
m_vSatellites = evGPS.m_vSatellites;
SafeRefresh();
}
return bChanged;
}
//////////////////////////////////////////////////////////////////////////////
///
/// \brief Called to erase the background of the control. Our function doesn't
/// do anything - OnPaint will draw everything
///
//////////////////////////////////////////////////////////////////////////////
void SatelliteControl::OnEraseBackground(wxEraseEvent& event)
{
// don't do anything .. OnPaint will draw everything
}
//////////////////////////////////////////////////////////////////////////////
///
/// \brief Trigger a refresh of the entire control in a thread safe manner
///
/// (calling Refresh() in a thread other than the main thread causes the
/// UI to hang under GTK)
///
//////////////////////////////////////////////////////////////////////////////
void SatelliteControl::SafeRefresh()
{
wxCommandEvent ev(wxEVT_SAFE_REFRESH, 0);
AddPendingEvent(ev);
}
//////////////////////////////////////////////////////////////////////////////
///
/// \brief Triggered in the main thread by a SafeRefresh() call from any
/// thread.
///
//////////////////////////////////////////////////////////////////////////////
void SatelliteControl::OnSafeRefresh(wxCommandEvent & event)
{
#if wxCHECK_VERSION(2, 5, 0)
wxMilliSleep(1);
#else
wxUsleep(1);
#endif
Refresh();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -