📄 frame.cpp
字号:
/// \brief Catches the WM_TIMECHANGE Windows message////// wxWidgets does not support the WM_TIMECHANGE event so we will add it/// here in a non-portable way/////////////////////////////////////////////////////////////////////////////////long MapFrame::MSWWindowProc(WXUINT nMsg, WXWPARAM wParam, WXLPARAM lParam){ long result = wxFrame::MSWWindowProc(nMsg,wParam,lParam); if ( nMsg == WM_TIMECHANGE ) { // user changed the clock in some way... notify the solar timer wxTimeChangeEvent event; m_SolarTimer.AddPendingEvent(event); } return result;}#endifvoid MapFrame::OnGPSUpdate(wxGPSEvent & event){ wxMutexLocker mlLocker(m_mtxGPS); m_evGPS = event; m_bNewGPSData = true;}///////////////////////////////////////////////////////////////////////////////// /// \brief Called when new GPS coordinates have been received.////// Moves the marker to indicate where the GPS says we are/////////////////////////////////////////////////////////////////////////////////void MapFrame::OnGPSUpdateIdle(wxGPSEvent & event){ Point ptCurrent; LibRoadnavDebug0(wxT("GPS"), wxT("MapFrame::OnGPSUpdate")); if (event.m_strErrorMessage != wxT("")) { wxMessageBox(event.m_strErrorMessage, wxT("Error"), wxOK | wxICON_ERROR, this); } if (m_bOnGPSInProgress) { LibRoadnavDebug0(wxT("GPS"), wxT("MapFrame::OnGPSUpdate already running - exiting")); return; } m_bOnGPSInProgress = true; bool bEnabled = event.m_bEnabled; bool bActive = event.m_bActive; bool bLocked = event.m_bLocked; Point pt = event.m_pt; double fSpeed = event.m_fSpeed; double fHeading = event.m_fHeading; wxString strLockType = event.m_strLockType; int nSat = event.m_nSat; LibRoadnavDebug5(wxT("GPS"), wxT("bEnabled = %d, bActive = %d, bLocked = %d, fSpeed = %.1f, fHeading = %.1f"), bEnabled, bActive, bLocked, fSpeed, fHeading); if (bLocked) { double fHeadingChange = fabs(m_fGPSHeading - fHeading); bool bPositionChange; bool bAngleChange; bPositionChange = fabs(m_ptGPS.m_fLong - pt.m_fLong) > 2e-6 || fabs(m_ptGPS.m_fLat - pt.m_fLat) > 2e-6; if (fHeadingChange > 180) fHeadingChange = 360 - fHeadingChange; bAngleChange = fHeadingChange > 5; if (bPositionChange || bAngleChange) { vector<bool> vBool; double fAngleDifference; if (bPositionChange) { Address adrGPS; adrGPS = FindCoordinates(pt, vBool, false, false, &m_cRecords); if (adrGPS.m_bValid) m_adrGPS = adrGPS; } m_ctlMap->SetMarker( MapMarker( wxT("GPS Position"), &m_adrGPS, fHeading, g_pConfig->Read(wxT("GPS Callout Box"), (long) false), g_pConfig->Read(wxT("GPS Small Label"), true), g_pConfig->Read(wxT("GPS Arrow"), true), g_pConfig->Read(wxT("GPS Icon"), wxT("")), false ), false); if (m_bScreenTracksGPS) { double fScreenEdge = 0.1; double fSafety = 0.05; double fScreenRelativeHeading; wxPoint ptScreenGPS; wxSize szMapCtl; wxRealPoint ptRelativeScreenGPS; ////////////////////////////////////////////////////////////////////////////// // Beginning of speed controlled zooming code ////////////////////////////////////////////////////////////////////////////// int iDesiredSpeedControlledDetailLevelOffset; bool bSignificantOffset; double fHighestExceededCutoff; vector<double>::iterator iCutoff; double fHysteresis; fHysteresis = 5; iDesiredSpeedControlledDetailLevelOffset = 0; bSignificantOffset = false; fHighestExceededCutoff = -1000; // determine the correct offset due to the current velocity for (iCutoff = m_vSpeedControlledDetailLevelCutoffs.begin(); iCutoff != m_vSpeedControlledDetailLevelCutoffs.end(); iCutoff++) { if (fSpeed > *iCutoff) { iDesiredSpeedControlledDetailLevelOffset--; if (*iCutoff > fHighestExceededCutoff) fHighestExceededCutoff = *iCutoff; } } if (fSpeed - fHighestExceededCutoff > fHysteresis) bSignificantOffset = true; // check for accelerating through auto-zoom cutoff + fHysteresis if ((m_iSpeedControlledDetailLevelOffset - iDesiredSpeedControlledDetailLevelOffset > 1) || (m_iSpeedControlledDetailLevelOffset - iDesiredSpeedControlledDetailLevelOffset == 1 && bSignificantOffset)) { m_iSpeedControlledDetailLevelOffset--; m_ctlMap->LessDetail(); } // check for decelerating through auto-zoom cutoff if ((iDesiredSpeedControlledDetailLevelOffset - m_iSpeedControlledDetailLevelOffset >= 1)) { m_iSpeedControlledDetailLevelOffset++; m_ctlMap->MoreDetail(); } ////////////////////////////////////////////////////////////////////////////// // End of speed controlled zooming code ////////////////////////////////////////////////////////////////////////////// ptScreenGPS = m_ctlMap->MapLongLatToScreen(pt); szMapCtl = m_ctlMap->GetSize(); fScreenRelativeHeading = fHeading - m_ctlMap->GetAngle(); ptRelativeScreenGPS.x = (((double) ptScreenGPS.x) / szMapCtl.x); ptRelativeScreenGPS.y = (((double) ptScreenGPS.y) / szMapCtl.y); if (!m_ctlMap->IsOnScreen(pt)) { // yikes, we're really far off m_ctlMap->SetCenterCoordinates(pt); } else if (ptRelativeScreenGPS.x < fScreenEdge) { // we're close to the left edge .. slide the screen left m_ctlMap->MoveCenterLeft(1.0 - ptRelativeScreenGPS.x - fScreenEdge - fSafety); // move it up/down so the car passes through the center of the screen m_ctlMap->MoveCenterUp(0.5 - ptRelativeScreenGPS.y - (0.5 - fScreenEdge - fSafety) * sin_deg(fScreenRelativeHeading - 90)); } else if (ptRelativeScreenGPS.y < fScreenEdge) { // we're close to the top edge .. slide the screen up m_ctlMap->MoveCenterUp(1.0 - ptRelativeScreenGPS.y - fScreenEdge - fSafety); // move it left/right so the car passes through the center of the screen m_ctlMap->MoveCenterLeft(0.5 - ptRelativeScreenGPS.x - (0.5 - fScreenEdge - fSafety) * cos_deg(fScreenRelativeHeading - 90)); } else if (ptRelativeScreenGPS.x > (1.0 - fScreenEdge)) { // we're close to the right edge .. slide the screen right m_ctlMap->MoveCenterRight(ptRelativeScreenGPS.x - fScreenEdge - fSafety); // move it up/down so the car passes through the center of the screen m_ctlMap->MoveCenterUp(0.5 - ptRelativeScreenGPS.y - (0.5 - fScreenEdge - fSafety) * sin_deg(fScreenRelativeHeading - 90)); } else if (ptRelativeScreenGPS.y > (1.0 - fScreenEdge)) { // we're close to the bottom edge .. slide the screen down m_ctlMap->MoveCenterDown(ptRelativeScreenGPS.y - fScreenEdge - fSafety); // move it left/right so the car passes through the center of the screen m_ctlMap->MoveCenterLeft(0.5 - ptRelativeScreenGPS.x - (0.5 - fScreenEdge - fSafety) * cos_deg(fScreenRelativeHeading - 90)); } } if (m_menuView->IsChecked(idView3DMode)) { m_ctlMap->SetCenterCoordinates(pt); m_ctlMap->SetAngle(fHeading); } else { fAngleDifference = fabs(m_ctlMap->GetAngle() - fHeading); if (fAngleDifference > 180) fAngleDifference = 360 - fAngleDifference; if (fAngleDifference > 45 && !m_bNorthAlwaysUp) m_ctlMap->SetAngle(fHeading); } if (m_menuView->IsChecked(idViewGPSHistory)) { MapTrack * pTrack; Point ptLast; pTrack = m_ctlMap->GetTrack(wxT("GPSHistory")); if (!pTrack) { vector<Point> vptCoords; vptCoords.push_back(pt); MapTrack cTrack(wxT("GPSHistory"), vptCoords, wxColor(0, 255, 255), false); m_ctlMap->SetTrack(cTrack); pTrack = m_ctlMap->GetTrack(wxT("GPSHistory")); } pTrack->m_vptCoordinates.push_back(pt); m_ctlMap->SetTrack(*pTrack); } m_SolarTimer.SetPosition(pt.m_fLong,pt.m_fLat); m_ptGPS = pt; m_fGPSSpeed = fSpeed; m_fGPSHeading = fHeading; } } if (m_pctlCompass) m_pctlCompass->SetDirection(fHeading); wxString strStreet = wxString::Format(wxT("%d "), m_adrGPS.m_iStreetNumber) + m_adrGPS.m_strStreetName + wxT(" ") + m_adrGPS.m_strStreetType; SetVariable(wxT("GPS Street"), strStreet); SetVariable(wxT("GPS City"), m_adrGPS.m_strCityName); SetVariable(wxT("GPS State"), m_adrGPS.m_strStateName); // if the home zip code is not set, then set it from the GPS coordinates if (m_adrGPS.m_iZipCode) { int iZipHome; g_pConfig->Read(wxT("HomeZipCode"), &iZipHome, 0); if (!iZipHome) { g_pConfig->Write(wxT("HomeZipCode"), m_adrGPS.m_iZipCode); g_pConfig->Flush(); } } if (!bEnabled) SetVariable(wxT("GPS Full Address"), wxT("GPS disabled")); else if (!bActive) SetVariable(wxT("GPS Full Address"), wxT("No GPS unit detected")); else if (!bLocked) SetVariable(wxT("GPS Full Address"), wxT("No GPS lock")); else SetVariable(wxT("GPS Full Address"), m_adrGPS.FormatAddress(false)); SetVariable(wxT("GPS Speed"), FormatSpeed(fSpeed)); SetVariable(wxT("GPS Heading"), wxString::Format(wxT("%.0f ("), fHeading) + FormatHeading(fHeading) + wxT(")")); LibRoadnavDebug0(wxT("GPS"), wxT("Calling m_pfrmGPS->OnGPSUpdate")); m_pfrmGPS->OnGPSUpdate(event); LibRoadnavDebug0(wxT("GPS"), wxT("Calling m_pfrmDirections->OnGPSUpdate")); m_pfrmDirections->OnGPSUpdate(bEnabled, bActive, bLocked, pt, fSpeed, fHeading, strLockType, nSat, m_adrGPS); m_bOnGPSInProgress = false; LibRoadnavDebug0(wxT("GPS"), wxT("MapFrame::OnGPSUpdate done"));}void MapFrame::SaveMarkers(){ int iMarker; for (iMarker = 0; iMarker < m_ctlMap->GetMarkerCount(); iMarker++) { wxString strMarker = m_ctlMap->GetMarker(iMarker).ToString(); g_pConfig->Write(wxString::Format(wxT("Marker%d"), iMarker), strMarker); } g_pConfig->Write(wxT("MarkerCount"), m_ctlMap->GetMarkerCount()); g_pConfig->Flush();}///////////////////////////////////////////////////////////////////////////////// /// \brief Handles the application being closed. Terminates worker threads, /// saves config settings/////////////////////////////////////////////////////////////////////////////////void MapFrame::OnClose(wxCloseEvent& event){ wxRect rectWindow; m_pfrmGPS->Hide(); m_pfrmDirections->Hide(); m_pfrmWhatsNearBy->Hide(); m_pfrmGPS->Destroy(); m_pfrmDirections->Destroy(); m_pfrmWhatsNearBy->Destroy(); Hide(); m_GPSMonitorThread->Delete(); delete m_GPSMonitorThread; m_DownloadThread->Delete(); delete m_DownloadThread; #ifdef USE_SCRIPTING delete m_pScripting;#endif LCDprocCleanup(); SaveMarkers(); Point ptCenter = m_ctlMap->GetCenterCoordinates(); g_pConfig->Write(wxT("CenterLong"), ptCenter.m_fLong); g_pConfig->Write(wxT("CenterLat"), ptCenter.m_fLat); g_pConfig->Write(wxT("MapAngle"), m_ctlMap->GetAngle()); g_pConfig->Write(wxT("DetailLevel"), m_ctlMap->GetDetailLevel() - m_iSpeedControlledDetailLevelOffset); g_pConfig->Write(wxT("TrackGPSMarker"), m_bScreenTracksGPS); g_pConfig->Write(wxT("IsMaximized"), IsMaximized()); SaveWindowPosition(g_pConfig, this, wxT("Window")); SaveWindowPosition(g_pConfig, m_pfrmGPS, wxT("GPSWindow")); SaveWindowPosition(g_pConfig, m_pfrmDirections, wxT("DirectionsWindow")); SaveWindowPosition(g_pConfig, m_pfrmWhatsNearBy, wxT("WhatsNearByWindow")); TTSUnload(); m_ctlMap->PopEventHandler(true); wxWindow::Destroy();}//////////////////////////////////////////////////////////////////////////////////// \brief Handles running a script/////////////////////////////////////////////////////////////////////////////////#ifdef USE_SCRIPTING void MapFrame::OnFileRunScript(wxCommandEvent & event){ wxFileDialog dlg(this, wxT("Run Script..."), wxT(""), wxT(""), wxT("*.rnv"), wxOPEN | wxFILE_MUST_EXIST ); if (dlg.ShowModal() == wxID_OK) { if (m_pScripting->RunFromFile(dlg.GetPath())) { wxMessageBox(wxT("Error running script"), wxT("Error"), wxOK | wxICON_ERROR, this); } else { wxMessageBox(wxT("Script run successfully"), wxT("Information"), wxOK | wxICON_INFORMATION, this); } }}#endif//////////////////////////////////////////////////////////////////////////////////// \brief Handles saving the shown map to a PNG file/////////////////////////////////////////////////////////////////////////////////void MapFrame::OnFileSaveAs(wxCommandEvent & event){ wxFileDialog dlg(this, wxT("Save As..."), wxT(""), wxT(""), wxT("*.png"),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -