📄 compasscontrol.cpp
字号:
/* * Roadnav * CompassControl.cpp * * Copyright (c) 2004 - 2007 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 CompassControl class - a control that graphically shows a/// direction./////////////////////////////////////////////////////////////////////////////////#ifdef HAVE_CONFIG_H# include <config.h>#endif#ifdef _MSC_VER#pragma warning(disable: 4786)#endif#include <wx/wx.h>#include <wx/image.h>#ifdef HAVE_MATH_H#include <math.h>#endif#include "CompassControl.h"#include "libroadnav/Constants.h"#include "libroadnav/MapSupport.h"//////////////////////////////////////////////////////////////////////////////////// CompassControl events/////////////////////////////////////////////////////////////////////////////////BEGIN_EVENT_TABLE(CompassControl, wxControl) EVT_PAINT(CompassControl::OnPaint) EVT_COMMAND(0, wxEVT_SAFE_REFRESH, CompassControl::OnSafeRefresh)END_EVENT_TABLE()IMPLEMENT_DYNAMIC_CLASS(CompassControl, wxControl);//////////////////////////////////////////////////////////////////////////////////// \brief Compass control constructor/////////////////////////////////////////////////////////////////////////////////CompassControl::CompassControl(){}//////////////////////////////////////////////////////////////////////////////////// \brief Compass control constructor/////////////////////////////////////////////////////////////////////////////////CompassControl::CompassControl(wxWindow* parent, wxWindowID id, wxPoint pt, wxSize sz){ m_fHeading = 0; Create(parent, id, pt, sz, wxNO_BORDER); SetSizeHints(90, 90);}//////////////////////////////////////////////////////////////////////////////////// \brief Static member that draws a compass with specified parameters/// on the supplied device context./////////////////////////////////////////////////////////////////////////////////void CompassControl::DrawCompass(wxDC * dc, wxColour clrBackground, wxColour clrForeground, double fHeading, wxPoint ptTopLeft, wxSize szSize){ int iWidth; int iHeight; wxPoint ptCenter; wxPoint arptCorners[8]; wxPoint arptNorth[4]; int iOuterRadius; int iInnerRadius; int iPoint; int iCircleRadius; wxPen penBackground(clrBackground, 1, wxSOLID); wxPen penForeground(clrForeground, 1, wxSOLID); wxBrush brBackground(clrBackground, wxSOLID); wxBrush brForeground(clrForeground, wxSOLID); iWidth = szSize.GetWidth(); iHeight = szSize.GetHeight(); iOuterRadius = iWidth > iHeight ? iHeight : iWidth; iOuterRadius = iOuterRadius / 2; iInnerRadius = iOuterRadius / 6; iCircleRadius = iInnerRadius * 4; ptCenter.x = iWidth / 2 + ptTopLeft.x; ptCenter.y = iHeight / 2 + ptTopLeft.y; for (iPoint = 0; iPoint < 8; iPoint++) { wxPoint ptPreRotate; ptPreRotate.x = ptCenter.x; ptPreRotate.y = ptCenter.y - ((iPoint % 2) ? iInnerRadius : iOuterRadius); arptCorners[iPoint] = RotatePoint(ptPreRotate, ptCenter, iPoint * 45 - fHeading); } arptNorth[0] = arptCorners[0]; arptNorth[1] = arptCorners[1]; arptNorth[2] = ptCenter; arptNorth[3] = arptCorners[7]; dc->SetBrush(*wxTRANSPARENT_BRUSH); dc->SetPen(penForeground); dc->DrawCircle(ptCenter, iCircleRadius); for (iPoint = 0; iPoint < 12; iPoint++) { wxPoint arptPoints[2]; arptPoints[0].x = ptCenter.x; arptPoints[0].y = ptCenter.y - iCircleRadius; arptPoints[1].x = ptCenter.x; arptPoints[1].y = ptCenter.y - iCircleRadius - iCircleRadius / 5; arptPoints[0] = RotatePoint(arptPoints[0], ptCenter, iPoint * 30 - fHeading); arptPoints[1] = RotatePoint(arptPoints[1], ptCenter, iPoint * 30 - fHeading); dc->DrawLines(2, arptPoints); } dc->SetBrush(brBackground); dc->DrawPolygon(8, arptCorners); dc->SetBrush(*wxGREY_BRUSH); dc->DrawCircle(ptCenter, iInnerRadius); dc->SetBrush(*wxBLUE_BRUSH); dc->DrawPolygon(4, arptNorth);}//////////////////////////////////////////////////////////////////////////////////// \brief Control needs to be repainted.- rotate the compass bitmap and/// draw it onto the screen/////////////////////////////////////////////////////////////////////////////////void CompassControl::OnPaint(wxPaintEvent& event){ wxPaintDC dc(this); DrawCompass(&dc, GetBackgroundColour(), GetForegroundColour(), m_fHeading, wxPoint(0, 0), dc.GetSize());}//////////////////////////////////////////////////////////////////////////////////// \brief Sets the orientation of the compass////// \param fHeading - 0 = north, 90 = east, 180 = south, 270 = west/////////////////////////////////////////////////////////////////////////////////void CompassControl::SetDirection(double fHeading){ double fHeadingChange; fHeadingChange = fabs(fHeading - m_fHeading); if (fHeadingChange > 180) fHeadingChange = 360 - fHeadingChange; // don't update for imperceptible changes if (fHeadingChange < 2) return; m_fHeading = fHeading; SafeRefresh();}//////////////////////////////////////////////////////////////////////////////////// \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 CompassControl::SafeRefresh(){ wxCommandEvent ev(wxEVT_SAFE_REFRESH, 0); AddPendingEvent(ev);}//////////////////////////////////////////////////////////////////////////////////// \brief Triggered in the main thread by a SafeRefresh() call from any/// thread./////////////////////////////////////////////////////////////////////////////////void CompassControl::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 + -