void MapWindow::DrawTeammate(HDC hdc, RECT rc) { POINT point; if (TeammateCodeValid) { if(PointVisible(TeammateLongitude, TeammateLatitude) ) { LatLon2Screen(TeammateLongitude, TeammateLatitude, point); SelectObject(hDCTemp,hBmpTeammatePosition); DrawBitmapX(hdc, point.x-NIBLSCALE(10), point.y-NIBLSCALE(10), 20,20, hDCTemp,0,0,SRCPAINT,true); DrawBitmapX(hdc, point.x-NIBLSCALE(10), point.y-NIBLSCALE(10), 20,20, hDCTemp,20,0,SRCAND,true); } } }
void MapWindow::DrawHeadUpLine(HDC hdc, POINT Orig, RECT rc, double fMin, double fMax ) { COLORREF rgbCol = RGB_BLACK; POINT p1, p2; double tmp = fMax*zoom.ResScaleOverDistanceModify(); double trackbearing = DisplayAircraftAngle+ (DerivedDrawInfo.Heading-DrawInfo.TrackBearing); p2.y= Orig.y - (int)(tmp*fastcosine(trackbearing)); p2.x= Orig.x + (int)(tmp*fastsine(trackbearing)); p1.y= Orig.y; p1.x= Orig.x; if (BlackScreen) rgbCol = RGB_INVDRAW; ForcedClipping=true; // Reduce the rectangle for a better effect rc.top+=NIBLSCALE(5); rc.right-=NIBLSCALE(5); rc.bottom-=NIBLSCALE(5); rc.left+=NIBLSCALE(5); _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p1, p2, rgbCol, rc); ForcedClipping=false; }
void MapWindow::DrawCrossHairs(HDC hdc, const POINT Orig, const RECT rc) { POINT o1, o2; o1.x = Orig.x+NIBLSCALE(20); o2.x = Orig.x-NIBLSCALE(20); o1.y = Orig.y; o2.y = Orig.y; if (BlackScreen) _DrawLine(hdc, PS_SOLID, 1, o1, o2, RGB_INVDRAW, rc); else _DrawLine(hdc, PS_SOLID, 1, o1, o2, RGB_DARKGREY, rc); SetPixel(hdc,o1.x,o1.y,RGB_YELLOW); SetPixel(hdc,o2.x,o2.y,RGB_YELLOW); o1.x = Orig.x; o2.x = Orig.x; o1.y = Orig.y+NIBLSCALE(20); o2.y = Orig.y-NIBLSCALE(20); if (BlackScreen) _DrawLine(hdc, PS_SOLID, 1, o1, o2, RGB_INVDRAW, rc); // 091219 else _DrawLine(hdc, PS_SOLID, 1, o1, o2, RGB_DARKGREY, rc); // 091219 SetPixel(hdc,o1.x,o1.y,RGB_YELLOW); SetPixel(hdc,o2.x,o2.y,RGB_YELLOW); }
void MapWindow::CalculateOrigin(const RECT rc, POINT *Orig) { if (mode.Is(Mode::MODE_PAN)) { // North up DisplayAngle = 0.0; DisplayAircraftAngle = DrawInfo.TrackBearing; GliderCenter = true; } else { if (mode.Is(Mode::MODE_TARGET_PAN)) { CalculateOrientationTargetPan(); } else { CalculateOrientationNormal(); } } if(mode.Is(Mode::MODE_TARGET_PAN)) { if (ScreenLandscape) { Orig->x = (rc.left + rc.right - targetPanSize)/2; Orig->y = (rc.bottom + rc.top)/2; } else { Orig->x = (rc.left + rc.right)/2; Orig->y = (rc.bottom + rc.top + targetPanSize)/2; } } else if(mode.Is(Mode::MODE_PAN) || mode.Is(Mode::MODE_CIRCLING)) { Orig->x = (rc.left + rc.right)/2; Orig->y = (rc.bottom + rc.top)/2; } else { // automagic northup smart if (DisplayOrientation == NORTHSMART) { double trackbearing = DrawInfo.TrackBearing; int middleXY,spanxy; if (ScreenLandscape) { middleXY=((rc.bottom-BottomSize)+rc.top)/2; spanxy=NIBLSCALE(50); Orig->y= middleXY + (int)(spanxy*fastcosine(trackbearing)); // This was moving too much the map! // spanx=NIBLSCALE(40); // Orig->x= middleX - (int)(spanx*fastsine(trackbearing)); Orig->x = (rc.left + rc.right)/2; } else { middleXY=(rc.left+rc.right)/2; spanxy=NIBLSCALE(50); Orig->x= middleXY - (int)(spanxy*fastsine(trackbearing)); Orig->y = ((rc.bottom-BottomSize) + rc.top)/2; } } else { // 100924 if we are in north up autorient, position the glider in middle screen if ((zoom.Scale()*1.4) >= AutoOrientScale) { Orig->x = (rc.left + rc.right)/2; Orig->y=((rc.bottom-BottomSize)+rc.top)/2; } else { // else do it normally using configuration Orig->x = ((rc.right - rc.left )*GliderScreenPositionX/100)+rc.left; Orig->y = ((rc.top - rc.bottom )*GliderScreenPositionY/100)+rc.bottom; } } } }
void MapWindow::DrawTeammate(LKSurface& Surface, const RECT& rc, const ScreenProjection& _Proj) { if (TeammateCodeValid) { if (PointVisible(TeammateLongitude, TeammateLatitude)) { const POINT point = _Proj.LonLat2Screen(TeammateLongitude, TeammateLatitude); hBmpTeammatePosition.Draw(Surface, point.x - NIBLSCALE(10), point.y - NIBLSCALE(10), IBLSCALE(20), IBLSCALE(20)); } } }
void MapWindow::DrawHeadUpLine(LKSurface& Surface, const POINT& Orig, const RECT& rc, double fMin, double fMax ) { const double tmp = fMax*zoom.ResScaleOverDistanceModify(); const double trackbearing = DisplayAircraftAngle+ (DerivedDrawInfo.Heading-DrawInfo.TrackBearing); const POINT p2 = { Orig.x + (int)(tmp*fastsine(trackbearing)), Orig.y - (int)(tmp*fastcosine(trackbearing)) }; const LKColor rgbCol = BlackScreen?RGB_INVDRAW:RGB_BLACK; // Reduce the rectangle for a better effect const RECT ClipRect = {rc.left+NIBLSCALE(5), rc.top+NIBLSCALE(5), rc.right-NIBLSCALE(5), rc.bottom-NIBLSCALE(5) }; Surface.DrawLine(PEN_SOLID, NIBLSCALE(1), Orig, p2, rgbCol, ClipRect); }
void MapWindow::DrawBitmapIn(LKSurface& Surface, const POINT &sc, const LKIcon& Icon, const bool autostretch) { if (!Icon) return; // don't draw Bitmap if no bitmap if (!PointVisible(sc)) return; assert(Icon.GetSize().cx == 10); assert(Icon.GetSize().cy == 10); if (autostretch) { Icon.Draw(Surface, sc.x - NIBLSCALE(5), sc.y - NIBLSCALE(5), IBLSCALE(10), IBLSCALE(10)); } else { Icon.Draw(Surface, sc.x - NIBLSCALE(5), sc.y - NIBLSCALE(5), 10, 10); } }
void MapWindow::DrawBitmapIn(const HDC hdc, const POINT &sc, const HBITMAP h, const bool autostretch) { if (!PointVisible(sc)) return; SelectObject(hDCTemp, h); DrawBitmapX(hdc, sc.x-NIBLSCALE(5), sc.y-NIBLSCALE(5), 10,10, hDCTemp,0,0,SRCPAINT, autostretch); DrawBitmapX(hdc, sc.x-NIBLSCALE(5), sc.y-NIBLSCALE(5), 10,10, hDCTemp,10,0,SRCAND, autostretch); }
void DrawTelescope(HDC hdc, double fAngle, int x, int y) { POINT Telescope[17] = { { 6 , 7 }, // 1 { 6 , 2 }, // 2 { 8 , -2 }, // 3 { 8 , -7 }, // 4 { 1 , -7 }, // 5 { 1 , -2 }, // 6 { -1 , -2 }, // 7 { -1 , -7 }, // 8 { -8 , -7 }, // 9 { -8 , -2 }, // 10 { -6 , 2 }, // 11 { -6 , 7 }, // 12 { -1 , 7 }, // 13 { -1 , 3 }, // 14 { 1 , 3 }, // 15 { 1 , 7 }, // 16 { 4 , 7 } // 17 }; bool bBlack = true; DrawWindRoseDirection( hdc, AngleLimit360( fAngle ), x, y + NIBLSCALE(18)); PolygonRotateShift(Telescope, 17, x, y, AngleLimit360( fAngle )); LKPen oldBPen ; LKBrush oldBrush ; if (!bBlack) { oldBPen = Surface.SelectObject(LK_WHITE_PEN)); oldBrush = Surface.SelectObject(LKBrush_White); }
void VDrawLine(const HDC&hdc, const RECT rc, int x1, int y1, int x2, int y2, COLORREF col) { POINT p0,p1; p0.x = x1; p0.y = y1; p1.x = x2; p1.y = y2; MapWindow::_DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p0, p1, col, rc); }
// LK Status message void MapWindow::DrawLKStatus(HDC hdc, RECT rc) { TextInBoxMode_t TextDisplayMode = {0}; TCHAR Buffer[LKSIZEBUFFERLARGE]; short bottomlines; short middlex=(rc.right-rc.left)/2; short left=rc.left+NIBLSCALE(5); short contenttop=rc.top+NIBLSCALE(50); TextDisplayMode.Color = RGB_BLACK; TextDisplayMode.NoSetFont = 1; //TextDisplayMode.AlligneRight = 0; TextDisplayMode.AlligneCenter = 1; TextDisplayMode.WhiteBold = 1; TextDisplayMode.Border = 1; // HFONT oldfont=(HFONT)Surface.SelectObject(LK8PanelBigFont); switch(ModeIndex) { case LKMODE_MAP: _stprintf(Buffer,TEXT("MAP mode, 1 of 1")); break; case LKMODE_INFOMODE: _stprintf(Buffer,TEXT("%d-%d"), ModeIndex,CURTYPE+1); break; case LKMODE_WP: _stprintf(Buffer,TEXT("%d-%d"), ModeIndex,CURTYPE+1); break; case LKMODE_NAV: _stprintf(Buffer,TEXT("%d-%d"), ModeIndex,CURTYPE+1); break; default: _stprintf(Buffer,TEXT("UNKOWN mode")); break; } TextInBox(hdc, &rc, Buffer, middlex, 200 , 0, &TextDisplayMode, false); //Surface.SelectObject(oldfont); return; }
// // The heading track line, like on Garmin units // void MapWindow::DrawHeading(HDC hdc, POINT Orig, RECT rc ) { if (DrawInfo.NAVWarning) return; // 100214 if ( mode.Is(MapWindow::Mode::MODE_CIRCLING)) return; POINT p2; double tmp = 200000*zoom.ResScaleOverDistanceModify(); if ( !( DisplayOrientation == TRACKUP || DisplayOrientation == NORTHCIRCLE || DisplayOrientation == TRACKCIRCLE )) { double trackbearing = DrawInfo.TrackBearing; p2.y= Orig.y - (int)(tmp*fastcosine(trackbearing)); p2.x= Orig.x + (int)(tmp*fastsine(trackbearing)); } else { p2.x=Orig.x; p2.y=Orig.y-(int)tmp; } // Reduce the rectangle for a better effect rc.top+=NIBLSCALE(5); rc.right-=NIBLSCALE(5); rc.bottom-=NIBLSCALE(5); rc.left+=NIBLSCALE(5); ForcedClipping=true; if (BlackScreen) _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), Orig, p2, RGB_INVDRAW, rc); // 091109 else _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), Orig, p2, RGB_BLACK, rc); ForcedClipping=false; }
// // The heading track line, like on Garmin units // void MapWindow::DrawHeading(HDC hdc, POINT Orig, RECT rc ) { if (GPS_INFO.NAVWarning) return; // 100214 if (zoom.RealScale()>5 || mode.Is(MapWindow::Mode::MODE_CIRCLING)) return; POINT p2; double tmp = 12000*zoom.ResScaleOverDistanceModify(); if ( !( DisplayOrientation == TRACKUP || DisplayOrientation == NORTHCIRCLE || DisplayOrientation == TRACKCIRCLE )) { double trackbearing = DrawInfo.TrackBearing; p2.y= Orig.y - (int)(tmp*fastcosine(trackbearing)); p2.x= Orig.x + (int)(tmp*fastsine(trackbearing)); } else { p2.x=Orig.x; p2.y=Orig.y-(int)tmp; } if (BlackScreen) _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), Orig, p2, RGB_INVDRAW, rc); // 091109 else _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), Orig, p2, RGB_BLACK, rc); }
// // Turn Rate Indicator // void MapWindow::DrawAcceleration(HDC hDC, const RECT rc) { const double ScaleX = (rc.right - rc.left)/10; const double ScaleY = (rc.top - rc.bottom)/10; const double ScaleZ = (rc.top - rc.bottom)/20; POINT Pos; Pos.x = (rc.right - rc.left)/2 + (int)(DrawInfo.AccelY * ScaleX); Pos.y = (rc.bottom - rc.top)/2 - (int)((DrawInfo.AccelZ - 1) * ScaleY); const double radius = NIBLSCALE(15) + (int)(DrawInfo.AccelX * ScaleZ); const HPEN oldPen = (HPEN) SelectObject(hDC, GetStockObject(BLACK_PEN)); const HBRUSH oldBrush = (HBRUSH)SelectObject(hDC, LKBrush_Red); Circle(hDC, Pos.x, Pos.y - (int)(radius/2), (int)radius, rc, true, true); SelectObject(hDC, oldBrush); SelectObject(hDC, oldPen); }
void MapWindow::DrawStartEndSector(LKSurface& Surface, const RECT& rc, const POINT &Start, const POINT &End, int Index, int Type, double Radius) { double tmp; LKSurface::OldPen oldpen; LKSurface::OldBrush oldbrush; switch (Type) { case 0: // CIRCLE tmp = Radius * zoom.ResScaleOverDistanceModify(); oldpen = Surface.SelectObject(hpStartFinishThick); oldbrush = Surface.SelectObject(LKBrush_Hollow); Surface.Circle(WayPointList[Index].Screen.x, WayPointList[Index].Screen.y, (int) tmp, rc, false, false); Surface.SelectObject(LKPen_Red_N1); Surface.Circle(WayPointList[Index].Screen.x, WayPointList[Index].Screen.y, (int) tmp, rc, false, false); Surface.SelectObject(oldpen); Surface.SelectObject(oldbrush); break; case 1: // LINE Surface.DrawLine(PEN_SOLID, NIBLSCALE(5), End, Start, taskcolor, rc); Surface.DrawLine(PEN_SOLID, NIBLSCALE(1), End, Start, LKColor(255, 0, 0), rc); break; case 2: // SECTOR Surface.DrawLine(PEN_SOLID, NIBLSCALE(5), WayPointList[Index].Screen, Start, taskcolor, rc); Surface.DrawLine(PEN_SOLID, NIBLSCALE(5), WayPointList[Index].Screen, End, taskcolor, rc); Surface.DrawLine(PEN_SOLID, NIBLSCALE(1), WayPointList[Index].Screen, Start, LKColor(255, 0, 0), rc); Surface.DrawLine(PEN_SOLID, NIBLSCALE(1), WayPointList[Index].Screen, End, LKColor(255, 0, 0), rc); break; } }
static void OnProgressPaint(WindowControl * Sender, LKSurface& Surface) { RECT PrintAreaR = Sender->GetClientRect(); const auto oldFont = Surface.SelectObject(MapWindowBoldFont); Surface.FillRect(&PrintAreaR, LKBrush_Petrol); // Create text area // we cannot use LKPen here because they are not still initialised for startup menu. no problem LKPen hP(PEN_SOLID,NIBLSCALE(1),RGB_GREEN); auto ohP = Surface.SelectObject(hP); const auto ohB = Surface.SelectObject(LKBrush_Petrol); Surface.Rectangle(PrintAreaR.left,PrintAreaR.top,PrintAreaR.right,PrintAreaR.bottom); Surface.SelectObject(ohP); hP.Release(); hP.Create(PEN_SOLID,NIBLSCALE(1),RGB_BLACK); ohP = Surface.SelectObject(hP); Surface.SelectObject(LK_HOLLOW_BRUSH); InflateRect(&PrintAreaR, -NIBLSCALE(2), -NIBLSCALE(2)); Surface.Rectangle(PrintAreaR.left,PrintAreaR.top,PrintAreaR.right,PrintAreaR.bottom); Surface.SetTextColor(RGB_WHITE); Surface.SetBackgroundTransparent(); InflateRect(&PrintAreaR, -NIBLSCALE(2), -NIBLSCALE(2)); const TCHAR* text = Sender->GetCaption(); Surface.DrawText(text, &PrintAreaR, DT_VCENTER|DT_SINGLELINE); Surface.SelectObject(ohB); Surface.SelectObject(ohP); Surface.SelectObject(oldFont); }
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::DrawAirspaceLabels(HDC hdc, const RECT rc, const POINT Orig_Aircraft) { static short int label_sequencing_divider = 0; CAirspaceList::const_iterator it; const CAirspaceList& airspaces_to_draw = CAirspaceManager::Instance().GetAirspacesForWarningLabels(); if (label_sequencing_divider) --label_sequencing_divider; // Draw warning position and label on top of all airspaces if (1) { CCriticalSection::CGuard guard(CAirspaceManager::Instance().MutexRef()); for (it=airspaces_to_draw.begin(); it != airspaces_to_draw.end(); ++it) { if ((*it)->WarningLevel() > awNone) { POINT sc; double lon; double lat; int vdist; AirspaceWarningDrawStyle_t vlabeldrawstyle, hlabeldrawstyle; bool distances_ready = (*it)->GetWarningPoint(lon, lat, hlabeldrawstyle, vdist, vlabeldrawstyle); TCHAR hbuf[NAME_SIZE+16], vDistanceText[16]; TextInBoxMode_t TextDisplayMode = {0}; bool hlabel_draws = false; bool vlabel_draws = false; // Horizontal warning point if (distances_ready && (hlabeldrawstyle > awsHidden) && PointVisible(lon, lat)) { LatLon2Screen(lon, lat, sc); DrawBitmapIn(hdc, sc, hAirspaceWarning,true); Units::FormatUserAltitude(vdist, vDistanceText, sizeof(vDistanceText)/sizeof(vDistanceText[0])); _tcscpy(hbuf, (*it)->Name()); wcscat(hbuf, TEXT(" ")); wcscat(hbuf, vDistanceText); switch (hlabeldrawstyle) { default: case awsHidden: case awsBlack: TextDisplayMode.Color = RGB_BLACK; break; case awsAmber: TextDisplayMode.Color = RGB_ORANGE; break; case awsRed: TextDisplayMode.Color = RGB_RED; break; } // sw TextDisplayMode.SetTextColor = 1; TextDisplayMode.AlligneCenter = 1; if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.Border = 1; } else { if (TextDisplayMode.Color==RGB_BLACK) TextDisplayMode.WhiteBold = 0; // no black outline for black background.. else TextDisplayMode.WhiteBold = 1; // outlined } hlabel_draws = TextInBox(hdc, &rc, hbuf, sc.x, sc.y+NIBLSCALE(15), 0, &TextDisplayMode, true); } // Vertical warning point if (distances_ready && vlabeldrawstyle > awsHidden) { //DrawBitmapIn(hdc, Orig_Aircraft, hAirspaceWarning); Units::FormatUserAltitude(vdist, vDistanceText, sizeof(vDistanceText)/sizeof(vDistanceText[0])); _tcscpy(hbuf, (*it)->Name()); wcscat(hbuf, TEXT(" ")); wcscat(hbuf, vDistanceText); switch (vlabeldrawstyle) { default: case awsHidden: case awsBlack: TextDisplayMode.Color = RGB_BLACK; break; case awsAmber: TextDisplayMode.Color = RGB_ORANGE; break; case awsRed: TextDisplayMode.Color = RGB_RED; break; } // sw TextDisplayMode.SetTextColor = 1; TextDisplayMode.AlligneCenter = 1; if ( (MapBox == (MapBox_t)mbBoxed) || (MapBox == (MapBox_t)mbBoxedNoUnit)) { TextDisplayMode.Border = 1; } else { if (TextDisplayMode.Color==RGB_BLACK) TextDisplayMode.WhiteBold = 0; // no black outline for black background.. else TextDisplayMode.WhiteBold = 1; // outlined } vlabel_draws = TextInBox(hdc, &rc, hbuf, Orig_Aircraft.x, Orig_Aircraft.y+NIBLSCALE(15), 0, &TextDisplayMode, true); } if (!label_sequencing_divider) CAirspaceManager::Instance().AirspaceWarningLabelPrinted(**it, hlabel_draws || vlabel_draws); }// if warnlevel>awnone }//for }// if(1) mutex if (!label_sequencing_divider) label_sequencing_divider=3; // Do label sequencing slower than update rate }
HWND CreateProgressDialog(TCHAR* text) { static int yFontSize, xFontSize; HDC hTempDC = NULL; if (doinitprogress) { doinitprogress=false; DWORD Style=0; Style = WS_CHILD | ES_MULTILINE | ES_CENTER | ES_READONLY | WS_CLIPCHILDREN | WS_CLIPSIBLINGS; hStartupWindow=CreateWindow(TEXT("STATIC"), TEXT("\0"), Style, 0, 0, ScreenSizeX, ScreenSizeY, hWndMainWindow, NULL, hInst, NULL); if (hStartupWindow==NULL) { StartupStore(_T("***** CRITIC, no startup window!%s"),NEWLINE); FailStore(_T("CRITIC, no startup window!")); return NULL; } if (!(hStartupDC = GetDC(hStartupWindow))) { StartupStore(_T("------ Cannot state startup window%s"),NEWLINE); FailStore(_T("Cannot state startup window")); return(NULL); } /* SHFullScreen(hProgress, SHFS_HIDETASKBAR |SHFS_HIDESIPBUTTON |SHFS_HIDESTARTICON); SetWindowPos(hProgress,HWND_TOP,0,0,0,0, SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW); */ //RECT rt; //GetClientRect(hStartupWindow,&rt); //FillRect(hStartupDC,&rt,(HBRUSH)GetStockObject(BLACK_BRUSH)); //SetWindowPos(hStartupWindow,HWND_TOP,0,0,0,0, SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW); //SHFullScreen(hStartupWindow, SHFS_HIDETASKBAR |SHFS_HIDESIPBUTTON |SHFS_HIDESTARTICON); //SetForegroundWindow(hStartupWindow); //UpdateWindow(hStartupWindow); ShowWindow(hStartupWindow,SW_SHOWNORMAL); BringWindowToTop(hStartupWindow); // Load welcome screen bitmap HBITMAP hWelcomeBitmap=NULL; TCHAR sDir[MAX_PATH]; TCHAR srcfile[MAX_PATH]; LocalPath(sDir,TEXT(LKD_BITMAPS)); // first look for lkstart_480x272.bmp for example _stprintf(srcfile,_T("%s\\LKSTART_%s.BMP"),sDir, GetSizeSuffix() ); if ( GetFileAttributes(srcfile) == 0xffffffff ) { // no custom file, get a generic one switch(ScreenSize) { case ss800x480: case ss640x480: case ss720x408: case ss896x672: _stprintf(srcfile,_T("%s\\LKSTART_LB.BMP"),sDir); break; case ss480x272: case ss480x234: case ss400x240: case ss320x240: _stprintf(srcfile,_T("%s\\LKSTART_LS.BMP"),sDir); break; case ss480x640: case ss480x800: _stprintf(srcfile,_T("%s\\LKSTART_PB.BMP"),sDir); break; case ss240x320: case ss272x480: _stprintf(srcfile,_T("%s\\LKSTART_PS.BMP"),sDir); break; default: _stprintf(srcfile,_T("%s\\LKSTART_DEFAULT.BMP"),sDir); break; } } #if (WINDOWSPC>0) hWelcomeBitmap=(HBITMAP)LoadImage(GetModuleHandle(NULL),srcfile,IMAGE_BITMAP,0,0,LR_LOADFROMFILE); #else hWelcomeBitmap=(HBITMAP)SHLoadDIBitmap(srcfile); #endif // still nothing? use internal (poor man) resource if (hWelcomeBitmap==NULL) hWelcomeBitmap=LoadBitmap(hInst, MAKEINTRESOURCE(IDB_SWIFT)); hTempDC = CreateCompatibleDC(hStartupDC); // AA HBITMAP oldBitmap = (HBITMAP)SelectObject(hTempDC, hWelcomeBitmap); SelectObject(hTempDC, LKSTARTBOTTOMFONT); SIZE TextSize; GetTextExtentPoint(hTempDC, _T("X"),1, &TextSize); yFontSize = TextSize.cy; xFontSize = TextSize.cx; BITMAP bm; GetObject(hWelcomeBitmap,sizeof(bm), &bm); StretchBlt(hStartupDC,0,0, ScreenSizeX,ScreenSizeY-1, hTempDC, 0, 0, 2,2, BLACKNESS); if ( (bm.bmWidth >ScreenSizeX)||(bm.bmHeight>ScreenSizeY)) { StretchBlt(hStartupDC,0,0, ScreenSizeX,ScreenSizeY-NIBLSCALE(2)-(yFontSize*2)-1, hTempDC, 0, 0, bm.bmWidth,bm.bmHeight, SRCCOPY); } else { BitBlt(hStartupDC,(ScreenSizeX-bm.bmWidth)/2,0,bm.bmWidth,bm.bmHeight,hTempDC, 0, 0, SRCCOPY); } DeleteObject(hWelcomeBitmap); // AA SelectObject(hTempDC, oldBitmap); if (DeleteDC(hTempDC)==0) StartupStore(_T("**** Cannot delete hTempDC\n")); } BringWindowToTop(hStartupWindow); // we shall return here also on shutdown and file reloads // RECT is left, top, right, bottom RECT PrintAreaR; PrintAreaR.left = NIBLSCALE(2); PrintAreaR.bottom = ScreenSizeY-NIBLSCALE(2); PrintAreaR.top = PrintAreaR.bottom - (yFontSize*2); PrintAreaR.right = ScreenSizeX - NIBLSCALE(2); HFONT oldFont=(HFONT)SelectObject(hStartupDC,LKSTARTBOTTOMFONT); HBRUSH hB=LKBrush_Petrol; FillRect(hStartupDC,&PrintAreaR, hB); // Create text area // we cannot use LKPen here because they are not still initialised for startup menu. no problem HPEN hP=(HPEN) CreatePen(PS_SOLID,NIBLSCALE(1),RGB_GREEN); SelectObject(hStartupDC,hP); SelectObject(hStartupDC,hB); Rectangle(hStartupDC, PrintAreaR.left,PrintAreaR.top,PrintAreaR.right,PrintAreaR.bottom); DeleteObject(hP); hP=(HPEN) CreatePen(PS_SOLID,NIBLSCALE(1),RGB_BLACK); SelectObject(hStartupDC,hP); Rectangle(hStartupDC, PrintAreaR.left+NIBLSCALE(2),PrintAreaR.top+NIBLSCALE(2),PrintAreaR.right-NIBLSCALE(2),PrintAreaR.bottom-NIBLSCALE(2)); SetTextColor(hStartupDC,RGB_WHITE); SetBkMode(hStartupDC,TRANSPARENT); unsigned int maxchars= (ScreenSizeX/xFontSize)-1; if (_tcslen(text) <maxchars) { maxchars=_tcslen(text); } ExtTextOut(hStartupDC,PrintAreaR.left+(xFontSize/2),PrintAreaR.top + ((PrintAreaR.bottom - PrintAreaR.top)/2)-(yFontSize/2), ETO_OPAQUE,NULL,text,maxchars,NULL); SelectObject(hStartupDC,oldFont); // Sleep(300); // Slow down display of data? No because in case of important things, Sleep is set by calling part DeleteObject(hP); return hStartupWindow; }
void MapWindow::DrawTask(HDC hdc, RECT rc, const POINT &Orig_Aircraft) { int i; double tmp; COLORREF whitecolor = RGB_WHITE; COLORREF origcolor = SetTextColor(hDCTemp, whitecolor); HPEN oldpen = 0; HBRUSH oldbrush = 0; static short size_tasklines=0; if (DoInit[MDI_DRAWTASK]) { switch (ScreenSize) { case ss480x272: case ss272x480: case ss320x240: case ss240x320: size_tasklines=NIBLSCALE(4); break; default: size_tasklines=NIBLSCALE(3); break; } DoInit[MDI_DRAWTASK]=false; } if (!WayPointList) return; oldpen = (HPEN) SelectObject(hdc, hpStartFinishThick); oldbrush = (HBRUSH) SelectObject(hdc, GetStockObject(HOLLOW_BRUSH)); LockTaskData(); // protect from external task changes for (i = 1; ValidTaskPoint(i); i++) { if (!ValidTaskPoint(i + 1)) { // final waypoint if (ActiveWayPoint > 1 || !ValidTaskPoint(2)) { // only draw finish line when past the first // waypoint. FIXED 110307: or if task is with only 2 tps DrawStartEndSector(hdc, rc, Task[i].Start, Task[i].End, Task[i].Index, FinishLine, FinishRadius); } } else { // normal sector if (AATEnabled != TRUE) { //_DrawLine(hdc, PS_DASH, NIBLSCALE(3), WayPointList[Task[i].Index].Screen, Task[i].Start, RGB_PETROL, rc); //_DrawLine(hdc, PS_DASH, NIBLSCALE(3), WayPointList[Task[i].Index].Screen, Task[i].End, RGB_PETROL, rc); // DrawDashLine(hdc, size_tasklines, WayPointList[Task[i].Index].Screen, Task[i].Start, RGB_PETROL, rc); // DrawDashLine(hdc, size_tasklines, WayPointList[Task[i].Index].Screen, Task[i].End, RGB_PETROL, rc); } int Type = 0; double Radius = 0.; GetTaskSectorParameter(i, &Type, &Radius); switch (Type) { case CIRCLE: tmp = Radius * zoom.ResScaleOverDistanceModify(); Circle(hdc, WayPointList[Task[i].Index].Screen.x, WayPointList[Task[i].Index].Screen.y, (int) tmp, rc, false, false); break; case SECTOR: tmp = Radius * zoom.ResScaleOverDistanceModify(); Segment(hdc, WayPointList[Task[i].Index].Screen.x, WayPointList[Task[i].Index].Screen.y, (int) tmp, rc, Task[i].AATStartRadial - DisplayAngle, Task[i].AATFinishRadial - DisplayAngle); break; case DAe: if (!AATEnabled) { // this Type exist only if not AAT task // JMW added german rules tmp = 500 * zoom.ResScaleOverDistanceModify(); Circle(hdc, WayPointList[Task[i].Index].Screen.x, WayPointList[Task[i].Index].Screen.y, (int) tmp, rc, false, false); tmp = 10e3 * zoom.ResScaleOverDistanceModify(); Segment(hdc, WayPointList[Task[i].Index].Screen.x, WayPointList[Task[i].Index].Screen.y, (int) tmp, rc, Task[i].AATStartRadial - DisplayAngle, Task[i].AATFinishRadial - DisplayAngle); } break; case LINE: if (!AATEnabled) { // this Type exist only if not AAT task if(ISGAAIRCRAFT) { POINT start,end; double rotation=AngleLimit360(Task[i].Bisector-DisplayAngle); int length=14*ScreenScale; //Make intermediate WP lines always of the same size independent by zoom level start.x=WayPointList[Task[i].Index].Screen.x+(long)(length*fastsine(rotation)); start.y=WayPointList[Task[i].Index].Screen.y-(long)(length*fastcosine(rotation)); rotation=Reciprocal(rotation); end.x=WayPointList[Task[i].Index].Screen.x+(long)(length*fastsine(rotation)); end.y=WayPointList[Task[i].Index].Screen.y-(long)(length*fastcosine(rotation)); _DrawLine(hdc, PS_SOLID, NIBLSCALE(3), start, end, taskcolor, rc); } else _DrawLine(hdc, PS_SOLID, NIBLSCALE(3), Task[i].Start, Task[i].End, taskcolor, rc); } break; case CONE: tmp = Radius * zoom.ResScaleOverDistanceModify(); int center_x = WayPointList[Task[i].Index].Screen.x; int center_y = WayPointList[Task[i].Index].Screen.y; Circle(hdc, center_x, center_y, (int) tmp, rc, false, false); HPEN prevPen = (HPEN)::SelectObject(hdc, hpTerrainLine); for( int j = 1; j < 5 && tmp > 0; ++j) { Circle(hdc, center_x, center_y, tmp -= NIBLSCALE(5), rc, true, true); } ::SelectObject(hdc, prevPen); break; } if (AATEnabled && !DoOptimizeRoute()) { // ELSE HERE IS *** AAT *** // JMW added iso lines if ((i == ActiveWayPoint) || (mode.Is(Mode::MODE_TARGET_PAN) && (i == TargetPanIndex))) { // JMW 20080616 flash arc line if very close to target static bool flip = false; if (DerivedDrawInfo.WaypointDistance < AATCloseDistance()*2.0) { flip = !flip; } else { flip = true; } if (flip) { for (int j = 0; j < MAXISOLINES - 1; j++) { if (TaskStats[i].IsoLine_valid[j] && TaskStats[i].IsoLine_valid[j + 1]) { _DrawLine(hdc, PS_SOLID, NIBLSCALE(2), TaskStats[i].IsoLine_Screen[j], TaskStats[i].IsoLine_Screen[j + 1], RGB(0, 0, 255), rc); } } } } } } } if ((ActiveWayPoint < 2) && ValidTaskPoint(0) && ValidTaskPoint(1)) { DrawStartEndSector(hdc, rc, Task[0].Start, Task[0].End, Task[0].Index, StartLine, StartRadius); if (EnableMultipleStartPoints) { for (i = 0; i < MAXSTARTPOINTS; i++) { if (StartPoints[i].Active && ValidWayPoint(StartPoints[i].Index)) { DrawStartEndSector(hdc, rc, StartPoints[i].Start, StartPoints[i].End, StartPoints[i].Index, StartLine, StartRadius); } } } } for (i = 0; ValidTaskPoint(i + 1); i++) { int imin = min(Task[i].Index, Task[i + 1].Index); int imax = max(Task[i].Index, Task[i + 1].Index); // JMW AAT! double bearing = Task[i].OutBound; POINT sct1, sct2; if (AATEnabled) { LatLon2Screen(Task[i].AATTargetLon, Task[i].AATTargetLat, sct1); LatLon2Screen(Task[i + 1].AATTargetLon, Task[i + 1].AATTargetLat, sct2); DistanceBearing(Task[i].AATTargetLat, Task[i].AATTargetLon, Task[i + 1].AATTargetLat, Task[i + 1].AATTargetLon, NULL, &bearing); // draw nominal track line DrawDashLine(hdc, NIBLSCALE(1), // 091217 WayPointList[imin].Screen, WayPointList[imax].Screen, taskcolor, rc); } else { sct1 = WayPointList[imin].Screen; sct2 = WayPointList[imax].Screen; } if ((i >= ActiveWayPoint && DoOptimizeRoute()) || !DoOptimizeRoute()) { POINT ClipPt1 = sct1, ClipPt2 = sct2; if(LKGeom::ClipLine((POINT) {rc.left, rc.top}, (POINT) {rc.right, rc.bottom}, ClipPt1, ClipPt2)) { DrawMulticolorDashLine(hdc, size_tasklines, sct1, sct2, taskcolor, RGB_BLACK,rc); // draw small arrow along task direction POINT p_p; POINT Arrow[2] = { {6, 6}, {-6, 6} }; ScreenClosestPoint(sct1, sct2, Orig_Aircraft, &p_p, NIBLSCALE(25)); threadsafePolygonRotateShift(Arrow, 2, p_p.x, p_p.y, bearing - DisplayAngle); _DrawLine(hdc, PS_SOLID, size_tasklines-NIBLSCALE(1), Arrow[0], p_p, taskcolor, rc); _DrawLine(hdc, PS_SOLID, size_tasklines-NIBLSCALE(1), Arrow[1], p_p, taskcolor, rc); } } } // Draw DashLine From current position to Active TurnPoint center if(ValidTaskPoint(ActiveWayPoint)) { POINT ptStart; LatLon2Screen(DrawInfo.Longitude, DrawInfo.Latitude, ptStart); DrawDashLine(hdc, NIBLSCALE(1), ptStart, WayPointList[Task[ActiveWayPoint].Index].Screen, taskcolor, rc); } { UnlockTaskData(); } // restore original color SetTextColor(hDCTemp, origcolor); SelectObject(hdc, oldpen); SelectObject(hdc, oldbrush); }
void MapWindow::DrawVisualGlide(LKSurface& Surface, const DiagrammStruct& sDia) { const RECT& rci = sDia.rc; unsigned short numboxrows = 1; #if BUGSTOP LKASSERT(Current_Multimap_SizeY < SIZE4); #endif switch (Current_Multimap_SizeY) { case SIZE0: case SIZE1: numboxrows = 3; break; case SIZE2: numboxrows = 2; break; case SIZE3: numboxrows = 1; break; case SIZE4: return; default: LKASSERT(0); break; } if (!ScreenLandscape) { numboxrows++; if (numboxrows > 3) numboxrows = 3; } TCHAR tmpT[30]; line1Font = LK8VisualTopFont; line2Font = LK8VisualBotFont; SIZE textSizeTop, textSizeBot; Surface.SelectObject(line1Font); _stprintf(tmpT, _T("MMMM")); Surface.GetTextSize(tmpT, &textSizeTop); Surface.SelectObject(line2Font); _stprintf(tmpT, _T("55.5%s 79%s%s "), Units::GetDistanceName(), MsgToken(2179), MsgToken(2183)); Surface.GetTextSize(tmpT, &textSizeBot); // we can cut the waypoint name, but not the value data, so we use the second row of data // to size the box for everything. maxtSizeX = textSizeBot.cx; int a = (rci.right-rci.left) / (textSizeBot.cx+BOXINTERVAL); int b = (rci.right-rci.left) - a * (textSizeBot.cx)-(BOXINTERVAL * (a + 1)); boxSizeX = textSizeBot.cx + (b / (a + 1)); boxSizeY = textSizeTop.cy + 1; // single line (wp name) + distance from bottombar if (numboxrows > 1) { boxSizeY += (textSizeBot.cy * (numboxrows - 1)) - NIBLSCALE(2); if (numboxrows > 2) boxSizeY -= NIBLSCALE(1); } #if DEBUG_SCR StartupStore(_T("boxX=%d boxY=%d \n"), boxSizeX, boxSizeY); #endif #if DEBUG_SCR StartupStore(_T("VG AREA LTRB: %d,%d %d,%d\n"), rci.left, rci.top, rci.right, rci.bottom); #endif const auto oldBrush = Surface.SelectObject(LKBrush_White); const auto oldPen = Surface.SelectObject(LK_BLACK_PEN); BrushReference brush_back; if (!INVERTCOLORS) { brush_back = LKBrush_Black; } else { brush_back = LKBrush_Nlight; } Surface.FillRect(&rci, brush_back); POINT center, p1, p2; center.y = rci.top + (rci.bottom - rci.top) / 2; center.x = rci.left + (rci.right - rci.left) / 2; // numSlotX is the number items we can print horizontally. unsigned short numSlotX = (rci.right - rci.left) / (boxSizeX + BOXINTERVAL); if (numSlotX > MAXBSLOT) numSlotX = MAXBSLOT; #if BUGSTOP LKASSERT(numSlotX > 0); #endif if (numSlotX == 0) return; unsigned short boxInterval = ((rci.right - rci.left)-(boxSizeX * numSlotX)) / (numSlotX + 1); unsigned short oddoffset = ( (rci.right-rci.left) - (boxSizeX * numSlotX) - boxInterval * (numSlotX + 1)) / 2; /* #if BUGSTOP // not really harmful LKASSERT(oddoffset<=boxInterval); #endif */ #if DEBUG_SCR StartupStore(_T("numSlotX=%d ScreenSizeX=%d boxSizeX=%d interval=%d offset=%d\n"), numSlotX, ScreenSizeX, boxSizeX, boxInterval, oddoffset); #endif unsigned int t; // The horizontal grid unsigned int slotCenterX[MAXBSLOT + 1]; for (t = 0; t < numSlotX; t++) { slotCenterX[t] = (t * boxSizeX) + boxInterval * (t + 1)+(boxSizeX / 2) + oddoffset+rci.left; #if DEBUG_SCR StartupStore(_T("slotCenterX[%d]=%d\n"), t, slotCenterX[t]); #endif } // Vertical coordinates of each up/down subwindow, excluding center line int upYtop = rci.top; #if MIDCENTER int upYbottom = center.y + (boxSizeY / 2); int downYtop = center.y - (boxSizeY / 2); #else int upYbottom = center.y - CENTERYSPACE; int downYtop = center.y + CENTERYSPACE; #endif int upSizeY = upYbottom - upYtop - (boxSizeY); ; int downYbottom = rci.bottom; int downSizeY = downYbottom - downYtop - (boxSizeY); ; #if 0 // Reassign dynamically the vertical scale for each subwindow size double vscale = 1000 * (100 - Current_Multimap_SizeY) / 100; #else // Set the vertical range double vscale; if (Units::GetUserAltitudeUnit() == unFeet) vscale = (1000 / TOFEET); else vscale = 300.0; #endif Surface.SetBackgroundTransparent(); RECT trc = rci; // Top part of visual rect, target is over us=unreachable=red trc.top = rci.top; trc.bottom = center.y - 1; #ifndef DITHER RenderSky(Surface, trc, RGB_WHITE, LKColor(150, 255, 150), GC_NO_COLOR_STEPS / 2); #else RenderSky(Surface, trc, RGB_WHITE, RGB_WHITE, GC_NO_COLOR_STEPS / 2); #endif // Bottom part, target is below us=reachable=green trc.top = center.y + 1; trc.bottom = rci.bottom; #ifndef DITHER RenderSky(Surface, trc, LKColor(255, 150, 150), RGB_WHITE, GC_NO_COLOR_STEPS / 2); #else RenderSky(Surface, trc, RGB_WHITE, RGB_WHITE,GC_NO_COLOR_STEPS / 2); #endif // Draw center line p1.x = rci.left + 1; p1.y = center.y; p2.x = rci.right - 1; p2.y = center.y; Surface.SelectObject(LKPen_Black_N1); Surface.DrawSolidLine(p1, p2, rci); #if DEBUG_SCR StartupStore(_T("... Center line: Y=%d\n"), center.y); #endif Surface.SelectObject(line1Font); Surface.SelectObject(LKPen_Black_N0); ResetVisualGlideGlobals(); short res = GetVisualGlidePoints(numSlotX); if (res == INVALID_VALUE) { #if DEBUG_DVG StartupStore(_T("...... GVGP says not ready, wait..\n")); #endif return; } if (res == 0) { #if DEBUG_DVG StartupStore(_T("...... GVGP says no data available!\n")); #endif return; } // Print them all! int offset = (boxSizeY / 2) + CENTERYSPACE; LKBrush bcolor; LKColor rgbcolor, textcolor; int wp; unsigned short zeroslot = 0; double minbrgdiff = 999.0; double minabrgdiff = 999.0; // absolute never negative for (unsigned short n = 0; n < numSlotX; n++) { wp = slotWpIndex[n]; if (!ValidWayPoint(wp)) { // empty slot nothing to print continue; } double brgdiff = WayPointCalc[wp].Bearing - DrawInfo.TrackBearing; // this check is worthless if (brgdiff < -180.0) { brgdiff += 360.0; } else { if (brgdiff > 180.0) brgdiff -= 360.0; } double abrgdiff = brgdiff; if (abrgdiff < 0) abrgdiff *= -1; if (abrgdiff < minabrgdiff) { zeroslot = n; minabrgdiff = abrgdiff; minbrgdiff = brgdiff; } } // Draw vertical line #define DEGRANGE 10 // degrees left and right to perfect target if (minabrgdiff < 1) { p1.x = slotCenterX[zeroslot]; } else { // set fullscale range if (minabrgdiff > DEGRANGE) { minabrgdiff = DEGRANGE; if (minbrgdiff < 0) minbrgdiff = -1 * DEGRANGE; else minbrgdiff = DEGRANGE; } // we shift of course in the opposite direction p1.x = slotCenterX[zeroslot]-(int) ((boxSizeX / (DEGRANGE * 2)) * minbrgdiff); } p2.x = p1.x; p1.y = rci.top + 1; p2.y = rci.bottom - 1; Surface.SelectObject(LKPen_Black_N1); Surface.DrawSolidLine(p1, p2, rci); for (unsigned short n = 0; n < numSlotX; n++) { wp = slotWpIndex[n]; if (!ValidWayPoint(wp)) { // empty slot nothing to print continue; } #if DEBUG_DVG StartupStore(_T("... DVG PRINT [%d]=%d <%s>\n"), n, wp, WayPointList[wp].Name); #endif Sideview_VGWpt[n] = wp; double altdiff = WayPointCalc[wp].AltArriv[AltArrivMode]; int ty; #if DEBUG_SCR StartupStore(_T("... wp=<%s>\n"), WayPointList[wp].Name); #endif // Since terrain can be approximated due to low precision maps, or waypoint position or altitude error, // we have a common problem: we get an obstacle to get to the waypoint because it is // positioned "BELOW" the terrain itself. We try to reduce this problem here. #define SAFETERRAIN 50 // Positive arrival altitude for the waypoint, upper window if (altdiff >= 0) { if (altdiff == 0)altdiff = 1; double d = vscale / altdiff; if (d == 0) d = 1; ty = upYbottom - (int) ((double) upSizeY / d)-(boxSizeY / 2); #if DEBUG_SCR StartupStore(_T("... upYbottom=%d upSizeY=%d / (vscale=%f/altdiff=%f = %f) =- %d ty=%d offset=%d\n"), upYbottom, upSizeY, vscale, altdiff, d, (int) ((double) upSizeY / d), ty, offset); #endif if ((ty - offset) < upYtop) ty = upYtop + offset; if ((ty + offset) > upYbottom) ty = upYbottom - offset; #if DEBUG_SCR StartupStore(_T("... upYtop=%d upYbottom=%d final ty=%d\n"), upYtop, upYbottom, ty); #endif // // This is too confusing. We want simple colors, not shaded // rgbcolor = MixColors( LKColor(50,255,50), LKColor(230,255,230), altdiff/(vscale-50)); // if (altdiff <= SAFETERRAIN) { rgbcolor = RGB_LIGHTYELLOW; } else { if (!CheckLandableReachableTerrainNew(&DrawInfo, &DerivedDrawInfo, WayPointCalc[wp].Distance, WayPointCalc[wp].Bearing)) { rgbcolor = RGB_LIGHTRED; } else { #ifdef DITHER rgbcolor = RGB_WHITE; #else rgbcolor = RGB_LIGHTGREEN; #endif } } bcolor.Create(rgbcolor); } else { double d = vscale / altdiff; if (d == 0) d = -1; ty = downYtop - (int) ((double) downSizeY / d)+(boxSizeY / 2); // - because the left part is negative, we are really adding. if ((ty - offset) < downYtop) ty = downYtop + offset; if ((ty + offset) > downYbottom) ty = downYbottom - offset; #ifdef DITHER rgbcolor = RGB_WHITE; // negative part, no need to render dark #else rgbcolor = RGB_LIGHTRED; #endif bcolor.Create(rgbcolor); } TCHAR line2[40], line3[40]; TCHAR value[40], unit[30]; TCHAR name[NAME_SIZE + 1]; double ar = (WayPointCalc[wp].AltArriv[AltArrivMode] * ALTITUDEMODIFY); _tcscpy(name, WayPointList[wp].Name); CharUpper(name); if (IsSafetyAltitudeInUse(wp)) textcolor = RGB_DARKBLUE; else textcolor = RGB_BLACK; switch (numboxrows) { case 0: #if BUGSTOP LKASSERT(0); #endif return; case 1: // 1 line: waypoint name VGTextInBox(Surface, n, 1, name, NULL, NULL, slotCenterX[n], ty, textcolor, bcolor); break; case 2: // 2 lines: waypoint name + altdiff LKFormatAltDiff(wp, false, value, unit); // Should we print also the GR? if ((ar >= -9999 && ar <= 9999) && (WayPointCalc[wp].GR < MAXEFFICIENCYSHOW)) { if (ar >= -999 && ar <= 999) _stprintf(line2, _T("%s "), value); else _stprintf(line2, _T("%s "), value); LKFormatGR(wp, false, value, unit); _tcscat(line2, value); } else { _stprintf(line2, _T("%s ---"), value); } VGTextInBox(Surface, n, 2, name, line2, NULL, slotCenterX[n], ty, textcolor, bcolor); break; case 3: // 3 lines: waypoint name + dist + altdiff LKFormatDist(wp, false, value, unit); _stprintf(line2, _T("%s%s"), value, unit); LKFormatBrgDiff(wp, false, value, unit); _stprintf(tmpT, _T(" %s%s"), value, unit); _tcscat(line2, tmpT); LKFormatAltDiff(wp, false, value, unit); // Should we print also the GR? if ((ar >= -9999 && ar <= 9999) && (WayPointCalc[wp].GR < MAXEFFICIENCYSHOW)) { if (ar >= -999 && ar <= 999) _stprintf(line3, _T("%s "), value); else _stprintf(line3, _T("%s "), value); LKFormatGR(wp, false, value, unit); _tcscat(line3, value); } else { _stprintf(line3, _T("%s ---"), value); } VGTextInBox(Surface, n, 3, name, line2, line3, slotCenterX[n], ty, textcolor, bcolor); break; default: #if BUGSTOP LKASSERT(0); #endif return; } } // for numSlotX // Cleanup and return Surface.SelectObject(oldBrush); Surface.SelectObject(oldPen); return; }
void MapWindow::VGTextInBox(LKSurface& Surface, unsigned short nslot, short numlines, const TCHAR* wText1, const TCHAR* wText2, const TCHAR *wText3, int x, int y, const LKColor& trgb, const LKBrush& bbrush) { #if BUGSTOP LKASSERT(wText1 != NULL); #endif if (!wText1) return; LKColor oldTextColor = Surface.SetTextColor(trgb); SIZE tsize; int tx, ty; Sideview_VGBox_Number++; Surface.SelectObject(line1Font); Surface.GetTextSize(wText1, &tsize); int line1fontYsize = tsize.cy; short vy = y + (boxSizeY / 2); Surface.SelectObject(bbrush); Surface.Rectangle( x - (boxSizeX / 2), y - (boxSizeY / 2)-1, x + (boxSizeX / 2), vy-1); Sideview_VGBox[nslot].top = y - (boxSizeY / 2); Sideview_VGBox[nslot].left = x - (boxSizeX / 2); Sideview_VGBox[nslot].bottom = vy; Sideview_VGBox[nslot].right = x + (boxSizeX / 2); PixelRect ClipRect(Sideview_VGBox[nslot]); ClipRect.Grow(-1*NIBLSCALE(2), 0); // text padding // // LINE 1 // tx = max<PixelScalar>(ClipRect.left, x - (tsize.cx / 2)); ty = y - (vy - y); Surface.DrawText(tx, ty, wText1, &ClipRect); if (numlines == 1) goto _end; #if BUGSTOP LKASSERT(wText2 != NULL); #endif if (!wText2) goto _end; // // LINE 2 // Surface.SetTextColor(RGB_BLACK); Surface.SelectObject(line2Font); Surface.GetTextSize(wText2, &tsize); tx = x - (tsize.cx / 2); ty += line1fontYsize - NIBLSCALE(2); Surface.DrawText(tx, ty, wText2); if (numlines == 2) goto _end; #if BUGSTOP LKASSERT(wText3 != NULL); #endif if (!wText3) goto _end; // // LINE 3 // Surface.SetTextColor(RGB_BLACK); Surface.GetTextSize(wText3, &tsize); tx = x - (tsize.cx / 2); ty += tsize.cy - NIBLSCALE(2); Surface.DrawText(tx, ty, wText3); _end: Surface.SetTextColor(oldTextColor); return; }
// Will return 0 if cancel or error, 1 if details needed, 2 if goto, 3 if alt1, 4 if alt2 short dlgWayQuickShowModal(void){ wf = NULL; TCHAR filename[MAX_PATH]; TCHAR sTmp[128]; if (ScreenLandscape) { LocalPathS(filename, TEXT("dlgWayQuick.xml")); wf = dlgLoadFromXML(CallBackTable, filename, TEXT("IDR_XML_WAYPOINTQUICK")); } else { LocalPathS(filename, TEXT("dlgWayQuick_P.xml")); wf = dlgLoadFromXML(CallBackTable, filename, TEXT("IDR_XML_WAYPOINTQUICK_P")); } if (!wf) return 0; ((WndButton *)wf->FindByName(TEXT("cmdGoto"))) ->SetOnClickNotify(OnGotoClicked); ((WndButton *)wf->FindByName(TEXT("cmdSetAlt1"))) ->SetOnClickNotify(OnSetAlt1Clicked); ((WndButton *)wf->FindByName(TEXT("cmdSetAlt2"))) ->SetOnClickNotify(OnSetAlt2Clicked); ((WndButton *)wf->FindByName(TEXT("cmdDetails"))) ->SetOnClickNotify(OnDetailsClicked); ((WndButton *)wf->FindByName(TEXT("cmdTask"))) ->SetOnClickNotify(OnTaskClicked); ((WndButton *)wf->FindByName(TEXT("cmdCancel"))) ->SetOnClickNotify(OnCancelClicked); retStatus=0; if (WPLSEL.Format == LKW_CUP) { TCHAR ttmp[50]; // and it is landable if ((WPLSEL.Style>1) && (WPLSEL.Style<6) ) { _stprintf(sTmp, TEXT("%s "), WPLSEL.Name); if (_tcslen(sTmp)>9) { sTmp[9]='\0'; _tcscat(sTmp, _T(" ")); } if ( _tcslen(WPLSEL.Freq)>0 ) { _stprintf(ttmp,_T("%s "),WPLSEL.Freq); _tcscat(sTmp, ttmp); } if ( WPLSEL.RunwayDir>=0 ) { _stprintf(ttmp,_T("RW %d "),WPLSEL.RunwayDir); _tcscat(sTmp, ttmp); } if ( WPLSEL.RunwayLen>0 ) { // we use Altitude instead of distance, to keep meters and feet _stprintf(ttmp,_T("%.0f%s"),Units::ToUserAltitude((double)WPLSEL.RunwayLen), Units::GetAltitudeName()); _tcscat(sTmp, ttmp); } } else { _stprintf(sTmp, _T(" %s"),WayPointList[SelectedWaypoint].Name); } } else { _stprintf(sTmp, _T(" %s"),WayPointList[SelectedWaypoint].Name); } wf->SetCaption(sTmp); if (ScreenLandscape) { // ((WndButton *)wf->FindByName(TEXT("cmdGoto"))) ->SetLeft(NIBLSCALE(3)); int left = ((WndButton *)wf->FindByName(TEXT("cmdGoto"))) ->GetLeft(); ((WndButton *)wf->FindByName(TEXT("cmdGoto"))) ->SetWidth(ScreenSizeX-NIBLSCALE(5)-left); ((WndButton *)wf->FindByName(TEXT("cmdSetAlt1"))) ->SetWidth((ScreenSizeX/2)-NIBLSCALE(5)); ((WndButton *)wf->FindByName(TEXT("cmdSetAlt1"))) ->SetLeft(NIBLSCALE(3)); ((WndButton *)wf->FindByName(TEXT("cmdSetAlt2"))) ->SetWidth((ScreenSizeX/2)-NIBLSCALE(7)); ((WndButton *)wf->FindByName(TEXT("cmdSetAlt2"))) ->SetLeft((ScreenSizeX/2)+NIBLSCALE(2)); ((WndButton *)wf->FindByName(TEXT("cmdDetails"))) ->SetWidth((ScreenSizeX/2)-NIBLSCALE(5)); ((WndButton *)wf->FindByName(TEXT("cmdDetails"))) ->SetLeft(NIBLSCALE(3)); ((WndButton *)wf->FindByName(TEXT("cmdTask"))) ->SetWidth((ScreenSizeX/2)-NIBLSCALE(7)); ((WndButton *)wf->FindByName(TEXT("cmdTask"))) ->SetLeft((ScreenSizeX/2)+NIBLSCALE(2)); ((WndButton *)wf->FindByName(TEXT("cmdCancel"))) ->SetLeft(NIBLSCALE(3)); ((WndButton *)wf->FindByName(TEXT("cmdCancel"))) ->SetWidth((ScreenSizeX)-NIBLSCALE(8)); } wf->ShowModal(); delete wf; wf = NULL; return retStatus; }
bool MapWindow::TextInBox(LKSurface& Surface, const RECT *clipRect, const TCHAR* Value, int x, int y, TextInBoxMode_t *Mode, bool noOverlap) { SIZE tsize; RECT brect; LKSurface::OldFont oldFont {}; bool drawn=false; if ((x<clipRect->left-WPCIRCLESIZE) || (x>clipRect->right+(WPCIRCLESIZE*3)) || (y<clipRect->top-WPCIRCLESIZE) || (y>clipRect->bottom+WPCIRCLESIZE)) { return drawn; } if (Mode == NULL) return false; const auto hbOld = Surface.SelectObject(LKBrush_White); const auto hpOld = Surface.SelectObject(LK_BLACK_PEN); if (Mode->Reachable){ if (Appearance.IndLandable == wpLandableDefault){ x += 5; // make space for the green circle }else if (Appearance.IndLandable == wpLandableAltA){ x += 0; } } // landable waypoint label inside white box if (!Mode->NoSetFont) { if (Mode->Border || Mode->WhiteBold){ oldFont = Surface.SelectObject(MapWaypointBoldFont); } else { oldFont = Surface.SelectObject(MapWaypointFont); } } Surface.GetTextSize(Value, &tsize); if (Mode->AlligneRight){ x -= tsize.cx; } else if (Mode->AlligneCenter){ x -= tsize.cx/2; y -= tsize.cy/2; } bool notoverlapping = true; if (Mode->Border || Mode->WhiteBorder){ POINT offset; brect.left = x-2; brect.right = brect.left+tsize.cx+4; brect.top = y+((tsize.cy+4)>>3)-2; brect.bottom = brect.top+3+tsize.cy-((tsize.cy+4)>>3); if (Mode->AlligneRight) x -= 3; if (TextInBoxMoveInView(clipRect, &offset, &brect)){ x += offset.x; y += offset.y; } #if CLIP_TEXT if (y>=clipRect->bottom || brect.bottom>=clipRect->bottom ) return false; #endif notoverlapping = checkLabelBlock(&brect); if (!noOverlap || notoverlapping) { LKSurface::OldPen oldPen; if (Mode->Border) { oldPen = Surface.SelectObject(LKPen_Black_N1); } else { oldPen = Surface.SelectObject(LK_WHITE_PEN); } Surface.RoundRect(brect, NIBLSCALE(4), NIBLSCALE(4)); Surface.SelectObject(oldPen); if (Mode->SetTextColor) Surface.SetTextColor(Mode->Color); else Surface.SetTextColor(RGB_BLACK); #ifndef __linux__ Surface.DrawText(x, y, Value); #else Surface.DrawText(x, y+NIBLSCALE(1), Value); #endif drawn=true; } } else if (Mode->FillBackground) {
// This is painting traffic icons on the screen. void MapWindow::LKDrawFLARMTraffic(HDC hDC, RECT rc, POINT Orig_Aircraft) { if (!EnableFLARMMap) return; if (!DrawInfo.FLARM_Available) return; // init scaled coords for traffic icon static int iCircleSize = 7; static int iRectangleSize = 4; static short scaler[5]; static short tscaler=0; if (DoInit[MDI_DRAWFLARMTRAFFIC]) { switch (ScreenSize) { case ss480x640: case ss480x800: case ss896x672: case ss800x480: case ss640x480: iCircleSize = 9; iRectangleSize = 5; scaler[0]=-1*(NIBLSCALE(4)-2); scaler[1]=NIBLSCALE(5)-2; scaler[2]=-1*(NIBLSCALE(6)-2); scaler[3]=NIBLSCALE(4)-2; scaler[4]=NIBLSCALE(2)-2; tscaler=NIBLSCALE(7)-2; break; case ss240x320: case ss272x480: case ss320x240: case ss480x272: case ss720x408: case ss480x234: case ss400x240: iCircleSize = 7; iRectangleSize = 4; scaler[0]=-1*(NIBLSCALE(8)-2); scaler[1]=NIBLSCALE(10)-2; scaler[2]=-1*(NIBLSCALE(12)-2); scaler[3]=NIBLSCALE(8)-2; scaler[4]=NIBLSCALE(4)-2; tscaler=NIBLSCALE(13)-2; break; default: iCircleSize = 7; iRectangleSize = 4; scaler[0]=-1*NIBLSCALE(4); scaler[1]=NIBLSCALE(5); scaler[2]=-1*NIBLSCALE(6); scaler[3]=NIBLSCALE(4); scaler[4]=NIBLSCALE(2); tscaler=NIBLSCALE(7); break; } DoInit[MDI_DRAWFLARMTRAFFIC]=false; } HPEN hpold; HPEN thinBlackPen = LKPen_Black_N1; POINT Arrow[5]; TCHAR lbuffer[50]; hpold = (HPEN)SelectObject(hDC, thinBlackPen); int i; int painted=0; // double dX, dY; TextInBoxMode_t displaymode = {0}; displaymode.NoSetFont = 1; #if 0 double screenrange = GetApproxScreenRange(); double scalefact = screenrange/6000.0; // FIX 100820 #endif HFONT oldfont = (HFONT)SelectObject(hDC, LK8MapFont); for (i=0,painted=0; i<FLARM_MAX_TRAFFIC; i++) { // limit to 10 icons map traffic if (painted>=10) { i=FLARM_MAX_TRAFFIC; continue; } if ( (DrawInfo.FLARM_Traffic[i].ID !=0) && (DrawInfo.FLARM_Traffic[i].Status != LKT_ZOMBIE) ) { painted++; double target_lon; double target_lat; target_lon = DrawInfo.FLARM_Traffic[i].Longitude; target_lat = DrawInfo.FLARM_Traffic[i].Latitude; #if (0) // No scaling, wrong if ((EnableFLARMMap==2)&&(scalefact>1.0)) { double distance; double bearing; DistanceBearing(DrawInfo.Latitude, DrawInfo.Longitude, target_lat, target_lon, &distance, &bearing); FindLatitudeLongitude(DrawInfo.Latitude, DrawInfo.Longitude, bearing, distance*scalefact, &target_lat, &target_lon); } #endif POINT sc, sc_name, sc_av; LatLon2Screen(target_lon, target_lat, sc); sc_name = sc; sc_name.y -= NIBLSCALE(16); sc_av = sc_name; wsprintf(lbuffer,_T("")); if (DrawInfo.FLARM_Traffic[i].Cn && DrawInfo.FLARM_Traffic[i].Cn[0]!=_T('?')) { // 100322 _tcscat(lbuffer,DrawInfo.FLARM_Traffic[i].Cn); } if (DrawInfo.FLARM_Traffic[i].Average30s>=0.1) { if (_tcslen(lbuffer) >0) _stprintf(lbuffer,_T("%s:%.1f"),lbuffer,LIFTMODIFY*DrawInfo.FLARM_Traffic[i].Average30s); else _stprintf(lbuffer,_T("%.1f"),LIFTMODIFY*DrawInfo.FLARM_Traffic[i].Average30s); } displaymode.Border=1; if (_tcslen(lbuffer)>0) TextInBox(hDC, lbuffer, sc.x+tscaler, sc.y+tscaler, 0, &displaymode, false); // red circle if ((DrawInfo.FLARM_Traffic[i].AlarmLevel>0) && (DrawInfo.FLARM_Traffic[i].AlarmLevel<4)) { DrawBitmapIn(hDC, sc, hFLARMTraffic,true); } #if 0 Arrow[0].x = -4; Arrow[0].y = 5; Arrow[1].x = 0; Arrow[1].y = -6; Arrow[2].x = 4; Arrow[2].y = 5; Arrow[3].x = 0; Arrow[3].y = 2; Arrow[4].x = -4; Arrow[4].y = 5; #endif Arrow[0].x = scaler[0]; Arrow[0].y = scaler[1]; Arrow[1].x = 0; Arrow[1].y = scaler[2]; Arrow[2].x = scaler[3]; Arrow[2].y = scaler[1]; Arrow[3].x = 0; Arrow[3].y = scaler[4]; Arrow[4].x = scaler[0]; Arrow[4].y = scaler[1]; /* switch (DrawInfo.FLARM_Traffic[i].Status) { // 100321 case LKT_GHOST: SelectObject(hDC, yellowBrush); break; case LKT_ZOMBIE: SelectObject(hDC, redBrush); break; default: SelectObject(hDC, greenBrush); break; } */ /************************************************************************* * calculate climb color *************************************************************************/ int iVarioIdx = (int)(2*DrawInfo.FLARM_Traffic[i].Average30s -0.5)+NO_VARIO_COLORS/2; if(iVarioIdx < 0) iVarioIdx =0; if(iVarioIdx >= NO_VARIO_COLORS) iVarioIdx =NO_VARIO_COLORS-1; SelectObject(hDC, *variobrush[iVarioIdx]); switch (DrawInfo.FLARM_Traffic[i].Status) { // 100321 case LKT_GHOST: Rectangle(hDC, sc.x-iRectangleSize, sc.y-iRectangleSize,sc.x+iRectangleSize, sc.y+iRectangleSize); break; case LKT_ZOMBIE: Circle(hDC, sc.x, sc.x, iCircleSize, rc, true, true ); break; default: PolygonRotateShift(Arrow, 5, sc.x, sc.y, DrawInfo.FLARM_Traffic[i].TrackBearing - DisplayAngle); Polygon(hDC,Arrow,5); break; } } } SelectObject(hDC, oldfont); SelectObject(hDC, hpold); }
// This is painting traffic icons on the screen. void MapWindow::LKDrawFLARMTraffic(LKSurface& Surface, const RECT& rc, const ScreenProjection& _Proj, const POINT& Orig_Aircraft) { if (!EnableFLARMMap) return; if (!DrawInfo.FLARM_Available) return; // init scaled coords for traffic icon static int iCircleSize = 7; static int iRectangleSize = 4; static short tscaler=0; if (DoInit[MDI_DRAWFLARMTRAFFIC]) { switch (ScreenSize) { case ss480x640: case ss480x800: case ss800x480: case ss640x480: iCircleSize = 9; iRectangleSize = 5; tscaler=NIBLSCALE(7)-2; break; case ss240x320: case ss272x480: case ss320x240: case ss480x272: case ss480x234: case ss400x240: iCircleSize = 7; iRectangleSize = 4; tscaler=NIBLSCALE(13)-2; break; default: iCircleSize = 7; iRectangleSize = 4; tscaler=NIBLSCALE(7); break; } DoInit[MDI_DRAWFLARMTRAFFIC]=false; } POINT Arrow[5]; TCHAR lbuffer[50]; const auto hpold = Surface.SelectObject(LKPen_Black_N1); int i; int painted=0; // double dX, dY; TextInBoxMode_t displaymode = {0}; displaymode.NoSetFont = 1; #if 0 double screenrange = GetApproxScreenRange(); double scalefact = screenrange/6000.0; // FIX 100820 #endif const auto oldfont = Surface.SelectObject(LK8MapFont); for (i=0,painted=0; i<FLARM_MAX_TRAFFIC; i++) { // limit to 10 icons map traffic if (painted>=10) { i=FLARM_MAX_TRAFFIC; continue; } if ( (DrawInfo.FLARM_Traffic[i].ID !=0) && (DrawInfo.FLARM_Traffic[i].Status != LKT_ZOMBIE) ) { painted++; double target_lon; double target_lat; target_lon = DrawInfo.FLARM_Traffic[i].Longitude; target_lat = DrawInfo.FLARM_Traffic[i].Latitude; #if (0) // No scaling, wrong if ((EnableFLARMMap==2)&&(scalefact>1.0)) { double distance; double bearing; DistanceBearing(DrawInfo.Latitude, DrawInfo.Longitude, target_lat, target_lon, &distance, &bearing); FindLatitudeLongitude(DrawInfo.Latitude, DrawInfo.Longitude, bearing, distance*scalefact, &target_lat, &target_lon); } #endif POINT sc, sc_name, sc_av; sc = _Proj.LonLat2Screen(target_lon, target_lat); sc_name = sc; sc_name.y -= NIBLSCALE(16); sc_av = sc_name; _tcscpy(lbuffer,_T("")); if (DrawInfo.FLARM_Traffic[i].Cn && DrawInfo.FLARM_Traffic[i].Cn[0]!=_T('?')) { // 100322 _tcscat(lbuffer,DrawInfo.FLARM_Traffic[i].Cn); } if (DrawInfo.FLARM_Traffic[i].Average30s>=0.1) { size_t len = _tcslen(lbuffer); if (len > 0) _stprintf(lbuffer + len,_T(":%.1f"),LIFTMODIFY*DrawInfo.FLARM_Traffic[i].Average30s); else _stprintf(lbuffer,_T("%.1f"),LIFTMODIFY*DrawInfo.FLARM_Traffic[i].Average30s); } displaymode.Border=1; if (_tcslen(lbuffer)>0) TextInBox(Surface, &rc, lbuffer, sc.x+tscaler, sc.y+tscaler, &displaymode, false); // red circle if ((DrawInfo.FLARM_Traffic[i].AlarmLevel>0) && (DrawInfo.FLARM_Traffic[i].AlarmLevel<4)) { DrawBitmapIn(Surface, sc, hFLARMTraffic,true); } #if 1 // 1 Arrow[0].x = -4; Arrow[0].y = 5; Arrow[1].x = 0; Arrow[1].y = -6; Arrow[2].x = 4; Arrow[2].y = 5; Arrow[3].x = 0; Arrow[3].y = 2; Arrow[4].x = -4; Arrow[4].y = 5; for (int q=0; q < 5; q++) { Arrow[q].x = (LONG) ((double)Arrow[q].x * 1.7); Arrow[q].y = (LONG) ((double)Arrow[q].y * 1.7); } #else Arrow[0].x = scaler[0]; Arrow[0].y = scaler[1]; Arrow[1].x = 0; Arrow[1].y = scaler[2]; Arrow[2].x = scaler[3]; Arrow[2].y = scaler[1]; Arrow[3].x = 0; Arrow[3].y = scaler[4]; Arrow[4].x = scaler[0]; Arrow[4].y = scaler[1]; #endif /* switch (DrawInfo.FLARM_Traffic[i].Status) { // 100321 case LKT_GHOST: Surface.SelectObject(yellowBrush); break; case LKT_ZOMBIE: Surface.SelectObject(redBrush); break; default: Surface.SelectObject(greenBrush); break; } */ /************************************************************************* * calculate climb color *************************************************************************/ int iVarioIdx = (int)(2*DrawInfo.FLARM_Traffic[i].Average30s -0.5)+NO_VARIO_COLORS/2; if(iVarioIdx < 0) iVarioIdx =0; if(iVarioIdx >= NO_VARIO_COLORS) iVarioIdx =NO_VARIO_COLORS-1; Surface.SelectObject(*variobrush[iVarioIdx]); switch (DrawInfo.FLARM_Traffic[i].Status) { // 100321 case LKT_GHOST: Surface.Rectangle(sc.x-iRectangleSize, sc.y-iRectangleSize,sc.x+iRectangleSize, sc.y+iRectangleSize); break; case LKT_ZOMBIE: Surface.DrawCircle(sc.x, sc.x, iCircleSize, rc, true ); break; default: PolygonRotateShift(Arrow, 5, sc.x, sc.y, DrawInfo.FLARM_Traffic[i].TrackBearing - DisplayAngle); Surface.Polygon(Arrow,5); break; } } } Surface.SelectObject(oldfont); Surface.SelectObject(hpold); }
int MapWindow::GetMapResolutionFactor(void) { return NIBLSCALE(30); }
// thecolor is relative to shapes, not to labels // TODO (maybe): get rid of LKM internal colors defined per shape level, // and assign them here dynamically. Easy and fast to do. void Topology::loadPenBrush(const COLORREF thecolor) { int psize; switch(scaleCategory) { case 20: // water lines switch(ScreenSize) { case ss800x480: case ss640x480: psize=3; break; case ss480x272: case ss320x240: case ss400x240: case ss480x640: case ss480x800: psize=2; break; case ss896x672: psize=3; break; //case ss480x272: //case ss480x234: //case ss240x320: //case ss272x480: default: psize=NIBLSCALE(1); break; } break; case 30: // big roads switch(ScreenSize) { case ss800x480: case ss640x480: psize=3; break; case ss480x272: case ss320x240: case ss400x240: case ss480x640: case ss480x800: psize=2; break; case ss896x672: psize=3; break; //case ss480x234: //case ss240x320: //case ss272x480: default: psize=NIBLSCALE(1); break; } break; case 40: // medium roads switch(ScreenSize) { case ss800x480: psize=2; break; case ss480x272: case ss640x480: case ss480x640: case ss480x800: psize=NIBLSCALE(1); break; case ss896x672: psize=2; break; //case ss480x234: //case ss400x240: //case ss320x240: //case ss240x320: //case ss272x480: default: psize=NIBLSCALE(1); break; } break; case 60: // railroads switch(ScreenSize) { //case ss800x480: //case ss640x480: //case ss896x672: //case ss480x272: //case ss480x234: //case ss400x240: //case ss320x240: //case ss480x640: //case ss480x800: //case ss240x320: //case ss272x480: default: psize=1; } break; default: psize=NIBLSCALE(1); break; } hPen = (HPEN)CreatePen(PS_SOLID, psize, thecolor); hbBrush=(HBRUSH)CreateSolidBrush(thecolor); }
void MapWindow::DrawTraffic(HDC hdc, RECT rc) { SIZE WPTextSize, DSTextSize, BETextSize, RETextSize, AATextSize, HLTextSize, MITextSize; TCHAR Buffer[LKSIZEBUFFERLARGE]; static RECT s_sortBox[6]; static TCHAR Buffer1[MAXTRAFFIC][MAXTRAFFICNUMPAGES][24], Buffer2[MAXTRAFFIC][MAXTRAFFICNUMPAGES][10]; static TCHAR Buffer3[MAXTRAFFIC][MAXTRAFFICNUMPAGES][10]; static TCHAR Buffer4[MAXTRAFFIC][MAXTRAFFICNUMPAGES][12], Buffer5[MAXTRAFFIC][MAXTRAFFICNUMPAGES][12]; static short s_maxnlname; char text[30]; short i, k, iRaw, wlen, rli=0, curpage, drawn_items_onpage; double value; COLORREF rcolor; // column0 starts after writing 1:2 (ModeIndex:CURTYPE+1) with a different font.. static short Column0; static short Column1, Column2, Column3, Column4, Column5; static POINT p1, p2; static short s_rawspace; // Printable area for live nearest values static short left,right,bottom; // one for each mapspace, no matter if 0 and 1 are unused short curmapspace=MapSpaceMode; static int TrafficNumraws=0; //static int TrafficNumpages=0; global.. // Vertical and horizontal spaces #define INTERRAW 1 #define HEADRAW NIBLSCALE(6) HBRUSH sortbrush; RECT invsel; if (INVERTCOLORS) { sortbrush=LKBrush_LightGreen; } else { sortbrush=LKBrush_DarkGreen; } if (DoInit[MDI_DRAWTRAFFIC]) { if ( ScreenSize < (ScreenSize_t)sslandscape ) { left=rc.left+NIBLSCALE(1); right=rc.right-NIBLSCALE(1); bottom=rc.bottom-BottomSize-NIBLSCALE(2); s_maxnlname=MAXNLNAME-5; // 7 chars max, 8 sized _stprintf(Buffer,TEXT("MAKSJSMM")); } else { left=rc.left+NIBLSCALE(5); right=rc.right-NIBLSCALE(5); bottom=rc.bottom-BottomSize; s_maxnlname=MAXNLNAME-3; // 9 chars, sized 10 _stprintf(Buffer,TEXT("ABCDEFGHMx")); } SelectObject(hdc, LK8InfoBigFont); // Text font for Nearest was LK8Title GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &WPTextSize); _stprintf(Buffer,TEXT("000.0")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &DSTextSize); _stprintf(Buffer,TEXT("<<123")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &BETextSize); _stprintf(Buffer,TEXT("5299")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &RETextSize); _stprintf(Buffer,TEXT("+9999")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &AATextSize); SelectObject(hdc, LK8InfoNormalFont); // Heading line was MapWindow QUI _stprintf(Buffer,TEXT("MMMM")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &HLTextSize); SelectObject(hdc, LK8PanelMediumFont); _stprintf(Buffer,TEXT("1.1")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &MITextSize); short afterwpname=left+WPTextSize.cx+NIBLSCALE(5); short intercolumn=(right-afterwpname- DSTextSize.cx-BETextSize.cx-RETextSize.cx-AATextSize.cx)/3; Column0=MITextSize.cx+LEFTLIMITER+NIBLSCALE(5); Column1=left; // WP align left Column2=afterwpname+DSTextSize.cx; // DS align right Column3=Column2+intercolumn+BETextSize.cx; // BE align right Column4=Column3+intercolumn+RETextSize.cx; // RE align right Column5=Column4+intercolumn+AATextSize.cx; // AA align right if ( ScreenSize < (ScreenSize_t)sslandscape ) { TopSize=rc.top+HEADRAW*2+HLTextSize.cy; p1.x=0; p1.y=TopSize; p2.x=rc.right; p2.y=p1.y; TopSize+=HEADRAW; TrafficNumraws=(bottom - TopSize) / (WPTextSize.cy+(INTERRAW*2)); if (TrafficNumraws>MAXTRAFFIC) TrafficNumraws=MAXTRAFFIC; s_rawspace=(WPTextSize.cy+INTERRAW); } else { TopSize=rc.top+HEADRAW*2+HLTextSize.cy; p1.x=0; p1.y=TopSize; p2.x=rc.right; p2.y=p1.y; TopSize+=HEADRAW/2; TrafficNumraws=(bottom - TopSize) / (WPTextSize.cy+INTERRAW); if (TrafficNumraws>MAXTRAFFIC) TrafficNumraws=MAXTRAFFIC; s_rawspace=(WPTextSize.cy+INTERRAW); } #define INTERBOX intercolumn/2 // Traffic name s_sortBox[0].left=Column0; // FIX 090925 era solo 0 if ( ScreenSize < (ScreenSize_t)sslandscape ) s_sortBox[0].right=left+WPTextSize.cx-NIBLSCALE(2); else s_sortBox[0].right=left+WPTextSize.cx-NIBLSCALE(10); s_sortBox[0].top=2; s_sortBox[0].bottom=p1.y; SortBoxX[MSM_TRAFFIC][0]=s_sortBox[0].right; // Distance if ( ScreenSize < (ScreenSize_t)sslandscape ) s_sortBox[1].left=Column1+afterwpname-INTERBOX; else s_sortBox[1].left=Column1+afterwpname-INTERBOX-NIBLSCALE(2); s_sortBox[1].right=Column2+INTERBOX; s_sortBox[1].top=2; s_sortBox[1].bottom=p1.y; SortBoxX[MSM_TRAFFIC][1]=s_sortBox[1].right; // Bearing s_sortBox[2].left=Column2+INTERBOX; s_sortBox[2].right=Column3+INTERBOX; s_sortBox[2].top=2; s_sortBox[2].bottom=p1.y; SortBoxX[MSM_TRAFFIC][2]=s_sortBox[2].right; // Vario s_sortBox[3].left=Column3+INTERBOX; s_sortBox[3].right=Column4+INTERBOX; s_sortBox[3].top=2; s_sortBox[3].bottom=p1.y; SortBoxX[MSM_TRAFFIC][3]=s_sortBox[3].right; // Altitude s_sortBox[4].left=Column4+INTERBOX; //s_sortBox[4].right=Column5+INTERBOX; s_sortBox[4].right=rc.right-1; s_sortBox[4].top=2; s_sortBox[4].bottom=p1.y; SortBoxX[MSM_TRAFFIC][4]=s_sortBox[4].right; SortBoxY[MSM_TRAFFIC]=p1.y; TrafficNumpages=roundupdivision(MAXTRAFFIC, TrafficNumraws); if (TrafficNumpages>MAXTRAFFICNUMPAGES) TrafficNumpages=MAXTRAFFICNUMPAGES; else if (TrafficNumpages<1) TrafficNumpages=1; SelectedRaw[MSM_TRAFFIC]=0; SelectedPage[MSM_TRAFFIC]=0; DoInit[MDI_DRAWTRAFFIC]=false; return; } // doinit DoTraffic(&DrawInfo, &DerivedDrawInfo); TrafficNumpages=roundupdivision(LKNumTraffic, TrafficNumraws); if (TrafficNumpages>MAXTRAFFICNUMPAGES) TrafficNumpages=MAXTRAFFICNUMPAGES; else if (TrafficNumpages<1) TrafficNumpages=1; curpage=SelectedPage[curmapspace]; if (curpage<0||curpage>=MAXTRAFFICNUMPAGES) { // DoStatusMessage(_T("ERR-041 traffic curpage invalid!")); // selection while waiting for data ready SelectedPage[curmapspace]=0; LKevent=LKEVENT_NONE; return; } switch (LKevent) { case LKEVENT_NONE: break; case LKEVENT_ENTER: LKevent=LKEVENT_NONE; i=LKSortedTraffic[SelectedRaw[curmapspace]+(curpage*TrafficNumraws)]; if ( (i<0) || (i>=MAXTRAFFIC) || (LKTraffic[i].ID<=0) ) { #if 0 // selection while waiting for data ready if (LKNumTraffic>0) DoStatusMessage(_T("ERR-045 Invalid selection")); #endif break; } LKevent=LKEVENT_NONE; // Do not update Traffic while in details mode, max 10m LastDoTraffic=DrawInfo.Time+600; dlgLKTrafficDetails(i); LastDoTraffic=0; break; case LKEVENT_DOWN: if (++SelectedRaw[curmapspace] >=TrafficNumraws) SelectedRaw[curmapspace]=0; // Reset LastDoTraffic so that it wont be updated while selecting an item LastDoTraffic=DrawInfo.Time+PAGINGTIMEOUT-1.0; break; case LKEVENT_UP: if (--SelectedRaw[curmapspace] <0) SelectedRaw[curmapspace]=TrafficNumraws-1; LastDoTraffic=DrawInfo.Time+PAGINGTIMEOUT-1.0; break; case LKEVENT_PAGEUP: LKevent=LKEVENT_NONE; break; case LKEVENT_PAGEDOWN: LKevent=LKEVENT_NONE; break; case LKEVENT_NEWRUN: for (i=0; i<MAXTRAFFIC; i++) { for (k=0; k<MAXTRAFFICNUMPAGES; k++) { _stprintf(Buffer1[i][k],_T("------------")); // 12 chars _stprintf(Buffer2[i][k],_T("----")); _stprintf(Buffer3[i][k],_T("----")); _stprintf(Buffer4[i][k],_T("----")); _stprintf(Buffer5[i][k],_T("----")); } } break; case LKEVENT_NEWPAGE: break; default: LKevent=LKEVENT_NONE; break; } if (INVERTCOLORS) _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p1, p2, RGB_GREEN, rc); else _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p1, p2, RGB_DARKGREEN, rc); SelectObject(hdc, LK8InfoNormalFont); // Heading line short cursortbox=SortedMode[curmapspace]; if ( ScreenSize < (ScreenSize_t)sslandscape ) { // portrait mode FillRect(hdc,&s_sortBox[cursortbox], sortbrush); _stprintf(Buffer,TEXT("%d.%d"),ModeIndex,CURTYPE+1); SelectObject(hdc, LK8PanelMediumFont); LKWriteText(hdc, Buffer, LEFTLIMITER, rc.top+TOPLIMITER , 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); SelectObject(hdc, LK8InfoNormalFont); // LKTOKEN _@M1331_ "TRF" _stprintf(Buffer,TEXT("%s %d/%d"), gettext(TEXT("_@M1331_")), curpage+1,TrafficNumpages); if (cursortbox==0) LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); // LKTOKEN _@M1300_ "Dist" _stprintf(Buffer, gettext(TEXT("_@M1300_"))); if (cursortbox==1) LKWriteText(hdc, Buffer, Column2, HEADRAW , 0, WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column2, HEADRAW , 0, WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1301_ "Dir" _stprintf(Buffer, gettext(TEXT("_@M1301_"))); if (cursortbox==2) LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1332_ "Var" _stprintf(Buffer, gettext(TEXT("_@M1332_"))); if (cursortbox==3) LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1334_ "Alt" _stprintf(Buffer, gettext(TEXT("_@M1334_"))); if (cursortbox==4) LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); } else { FillRect(hdc,&s_sortBox[cursortbox], sortbrush); if ( (ScreenSize == (ScreenSize_t)ss640x480) || (ScreenSize == (ScreenSize_t)ss320x240)|| ScreenSize==ss896x672 ) { _stprintf(Buffer,TEXT("%d.%d"),ModeIndex,CURTYPE+1); SelectObject(hdc, LK8PanelMediumFont); LKWriteText(hdc, Buffer, LEFTLIMITER, rc.top+TOPLIMITER , 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); SelectObject(hdc, LK8InfoNormalFont); // LKTOKEN _@M1331_ "TRF" _stprintf(Buffer,TEXT("%s %d/%d"), gettext(TEXT("_@M1331_")), curpage+1,TrafficNumpages); if (cursortbox==0) LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0,WTMODE_NORMAL, WTALIGN_LEFT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0,WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); // LKTOKEN _@M1300_ "Dist" _stprintf(Buffer, gettext(TEXT("_@M1300_"))); if (cursortbox==1) LKWriteText(hdc, Buffer, Column2, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column2, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1301_ "Dir" _stprintf(Buffer, gettext(TEXT("_@M1301_"))); if (cursortbox==2) LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1332_ "Var" _stprintf(Buffer, gettext(TEXT("_@M1332_"))); if (cursortbox==3) LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1334_ "Alt" _stprintf(Buffer, gettext(TEXT("_@M1334_"))); if (cursortbox==4) LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); } else { _stprintf(Buffer,TEXT("%d.%d"),ModeIndex,CURTYPE+1); SelectObject(hdc, LK8PanelMediumFont); LKWriteText(hdc, Buffer, LEFTLIMITER, rc.top+TOPLIMITER , 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); SelectObject(hdc, LK8InfoNormalFont); // LKTOKEN _@M1331_ "TRF" _stprintf(Buffer,TEXT("%s %d/%d"), gettext(TEXT("_@M1331_")), curpage+1,TrafficNumpages); if (cursortbox==0) LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0,WTMODE_NORMAL, WTALIGN_LEFT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0,WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); // LKTOKEN _@M1304_ "Distance" _stprintf(Buffer, gettext(TEXT("_@M1304_"))); if (cursortbox==1) LKWriteText(hdc, Buffer, Column2, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column2, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1305_ "Direction" _stprintf(Buffer, gettext(TEXT("_@M1305_"))); if (cursortbox==2) LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1333_ "Vario" _stprintf(Buffer, gettext(TEXT("_@M1333_"))); if (cursortbox==3) LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1334_ "Alt" _stprintf(Buffer, gettext(TEXT("_@M1334_"))); if (cursortbox==4) LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); } } // landscape mode SelectObject(hdc, LK8InfoBigFont); // Text font for Nearest #ifdef DEBUG_LKT_DRAWTRAFFIC TCHAR v2buf[100]; wsprintf(v2buf,_T("MAXTRAFFIC=%d LKNumTraff=%d / TrafficNumraws=%d TrafficNumpages=%d calc=%d\n"),MAXTRAFFIC, LKNumTraffic,TrafficNumraws, TrafficNumpages, (short)(ceil(MAXTRAFFIC/TrafficNumraws))); StartupStore(v2buf); #endif for (i=0, drawn_items_onpage=0; i<TrafficNumraws; i++) { iRaw=TopSize+(s_rawspace*i); short curraw=(curpage*TrafficNumraws)+i; if (curraw>=MAXTRAFFIC) break; rli=LKSortedTraffic[curraw]; #ifdef DEBUG_LKT_DRAWTRAFFIC StartupStore(_T("..LKDrawTraff page=%d curraw=%d rli=%d \n"), curpage,curraw,rli); #endif if ( (rli>=0) && (LKTraffic[rli].ID>0) ) { // Traffic name wlen=wcslen(LKTraffic[rli].Name); // if name is unknown then it is a '?' if (wlen==1) { _stprintf(Buffer,_T("%06x"),LKTraffic[rli].ID); Buffer[s_maxnlname]='\0'; } else { // if XY I-ABCD doesnt fit.. if ( (wlen+3)>s_maxnlname) { LK_tcsncpy(Buffer, LKTraffic[rli].Name, s_maxnlname); } else { unsigned short cnlen=_tcslen(LKTraffic[rli].Cn); // if cn is XY create XY I-ABCD if (cnlen==1 || cnlen==2) { _tcscpy(Buffer,LKTraffic[rli].Cn); _tcscat(Buffer,_T(" ")); _tcscat(Buffer,LKTraffic[rli].Name); // for safety Buffer[s_maxnlname]='\0'; } else { // else use only long name LK_tcsncpy(Buffer, LKTraffic[rli].Name, wlen); } } ConvToUpper(Buffer); } if (LKTraffic[rli].Locked) { TCHAR buf2[LKSIZEBUFFERLARGE]; _stprintf(buf2,_T("*%s"),Buffer); buf2[s_maxnlname]='\0'; _tcscpy(Buffer,buf2); } #ifdef DEBUG_LKT_DRAWTRAFFIC StartupStore(_T(".. Traffic[%d] Name=<%s> Id=<%0x> Status=%d Named:<%s>\n"),rli,LKTraffic[rli].Name, LKTraffic[rli].ID, LKTraffic[rli].Status,Buffer); #endif _tcscpy(Buffer1[i][curpage],Buffer); // Distance value=LKTraffic[rli].Distance*DISTANCEMODIFY; _stprintf(Buffer2[i][curpage],TEXT("%0.1lf"),value); // relative bearing if (!MapWindow::mode.Is(MapWindow::Mode::MODE_CIRCLING)) { value = LKTraffic[rli].Bearing - DrawInfo.TrackBearing; if (value < -180.0) value += 360.0; else if (value > 180.0) value -= 360.0; #ifndef __MINGW32__ if (value > 1) _stprintf(Buffer3[i][curpage], TEXT("%2.0f\xB0\xBB"), value); else if (value < -1) _stprintf(Buffer3[i][curpage], TEXT("\xAB%2.0f\xB0"), -value); else _tcscpy(Buffer3[i][curpage], TEXT("\xAB\xBB")); #else if (value > 1) _stprintf(Buffer3[i][curpage], TEXT("%2.0f°»"), value); else if (value < -1) _stprintf(Buffer3[i][curpage], TEXT("«%2.0f°"), -value); else _tcscpy(Buffer3[i][curpage], TEXT("«»")); #endif } else { _stprintf(Buffer3[i][curpage], _T("%2.0f°"), LKTraffic[rli].Bearing); } // Vario value=LIFTMODIFY*LKTraffic[rli].Average30s; if (value<-6 || value>6) _stprintf(Buffer4[i][curpage],_T("---")); else { sprintf(text,"%+.1f",value); _stprintf(Buffer4[i][curpage],_T("%S"),text); } // Altitude value=ALTITUDEMODIFY*LKTraffic[rli].Altitude; if (value<-1000 || value >45000 ) strcpy(text,"---"); else sprintf(text,"%.0f",value); wsprintf(Buffer5[i][curpage], TEXT("%S"),text); } else { // Empty traffic, fill in all empty data and maybe break loop _stprintf(Buffer1[i][curpage],_T("------------")); _stprintf(Buffer2[i][curpage],_T("---")); _stprintf(Buffer3[i][curpage],_T("---")); _stprintf(Buffer4[i][curpage],_T("---")); _stprintf(Buffer5[i][curpage],_T("---")); } if ((rli>=0) && (LKTraffic[rli].ID>0)) { drawn_items_onpage++; if (LKTraffic[rli].Status == LKT_REAL) { rcolor=RGB_WHITE; SelectObject(hdc, LK8InfoBigFont); } else { if (LKTraffic[rli].Status == LKT_GHOST) { rcolor=RGB_LIGHTYELLOW; } else { rcolor=RGB_LIGHTRED; } SelectObject(hdc, LK8InfoBigItalicFont); } } else rcolor=RGB_GREY; LKWriteText(hdc, Buffer1[i][curpage], Column1, iRaw , 0, WTMODE_NORMAL, WTALIGN_LEFT, rcolor, false); SelectObject(hdc, LK8InfoBigFont); // Text font for Nearest LKWriteText(hdc, Buffer2[i][curpage], Column2, iRaw , 0, WTMODE_NORMAL, WTALIGN_RIGHT, rcolor, false); LKWriteText(hdc, Buffer3[i][curpage], Column3, iRaw , 0, WTMODE_NORMAL, WTALIGN_RIGHT, rcolor, false); LKWriteText(hdc, Buffer4[i][curpage], Column4, iRaw , 0, WTMODE_NORMAL, WTALIGN_RIGHT, rcolor, false); LKWriteText(hdc, Buffer5[i][curpage], Column5, iRaw , 0, WTMODE_NORMAL, WTALIGN_RIGHT, rcolor, false); } // for if (LKevent==LKEVENT_NEWRUN || LKevent==LKEVENT_NEWPAGE ) { LKevent=LKEVENT_NONE; return; } if (drawn_items_onpage>0) { if (SelectedRaw[curmapspace] <0 || SelectedRaw[curmapspace]>(TrafficNumraws-1)) { LKevent=LKEVENT_NONE; // 100328 return; } if (SelectedRaw[curmapspace] >= drawn_items_onpage) { if (LKevent==LKEVENT_DOWN) SelectedRaw[curmapspace]=0; else if (LKevent==LKEVENT_UP) SelectedRaw[curmapspace]=drawn_items_onpage-1; else { SelectedRaw[curmapspace]=0; } } invsel.left=left; invsel.right=right; invsel.top=TopSize+(s_rawspace*SelectedRaw[curmapspace])+NIBLSCALE(2); invsel.bottom=TopSize+(s_rawspace*(SelectedRaw[curmapspace]+1))-NIBLSCALE(1); InvertRect(hdc,&invsel); } LKevent=LKEVENT_NONE; return; }
void MapWindow::DrawThermalHistory(HDC hdc, RECT rc) { SIZE WPTextSize, DSTextSize, BETextSize, RETextSize, AATextSize, HLTextSize, MITextSize; TCHAR Buffer[LKSIZEBUFFERLARGE]; static RECT s_sortBox[6]; static TCHAR Buffer1[MAXTHISTORY][MAXTHISTORYNUMPAGES][24], Buffer2[MAXTHISTORY][MAXTHISTORYNUMPAGES][10]; static TCHAR Buffer3[MAXTHISTORY][MAXTHISTORYNUMPAGES][10]; static TCHAR Buffer4[MAXTHISTORY][MAXTHISTORYNUMPAGES][12], Buffer5[MAXTHISTORY][MAXTHISTORYNUMPAGES][12]; static short s_maxnlname; char text[30]; short i, k, iRaw, wlen, rli=0, curpage, drawn_items_onpage; double value; COLORREF rcolor; // column0 starts after writing 1:2 (ModeIndex:CURTYPE+1) with a different font.. static short Column0; static short Column1, Column2, Column3, Column4, Column5; static POINT p1, p2; static short s_rawspace; // Printable area for live nearest values static short left,right,bottom; // one for each mapspace, no matter if 0 and 1 are unused short curmapspace=MapSpaceMode; static int thistoryNumraws=0; // Vertical and horizontal spaces #define INTERRAW 1 #define HEADRAW NIBLSCALE(6) HBRUSH sortbrush; RECT invsel; if (INVERTCOLORS) { sortbrush=LKBrush_LightGreen; } else { sortbrush=LKBrush_DarkGreen; } if (DoInit[MDI_DRAWTHERMALHISTORY]) { if ( ScreenSize < (ScreenSize_t)sslandscape ) { left=rc.left+NIBLSCALE(1); right=rc.right-NIBLSCALE(1); bottom=rc.bottom-BottomSize-NIBLSCALE(2); s_maxnlname=MAXNLNAME-5; // 7 chars max, 8 sized _stprintf(Buffer,TEXT("MAKSJSMM")); } else { left=rc.left+NIBLSCALE(5); right=rc.right-NIBLSCALE(5); bottom=rc.bottom-BottomSize; s_maxnlname=MAXNLNAME-3; // 9 chars, sized 10 _stprintf(Buffer,TEXT("ABCDEFGHMx")); } SelectObject(hdc, LK8InfoBigFont); // Text font for Nearest was LK8Title GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &WPTextSize); _stprintf(Buffer,TEXT("000.0")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &DSTextSize); _stprintf(Buffer,TEXT("<<123")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &BETextSize); _stprintf(Buffer,TEXT("5299")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &RETextSize); _stprintf(Buffer,TEXT("+9999")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &AATextSize); SelectObject(hdc, LK8InfoNormalFont); // Heading line was MapWindow QUI _stprintf(Buffer,TEXT("MMMM")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &HLTextSize); SelectObject(hdc, LK8PanelMediumFont); _stprintf(Buffer,TEXT("1.1")); GetTextExtentPoint(hdc, Buffer, _tcslen(Buffer), &MITextSize); short afterwpname=left+WPTextSize.cx+NIBLSCALE(5); short intercolumn=(right-afterwpname- DSTextSize.cx-BETextSize.cx-RETextSize.cx-AATextSize.cx)/3; Column0=MITextSize.cx+LEFTLIMITER+NIBLSCALE(5); Column1=left; // WP align left Column2=afterwpname+DSTextSize.cx; // DS align right Column3=Column2+intercolumn+BETextSize.cx; // BE align right Column4=Column3+intercolumn+RETextSize.cx; // RE align right Column5=Column4+intercolumn+AATextSize.cx; // AA align right if ( ScreenSize < (ScreenSize_t)sslandscape ) { TopSize=rc.top+HEADRAW*2+HLTextSize.cy; p1.x=0; p1.y=TopSize; p2.x=rc.right; p2.y=p1.y; TopSize+=HEADRAW; thistoryNumraws=(bottom - TopSize) / (WPTextSize.cy+(INTERRAW*2)); if (thistoryNumraws>MAXTHISTORY) thistoryNumraws=MAXTHISTORY; s_rawspace=(WPTextSize.cy+INTERRAW); } else { TopSize=rc.top+HEADRAW*2+HLTextSize.cy; p1.x=0; p1.y=TopSize; p2.x=rc.right; p2.y=p1.y; TopSize+=HEADRAW/2; thistoryNumraws=(bottom - TopSize) / (WPTextSize.cy+INTERRAW); if (thistoryNumraws>MAXTHISTORY) thistoryNumraws=MAXTHISTORY; s_rawspace=(WPTextSize.cy+INTERRAW); } #define INTERBOX intercolumn/2 // Thermal name s_sortBox[0].left=Column0; // FIX 090925 era solo 0 if ( ScreenSize < (ScreenSize_t)sslandscape ) s_sortBox[0].right=left+WPTextSize.cx-NIBLSCALE(2); else s_sortBox[0].right=left+WPTextSize.cx-NIBLSCALE(10); s_sortBox[0].top=2; s_sortBox[0].bottom=p1.y; SortBoxX[MSM_THERMALS][0]=s_sortBox[0].right; // Distance if ( ScreenSize < (ScreenSize_t)sslandscape ) s_sortBox[1].left=Column1+afterwpname-INTERBOX; else s_sortBox[1].left=Column1+afterwpname-INTERBOX-NIBLSCALE(2); s_sortBox[1].right=Column2+INTERBOX; s_sortBox[1].top=2; s_sortBox[1].bottom=p1.y; SortBoxX[MSM_THERMALS][1]=s_sortBox[1].right; // Bearing s_sortBox[2].left=Column2+INTERBOX; s_sortBox[2].right=Column3+INTERBOX; s_sortBox[2].top=2; s_sortBox[2].bottom=p1.y; SortBoxX[MSM_THERMALS][2]=s_sortBox[2].right; // Vario s_sortBox[3].left=Column3+INTERBOX; s_sortBox[3].right=Column4+INTERBOX; s_sortBox[3].top=2; s_sortBox[3].bottom=p1.y; SortBoxX[MSM_THERMALS][3]=s_sortBox[3].right; // Altitude s_sortBox[4].left=Column4+INTERBOX; //s_sortBox[4].right=Column5+INTERBOX; s_sortBox[4].right=rc.right-1; s_sortBox[4].top=2; s_sortBox[4].bottom=p1.y; SortBoxX[MSM_THERMALS][4]=s_sortBox[4].right; SortBoxY[MSM_THERMALS]=p1.y; THistoryNumpages=roundupdivision(MAXTHISTORY, thistoryNumraws); if (THistoryNumpages>MAXTHISTORYNUMPAGES) THistoryNumpages=MAXTHISTORYNUMPAGES; else if (THistoryNumpages<1) THistoryNumpages=1; SelectedRaw[MSM_THERMALS]=0; SelectedPage[MSM_THERMALS]=0; DoInit[MDI_DRAWTHERMALHISTORY]=false; return; } // doinit DoThermalHistory(&GPS_INFO, &CALCULATED_INFO); THistoryNumpages=roundupdivision(LKNumThermals, thistoryNumraws); if (THistoryNumpages>MAXTHISTORYNUMPAGES) THistoryNumpages=MAXTHISTORYNUMPAGES; else if (THistoryNumpages<1) THistoryNumpages=1; curpage=SelectedPage[curmapspace]; if (curpage<0||curpage>=MAXTHISTORYNUMPAGES) { #if TESTBENCH DoStatusMessage(_T("ERR-041 thermals curpage invalid")); // selection while waiting for data ready #endif SelectedPage[curmapspace]=0; LKevent=LKEVENT_NONE; return; } switch (LKevent) { case LKEVENT_NONE: break; case LKEVENT_ENTER: LKevent=LKEVENT_NONE; i=LKSortedThermals[SelectedRaw[curmapspace]+(curpage*thistoryNumraws)]; if ( (i<0) || (i>=MAXTHISTORY) || (CopyThermalHistory[i].Valid != true) ) { #if 0 // selection while waiting for data ready if (LKNumThermals>0) DoStatusMessage(_T("ERR-045 Invalid selection")); #endif break; } LKevent=LKEVENT_NONE; // Do not update while in details mode, max 10m LastDoThermalH=GPS_INFO.Time+600; dlgThermalDetails(i); LastDoThermalH=0; break; case LKEVENT_DOWN: if (++SelectedRaw[curmapspace] >=thistoryNumraws) SelectedRaw[curmapspace]=0; // Reset LastDoThermalH so that it wont be updated while selecting an item LastDoThermalH=GPS_INFO.Time+PAGINGTIMEOUT-1.0; break; case LKEVENT_UP: if (--SelectedRaw[curmapspace] <0) SelectedRaw[curmapspace]=thistoryNumraws-1; LastDoThermalH=GPS_INFO.Time+PAGINGTIMEOUT-1.0; break; case LKEVENT_PAGEUP: LKevent=LKEVENT_NONE; break; case LKEVENT_PAGEDOWN: LKevent=LKEVENT_NONE; break; case LKEVENT_NEWRUN: for (i=0; i<MAXTHISTORY; i++) { for (k=0; k<MAXTHISTORYNUMPAGES; k++) { _stprintf(Buffer1[i][k],_T("------------")); // 12 chars _stprintf(Buffer2[i][k],_T("----")); _stprintf(Buffer3[i][k],_T("----")); _stprintf(Buffer4[i][k],_T("----")); _stprintf(Buffer5[i][k],_T("----")); } } break; case LKEVENT_NEWPAGE: break; default: LKevent=LKEVENT_NONE; break; } if (INVERTCOLORS) _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p1, p2, RGB_GREEN, rc); else _DrawLine(hdc, PS_SOLID, NIBLSCALE(1), p1, p2, RGB_DARKGREEN, rc); SelectObject(hdc, LK8InfoNormalFont); // Heading line short cursortbox=SortedMode[curmapspace]; if ( ScreenSize < (ScreenSize_t)sslandscape ) { // portrait mode FillRect(hdc,&s_sortBox[cursortbox], sortbrush); _stprintf(Buffer,TEXT("%d.%d"),ModeIndex,CURTYPE+1); SelectObject(hdc, LK8PanelMediumFont); LKWriteText(hdc, Buffer, LEFTLIMITER, rc.top+TOPLIMITER , 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); SelectObject(hdc, LK8InfoNormalFont); _stprintf(Buffer,TEXT("%s %d/%d"), gettext(TEXT("_@M1670_")), curpage+1,THistoryNumpages); if (cursortbox==0) LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); // LKTOKEN _@M1300_ "Dist" _stprintf(Buffer, gettext(TEXT("_@M1300_"))); if (cursortbox==1) LKWriteText(hdc, Buffer, Column2, HEADRAW , 0, WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column2, HEADRAW , 0, WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1301_ "Dir" _stprintf(Buffer, gettext(TEXT("_@M1301_"))); if (cursortbox==2) LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); _stprintf(Buffer, gettext(TEXT("_@M1673_"))); // Avg if (cursortbox==3) LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); _stprintf(Buffer, gettext(TEXT("_@M1307_"))); // AltArr if (cursortbox==4) LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); } else { FillRect(hdc,&s_sortBox[cursortbox], sortbrush); if ( (ScreenSize == (ScreenSize_t)ss640x480) || (ScreenSize == (ScreenSize_t)ss320x240)|| ScreenSize==ss896x672 ) { _stprintf(Buffer,TEXT("%d.%d"),ModeIndex,CURTYPE+1); SelectObject(hdc, LK8PanelMediumFont); LKWriteText(hdc, Buffer, LEFTLIMITER, rc.top+TOPLIMITER , 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); SelectObject(hdc, LK8InfoNormalFont); _stprintf(Buffer,TEXT("%s %d/%d"), gettext(TEXT("_@M1670_")), curpage+1,THistoryNumpages); // THE if (cursortbox==0) LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0,WTMODE_NORMAL, WTALIGN_LEFT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0,WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); // LKTOKEN _@M1300_ "Dist" _stprintf(Buffer, gettext(TEXT("_@M1300_"))); if (cursortbox==1) LKWriteText(hdc, Buffer, Column2, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column2, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1301_ "Dir" _stprintf(Buffer, gettext(TEXT("_@M1301_"))); if (cursortbox==2) LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); _stprintf(Buffer, gettext(TEXT("_@M1673_"))); // Avg if (cursortbox==3) LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); _stprintf(Buffer, gettext(TEXT("_@M1307_"))); // AltArr if (cursortbox==4) LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); } else { _stprintf(Buffer,TEXT("%d.%d"),ModeIndex,CURTYPE+1); SelectObject(hdc, LK8PanelMediumFont); LKWriteText(hdc, Buffer, LEFTLIMITER, rc.top+TOPLIMITER , 0, WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); SelectObject(hdc, LK8InfoNormalFont); // LKTOKEN _@M1670_ "THE" _stprintf(Buffer,TEXT("%s %d/%d"), gettext(TEXT("_@M1670_")), curpage+1,THistoryNumpages); if (cursortbox==0) LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0,WTMODE_NORMAL, WTALIGN_LEFT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column0, HEADRAW-NIBLSCALE(1) , 0,WTMODE_NORMAL, WTALIGN_LEFT, RGB_LIGHTGREEN, false); // LKTOKEN _@M1304_ "Distance" _stprintf(Buffer, gettext(TEXT("_@M1304_"))); if (cursortbox==1) LKWriteText(hdc, Buffer, Column2, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column2, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); // LKTOKEN _@M1305_ "Direction" _stprintf(Buffer, gettext(TEXT("_@M1305_"))); if (cursortbox==2) LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column3, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); _stprintf(Buffer, gettext(TEXT("_@M1673_"))); // Avg if (cursortbox==3) LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column4, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); _stprintf(Buffer, gettext(TEXT("_@M1307_"))); // AltArr if (cursortbox==4) LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_BLACK, false); else LKWriteText(hdc, Buffer, Column5, HEADRAW , 0,WTMODE_NORMAL, WTALIGN_RIGHT, RGB_WHITE, false); } } // landscape mode SelectObject(hdc, LK8InfoBigFont); // Text font for Nearest #ifdef DEBUG_LKT_DRAWTHISTORY TCHAR v2buf[100]; wsprintf(v2buf,_T("MAXTHISTORY=%d LKNumTherm=%d / thistoryNumraws=%d THistoryNumpages=%d calc=%d\n"),MAXTHISTORY, LKNumThermals,thistoryNumraws, THistoryNumpages, (short)(ceil(MAXTHISTORY/thistoryNumraws))); StartupStore(v2buf); #endif for (i=0, drawn_items_onpage=0; i<thistoryNumraws; i++) { iRaw=TopSize+(s_rawspace*i); short curraw=(curpage*thistoryNumraws)+i; if (curraw>=MAXTHISTORY) break; rli=LKSortedThermals[curraw]; #ifdef DEBUG_LKT_DRAWTHISTORY StartupStore(_T("..LKDrawThistory page=%d curraw=%d rli=%d \n"), curpage,curraw,rli); #endif if ( (rli>=0) && (CopyThermalHistory[rli].Valid==true) ) { // Thermal name wlen=wcslen(CopyThermalHistory[rli].Name); if (wlen>s_maxnlname) { LKASSERT(CopyThermalHistory[rli].Name); _tcsncpy(Buffer, CopyThermalHistory[rli].Name, s_maxnlname); Buffer[s_maxnlname]='\0'; } else { LKASSERT(CopyThermalHistory[rli].Name); _tcsncpy(Buffer, CopyThermalHistory[rli].Name, wlen); Buffer[wlen]='\0'; } if (IsThermalMultitarget(rli)) { TCHAR Buffer2[40]; _stprintf(Buffer2,_T(">%s"),Buffer); wcscpy(Buffer,Buffer2); } ConvToUpper(Buffer); _tcscpy(Buffer1[i][curpage],Buffer); // Distance value=CopyThermalHistory[rli].Distance*DISTANCEMODIFY; _stprintf(Buffer2[i][curpage],TEXT("%0.1lf"),value); // relative bearing if (!MapWindow::mode.Is(MapWindow::Mode::MODE_CIRCLING)) { value = CopyThermalHistory[rli].Bearing - GPS_INFO.TrackBearing; if (value < -180.0) value += 360.0; else if (value > 180.0) value -= 360.0; #ifndef __MINGW32__ if (value > 1) _stprintf(Buffer3[i][curpage], TEXT("%2.0f\xB0\xBB"), value); else if (value < -1) _stprintf(Buffer3[i][curpage], TEXT("\xAB%2.0f\xB0"), -value); else _tcscpy(Buffer3[i][curpage], TEXT("\xAB\xBB")); #else if (value > 1) _stprintf(Buffer3[i][curpage], TEXT("%2.0f°»"), value); else if (value < -1) _stprintf(Buffer3[i][curpage], TEXT("«%2.0f°"), -value); else _tcscpy(Buffer3[i][curpage], TEXT("«»")); #endif } else { _stprintf(Buffer3[i][curpage], _T("%2.0f°"), CopyThermalHistory[rli].Bearing); } // Average lift value=LIFTMODIFY*CopyThermalHistory[rli].Lift; if (value<-99 || value>99) _stprintf(Buffer4[i][curpage],_T("---")); else { sprintf(text,"%+.1f",value); _stprintf(Buffer4[i][curpage],_T("%S"),text); } // Altitude value=ALTITUDEMODIFY*CopyThermalHistory[rli].Arrival; if (value<-1000 || value >45000 ) strcpy(text,"---"); else sprintf(text,"%.0f",value); wsprintf(Buffer5[i][curpage], TEXT("%S"),text); } else { // Empty thermals, fill in all empty data and maybe break loop _stprintf(Buffer1[i][curpage],_T("------------")); _stprintf(Buffer2[i][curpage],_T("---")); _stprintf(Buffer3[i][curpage],_T("---")); _stprintf(Buffer4[i][curpage],_T("---")); _stprintf(Buffer5[i][curpage],_T("---")); } if ((rli>=0) && (CopyThermalHistory[rli].Valid==true)) { drawn_items_onpage++; if (CopyThermalHistory[rli].Arrival >=0) { rcolor=RGB_WHITE; SelectObject(hdc, LK8InfoBigFont); } else { rcolor=RGB_LIGHTRED; SelectObject(hdc, LK8InfoBigItalicFont); } } else rcolor=RGB_GREY; LKWriteText(hdc, Buffer1[i][curpage], Column1, iRaw , 0, WTMODE_NORMAL, WTALIGN_LEFT, rcolor, false); SelectObject(hdc, LK8InfoBigFont); // Text font for Nearest LKWriteText(hdc, Buffer2[i][curpage], Column2, iRaw , 0, WTMODE_NORMAL, WTALIGN_RIGHT, rcolor, false); LKWriteText(hdc, Buffer3[i][curpage], Column3, iRaw , 0, WTMODE_NORMAL, WTALIGN_RIGHT, rcolor, false); LKWriteText(hdc, Buffer4[i][curpage], Column4, iRaw , 0, WTMODE_NORMAL, WTALIGN_RIGHT, rcolor, false); LKWriteText(hdc, Buffer5[i][curpage], Column5, iRaw , 0, WTMODE_NORMAL, WTALIGN_RIGHT, rcolor, false); } // for if (LKevent==LKEVENT_NEWRUN || LKevent==LKEVENT_NEWPAGE ) { LKevent=LKEVENT_NONE; return; } if (drawn_items_onpage>0) { if (SelectedRaw[curmapspace] <0 || SelectedRaw[curmapspace]>(thistoryNumraws-1)) { LKevent=LKEVENT_NONE; // 100328 return; } if (SelectedRaw[curmapspace] >= drawn_items_onpage) { if (LKevent==LKEVENT_DOWN) SelectedRaw[curmapspace]=0; else if (LKevent==LKEVENT_UP) SelectedRaw[curmapspace]=drawn_items_onpage-1; else { SelectedRaw[curmapspace]=0; } } invsel.left=left; invsel.right=right; invsel.top=TopSize+(s_rawspace*SelectedRaw[curmapspace])+NIBLSCALE(2); invsel.bottom=TopSize+(s_rawspace*(SelectedRaw[curmapspace]+1))-NIBLSCALE(1); InvertRect(hdc,&invsel); } LKevent=LKEVENT_NONE; return; }