// handle custom keys. Input: key pressed (center, left etc.) // Returns true if handled successfully, false if not // // Passthrough mode for keys>=1000 (custom menu keys) // bool CustomKeyHandler(const int key) { int ckeymode; static bool doinit=true; static int oldModeIndex; if (doinit) { oldModeIndex=LKMODE_INFOMODE;; doinit=false; } if (key>=1000) { ckeymode=key-1000; LKASSERT((ckeymode>=0 && ckeymode<ckTOP)); goto passthrough; } switch(key) { case CKI_BOTTOMCENTER: ckeymode=CustomKeyModeCenter; break; case CKI_BOTTOMLEFT: ckeymode=CustomKeyModeLeft; break; case CKI_BOTTOMRIGHT: ckeymode=CustomKeyModeRight; break; case CKI_BOTTOMICON: ckeymode=CustomKeyModeAircraftIcon; break; case CKI_TOPLEFT: ckeymode=CustomKeyModeLeftUpCorner; break; case CKI_TOPRIGHT: ckeymode=CustomKeyModeRightUpCorner; break; case CKI_CENTERSCREEN: ckeymode=CustomKeyModeCenterScreen; break; default: DoStatusMessage(_T("ERR-725 UNKNOWN CUSTOMKEY")); return false; break; } passthrough: switch(ckeymode) { case ckDisabled: break; case ckZoomIn: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif MapWindow::zoom.EventScaleZoom(1); return true; break; case ckZoomInMore: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif MapWindow::zoom.EventScaleZoom(2); return true; break; case ckZoomOut: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif MapWindow::zoom.EventScaleZoom(-1); return true; break; case ckZoomOutMore: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif MapWindow::zoom.EventScaleZoom(-2); return true; break; case ckMenu: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif ShowMenu(); return true; case ckBackMode: PreviousModeIndex(); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckToggleMap: //TODO if (ModeIndex==LKMODE_MAP) SetModeIndex(oldModeIndex); else { oldModeIndex=ModeIndex; SetModeIndex(LKMODE_MAP); } MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckTrueWind: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::setMode(_T("TrueWind")); return true; case ckTeamCode: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventSetup(_T("Teamcode")); return true; case ckToggleOverlays: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif ToggleMultimapOverlays(); return true; case ckToggleMapLandable: if (ModeIndex==LKMODE_MAP) SetModeIndex(LKMODE_WP); else SetModeIndex(LKMODE_MAP); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckLandables: SetModeIndex(LKMODE_WP); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckToggleMapCommons: if (ModeIndex==LKMODE_MAP) SetModeIndex(LKMODE_NAV); else SetModeIndex(LKMODE_MAP); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckCommons: SetModeIndex(LKMODE_NAV); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckToggleMapTraffic: if (ModeIndex==LKMODE_MAP) SetModeIndex(LKMODE_TRF); else SetModeIndex(LKMODE_MAP); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckTraffic: SetModeIndex(LKMODE_TRF); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckInvertColors: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventInvertColor(NULL); return true; case ckTimeGates: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventTimeGates(NULL); return true; case ckMarkLocation: InputEvents::eventMarkLocation(_T("")); return true; case ckAutoZoom: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventZoom(_T("auto toggle")); InputEvents::eventZoom(_T("auto show")); return true; case ckActiveMap: // NO MORE USED BUT KEPT FOR OPTIMIZING COMPILER return true; case ckBooster: DoStatusMessage(_T("FEEL THE THERMAL")); if (EnableSoundModes) LKSound(_T("LK_BOOSTER.WAV")); return true; case ckGoHome: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif if (ValidWayPoint(HomeWaypoint)) { if ( (ValidTaskPoint(ActiveWayPoint)) && (Task[ActiveWayPoint].Index == HomeWaypoint )) { // LKTOKEN _@M82_ = "Already going home" DoStatusMessage(gettext(TEXT("_@M82_"))); } else { GotoWaypoint(HomeWaypoint); } } else // LKTOKEN _@M465_ = "No Home to go!" DoStatusMessage(gettext(TEXT("_@M465_"))); return true; case ckPanorama: if (PGZoomTrigger==false) PGZoomTrigger=true; else LastZoomTrigger=0; #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif return true; case ckMultitargetRotate: RotateOvertarget(); return true; case ckMultitargetMenu: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::setMode(_T("MTarget")); return true; case ckBaroToggle: ToggleBaroAltitude(); return true; case ckBasicSetup: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventSetup(_T("Basic")); return true; case ckSimMenu: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::setMode(_T("SIMMENU")); return true; case ckToggleMapAirspace: if (ModeIndex==LKMODE_MAP) SetModeType(LKMODE_WP,WP_AIRSPACES); else SetModeIndex(LKMODE_MAP); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckAirspaceAnalysis: SetModeType(LKMODE_MAP,MP_MAPASP); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckOptimizeRoute: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif PGOptimizeRoute=!PGOptimizeRoute; if (ISPARAGLIDER && PGOptimizeRoute) { AATEnabled = true; ClearOptimizedTargetPos(); } return true; case ckLockScreen: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventService(_T("LOCKMODE")); return true; case ckWhereAmI: // no sound here, chime is played by service event InputEvents::eventService(_T("ORACLE")); return true; case ckUseTotalEnergy: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventService(_T("TOTALEN")); return true; case ckNotepad: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventChecklist(_T("")); return true; case ckTerrainColors: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventService(_T("TERRCOL")); return true; case ckNearestAirspace: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventNearestAirspaceDetails(NULL); return true; case ckOlcAnalysis: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventSetup(_T("OlcAnalysis")); return true; case ckTerrainColorsBack: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventService(_T("TERRCOLBACK")); return true; case ckForceFreeFlightRestart: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif if (!CALCULATED_INFO.Flying) { DoStatusMessage(MsgToken(922)); // NOT FLYING } else { if (MessageBoxX(hWndMapWindow, MsgToken(1754), _T(""), MB_YESNO|MB_ICONQUESTION) == IDYES) { LKSW_ForceFreeFlightRestart=true; } } return true; case ckCustomMenu1: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif extern void dlgCustomMenuShowModal(void); InputEvents::eventMode(_T("MYMODE")); return true; case ckTaskCalc: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventCalculator(NULL); return true; case ckTaskTarget: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventSetup(_T("Target")); return true; case ckArmAdvance: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventArmAdvance(_T("toggle")); InputEvents::eventArmAdvance(_T("show")); return true; case ckMessageRepeat: InputEvents::eventRepeatStatusMessage(NULL); return true; case ckWaypointLookup: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventWaypointDetails(_T("select")); return true; case ckPan: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventPan(_T("toggle")); return true; case ckWindRose: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif UseWindRose=!UseWindRose; return true; case ckFlarmRadar: SetModeType(LKMODE_MAP,MP_RADAR); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckDeviceA: if(devA() && devA()->Config) { devA()->Config(devA()); } return true; case ckDeviceB: if(devB() && devB()->Config) { devB()->Config(devB()); } return true; case ckResetOdometer: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif if (MessageBoxX(hWndMapWindow, MsgToken(2229), _T(""), MB_YESNO|MB_ICONQUESTION) == IDYES) { LKSW_ResetOdometer=true; } return true; case ckForceLanding: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif if ( !CALCULATED_INFO.Flying ) { DoStatusMessage(MsgToken(922)); // NOT FLYING } else { if ( (GPS_INFO.Speed > TakeOffSpeedThreshold) && (!GPS_INFO.NAVWarning) ) { DoStatusMessage(MsgToken(1799)); // STOP MOVING! } else { if (MessageBoxX(hWndMapWindow, MsgToken(2230), _T(""), MB_YESNO|MB_ICONQUESTION) == IDYES) { LKSW_ForceLanding=true; } } } return true; case ckResetTripComputer: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif if (MessageBoxX(hWndMapWindow, MsgToken(2236), _T(""), MB_YESNO|MB_ICONQUESTION) == IDYES) { LKSW_ResetTripComputer=true; } return true; case ckSonarToggle: SonarWarning = !SonarWarning; TCHAR sonarmsg[60]; _stprintf(sonarmsg,_T("%s "),MsgToken(1293)); // SONAR if (SonarWarning) _tcscat(sonarmsg,MsgToken(1643)); // ENABLED else _tcscat(sonarmsg,MsgToken(1600)); // DISABLED DoStatusMessage(sonarmsg,NULL,false); if (EnableSoundModes) { if (SonarWarning) LKSound(TEXT("LK_TONEUP.WAV")); else LKSound(TEXT("LK_TONEDOWN.WAV")); } return true; case ckResetView: ModeType[LKMODE_MAP] = MP_MOVING; ModeType[LKMODE_INFOMODE]= IM_CRUISE; ModeType[LKMODE_WP] = WP_AIRPORTS; ModeType[LKMODE_NAV] = NV_COMMONS; ModeType[LKMODE_TRF] = TF_LIST; SetModeType(LKMODE_MAP,MP_MOVING); MapWindow::RefreshMap(); SoundModeIndex(); return true; case ckMapOrient: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif TCHAR MapOrientMsg[60]; if (MapSpaceMode==MSM_MAP) { DisplayOrientation++; if(DisplayOrientation > NORTHSMART) DisplayOrientation = 0; MapWindow::SetAutoOrientation(true); // 101008 reset it switch(DisplayOrientation) { case TRACKUP : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M737_"))) ; break; // _@M737_ "Track up" case NORTHUP : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M483_"))) ; break; // _@M483_ "North up" case NORTHCIRCLE : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M482_"))) ; break; // _@M482_ "North circling" case TRACKCIRCLE : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M682_"))) ; break; // _@M682_ "Target circling" _@M485_ "NorthUp above " case NORTHTRACK : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M484_"))) ; break; // _@M484_ "North/track" case NORTHSMART : _stprintf(MapOrientMsg,_T("%s"),gettext(TEXT("_@M481_"))) ; break; // _@M481_ "North Smart" } DoStatusMessage(MapOrientMsg,NULL,false); } else { SetMMNorthUp(GetSideviewPage(), (GetMMNorthUp(GetSideviewPage())+1)%2); } return true; case ckResetComm: #ifndef DISABLEAUDIO if (EnableSoundModes) PlayResource(TEXT("IDR_WAV_CLICK")); #endif InputEvents::eventRestartCommPorts(NULL); return true; default: DoStatusMessage(_T("ERR-726 INVALID CUSTOMKEY")); StartupStore(_T("... ERR-726 INVALID CUSTOMKEY=%d\n"),ckeymode); break; } return false; }
int MapWindow::SharedTopView(LKSurface& Surface, DiagrammStruct* psDia , double fAS_Bearing, double fWP_Bearing) { int iOldDisplayOrientation = DisplayOrientation; DiagrammStruct m_Dia = *psDia; const RECT& rct = m_Dia.rc; unsigned short getsideviewpage=GetSideviewPage(); LKASSERT(getsideviewpage<NUMBER_OF_SHARED_MULTIMAPS); LKASSERT(Current_Multimap_SizeY!=SIZE0); DisplayOrientation = GetMMNorthUp(getsideviewpage); switch(GetMMNorthUp(getsideviewpage)) { case TRACKUP: break; case NORTHUP: default: m_Dia.fXMin = -m_Dia.fXMax; break; } double fOldScale = zoom.Scale(); const auto hfOld = Surface.SelectObject(LK8PanelUnitFont); if(zoom.AutoZoom()) zoom.AutoZoom(false); double fFact = 1.25 ; #ifdef INIT_CASE switch(ScreenSize) { case ss800x480: fFact=0.750; break; case ss640x480: fFact=0.938; break; case ss480x272: fFact=0.708; break; case ss400x240: fFact=0.750; break; case ss320x240: fFact=0.938; break; case ss480x800: fFact=1.250; break; case ss480x640: fFact=1.250; break; case ss272x480: fFact=1.250; break; case ss240x400: fFact=1.250; break; case ss240x320: fFact=1.250; break; default: fFact=1.000; break; } #endif if((ScreenSizeX > 0) && (ScreenSizeY > 0)) { if(ScreenSizeX > ScreenSizeY) fFact = (double)ScreenSizeY/(double)ScreenSizeX * 1.250; } PanLatitude = DrawInfo.Latitude; PanLongitude = DrawInfo.Longitude; switch(GetMMNorthUp(getsideviewpage)) { case TRACKUP: DisplayAngle = AngleLimit360(fAS_Bearing +270.0); DisplayAircraftAngle = AngleLimit360(fWP_Bearing); break; case NORTHUP: default: DisplayAngle = 0; if( getsideviewpage == IM_HEADING || getsideviewpage==IM_VISUALGLIDE) DisplayAircraftAngle = AngleLimit360(fAS_Bearing); else DisplayAircraftAngle = AngleLimit360(DrawInfo.TrackBearing); break; } int iOldLocator = EnableThermalLocator; EnableThermalLocator =0; /*******/ #warning "wrong place for do that, always bad idea to change layout inside drawing fonctions !" MapWindow::ChangeDrawRect(rct); // set new area for terrain and topology /*******/ zoom.RequestedScale((m_Dia.fXMax -m_Dia.fXMin) * fFact * (DISTANCEMODIFY)/10.0f); POINT Orig = { CalcDistanceCoordinat(0.0, (DiagrammStruct*) &m_Dia),(rct.bottom-rct.top)/2}; POINT Orig_Aircraft= {0,0}; zoom.ModifyMapScale(); zoom.UpdateMapScale(); const ScreenProjection _Proj = CalculateScreenPositions( Orig, rct, &Orig_Aircraft); CalculateScreenPositionsAirspace(rct, _Proj); bool terrainpainted=false; if (IsMultimapTerrain() && DerivedDrawInfo.TerrainValid && RasterTerrain::isTerrainLoaded() ) { LKTextBlack=false; BlackScreen=false; LockTerrainDataGraphics(); DrawTerrain(Surface, rct, _Proj, GetAzimuth(), 40.0); UnlockTerrainDataGraphics(); terrainpainted=true; } else { // We fill up the background wity chosen empty map color Surface.FillRect(&rct, hInvBackgroundBrush[BgMapColor]); // We force LK painting black values on screen depending on the background color in use // blackscreen would force everything to be painted white, instead LKTextBlack=BgMapColorTextBlack[BgMapColor]; if (BgMapColor>6 ) BlackScreen=true; else BlackScreen=false; } ResetLabelDeclutter(); // We reduce screen cluttering for some cases.. short olddecluttermode=DeclutterMode; if (Current_Multimap_SizeY==SIZE4) goto _nomoredeclutter; if (Current_Multimap_SizeY<SIZE3) { DeclutterMode+=2; } else { if (Current_Multimap_SizeY==SIZE3) DeclutterMode++; } if (DeclutterMode>dmVeryHigh) DeclutterMode=dmVeryHigh; _nomoredeclutter: if (IsMultimapTopology()) { // Do not print topology labels, to be used with another config later! // SaturateLabelDeclutter(); DrawTopology(Surface, rct, _Proj); } else { // No topology is desired, but terrain requires water areas nevertheless if (terrainpainted) { DrawTopology(Surface, rct, _Proj, true); // water only! } } if (IsMultimapAirspace()) { DrawAirSpace(Surface, rct, _Proj); // full screen, to hide clipping effect on low border } if (Flags_DrawTask && MapSpaceMode!=MSM_MAPASP && ValidTaskPoint(ActiveTaskPoint) && ValidTaskPoint(1)) { DrawTaskAAT(Surface, rct); DrawTask(Surface, rct, _Proj, Orig_Aircraft); } if (IsMultimapWaypoints()) { DrawWaypointsNew(Surface,rct); } if (Flags_DrawFAI) DrawFAIOptimizer(Surface, rct, _Proj, Orig_Aircraft); DeclutterMode=olddecluttermode; // set it back correctly /* THIS STUFF DOES NOT WORK IN SHARED MAPS, YET NEED FIXING LatLon2Screen for shared maps using Sideview #ifdef GTL2 if (((FinalGlideTerrain == 2) || (FinalGlideTerrain == 4)) && DerivedDrawInfo.TerrainValid) DrawTerrainAbove(hdc, rct); #endif */ // // Stuff for MAPTRK only (M1) if (MapSpaceMode==MSM_MAPTRK) { if(IsMultimapTerrain() || IsMultimapTopology() ) { if (FinalGlideTerrain && DerivedDrawInfo.TerrainValid) DrawGlideThroughTerrain(Surface, rct, _Proj); } if (extGPSCONNECT) DrawBearing(Surface, rct, _Proj); // Wind arrow if (IsMultimapOverlaysGauges()) DrawWindAtAircraft2(Surface, Orig_Aircraft, rct); } if (MapSpaceMode==MSM_MAPWPT) { if (extGPSCONNECT) DrawBearing(Surface, rct, _Proj); } switch(GetMMNorthUp(getsideviewpage)) { case NORTHUP: default: DrawCompass( Surface, rct, 0); break; case TRACKUP: if(getsideviewpage == IM_HEADING || getsideviewpage == IM_VISUALGLIDE) DrawCompass( Surface, rct, DrawInfo.TrackBearing-90.0); else DrawCompass( Surface, rct, DisplayAngle); break; } /**************************************************************************************************** * draw vertical line ****************************************************************************************************/ POINT line[2]; line[0].x = rct.left; line[0].y = Orig_Aircraft.y-1; line[1].x = rct.right; line[1].y = line[0].y; switch(GetMMNorthUp(getsideviewpage)) { case TRACKUP: // Are we are not topview fullscreen? if (Current_Multimap_SizeY<SIZE4 && !(MapSpaceMode==MSM_VISUALGLIDE)) { Surface.DrawDashLine(NIBLSCALE(1), line[0], line[1], Sideview_TextColor, rct); } else { if (TrackBar) { DrawHeadUpLine(Surface, Orig, rct, psDia->fXMin ,psDia->fXMax); if (ISGAAIRCRAFT) DrawFuturePos(Surface, Orig, rct, true); } } break; case NORTHUP: default: if (TrackBar) { DrawHeadUpLine(Surface, Orig, rct, psDia->fXMin ,psDia->fXMax); if (ISGAAIRCRAFT) DrawFuturePos(Surface, Orig, rct, true); } break; } DrawAircraft(Surface, Orig_Aircraft); // M3 has sideview always on, so wont apply here, and no need to check if (Current_Multimap_SizeY==SIZE4) { DrawMapScale(Surface,rct,0); } MapWindow::zoom.RequestedScale(fOldScale); EnableThermalLocator = iOldLocator; DisplayOrientation = iOldDisplayOrientation; Surface.SelectObject(hfOld); return 0; }
void MapWindow::LKDrawMultimap_Asp(HDC hdc, const RECT rc) { RECT rci = rc; rci.bottom -= BottomSize; #if 0 if (DoInit[MDI_MAPASP]) { DoInit[MDI_MAPASP]=false; } #endif switch(LKevent) { // // USABLE EVENTS // case LKEVENT_NEWRUN: // Upon entering a new multimap, Active is forced reset. It should not be necessary ActiveMap=false; if (MapSpaceMode==MSM_VISUALGLIDE) { GetVisualGlidePoints(0); // reset upon entering! } break; case LKEVENT_TOPLEFT: IsMultimapConfigShown=true; InputEvents::setMode(_T("MMCONF")); break; case LKEVENT_TOPRIGHT: if (MapSpaceMode==MSM_MAPASP) { Sonar_IsEnabled = !Sonar_IsEnabled; if (EnableSoundModes) { if (Sonar_IsEnabled) LKSound(TEXT("LK_TONEUP.WAV")); else LKSound(TEXT("LK_TONEDOWN.WAV")); } } // ACTIVE is available only when there is a topview shown! if ( (MapSpaceMode==MSM_MAPTRK || MapSpaceMode==MSM_MAPWPT) && (Current_Multimap_TopRect.bottom>0)) { ActiveMap = !ActiveMap; if (EnableSoundModes) { if (ActiveMap) LKSound(TEXT("LK_TONEUP.WAV")); else LKSound(TEXT("LK_TONEDOWN.WAV")); } } break; default: // THIS SHOULD NEVER HAPPEN, but always CHECK FOR IT! break; } // // If the map is active in the proper mapspace, we shall manage here the action // if (LKevent==LKEVENT_SHORTCLICK && ActiveMap && (MapSpaceMode==MSM_MAPTRK || MapSpaceMode==MSM_MAPWPT)) { // // It would be a GOOD IDEA to keep this as a global, updated of course. // We need to know very often how is the screen splitted, and where! // It should be made global somewhere else, not here. // if ( YstartScreen < Current_Multimap_TopRect.bottom) { double Xstart, Ystart; SideviewScreen2LatLon(XstartScreen, YstartScreen, Xstart, Ystart); MapWindow::Event_NearestWaypointDetails(Xstart, Ystart, 1.0e5, false); LKevent=LKEVENT_NONE; ActiveMap=false; return; } } // // This is doing all rendering, including terrain and topology, which is not good. // #ifdef ENABLE_ALL_AS_FOR_SIDEVIEW int oldAltMode = AltitudeMode ; if (GetSideviewPage() == IM_NEAR_AS) AltitudeMode = ALLON; #endif RenderAirspace(hdc, rci); #ifdef ENABLE_ALL_AS_FOR_SIDEVIEW AltitudeMode = oldAltMode; #endif LKevent=LKEVENT_NONE; }
void MapWindow::LKDrawMultimap_Asp(LKSurface& Surface, const RECT& rc) { RECT rci = rc; rci.bottom -= BottomSize; #if 0 if (DoInit[MDI_MAPASP]) { DoInit[MDI_MAPASP]=false; } #endif switch(LKevent) { // // USABLE EVENTS // case LKEVENT_NEWRUN: // Upon entering a new multimap, Active is forced reset. It should not be necessary if (MapSpaceMode==MSM_VISUALGLIDE) { GetVisualGlidePoints(0); // reset upon entering! } break; case LKEVENT_TOPLEFT: IsMultimapConfigShown=true; InputEvents::setMode(_T("MMCONF")); break; case LKEVENT_TOPRIGHT: if (MapSpaceMode==MSM_MAPASP) { SonarWarning = !SonarWarning; if (SonarWarning) LKSound(TEXT("LK_TONEUP.WAV")); else LKSound(TEXT("LK_TONEDOWN.WAV")); } // ACTIVE is available only when there is a topview shown! if ( (MapSpaceMode==MSM_MAPTRK || MapSpaceMode==MSM_MAPWPT) && (Current_Multimap_TopRect.bottom>0)) { LKSound(TEXT("LK_TONEDOWN.WAV")); } break; default: // THIS SHOULD NEVER HAPPEN, but always CHECK FOR IT! break; } // // If the map is active in the proper mapspace, we shall manage here the action // if (LKevent==LKEVENT_LONGCLICK /*&& ActiveMap && (MapSpaceMode==MSM_MAPTRK || MapSpaceMode==MSM_MAPWPT)*/) { // // It would be a GOOD IDEA to keep this as a global, updated of course. // We need to know very often how is the screen splitted, and where! // It should be made global somewhere else, not here. // if ( startScreen.y < Current_Multimap_TopRect.bottom) { if( PtInRect(&rc, startScreen)) { /* * we can't show dialog from Draw thread * instead, new event is queued, dialog will be popup by main thread */ InputEvents::processGlideComputer(GCE_WAYPOINT_DETAILS_SCREEN); // LKevent=LKEVENT_NONE; } } } // // This is doing all rendering, including terrain and topology, which is not good. // #ifdef ENABLE_ALL_AS_FOR_SIDEVIEW int oldAltMode = AltitudeMode ; if (GetSideviewPage() == IM_NEAR_AS) AltitudeMode = ALLON; #endif RenderAirspace(Surface, rci); #ifdef ENABLE_ALL_AS_FOR_SIDEVIEW AltitudeMode = oldAltMode; #endif // LKevent=LKEVENT_NONE; }
void MapWindow::RenderNearAirspace(LKSurface& Surface, const RECT rci) { RECT rc = rci; /* rectangle for sideview */ RECT rct = rc; /* rectangle for topview */ rc.top = (int)((double)(rci.bottom-rci.top )*fSplitFact); rct.bottom = rc.top ; // Expose the topview rect size in use.. Current_Multimap_TopRect=rct; LKFont hfOldFnt = Surface.SelectObject(LK8PanelUnitFont/* Sender->GetFont()*/); int *iSplit = &Multimap_SizeY[Get_Current_Multimap_Type()]; int k; static double fHeigtScaleFact = 1.0; double GPSlat, GPSlon, GPSalt, GPSbrg; double calc_terrainalt; double calc_altitudeagl; // double alt; TCHAR text[TBSIZE+1]; TCHAR buffer[TBSIZE+1]; CAirspaceBase near_airspace; CAirspace *found = NULL; // bool bFound = false; DiagrammStruct sDia; bool bAS_Inside=false; int iAS_Bearing=0; int iAS_HorDistance=15000; int iABS_AS_HorDistance=0; int iAS_VertDistance=0; bool bValid; static bool bHeightScale = false; long wpt_brg = 0; POINT line[2]; POINT TxYPt; POINT TxXPt; SIZE tsize; LKColor GREEN_COL = RGB_GREEN; LKColor BLUE_COL = RGB_BLUE; LKColor LIGHTBLUE_COL = RGB_LIGHTBLUE; BOOL bInvCol = true; //INVERTCOLORS unsigned short getsideviewpage=GetSideviewPage(); LKASSERT(getsideviewpage<3); if(bInvCol) Sideview_TextColor = INV_GROUND_TEXT_COLOUR; else Sideview_TextColor = RGB_WHITE; switch(LKevent) { case LKEVENT_NEWRUN: // CALLED ON ENTRY: when we select this page coming from another mapspace bHeightScale = false; // fZOOMScale[getsideviewpage] = 1.0; fHeigtScaleFact = 1.0; if (IsMultimapTopology()) ForceVisibilityScan=true; break; case LKEVENT_UP: // click on upper part of screen, excluding center if(bHeightScale) fHeigtScaleFact /= ZOOMFACTOR; else fZOOMScale[getsideviewpage] /= ZOOMFACTOR; if (IsMultimapTopology()) ForceVisibilityScan=true; break; case LKEVENT_DOWN: // click on lower part of screen, excluding center if(bHeightScale) fHeigtScaleFact *= ZOOMFACTOR; else fZOOMScale[getsideviewpage] *= ZOOMFACTOR; if (IsMultimapTopology()) ForceVisibilityScan=true; break; case LKEVENT_LONGCLICK: for (k=0 ; k <= Sideview_iNoHandeldSpaces; k++) { if( Sideview_pHandeled[k].psAS != NULL) { if (PtInRect(&(Sideview_pHandeled[k].rc), startScreen)) { #if 1 // MULTISELECT dlgAddMultiSelectListItem((long*) Sideview_pHandeled[k].psAS, 0, IM_AIRSPACE, 0); #else if (EnableSoundModes)PlayResource(TEXT("IDR_WAV_BTONE4")); dlgAirspaceDetails(Sideview_pHandeled[k].psAS); // dlgA #endif LKevent=LKEVENT_NONE; } } } dlgMultiSelectListShowModal(); if ( LKevent != LKEVENT_NONE ) { if (PtInRect(&rc, startScreen)) bHeightScale = !bHeightScale; if (PtInRect(&rct, startScreen)) bHeightScale = false; } break; case LKEVENT_PAGEUP: #ifdef OFFSET_SETP if(bHeightScale) fOffset -= OFFSET_SETP; else #endif { if(*iSplit == SIZE1) *iSplit = SIZE0; if(*iSplit == SIZE2) *iSplit = SIZE1; if(*iSplit == SIZE3) *iSplit = SIZE2; } break; case LKEVENT_PAGEDOWN: #ifdef OFFSET_SETP if(bHeightScale) fOffset += OFFSET_SETP; else #endif { if(*iSplit == SIZE2) *iSplit = SIZE3; if(*iSplit == SIZE1) *iSplit = SIZE2; if(*iSplit == SIZE0) *iSplit = SIZE1; } break; } LKASSERT(((*iSplit==SIZE0)||(*iSplit==SIZE1)||(*iSplit==SIZE2)||(*iSplit==SIZE3)||(*iSplit==SIZE4))); LKevent=LKEVENT_NONE; // Current_Multimap_SizeY is global, and must be used by all multimaps! // It is defined in Multimap.cpp and as an external in Multimap.h // It is important that it is updated, because we should resize terrain // only if needed! Resizing terrain takes some cpu and some time. // So we need to know when this is not necessary, having the same size of previous // multimap, if we are switching. // The current implementation is terribly wrong by managing resizing of sideview in // each multimap: it should be done by a common layer. // CAREFUL: // If for any reason DrawTerrain() is called after resizing to 0 (full sideview) // LK WILL CRASH with no hope to recover. if(Current_Multimap_SizeY != *iSplit) { Current_Multimap_SizeY=*iSplit; SetSplitScreenSize(*iSplit); rc.top = (long)((double)(rci.bottom-rci.top )*fSplitFact); rct.bottom = rc.top ; } if(bInvCol) { GREEN_COL = GREEN_COL.ChangeBrightness(0.6); BLUE_COL = BLUE_COL.ChangeBrightness(0.6);; LIGHTBLUE_COL = LIGHTBLUE_COL.ChangeBrightness(0.4);; } GPSlat = DrawInfo.Latitude; GPSlon = DrawInfo.Longitude; GPSalt = DrawInfo.Altitude; GPSbrg = DrawInfo.TrackBearing; calc_terrainalt = DerivedDrawInfo.TerrainAlt; calc_altitudeagl = DerivedDrawInfo.AltitudeAGL; GPSalt = DerivedDrawInfo.NavAltitude; bValid = false; iAS_HorDistance = 5000; iAS_Bearing = (int)GPSbrg; iAS_VertDistance= 0; found = CAirspaceManager::Instance().GetNearestAirspaceForSideview(); if(found != NULL) { near_airspace = CAirspaceManager::Instance().GetAirspaceCopy(found); bValid = near_airspace.GetDistanceInfo(bAS_Inside, iAS_HorDistance, iAS_Bearing, iAS_VertDistance); } iABS_AS_HorDistance = abs( iAS_HorDistance); wpt_brg = (long)AngleLimit360(GPSbrg - iAS_Bearing + 90.0); // Variables from ASP system here contain the following informations: // fAS_HorDistance - always contains horizontal distance from the asp, negative if horizontally inside (This does not mean that we're inside vertically as well!) // fAS_Bearing - always contains bearing to the nearest horizontal point // bValid - true if bAS_Inside, iAS_HorDistance, iAS_Bearing, iAS_VertDistance contains valid informations // this will be true if the asp border is close enough to be tracked by the warning system // bAS_Inside - current position is inside in the asp, calculated by the warning system // iAS_HorDistance - horizontal distance to the nearest horizontal border, negative if horizontally inside, calculated by the warning system // iAS_Bearing - bearing to the nearest horizontal border, calculated by the warning system // iAS_VertDistance - vertical distance to the nearest asp border, negative if the border is above us, positive if the border below us, calculated by the warning system // near_airspace.WarningLevel(): // awNone - no warning condition exists // awYellow - current position is near to a warning position // awRed - current posisiton is forbidden by asp system, we are in a warning position /********************************************************************* * calc the horizontal zoom *********************************************************************/ sDia.fXMin = -5000.0; sDia.fXMax = 5000.0; /* even when invalid the horizontal distance is calculated correctly */ if(bValid) { double fScaleDist = iABS_AS_HorDistance; sDia.fXMin = min(-2500.0 , fScaleDist * 1.5 ); sDia.fXMax = max( 2500.0 , fScaleDist * 1.5 ); #ifdef NEAR_AS_ZOOM_1000M if(((iABS_AS_HorDistance) < 900) && (bValid)) // 1km zoom { sDia.fXMin = min(-900.0, fScaleDist * 1.5 ); sDia.fXMax = max( 900.0, fScaleDist * 1.5 ); } #endif #ifdef NEAR_AS_ZOOM_1000FT if((abs(iABS_AS_HorDistance) < 333)) // 1000ft zoom { sDia.fXMin = min(-333.0, fScaleDist * 1.5 ); sDia.fXMax = max( 333.0, fScaleDist * 1.5 ); } #endif } #define RND_FACT 10.0 if( ( sDia.fXMax *fZOOMScale[getsideviewpage]) > 100000) fZOOMScale[getsideviewpage] /= ZOOMFACTOR; if(( sDia.fXMax *fZOOMScale[getsideviewpage]) < 500) { fZOOMScale[getsideviewpage] *= ZOOMFACTOR; } double fOldZoomScale=-1; if(fZOOMScale[getsideviewpage] != fOldZoomScale) { fOldZoomScale = fZOOMScale[getsideviewpage]; sDia.fXMax = sDia.fXMax *fZOOMScale[getsideviewpage]; sDia.fXMin = -sDia.fXMax /5; } /********************************************************************* * calc the vertical zoom *********************************************************************/ sDia.fYMin = max(0.0, GPSalt-2300); sDia.fYMax = max(MAXALTTODAY, GPSalt+1000); if(bValid) { double fBottom = near_airspace.Base()->Altitude; sDia.fYMin = min(fBottom*0.8, sDia.fYMin ); sDia.fYMin = max(0.0, sDia.fYMin ); if(sDia.fYMin < 300) sDia.fYMin =0; sDia.fYMax = max((fBottom*1.2f), sDia.fYMax ); if(abs(iAS_VertDistance) < 250) { sDia.fYMax = ((int)((GPSalt+abs(iAS_VertDistance))/400) + 2) *400 ; sDia.fYMin = ((int)((GPSalt-abs(iAS_VertDistance))/400) - 1) *400 ; if(sDia.fYMin-MIN_ALTITUDE < 0) sDia.fYMin = 0; } #ifdef VERTICAL_ZOOM_50 if(abs(iAS_VertDistance) < 50) { sDia.fYMax = ((int)((GPSalt+abs(iAS_VertDistance))/100) + 2) *100 ; sDia.fYMin = ((int)((GPSalt-abs(iAS_VertDistance))/100) - 1) *100 ; if(sDia.fYMin-MIN_ALTITUDE < 0) sDia.fYMin = 0; } #endif sDia.fYMin = max((double)0.0f,(double) sDia.fYMin); #ifdef OFFSET_SETP if(( sDia.fYMax + fOffset) > MAX_ALTITUDE) fOffset -= OFFSET_SETP; if(( sDia.fYMin + fOffset) < 0.0) fOffset += OFFSET_SETP; sDia.fYMin += fOffset; sDia.fYMax += fOffset; #endif // if(fHeigtScaleFact * sDia.fYMax > MAX_ALTITUDE ) // fHeigtScaleFact /=ZOOMFACTOR; if(fHeigtScaleFact * sDia.fYMax < MIN_ALTITUDE ) fHeigtScaleFact *=ZOOMFACTOR; sDia.fYMax *= fHeigtScaleFact; } /**************************************************************************************************** * draw topview first ****************************************************************************************************/ if(fSplitFact > 0.0) { sDia.rc = rct; sDia.rc.bottom-=1; SharedTopView(Surface, &sDia, (double) iAS_Bearing, (double) wpt_brg); } /**************************************************************************************************** * draw airspace and terrain elements ****************************************************************************************************/ RECT rcc = rc; /* rc corrected */ if(sDia.fYMin < GC_SEA_LEVEL_TOLERANCE) rcc.bottom -= SV_BORDER_Y; /* scale witout sea */ sDia.rc = rcc; RenderAirspaceTerrain(Surface, GPSlat, GPSlon, iAS_Bearing, &sDia ); LKFont hfOld = Surface.SelectObject(LK8InfoNormalFont); if(bValid) { LKASSERT(_tcslen(near_airspace.Name())<TBSIZE); // Diagnostic only in 3.1j, to be REMOVED LK_tcsncpy(Sideview_szNearAS, near_airspace.Name(), TBSIZE ); } else { _stprintf(text,TEXT("%s"), MsgToken(1259)); // LKTOKEN _@M1259_ "Too far, not calculated" Surface.GetTextSize(text, _tcslen(text), &tsize); TxYPt.x = (rc.right-rc.left-tsize.cx)/2; TxYPt.y = (rc.bottom-rc.top)/2; Surface.SetBkMode(TRANSPARENT); Surface.DrawText(TxYPt.x, TxYPt.y-20, text, _tcslen(text)); _stprintf(Sideview_szNearAS,TEXT("%s"), text); } Surface.SelectObject(hfOld); /**************************************************************************************************** * draw airspace and terrain elements ****************************************************************************************************/ /**************************************************************************************************** * draw diagram ****************************************************************************************************/ double xtick = 1.0; double fRange =fabs(sDia.fXMax - sDia.fXMin) ; if (fRange>3.0*1000.0) xtick = 2.0; if (fRange>15*1000.0) xtick = 5.0; if (fRange>50.0*1000.0) xtick = 10.0; if (fRange>100.0*1000.0) xtick = 20.0; if (fRange>200.0*1000.0) xtick = 25.0; if (fRange>250.0*1000.0) xtick = 50.0; if (fRange>500.0*1000.0) xtick = 100.0; if (fRange>1000.0*1000.0) xtick = 1000.0; if(bInvCol) { Surface.SelectObject(LK_BLACK_PEN); Surface.SelectObject(LKBrush_Black); } else { Surface.SelectObject(LK_WHITE_PEN); Surface.SelectObject(LKBrush_White); } LKColor txtCol = GROUND_TEXT_COLOUR; if(bInvCol) if(sDia.fYMin > GC_SEA_LEVEL_TOLERANCE) txtCol = INV_GROUND_TEXT_COLOUR; Surface.SetBkMode(TRANSPARENT); Surface.SetTextColor(txtCol); _stprintf(text, TEXT("%s"),Units::GetUnitName(Units::GetUserDistanceUnit())); switch(GetMMNorthUp(getsideviewpage)) { case NORTHUP: default: DrawXGrid(Surface, rc , xtick/DISTANCEMODIFY, xtick, 0,TEXT_ABOVE_LEFT, RGB_BLACK, &sDia,text); break; case TRACKUP: DrawXGrid(Surface, rci, xtick/DISTANCEMODIFY, xtick, 0,TEXT_ABOVE_LEFT, RGB_BLACK, &sDia,text); break; } Surface.SetTextColor(Sideview_TextColor); double fHeight = (sDia.fYMax-sDia.fYMin); double ytick = 100.0; if (fHeight >500.0) ytick = 200.0; if (fHeight >1000.0) ytick = 500.0; if (fHeight >2000.0) ytick = 1000.0; if (fHeight >4000.0) ytick = 2000.0; if (fHeight >8000.0) ytick = 4000.0; if(Units::GetUserAltitudeUnit() == unFeet) ytick = ytick * FEET_FACTOR; _stprintf(text, TEXT("%s"),Units::GetUnitName(Units::GetUserAltitudeUnit())); if(sDia.fYMin < GC_SEA_LEVEL_TOLERANCE) rc.bottom -= SV_BORDER_Y; /* scale witout sea */ DrawYGrid(Surface, rc, ytick/ALTITUDEMODIFY,ytick, 0,TEXT_UNDER_RIGHT ,Sideview_TextColor, &sDia, text); if(!bInvCol) Surface.SetBkMode(OPAQUE); /**************************************************************************************************** * draw AGL ****************************************************************************************************/ if(calc_altitudeagl - sDia.fYMin > 500) { Surface.SetTextColor(LIGHTBLUE_COL); Units::FormatUserAltitude(calc_altitudeagl, buffer, 7); LK_tcsncpy(text, MsgToken(1742), TBSIZE-_tcslen(buffer)); // AGL: _tcscat(text,buffer); Surface.GetTextSize(text, _tcslen(text), &tsize); TxYPt.x = CalcDistanceCoordinat(0, &sDia)- tsize.cx/2; TxYPt.y = CalcHeightCoordinat( (calc_terrainalt + calc_altitudeagl )*0.8, &sDia ); if((tsize.cy) < ( CalcHeightCoordinat( calc_terrainalt, &sDia )- TxYPt.y )) { Surface.DrawText(TxYPt.x+IBLSCALE(1), TxYPt.y , text, _tcslen(text)); } } Surface.SetBkMode(TRANSPARENT); /**************************************************************************************************** * Print current Elevation ****************************************************************************************************/ Surface.SetTextColor(RGB_BLACK); int x,y; if((calc_terrainalt- sDia.fYMin) > 0) { Units::FormatUserAltitude(calc_terrainalt, buffer, 7); LK_tcsncpy(text, MsgToken(1743), TBSIZE-_tcslen(buffer)); // ELV: _tcscat(text,buffer); Surface.GetTextSize(text, _tcslen(text), &tsize); x = CalcDistanceCoordinat(0, &sDia) - tsize.cx/2; y = CalcHeightCoordinat( calc_terrainalt, &sDia ); if ((ELV_FACT*tsize.cy) < abs(rc.bottom - y)) { Surface.DrawText(x, rc.bottom -(int)(ELV_FACT * tsize.cy), text, _tcslen(text)); } } /**************************************************************************************************** * draw side elements ****************************************************************************************************/ Surface.SetTextColor(Sideview_TextColor); Surface.SetBkMode(OPAQUE); LKFont hfOld2 = Surface.SelectObject(LK8InfoNormalFont); // DrawTelescope ( hdc, iAS_Bearing-90.0, rc.right - NIBLSCALE(13), rc.top + NIBLSCALE(58)); Surface.SelectObject(hfOld2); Surface.SetBkMode(TRANSPARENT); Surface.SelectObject(hfOld); Surface.SetTextColor(GROUND_TEXT_COLOUR); if(bInvCol) if(sDia.fYMin > GC_SEA_LEVEL_TOLERANCE) Surface.SetTextColor(INV_GROUND_TEXT_COLOUR); /****************************************************************************************************/ /****************************************************************************************************/ /**************************************************************************************************** * draw distances to next airspace ****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ if (bValid) { /**************************************************************************************************** * draw horizontal distance to next airspace ****************************************************************************************************/ Surface.SetTextColor(Sideview_TextColor); Surface.SetBkMode(OPAQUE); LKFont hfOldU = Surface.SelectObject(LK8InfoNormalFont); // horizontal distance line[0].x = CalcDistanceCoordinat(0, &sDia); line[0].y = CalcHeightCoordinat( GPSalt, &sDia ); line[1].x = CalcDistanceCoordinat(iABS_AS_HorDistance, &sDia); line[1].y = line[0].y; Surface.DrawDashLine(THICK_LINE, line[0], line[1], Sideview_TextColor, rc); if(iAS_HorDistance < 0) { line[0].y = CalcHeightCoordinat( GPSalt - (double)iAS_VertDistance, &sDia ); line[1].y = line[0].y; Surface.DrawDashLine(THICK_LINE, line[0], line[1], Sideview_TextColor, rc); } bool bLeft = false; if( line[0].x < line[1].x) bLeft = false; else bLeft = true; Units::FormatUserDistance(iABS_AS_HorDistance, buffer, 7); _stprintf(text,_T(" %s"),buffer); Surface.GetTextSize(text, _tcslen(text), &tsize); if((GPSalt- sDia.fYMin /*-calc_terrainalt */) < 300) TxXPt.y = CalcHeightCoordinat( GPSalt, &sDia ) - tsize.cy; else TxXPt.y = CalcHeightCoordinat( GPSalt, &sDia ) + NIBLSCALE(3); if(tsize.cx > (line[1].x - line[0].x) ) TxXPt.x = CalcDistanceCoordinat( iABS_AS_HorDistance ,&sDia) -tsize.cx- NIBLSCALE(3); else TxXPt.x = CalcDistanceCoordinat( iABS_AS_HorDistance / 2.0, &sDia) -tsize.cx/2; Surface.DrawText(TxXPt.x, TxXPt.y, text, _tcslen(text)); /**************************************************************************************************** * draw vertical distance to next airspace ****************************************************************************************************/ line[0].x = CalcDistanceCoordinat( iABS_AS_HorDistance , &sDia); line[0].y = CalcHeightCoordinat( GPSalt, &sDia ); line[1].x = line[0].x; line[1].y = CalcHeightCoordinat( GPSalt - (double)iAS_VertDistance, &sDia ); Surface.DrawDashLine(THICK_LINE, line[0], line[1], Sideview_TextColor, rc); Units::FormatUserAltitude( (double)abs(iAS_VertDistance), buffer, 7); _stprintf(text,_T(" %s"),buffer); Surface.GetTextSize(text, _tcslen(text), &tsize); if ( bLeft ) TxYPt.x = CalcDistanceCoordinat(iABS_AS_HorDistance, &sDia)- tsize.cx - NIBLSCALE(3); else TxYPt.x = CalcDistanceCoordinat(iABS_AS_HorDistance, &sDia)+ NIBLSCALE(5); if( abs( line[0].y - line[1].y) > tsize.cy) TxYPt.y = CalcHeightCoordinat( GPSalt - (double)iAS_VertDistance/2.0, &sDia) -tsize.cy/2 ; else TxYPt.y = min( line[0].y , line[1].y) - tsize.cy ; Surface.DrawText(TxYPt.x, TxYPt.y , text, _tcslen(text)); Surface.SelectObject(hfOldU); } /**************************************************************************************************** * draw plane sideview at least ****************************************************************************************************/ RenderPlaneSideview(Surface, 0.0 , GPSalt,wpt_brg, &sDia ); hfOldFnt = Surface.SelectObject(LK8InfoNormalFont/* Sender->GetFont()*/); DrawMultimap_SideTopSeparator(Surface,rct); /**************************************************************************************************** * draw selection frame ****************************************************************************************************/ if(bHeightScale) DrawSelectionFrame(Surface, rc); #ifdef TOP_SELECTION_FRAME else DrawSelectionFrame(hdc, rci); #endif Surface.SelectObject(hfOldFnt/* Sender->GetFont()*/); Surface.SetBkMode(TRANSPARENT); Surface.SelectObject(hfOldFnt/* Sender->GetFont()*/); }