Esempio n. 1
0
// 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;

}
Esempio n. 2
0
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;

}
Esempio n. 3
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;

}
Esempio n. 4
0
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;

}
Esempio n. 5
0
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()*/);
}