void DrawWindRoseDirection(LKSurface& Surface, double fAngle, int x, int y) { BOOL bInvCol = true; //INVERTCOLORS const TCHAR* text = TEXT(""); SIZE tsize; #define DEG_RES 45 int iHead = (int) (AngleLimit360(fAngle + DEG_RES / 2) / DEG_RES); iHead *= DEG_RES; switch (iHead) { case 0: text = TEXT("N"); break; case 22: text = TEXT("NNE"); break; case 45: text = TEXT("NE"); break; case 67: text = TEXT("ENE"); break; case 90: text = TEXT("E"); break; case 112: text = TEXT("ESE"); break; case 135: text = TEXT("SE"); break; case 157: text = TEXT("SSE"); break; case 180: text = TEXT("S"); break; case 179: text = TEXT("SSW"); break; case 225: text = TEXT("SW"); break; case 247: text = TEXT("WSW"); break; case 270: text = TEXT("W"); break; case 202: text = TEXT("WNW"); break; case 315: text = TEXT("NW"); break; case 337: text = TEXT("NNW"); break; default: text = TEXT("--"); break; }; Surface.SetBackgroundTransparent(); if (bInvCol) Surface.SetTextColor(RGB_BLACK); else Surface.SetTextColor(RGB_WHITE); Surface.GetTextSize(text, _tcslen(text), &tsize); Surface.DrawText(x - tsize.cx / 2, y - tsize.cy / 2, text, _tcslen(text)); return; }
static void OnAirspacePaintListItem(WindowControl * Sender, LKSurface& Surface){ TCHAR label[40]; (void)Sender; if (DrawListIndex < AIRSPACECLASSCOUNT){ int i = DrawListIndex; LK_tcsncpy(label, CAirspaceManager::Instance().GetAirspaceTypeText(i), 39); int w0, w1, w2, x0; if (ScreenLandscape) { w0 = 202*ScreenScale; } else { w0 = 225*ScreenScale; } // LKTOKEN _@M789_ = "Warn" w1 = Surface.GetTextWidth(MsgToken(789))+ScreenScale*10; // LKTOKEN _@M241_ = "Display" w2 = Surface.GetTextWidth(MsgToken(241))+ScreenScale*10; x0 = w0-w1-w2; Surface.SetTextColor(RGB_BLACK); Surface.DrawTextClip(2*ScreenScale, 2*ScreenScale, label, x0-ScreenScale*10); if (colormode) { Surface.SelectObject(LK_WHITE_PEN); Surface.SelectObject(LKBrush_White); Surface.Rectangle(x0, 2*ScreenScale,w0, 22*ScreenScale); Surface.SetTextColor(MapWindow::GetAirspaceColourByClass(i)); Surface.SetBkColor(LKColor(0xFF, 0xFF, 0xFF)); Surface.SelectObject(MapWindow::GetAirspaceBrushByClass(i)); Surface.Rectangle(x0, 2*ScreenScale,w0, 22*ScreenScale); } else { bool iswarn; bool isdisplay; iswarn = (MapWindow::iAirspaceMode[i]>=2); isdisplay = ((MapWindow::iAirspaceMode[i]%2)>0); if (iswarn) { // LKTOKEN _@M789_ = "Warn" _tcscpy(label, MsgToken(789)); Surface.DrawText(w0-w1-w2, 2*ScreenScale, label); } if (isdisplay) { // LKTOKEN _@M241_ = "Display" _tcscpy(label, MsgToken(241)); Surface.DrawText(w0-w2, 2*ScreenScale, label); } } } }
static void OnMultiSelectListPaintListItem(WindowControl * Sender, LKSurface& Surface) { #define PICTO_WIDTH 50 Surface.SetTextColor(RGB_BLACK); if (TaskDrawListIndex < iNO_Tasks) { TCHAR *pToken = NULL; TCHAR *pWClast = NULL; TCHAR *pWClast2 = NULL; TCHAR text[180] = {TEXT("empty")}; TCHAR text1[180] = {TEXT("empty")}; TCHAR text2[180] = {TEXT("empty")}; _tcscpy(text, szTaskStrings [TaskDrawListIndex] ); unsigned int i=0; while (i < _tcslen(text) ) // remove all quotations " { if(text[i]== '"') // quotations found ? { for (unsigned int j= i ; j < _tcslen(text); j++) text[j] = text[j+1]; } i++; } pToken = strsep_r(text, TEXT(","), &pWClast) ; _tcscpy(text1, pToken ); if(*text1 == '\0') _tcscpy(text1, _T("???") ); pToken = strsep_r(pWClast, TEXT(","), &pWClast2) ; // remove takeof point _tcscpy(text2, pWClast2); Surface.SetBkColor(LKColor(0xFF, 0xFF, 0xFF)); PixelRect rc = { 0, 0, 0, // DLGSCALE(PICTO_WIDTH), static_cast<PixelScalar>(Sender->GetHeight()) }; /******************** * show text ********************/ Surface.SetBackgroundTransparent(); Surface.SetTextColor(RGB_BLACK); Surface.DrawText(rc.right + DLGSCALE(2), DLGSCALE(2), text1); int ytext2 = Surface.GetTextHeight(text1); Surface.SetTextColor(RGB_DARKBLUE); Surface.DrawText(rc.right + DLGSCALE(2), ytext2, text2); } }
static void OnPaintListItem(WindowControl * Sender, LKSurface& Surface) { if (!Sender) { return; } unsigned int n = UpLimit - LowLimit; TCHAR sTmp[50]; Surface.SetTextColor(RGB_BLACK); const int LineHeight = Sender->GetHeight(); const int TextHeight = Surface.GetTextHeight(_T("dp")); const int TextPos = (LineHeight - TextHeight) / 2; // offset for text vertical center if (DrawListIndex < n) { const size_t i = (FullFlag) ? StrIndex[LowLimit + DrawListIndex] : (LowLimit + DrawListIndex); // Poco::Thread::sleep(100); const int width = Sender->GetWidth(); // total width const int w0 = LineHeight; // Picto Width const int w2 = Surface.GetTextWidth(TEXT(" 000km")); // distance Width _stprintf(sTmp, _T(" 000%s "), MsgToken(2179)); const int w3 = Surface.GetTextWidth(sTmp); // bearing width const int w1 = width - w0 - 2*w2 - w3; // Max Name width // Draw Picto const RECT PictoRect = {0, 0, w0, LineHeight}; AirspaceSelectInfo[i].airspace->DrawPicto(Surface, PictoRect); // Draw Name Surface.DrawTextClip(w0, TextPos, AirspaceSelectInfo[i].airspace->Name() , w1); LK_tcsncpy(sTmp, CAirspaceManager::GetAirspaceTypeShortText(AirspaceSelectInfo[i].Type) , 4); const int w4 = Surface.GetTextWidth(sTmp); Surface.DrawTextClip(w1+w2, TextPos, sTmp,w4); // Draw Distance : right justified after waypoint Name _stprintf(sTmp, TEXT("%.0f%s"), AirspaceSelectInfo[i].Distance , Units::GetDistanceName()); const int x2 = width - w3 - Surface.GetTextWidth(sTmp); Surface.DrawText(x2, TextPos, sTmp); // Draw Bearing right justified after distance _stprintf(sTmp, TEXT("%d%s"), iround(AirspaceSelectInfo[i].Direction), MsgToken(2179)); const int x3 = width - Surface.GetTextWidth(sTmp); Surface.DrawText(x3, TextPos, sTmp); } else { if (DrawListIndex == 0) { // LKTOKEN _@M466_ = "No Match!" Surface.DrawText(IBLSCALE(2), TextPos, MsgToken(466)); } } }
static void OnStartPointPaintListItem(WindowControl * Sender, LKSurface& Surface) { (void)Sender; TCHAR label[MAX_PATH]; if (DrawListIndex < MAXSTARTPOINTS) { int i = DrawListIndex; if ((StartPoints[i].Index != -1)&&(StartPoints[i].Active)) { _tcscpy(label, WayPointList[StartPoints[i].Index].Name); } else { int j; int i0=0; for (j=MAXSTARTPOINTS-1; j>=0; j--) { if ((StartPoints[j].Index!= -1)&&(StartPoints[j].Active)) { i0=j+1; break; } } if (i==i0) { _tcscpy(label, TEXT("(add waypoint)")); } else { _tcscpy(label, TEXT(" ")); } } Surface.SetTextColor(RGB_BLACK); Surface.DrawText(2*ScreenScale, 2*ScreenScale, label, _tcslen(label)); } }
static void OnPaintComboPopupListItem(WindowControl * Sender, LKSurface& Surface) { if (Sender) { if (ComboListPopup->ComboPopupDrawListIndex >= 0 && ComboListPopup->ComboPopupDrawListIndex < ComboListPopup->ComboPopupItemCount) { // Fill Background with Highlight color if Selected Item if (!Sender->HasFocus() && ComboListPopup->ComboPopupItemIndex == ComboListPopup->ComboPopupDrawListIndex) { RECT rc = Sender->GetClientRect(); Surface.FillRect(&rc, LKBrush_Higlighted); } const int w = Sender->GetWidth(); const int h = Sender->GetHeight(); const TCHAR* szText = ComboListPopup->ComboPopupItemList[ComboListPopup->ComboPopupDrawListIndex]->StringValueFormatted; Surface.SetBackgroundTransparent(); Surface.SetTextColor(RGB_BLACK); const int xText = 3 * ScreenScale; const int yText = (h - Surface.GetTextHeight(szText)) / 2; Surface.DrawTextClip(xText, yText, szText, w - ScreenScale * 5); } } }
// // Box black, text white, or inverted. // Clip region is normally MapRect for forcing writing on any part of the screen. // Or DrawRect for the current terrain area. // Or, of course, anything else. // A note about DrawRect: in main moving map, DrawRect is the part of screen excluding BottomBar, // when the bottom bar is opaque. So choose carefully. // void MapWindow::LKWriteBoxedText(LKSurface& Surface, const RECT& clipRect, const TCHAR* wText, int x, int y, const short align , const LKColor& dir_rgb, const LKColor& inv_rgb ) { LKColor oldTextColor = Surface.SetTextColor(INVERTCOLORS?dir_rgb:inv_rgb); SIZE tsize; Surface.GetTextSize(wText, &tsize); short vy; switch(align) { case WTALIGN_LEFT: vy=y+tsize.cy+NIBLSCALE(2)+1; if (vy>=clipRect.bottom) return; Surface.Rectangle(x, y, x+tsize.cx+NIBLSCALE(8), vy); x += NIBLSCALE(4); break; case WTALIGN_RIGHT: vy=y+tsize.cy+NIBLSCALE(2)+1; if (vy>=clipRect.bottom) return; Surface.Rectangle(x-tsize.cx-NIBLSCALE(8), y, x, vy); x -= (tsize.cx+NIBLSCALE(4)); break; case WTALIGN_CENTER: vy=y+(tsize.cy/2)+NIBLSCALE(1)+1; if (vy>=clipRect.bottom) return; Surface.Rectangle(x-(tsize.cx/2)-NIBLSCALE(4), y-(tsize.cy/2)-NIBLSCALE(1)-1, x+(tsize.cx/2)+NIBLSCALE(4), vy); x -= (tsize.cx/2); // just a trick to avoid calculating: // y -= ((tsize.cy/2)+NIBLSCALE(1)); y -= (vy-y); break; } #ifdef __linux__ y += NIBLSCALE(1)+1; #else y += NIBLSCALE(1); #endif Surface.DrawText(x, y, wText); //SetTextColor(hDC,RGB_BLACK); THIS WAS FORCED BLACk SO FAR 121005 Surface.SetTextColor(oldTextColor); }
static void OnPaintDetailsListItem(WindowControl * Sender, LKSurface& Surface){ (void)Sender; if (DrawListIndex < (int)aTextLine.size()){ LKASSERT(DrawListIndex>=0); const TCHAR* szText = aTextLine[DrawListIndex]; Surface.SetTextColor(RGB_BLACK); Surface.DrawText(2*ScreenScale, 2*ScreenScale, szText); } }
void OnPaintIgcFileListItem(WindowControl * Sender, LKSurface& Surface) { if (DrawListIndex < FileList.size()) { FileList_t::const_iterator ItFileName = FileList.begin(); std::advance(ItFileName, DrawListIndex); int w0 = Sender->GetWidth(); Surface.SetTextColor(RGB_BLACK); Surface.DrawTextClip(2 * ScreenScale, 2 * ScreenScale, ItFileName->c_str(), w0 - ScreenScale * 5); } }
static void OnAirspacePatternsPaintListItem(WindowControl * Sender, LKSurface& Surface) { (void) Sender; if ((DrawListIndex < NUMAIRSPACEBRUSHES) &&(DrawListIndex >= 0)) { int i = DrawListIndex; Surface.SelectObject(LKBrush_White); Surface.SelectObject(LK_BLACK_PEN); Surface.SetBkColor(LKColor(0xFF, 0xFF, 0xFF)); Surface.SelectObject(MapWindow::GetAirspaceBrush(i)); Surface.SetTextColor(LKColor(0x00, 0x00, 0x00)); Surface.Rectangle(100 * ScreenScale, 2 * ScreenScale, 180 * ScreenScale, 22 * ScreenScale); } }
static void OnAirspaceColoursPaintListItem(WindowControl * Sender, LKSurface& Surface){ (void)Sender; if ((DrawListIndex < NUMAIRSPACECOLORS) &&(DrawListIndex>=0)) { int i = DrawListIndex; Surface.SelectObject(LKBrush_White); Surface.SelectObject(LK_BLACK_PEN); Surface.SetBkColor(LKColor(0xFF, 0xFF, 0xFF)); Surface.SelectObject(MapWindow::GetAirspaceSldBrush(i)); // this is the solid brush Surface.SetTextColor(MapWindow::GetAirspaceColour(i)); Surface.Rectangle( 100*ScreenScale, 2*ScreenScale, 180*ScreenScale, 22*ScreenScale); } }
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); }
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; }
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) {
int RenderFAISector (LKSurface& Surface, const RECT& rc , double lat1, double lon1, double lat2, double lon2, int iOpposite , const LKColor& fillcolor) { POINT Pt1; float fFAI_Percentage = FAI_NORMAL_PERCENTAGE; double fDist_a, fDist_b, fDist_c, fAngle; int i; int iPolyPtr=0; double lat_d,lon_d; double alpha, fDistTri, cos_alpha=0; POINT apSectorPolygon[MAX_FAI_SECTOR_PTS+1]; DistanceBearing(lat1, lon1, lat2, lon2, &fDist_c, &fAngle); if(fabs(fDist_c) < 1000.0) /* distance too short for a FAI sector */ return -1; double fDistMax = fDist_c/FAI_NORMAL_PERCENTAGE; double fDistMin = fDist_c/(1.0-2.0*FAI28_45Threshold); double fDelta_Dist = 2.0* fDist_c*fFAI_Percentage / (double)(FAI_SECTOR_STEPS-1); double fA, fB; double fMinLeg, fMaxLeg,fDiff=0; double dir = -1.0; BOOL bBigFAISector = false; if(fDistMax > FAI28_45Threshold) { bBigFAISector = true; fDistMax = fDist_c/FAI_BIG_PERCENTAGE; } if(fDistMin < FAI28_45Threshold) { fDistMin = fDist_c/(1.0-2.0*FAI_NORMAL_PERCENTAGE); } if (iOpposite >0) { dir = 1.0; } //#define HELP_LINES #ifdef HELP_LINES int x2,y2, style; FindLatitudeLongitude(lat1, lon1, AngleLimit360 (fAngle), fDist_c/2, &lat_d, &lon_d); x1 = (lon_d - lon_c)*fastcosine(lat_d); y1 = (lat_d - lat_c); FindLatitudeLongitude(lat_d, lon_d, AngleLimit360 (fAngle-90.0), fDist_c, &lat_d, &lon_d); x2 = (lon_d - lon_c)*fastcosine(lat_d); y2 = (lat_d - lat_c); Surface.DrawLine(rc, x1, y1, x2, y2, style); #endif /******************************************************************** * right below threshold 1 ********************************************************************/ fA = fDistMin; if(fDistMax > FAI28_45Threshold) fB = FAI28_45Threshold; else fB = fDistMax ; if(fA<fB) { fDelta_Dist =(fB-fA)/ (double)(FAI_SECTOR_STEPS-1); fDistTri = fA; for(i =0 ;i < FAI_SECTOR_STEPS; i++) { fDist_a = FAI_NORMAL_PERCENTAGE * fDistTri; fDist_b = fDistTri - fDist_a - fDist_c; LKASSERT(fDist_c*fDist_b!=0); cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b); alpha = acos(cos_alpha)*180/PI * dir; FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d); MapWindow::LatLon2Screen(lon_d, lat_d, Pt1); LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS); apSectorPolygon[iPolyPtr++] = Pt1; fDistTri += fDelta_Dist; } } /******************************************************************** * right threshold extender 2 ********************************************************************/ if(fDistMin < FAI28_45Threshold) if(bBigFAISector && (fDistMin < FAI28_45Threshold)) { fMaxLeg = FAI28_45Threshold*FAI_BIG_MAX_PERCENTAGE; fMinLeg = FAI28_45Threshold*FAI_BIG_PERCENTAGE; fA = FAI28_45Threshold*FAI_NORMAL_PERCENTAGE; fB = FAI28_45Threshold-fMaxLeg-fDist_c; if(fB < fMinLeg) fB = fMinLeg; fDist_a = fA; fDelta_Dist = (fB-fA) / (double)(FAI_SECTOR_STEPS-1); for(i =0 ;i < FAI_SECTOR_STEPS; i++) { fDist_b = FAI28_45Threshold - fDist_a - fDist_c; LKASSERT(fDist_c*fDist_b!=0); cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b); alpha = acos(cos_alpha)*180/PI * dir; FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d); MapWindow::LatLon2Screen(lon_d, lat_d, Pt1); LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS); apSectorPolygon[iPolyPtr++] = Pt1; fDist_a += fDelta_Dist; } } /******************************************************************** * right above threshold 3 ********************************************************************/ if(bBigFAISector) { fA = FAI28_45Threshold; if(fDistMin > fA) fA= fDistMin; fB =fDist_c/(1- FAI_BIG_PERCENTAGE-FAI_BIG_MAX_PERCENTAGE); if(fA < fB) { fDelta_Dist =(fB-fA)/ (double)(FAI_SECTOR_STEPS-1); fDistTri = fA; for(i =0 ;i < FAI_SECTOR_STEPS; i++) { fMaxLeg = fDistTri*FAI_BIG_MAX_PERCENTAGE; fMinLeg = fDistTri*FAI_BIG_PERCENTAGE; fDist_a = fDistTri-fMinLeg-fDist_c;; fDist_b = fMinLeg; if(fDist_a > fMaxLeg) { fDiff = fDist_a - fMaxLeg; fDist_b+=fDiff; fDist_a-=fDiff; } LKASSERT(fDist_c*fDist_b!=0); cos_alpha = ( fDist_a*fDist_a + fDist_c*fDist_c - fDist_b*fDist_b )/(2.0*fDist_c*fDist_a); alpha = acos(cos_alpha)*180/PI * dir; FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_a, &lat_d, &lon_d); MapWindow::LatLon2Screen(lon_d, lat_d, Pt1); LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS); apSectorPolygon[iPolyPtr++] = Pt1; fDistTri += fDelta_Dist; } } } /******************************************************************** * TOP limited round 4 ********************************************************************/ if(fDistMax <= FAI28_45Threshold) fDist_b = fDistMax*(1.0-2*FAI_NORMAL_PERCENTAGE); else fDist_b = fDistMax*FAI_BIG_MAX_PERCENTAGE; fDist_a = fDistMax-fDist_b-fDist_c; fDelta_Dist = (fDist_a-fDist_b) / (double)(FAI_SECTOR_STEPS-1); for(i =0 ;i < FAI_SECTOR_STEPS; i++) { LKASSERT(fDist_c*fDist_b!=0); cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b); alpha = acos(cos_alpha)*180/PI * dir; FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d); MapWindow::LatLon2Screen(lon_d, lat_d, Pt1); LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS); apSectorPolygon[iPolyPtr++] = Pt1; fDist_a -= fDelta_Dist; fDist_b += fDelta_Dist; } /******************************************************************** * calc left leg ********************************************************************/ /******************************************************************** * LEFT above threshold 5 ********************************************************************/ if(bBigFAISector) { fB = FAI28_45Threshold; if( fB < fDistMin) fB = fDistMin; fA =fDist_c/(1- FAI_BIG_PERCENTAGE-FAI_BIG_MAX_PERCENTAGE); if(fA >= fB) { fDelta_Dist =(fA-fB)/ (double)(FAI_SECTOR_STEPS-1); fDistTri = fA; for(i =0 ;i < FAI_SECTOR_STEPS; i++) { fMaxLeg = fDistTri*FAI_BIG_MAX_PERCENTAGE; fMinLeg = fDistTri*FAI_BIG_PERCENTAGE; fDist_a = fDistTri-fMinLeg-fDist_c; fDist_b = fMinLeg; if(fDist_a > fMaxLeg) { fDiff = fDist_a - fMaxLeg; fDist_b+=fDiff; fDist_a-=fDiff; } LKASSERT(fDist_c*fDist_b!=0); cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b); alpha = acos(cos_alpha)*180/PI * dir; FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d); MapWindow::LatLon2Screen(lon_d, lat_d, Pt1); LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS); apSectorPolygon[iPolyPtr++] = Pt1; fDistTri -= fDelta_Dist; } } } /******************************************************************** * LEFT threshold extender 6 ********************************************************************/ if(fDistMin < FAI28_45Threshold) if((fDistMin < FAI28_45Threshold) && (FAI28_45Threshold < fDistMax)) { fMaxLeg = FAI28_45Threshold*FAI_BIG_MAX_PERCENTAGE; fMinLeg = FAI28_45Threshold*FAI_BIG_PERCENTAGE; fA = FAI28_45Threshold*FAI_NORMAL_PERCENTAGE; fB = FAI28_45Threshold-fMaxLeg-fDist_c; if(fB < fMinLeg) fB = fMinLeg; fDist_b = fB; fDelta_Dist = (fA-fB) / (double)(FAI_SECTOR_STEPS-1); for(i =0 ;i < FAI_SECTOR_STEPS; i++) { fDist_a = FAI28_45Threshold - fDist_b - fDist_c; LKASSERT(fDist_c*fDist_b!=0); cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b); alpha = acos(cos_alpha)*180/PI * dir; FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d); MapWindow::LatLon2Screen(lon_d, lat_d, Pt1); LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS); apSectorPolygon[iPolyPtr++] = Pt1; fDist_b += fDelta_Dist; } } /******************************************************************** * LEFT below threshold 7 ********************************************************************/ fA = fDistMin; if(fDistMax > FAI28_45Threshold) fB = FAI28_45Threshold; else fB = fDistMax ; if(fA<fB) { fDelta_Dist =(fB-fA)/ (double)(FAI_SECTOR_STEPS-1); fDistTri = fB; for(i =0 ;i < FAI_SECTOR_STEPS; i++) { fDist_b = FAI_NORMAL_PERCENTAGE * fDistTri; fDist_a = fDistTri - fDist_b - fDist_c; LKASSERT(fDist_c*fDist_b!=0); cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b); alpha = acos(cos_alpha)*180/PI * dir; FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d); MapWindow::LatLon2Screen(lon_d, lat_d, Pt1); LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS); apSectorPolygon[iPolyPtr++] = Pt1; fDistTri -= fDelta_Dist; } } /******************************************************************** * low open PEAK round 8 ********************************************************************/ if(fDistMin >FAI28_45Threshold) { fDist_b = fDistMin*FAI_BIG_PERCENTAGE; fDist_a = fDistMin-fDist_b-fDist_c; fDelta_Dist = (fDist_b-fDist_a) / (double)(FAI_SECTOR_STEPS-1); for(i =0 ;i < FAI_SECTOR_STEPS; i++) { LKASSERT(fDist_c*fDist_b!=0); cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b); alpha = acos(cos_alpha)*180/PI * dir; FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d); MapWindow::LatLon2Screen(lon_d, lat_d, Pt1); LKASSERT(iPolyPtr < MAX_FAI_SECTOR_PTS); apSectorPolygon[iPolyPtr++] = Pt1; fDist_a += fDelta_Dist; fDist_b -= fDelta_Dist; } } /******************************************************************** * draw polygon ********************************************************************/ LKPen hpSectorPen(PEN_SOLID, IBLSCALE(2), fillcolor ); LKPen hpOldPen = Surface.SelectObject(hpSectorPen); LKBrush hpOldBrush = Surface.SelectObject(LKBrush_Hollow); Surface.Polygon(apSectorPolygon,iPolyPtr,rc); Surface.SelectObject(hpOldPen); Surface.SelectObject(hpOldBrush); hpSectorPen.Release(); /******************************************************************** * calc round leg grid ********************************************************************/ hpSectorPen.Create(PEN_SOLID, (1), RGB_BLACK ); Surface.SelectObject(hpSectorPen); Surface.SetTextColor(RGB_BLACK); double fTic= 1/DISTANCEMODIFY; if(fDist_c > 5/DISTANCEMODIFY) fTic = 10/DISTANCEMODIFY; if(fDist_c > 50/DISTANCEMODIFY) fTic = 25/DISTANCEMODIFY; if(fDist_c > 100/DISTANCEMODIFY) fTic = 50/DISTANCEMODIFY; // if(fDist_c > 200/DISTANCEMODIFY) fTic = 100/DISTANCEMODIFY; if(fDist_c > 500/DISTANCEMODIFY) fTic = 250/DISTANCEMODIFY; POINT line[2]; BOOL bFirstUnit = true; LKASSERT(fTic!=0); fDistTri = ((int)(fDistMin/fTic)+1) * fTic ; LKFont hfOld = Surface.SelectObject(LK8PanelUnitFont); int iCnt = 0; while(fDistTri <= fDistMax) { TCHAR text[180]; SIZE tsize; if(bFirstUnit) _stprintf(text, TEXT("%i%s"), (int)(fDistTri*DISTANCEMODIFY), Units::GetUnitName(Units::GetUserDistanceUnit())); else _stprintf(text, TEXT("%i"), (int)(fDistTri*DISTANCEMODIFY)); bFirstUnit = false; Surface.GetTextSize(text, _tcslen(text), &tsize); int j=0; if(fDistTri < FAI28_45Threshold) { fDist_b = fDistTri*FAI_NORMAL_PERCENTAGE; fDist_a = fDistTri-fDist_b-fDist_c; fDelta_Dist = (fDist_a-fDist_b) / (double)(FAI_SECTOR_STEPS-1); } else { fMaxLeg = fDistTri*FAI_BIG_MAX_PERCENTAGE; fMinLeg = fDistTri*FAI_BIG_PERCENTAGE; fA = fMaxLeg; fB = fDistTri-fA-fDist_c; fDist_a = fA; fDist_b = fB; if(fB < fMinLeg) { fDiff = fMinLeg-fB; fB+=2*fDiff; fDist_b += fDiff; fDist_a -= fDiff; } if(fB > fMaxLeg) { fDiff = fB - fMaxLeg; fB+=2*fDiff; fDist_b-=fDiff; fDist_a+=fDiff; } fFAI_Percentage = FAI_BIG_PERCENTAGE; fDelta_Dist = (fA-fB) / (double)(FAI_SECTOR_STEPS-1); } for(i =0 ;i < FAI_SECTOR_STEPS; i++) { LKASSERT(fDist_c*fDist_b!=0); cos_alpha = ( fDist_b*fDist_b + fDist_c*fDist_c - fDist_a*fDist_a )/(2.0*fDist_c*fDist_b); alpha = acos(cos_alpha)*180/PI * dir; FindLatitudeLongitude(lat1, lon1, AngleLimit360( fAngle + alpha ) , fDist_b, &lat_d, &lon_d); MapWindow::LatLon2Screen(lon_d, lat_d, line[0]); if(j> 0) { ForcedClipping=true; Surface.DrawLine(PEN_DASH, NIBLSCALE(1), line[0] , line[1] , RGB_BLACK, rc); ForcedClipping=false; } if(j==0) { Surface.DrawText(line[0].x, line[0].y, text, _tcslen(text)); j=1; } // TCHAR text[180]; SIZE tsize; if(iCnt==0) _stprintf(text, TEXT("%i%s"), (int)(fDistTri*DISTANCEMODIFY), Units::GetUnitName(Units::GetUserDistanceUnit())); else _stprintf(text, TEXT("%i"), (int)(fDistTri*DISTANCEMODIFY)); Surface.GetTextSize(text, _tcslen(text), &tsize); if(i == 0) Surface.DrawText(line[0].x, line[0].y, text, _tcslen(text)); if(iCnt > 1) if(i == FAI_SECTOR_STEPS-1) Surface.DrawText(line[0].x, line[0].y, text, _tcslen(text)); if(iCnt > 2) if((i== (FAI_SECTOR_STEPS/2))) Surface.DrawText(line[0].x, line[0].y, text, _tcslen(text)); line[1] = line[0]; fDist_a -= fDelta_Dist; fDist_b += fDelta_Dist; } fDistTri+=fTic;iCnt++; // if((iCnt %2) ==0) // DrawText(hdc, line[0].x, line[0].y, ETO_OPAQUE, NULL, text, _tcslen(text), NULL); } Surface.SelectObject(hfOld); Surface.SelectObject(hpOldPen); return 0; }
void Statistics::RenderSpeed(LKSurface& Surface, const RECT& rc) { if ((flightstats.Task_Speed.sum_n<2) || !ValidTaskPoint(ActiveTaskPoint)) { DrawNoData(Surface, rc); return; } ResetScale(); ScaleXFromData(rc, &flightstats.Task_Speed); ScaleYFromData(rc, &flightstats.Task_Speed); ScaleYFromValue(rc, 0); ScaleXFromValue(rc, flightstats.Task_Speed.x_min+1.0); // in case no data ScaleXFromValue(rc, flightstats.Task_Speed.x_min); for(int j=1;j<MAXTASKPOINTS;j++) { if (ValidTaskPoint(j) && (flightstats.LegStartTime[j]>=0)) { double xx = (flightstats.LegStartTime[j]-CALCULATED_INFO.TaskStartTime)/3600.0; if (xx>=0) { DrawLine(Surface, rc, xx, y_min, xx, y_max, STYLE_REDTHICK); } } } DrawXGrid(Surface, rc, 0.5, flightstats.Task_Speed.x_min, STYLE_THINDASHPAPER, 0.5, true); /* DrawYGrid(hdc, rc, 10/TASKSPEEDMODIFY, 0, STYLE_THINDASHPAPER, 10, true);*/ if(Units::GetUserHorizontalSpeedUnit() == unStatuteMilesPerHour) { DrawYGrid(Surface, rc, 5.0/TASKSPEEDMODIFY, 0, STYLE_THINDASHPAPER, 5.0, true); } else { DrawYGrid(Surface, rc, 10/TASKSPEEDMODIFY, 0, STYLE_THINDASHPAPER, 10, true); } DrawLineGraph(Surface, rc, &flightstats.Task_Speed,STYLE_MEDIUMBLACK); DrawTrend(Surface, rc, &flightstats.Task_Speed, STYLE_BLUETHIN); if(INVERTCOLORS || IsDithered()) Surface.SetTextColor(RGB_DARKGREEN); else Surface.SetTextColor(RGB_GREEN); Surface.SetBackgroundOpaque(); TCHAR text[80]; DrawXLabel(Surface, rc, TEXT(" t/h ")); _stprintf(text,TEXT(" v/%s "),Units::GetHorizontalSpeedName()); DrawYLabel(Surface, rc, text); // DrawXLabel(hdc, rc, TEXT("t")); // DrawYLabel(hdc, rc, TEXT("V")); }
void MapWindow::DrawFAIOptimizer(LKSurface& Surface, const RECT& rc, const POINT &Orig_Aircraft) { LKColor whitecolor = RGB_WHITE; LKColor origcolor = Surface.SetTextColor(whitecolor); LKPen oldpen = Surface.SelectObject(hpStartFinishThick); LKBrush oldbrush = Surface.SelectObject(LKBrush_Hollow); /********************************************************************/ unsigned int ui; double lat1 = 0; double lon1 = 0; double lat2 = 0; double lon2 = 0; BOOL bFlat = false; BOOL bFAI = false; double fDist, fAngle; LockTaskData(); // protect from external task changes bFAI = CContestMgr::Instance().FAI(); CContestMgr::CResult result = CContestMgr::Instance().Result( CContestMgr::TYPE_FAI_TRIANGLE, true); const CPointGPSArray &points = result.PointArray(); unsigned int iSize = points.size(); CContestMgr::TType sType = result.Type(); double lat_CP = CContestMgr::Instance().GetClosingPoint().Latitude(); double lon_CP = CContestMgr::Instance().GetClosingPoint().Longitude(); double fFAIDistance = result.Distance(); UnlockTaskData(); // protect from external task changes if((sType == CContestMgr::TYPE_FAI_TRIANGLE) && iSize>0) { LKASSERT(iSize<100); for(ui=0; ui< iSize-1; ui++) { LockTaskData(); // protect from external task changes lat1 = points[ui].Latitude(); lon1 = points[ui].Longitude(); lat2 = points[ui+1].Latitude(); lon2 = points[ui+1].Longitude(); UnlockTaskData(); DistanceBearing(lat1, lon1, lat2, lon2, &fDist, &fAngle); #if BUGSTOP LKASSERT(fFAIDistance!=0); #endif if (fFAIDistance==0) fFAIDistance=0.1; if(((fDist > FAI_MIN_DISTANCE_THRESHOLD) && (ui < 3) && !bFlat && (fDist/ fFAIDistance > 0.05)) ) { LKColor rgbCol = RGB_BLUE; switch(ui) { case 0: rgbCol = RGB_YELLOW; break; case 1: rgbCol = RGB_CYAN ; break; case 2: rgbCol = RGB_GREEN ; break; default: break; } RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, 1, rgbCol ); RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, 0, rgbCol ); } if (fFAIDistance > 0) /* check if triangle is too flat for second sector */ if(fDist/ fFAIDistance > 0.45) bFlat = true; } /*********************************************************/ if(ISPARAGLIDER && bFAI) { LKPen hpSectorPen(PEN_SOLID, IBLSCALE(2), FAI_SECTOR_COLOR ); LKPen hOldPen = Surface.SelectObject(hpSectorPen); POINT Pt1; MapWindow::LatLon2Screen(lon_CP, lat_CP, Pt1); FindLatitudeLongitude(lat1, lon1, 0 , fFAIDistance* 0.20, &lat2, &lon2); /* 1000m destination circle */ int iRadius = (int)((lat2-lat1)*zoom.DrawScale()); Surface.Circle(Pt1.x, Pt1.y, iRadius , rc, true , false); FindLatitudeLongitude(lat1, lon1, 0 , 500, &lat2, &lon2); /* 1000m destination circle */ iRadius = (int)((lat2-lat1)*zoom.DrawScale()); Surface.Circle(Pt1.x, Pt1.y, iRadius , rc, true , false); Surface.SelectObject (hOldPen); } /*********************************************************/ } /********************************************************************/ // restore original color Surface.SetTextColor(origcolor); Surface.SelectObject(oldpen); Surface.SelectObject(oldbrush); }
void MapWindow::LKWriteText(LKSurface& Surface, const TCHAR* wText, int x, int y, const bool lwmode, const short align, const LKColor& rgb_text, bool invertable, RECT* ClipRect) { SIZE tsize; Surface.GetTextSize(wText, &tsize); LKColor textColor = rgb_text; // by default, LK8000 is white on black, i.e. inverted if ((!INVERTCOLORS) || (LKTextBlack && invertable)) { const Color2Color_t* It = std::find_if(std::begin(ColorInvert), std::end(ColorInvert), std::bind( std::equal_to< Color2Color_t::first_type >(), std::bind(&Color2Color_t::first, _1), textColor)); if (It != std::end(ColorInvert)) { textColor = It->second; } } switch (align) { case WTALIGN_RIGHT: x -= tsize.cx; break; case WTALIGN_CENTER: x -= tsize.cx / 2; y -= tsize.cy / 2; break; } //rgb_text=RGB_MAGENTA; bool moreoutline = false; Surface.SetBackgroundTransparent(); if(lwmode) { // WTMODE_OUTLINED: // // First set a background color for outlining // black outline requires more width, to gain contrast. // const Color2Outline_t* It = std::find_if(std::begin(ColorOutLine), std::end(ColorOutLine), std::bind( std::equal_to<Color2Outline_t::first_type>(), std::bind(&Color2Outline_t::first, _1), textColor)); if (It != std::end(ColorOutLine)) { // Here we invert colors, looking at the foreground. The trick is that the foreground // colour is slightly different white to white, in order to understand how to invert it // correctly! Surface.SetTextColor(It->second.first); moreoutline = It->second.second; } else { // this is the default also for white text. Normally we are writing on a // not-too-light background Surface.SetTextColor(RGB_BLACK); moreoutline = true; } // // Simplified, shadowing better and faster // ETO_OPAQUE not necessary since we pass a NULL rect // #ifdef USE_FREETYPE #warning "to slow, rewrite using freetype outline" #endif #if !defined(PNA) || !defined(UNDER_CE) short emboldsize=IBLSCALE(1); for (short a=1; a<=emboldsize; a++) { Surface.DrawText(x - a, y - a, wText, ClipRect); Surface.DrawText(x - a, y + a, wText, ClipRect); Surface.DrawText(x + a, y - a, wText, ClipRect); Surface.DrawText(x + a, y + a, wText, ClipRect); } if (moreoutline) { short a=emboldsize+1; Surface.DrawText(x - a, y, wText, ClipRect); Surface.DrawText(x + a, y, wText, ClipRect); Surface.DrawText(x, y - a, wText, ClipRect); Surface.DrawText(x, y + a, wText, ClipRect); } #else Surface.DrawText(x - 1, y - 1, wText, ClipRect); Surface.DrawText(x - 1, y + 1, wText, ClipRect); Surface.DrawText(x + 1, y - 1, wText, ClipRect); Surface.DrawText(x + 1, y + 1, wText, ClipRect); // SetTextColor(hDC,RGB_GREY); // This would give an Emboss effect // Surface.DrawText(x, y+2, 0, wText, maxsize); if (moreoutline) { Surface.DrawText(x - 2, y, wText, ClipRect); Surface.DrawText(x + 2, y, wText, ClipRect); Surface.DrawText(x, y - 2, wText, ClipRect); Surface.DrawText(x, y + 2, wText, ClipRect); } #endif Surface.SetTextColor(textColor); Surface.DrawText(x, y, wText, ClipRect); Surface.SetTextColor(RGB_BLACK); } else { // WTMODE_NORMAL: Surface.SetTextColor(textColor); Surface.DrawText(x, y, wText, ClipRect); Surface.SetTextColor(RGB_BLACK); } return; }
void MapWindow::RenderNearAirspace(LKSurface& Surface, const RECT rci) { RECT rc = rci; /* rectangle for sideview */ RECT rct = rc; /* rectangle for topview */ rc.top = (int)((double)(rci.bottom-rci.top )*fSplitFact); rct.bottom = rc.top ; // Expose the topview rect size in use.. Current_Multimap_TopRect=rct; LKFont hfOldFnt = Surface.SelectObject(LK8PanelUnitFont/* Sender->GetFont()*/); int *iSplit = &Multimap_SizeY[Get_Current_Multimap_Type()]; int k; static double fHeigtScaleFact = 1.0; double GPSlat, GPSlon, GPSalt, GPSbrg; double calc_terrainalt; double calc_altitudeagl; // double alt; TCHAR text[TBSIZE+1]; TCHAR buffer[TBSIZE+1]; CAirspaceBase near_airspace; CAirspace *found = NULL; // bool bFound = false; DiagrammStruct sDia; bool bAS_Inside=false; int iAS_Bearing=0; int iAS_HorDistance=15000; int iABS_AS_HorDistance=0; int iAS_VertDistance=0; bool bValid; static bool bHeightScale = false; long wpt_brg = 0; POINT line[2]; POINT TxYPt; POINT TxXPt; SIZE tsize; LKColor GREEN_COL = RGB_GREEN; LKColor BLUE_COL = RGB_BLUE; LKColor LIGHTBLUE_COL = RGB_LIGHTBLUE; BOOL bInvCol = true; //INVERTCOLORS unsigned short getsideviewpage=GetSideviewPage(); LKASSERT(getsideviewpage<3); if(bInvCol) Sideview_TextColor = INV_GROUND_TEXT_COLOUR; else Sideview_TextColor = RGB_WHITE; switch(LKevent) { case LKEVENT_NEWRUN: // CALLED ON ENTRY: when we select this page coming from another mapspace bHeightScale = false; // fZOOMScale[getsideviewpage] = 1.0; fHeigtScaleFact = 1.0; if (IsMultimapTopology()) ForceVisibilityScan=true; break; case LKEVENT_UP: // click on upper part of screen, excluding center if(bHeightScale) fHeigtScaleFact /= ZOOMFACTOR; else fZOOMScale[getsideviewpage] /= ZOOMFACTOR; if (IsMultimapTopology()) ForceVisibilityScan=true; break; case LKEVENT_DOWN: // click on lower part of screen, excluding center if(bHeightScale) fHeigtScaleFact *= ZOOMFACTOR; else fZOOMScale[getsideviewpage] *= ZOOMFACTOR; if (IsMultimapTopology()) ForceVisibilityScan=true; break; case LKEVENT_LONGCLICK: for (k=0 ; k <= Sideview_iNoHandeldSpaces; k++) { if( Sideview_pHandeled[k].psAS != NULL) { if (PtInRect(&(Sideview_pHandeled[k].rc), startScreen)) { #if 1 // MULTISELECT dlgAddMultiSelectListItem((long*) Sideview_pHandeled[k].psAS, 0, IM_AIRSPACE, 0); #else if (EnableSoundModes)PlayResource(TEXT("IDR_WAV_BTONE4")); dlgAirspaceDetails(Sideview_pHandeled[k].psAS); // dlgA #endif LKevent=LKEVENT_NONE; } } } dlgMultiSelectListShowModal(); if ( LKevent != LKEVENT_NONE ) { if (PtInRect(&rc, startScreen)) bHeightScale = !bHeightScale; if (PtInRect(&rct, startScreen)) bHeightScale = false; } break; case LKEVENT_PAGEUP: #ifdef OFFSET_SETP if(bHeightScale) fOffset -= OFFSET_SETP; else #endif { if(*iSplit == SIZE1) *iSplit = SIZE0; if(*iSplit == SIZE2) *iSplit = SIZE1; if(*iSplit == SIZE3) *iSplit = SIZE2; } break; case LKEVENT_PAGEDOWN: #ifdef OFFSET_SETP if(bHeightScale) fOffset += OFFSET_SETP; else #endif { if(*iSplit == SIZE2) *iSplit = SIZE3; if(*iSplit == SIZE1) *iSplit = SIZE2; if(*iSplit == SIZE0) *iSplit = SIZE1; } break; } LKASSERT(((*iSplit==SIZE0)||(*iSplit==SIZE1)||(*iSplit==SIZE2)||(*iSplit==SIZE3)||(*iSplit==SIZE4))); LKevent=LKEVENT_NONE; // Current_Multimap_SizeY is global, and must be used by all multimaps! // It is defined in Multimap.cpp and as an external in Multimap.h // It is important that it is updated, because we should resize terrain // only if needed! Resizing terrain takes some cpu and some time. // So we need to know when this is not necessary, having the same size of previous // multimap, if we are switching. // The current implementation is terribly wrong by managing resizing of sideview in // each multimap: it should be done by a common layer. // CAREFUL: // If for any reason DrawTerrain() is called after resizing to 0 (full sideview) // LK WILL CRASH with no hope to recover. if(Current_Multimap_SizeY != *iSplit) { Current_Multimap_SizeY=*iSplit; SetSplitScreenSize(*iSplit); rc.top = (long)((double)(rci.bottom-rci.top )*fSplitFact); rct.bottom = rc.top ; } if(bInvCol) { GREEN_COL = GREEN_COL.ChangeBrightness(0.6); BLUE_COL = BLUE_COL.ChangeBrightness(0.6);; LIGHTBLUE_COL = LIGHTBLUE_COL.ChangeBrightness(0.4);; } GPSlat = DrawInfo.Latitude; GPSlon = DrawInfo.Longitude; GPSalt = DrawInfo.Altitude; GPSbrg = DrawInfo.TrackBearing; calc_terrainalt = DerivedDrawInfo.TerrainAlt; calc_altitudeagl = DerivedDrawInfo.AltitudeAGL; GPSalt = DerivedDrawInfo.NavAltitude; bValid = false; iAS_HorDistance = 5000; iAS_Bearing = (int)GPSbrg; iAS_VertDistance= 0; found = CAirspaceManager::Instance().GetNearestAirspaceForSideview(); if(found != NULL) { near_airspace = CAirspaceManager::Instance().GetAirspaceCopy(found); bValid = near_airspace.GetDistanceInfo(bAS_Inside, iAS_HorDistance, iAS_Bearing, iAS_VertDistance); } iABS_AS_HorDistance = abs( iAS_HorDistance); wpt_brg = (long)AngleLimit360(GPSbrg - iAS_Bearing + 90.0); // Variables from ASP system here contain the following informations: // fAS_HorDistance - always contains horizontal distance from the asp, negative if horizontally inside (This does not mean that we're inside vertically as well!) // fAS_Bearing - always contains bearing to the nearest horizontal point // bValid - true if bAS_Inside, iAS_HorDistance, iAS_Bearing, iAS_VertDistance contains valid informations // this will be true if the asp border is close enough to be tracked by the warning system // bAS_Inside - current position is inside in the asp, calculated by the warning system // iAS_HorDistance - horizontal distance to the nearest horizontal border, negative if horizontally inside, calculated by the warning system // iAS_Bearing - bearing to the nearest horizontal border, calculated by the warning system // iAS_VertDistance - vertical distance to the nearest asp border, negative if the border is above us, positive if the border below us, calculated by the warning system // near_airspace.WarningLevel(): // awNone - no warning condition exists // awYellow - current position is near to a warning position // awRed - current posisiton is forbidden by asp system, we are in a warning position /********************************************************************* * calc the horizontal zoom *********************************************************************/ sDia.fXMin = -5000.0; sDia.fXMax = 5000.0; /* even when invalid the horizontal distance is calculated correctly */ if(bValid) { double fScaleDist = iABS_AS_HorDistance; sDia.fXMin = min(-2500.0 , fScaleDist * 1.5 ); sDia.fXMax = max( 2500.0 , fScaleDist * 1.5 ); #ifdef NEAR_AS_ZOOM_1000M if(((iABS_AS_HorDistance) < 900) && (bValid)) // 1km zoom { sDia.fXMin = min(-900.0, fScaleDist * 1.5 ); sDia.fXMax = max( 900.0, fScaleDist * 1.5 ); } #endif #ifdef NEAR_AS_ZOOM_1000FT if((abs(iABS_AS_HorDistance) < 333)) // 1000ft zoom { sDia.fXMin = min(-333.0, fScaleDist * 1.5 ); sDia.fXMax = max( 333.0, fScaleDist * 1.5 ); } #endif } #define RND_FACT 10.0 if( ( sDia.fXMax *fZOOMScale[getsideviewpage]) > 100000) fZOOMScale[getsideviewpage] /= ZOOMFACTOR; if(( sDia.fXMax *fZOOMScale[getsideviewpage]) < 500) { fZOOMScale[getsideviewpage] *= ZOOMFACTOR; } double fOldZoomScale=-1; if(fZOOMScale[getsideviewpage] != fOldZoomScale) { fOldZoomScale = fZOOMScale[getsideviewpage]; sDia.fXMax = sDia.fXMax *fZOOMScale[getsideviewpage]; sDia.fXMin = -sDia.fXMax /5; } /********************************************************************* * calc the vertical zoom *********************************************************************/ sDia.fYMin = max(0.0, GPSalt-2300); sDia.fYMax = max(MAXALTTODAY, GPSalt+1000); if(bValid) { double fBottom = near_airspace.Base()->Altitude; sDia.fYMin = min(fBottom*0.8, sDia.fYMin ); sDia.fYMin = max(0.0, sDia.fYMin ); if(sDia.fYMin < 300) sDia.fYMin =0; sDia.fYMax = max((fBottom*1.2f), sDia.fYMax ); if(abs(iAS_VertDistance) < 250) { sDia.fYMax = ((int)((GPSalt+abs(iAS_VertDistance))/400) + 2) *400 ; sDia.fYMin = ((int)((GPSalt-abs(iAS_VertDistance))/400) - 1) *400 ; if(sDia.fYMin-MIN_ALTITUDE < 0) sDia.fYMin = 0; } #ifdef VERTICAL_ZOOM_50 if(abs(iAS_VertDistance) < 50) { sDia.fYMax = ((int)((GPSalt+abs(iAS_VertDistance))/100) + 2) *100 ; sDia.fYMin = ((int)((GPSalt-abs(iAS_VertDistance))/100) - 1) *100 ; if(sDia.fYMin-MIN_ALTITUDE < 0) sDia.fYMin = 0; } #endif sDia.fYMin = max((double)0.0f,(double) sDia.fYMin); #ifdef OFFSET_SETP if(( sDia.fYMax + fOffset) > MAX_ALTITUDE) fOffset -= OFFSET_SETP; if(( sDia.fYMin + fOffset) < 0.0) fOffset += OFFSET_SETP; sDia.fYMin += fOffset; sDia.fYMax += fOffset; #endif // if(fHeigtScaleFact * sDia.fYMax > MAX_ALTITUDE ) // fHeigtScaleFact /=ZOOMFACTOR; if(fHeigtScaleFact * sDia.fYMax < MIN_ALTITUDE ) fHeigtScaleFact *=ZOOMFACTOR; sDia.fYMax *= fHeigtScaleFact; } /**************************************************************************************************** * draw topview first ****************************************************************************************************/ if(fSplitFact > 0.0) { sDia.rc = rct; sDia.rc.bottom-=1; SharedTopView(Surface, &sDia, (double) iAS_Bearing, (double) wpt_brg); } /**************************************************************************************************** * draw airspace and terrain elements ****************************************************************************************************/ RECT rcc = rc; /* rc corrected */ if(sDia.fYMin < GC_SEA_LEVEL_TOLERANCE) rcc.bottom -= SV_BORDER_Y; /* scale witout sea */ sDia.rc = rcc; RenderAirspaceTerrain(Surface, GPSlat, GPSlon, iAS_Bearing, &sDia ); LKFont hfOld = Surface.SelectObject(LK8InfoNormalFont); if(bValid) { LKASSERT(_tcslen(near_airspace.Name())<TBSIZE); // Diagnostic only in 3.1j, to be REMOVED LK_tcsncpy(Sideview_szNearAS, near_airspace.Name(), TBSIZE ); } else { _stprintf(text,TEXT("%s"), MsgToken(1259)); // LKTOKEN _@M1259_ "Too far, not calculated" Surface.GetTextSize(text, _tcslen(text), &tsize); TxYPt.x = (rc.right-rc.left-tsize.cx)/2; TxYPt.y = (rc.bottom-rc.top)/2; Surface.SetBkMode(TRANSPARENT); Surface.DrawText(TxYPt.x, TxYPt.y-20, text, _tcslen(text)); _stprintf(Sideview_szNearAS,TEXT("%s"), text); } Surface.SelectObject(hfOld); /**************************************************************************************************** * draw airspace and terrain elements ****************************************************************************************************/ /**************************************************************************************************** * draw diagram ****************************************************************************************************/ double xtick = 1.0; double fRange =fabs(sDia.fXMax - sDia.fXMin) ; if (fRange>3.0*1000.0) xtick = 2.0; if (fRange>15*1000.0) xtick = 5.0; if (fRange>50.0*1000.0) xtick = 10.0; if (fRange>100.0*1000.0) xtick = 20.0; if (fRange>200.0*1000.0) xtick = 25.0; if (fRange>250.0*1000.0) xtick = 50.0; if (fRange>500.0*1000.0) xtick = 100.0; if (fRange>1000.0*1000.0) xtick = 1000.0; if(bInvCol) { Surface.SelectObject(LK_BLACK_PEN); Surface.SelectObject(LKBrush_Black); } else { Surface.SelectObject(LK_WHITE_PEN); Surface.SelectObject(LKBrush_White); } LKColor txtCol = GROUND_TEXT_COLOUR; if(bInvCol) if(sDia.fYMin > GC_SEA_LEVEL_TOLERANCE) txtCol = INV_GROUND_TEXT_COLOUR; Surface.SetBkMode(TRANSPARENT); Surface.SetTextColor(txtCol); _stprintf(text, TEXT("%s"),Units::GetUnitName(Units::GetUserDistanceUnit())); switch(GetMMNorthUp(getsideviewpage)) { case NORTHUP: default: DrawXGrid(Surface, rc , xtick/DISTANCEMODIFY, xtick, 0,TEXT_ABOVE_LEFT, RGB_BLACK, &sDia,text); break; case TRACKUP: DrawXGrid(Surface, rci, xtick/DISTANCEMODIFY, xtick, 0,TEXT_ABOVE_LEFT, RGB_BLACK, &sDia,text); break; } Surface.SetTextColor(Sideview_TextColor); double fHeight = (sDia.fYMax-sDia.fYMin); double ytick = 100.0; if (fHeight >500.0) ytick = 200.0; if (fHeight >1000.0) ytick = 500.0; if (fHeight >2000.0) ytick = 1000.0; if (fHeight >4000.0) ytick = 2000.0; if (fHeight >8000.0) ytick = 4000.0; if(Units::GetUserAltitudeUnit() == unFeet) ytick = ytick * FEET_FACTOR; _stprintf(text, TEXT("%s"),Units::GetUnitName(Units::GetUserAltitudeUnit())); if(sDia.fYMin < GC_SEA_LEVEL_TOLERANCE) rc.bottom -= SV_BORDER_Y; /* scale witout sea */ DrawYGrid(Surface, rc, ytick/ALTITUDEMODIFY,ytick, 0,TEXT_UNDER_RIGHT ,Sideview_TextColor, &sDia, text); if(!bInvCol) Surface.SetBkMode(OPAQUE); /**************************************************************************************************** * draw AGL ****************************************************************************************************/ if(calc_altitudeagl - sDia.fYMin > 500) { Surface.SetTextColor(LIGHTBLUE_COL); Units::FormatUserAltitude(calc_altitudeagl, buffer, 7); LK_tcsncpy(text, MsgToken(1742), TBSIZE-_tcslen(buffer)); // AGL: _tcscat(text,buffer); Surface.GetTextSize(text, _tcslen(text), &tsize); TxYPt.x = CalcDistanceCoordinat(0, &sDia)- tsize.cx/2; TxYPt.y = CalcHeightCoordinat( (calc_terrainalt + calc_altitudeagl )*0.8, &sDia ); if((tsize.cy) < ( CalcHeightCoordinat( calc_terrainalt, &sDia )- TxYPt.y )) { Surface.DrawText(TxYPt.x+IBLSCALE(1), TxYPt.y , text, _tcslen(text)); } } Surface.SetBkMode(TRANSPARENT); /**************************************************************************************************** * Print current Elevation ****************************************************************************************************/ Surface.SetTextColor(RGB_BLACK); int x,y; if((calc_terrainalt- sDia.fYMin) > 0) { Units::FormatUserAltitude(calc_terrainalt, buffer, 7); LK_tcsncpy(text, MsgToken(1743), TBSIZE-_tcslen(buffer)); // ELV: _tcscat(text,buffer); Surface.GetTextSize(text, _tcslen(text), &tsize); x = CalcDistanceCoordinat(0, &sDia) - tsize.cx/2; y = CalcHeightCoordinat( calc_terrainalt, &sDia ); if ((ELV_FACT*tsize.cy) < abs(rc.bottom - y)) { Surface.DrawText(x, rc.bottom -(int)(ELV_FACT * tsize.cy), text, _tcslen(text)); } } /**************************************************************************************************** * draw side elements ****************************************************************************************************/ Surface.SetTextColor(Sideview_TextColor); Surface.SetBkMode(OPAQUE); LKFont hfOld2 = Surface.SelectObject(LK8InfoNormalFont); // DrawTelescope ( hdc, iAS_Bearing-90.0, rc.right - NIBLSCALE(13), rc.top + NIBLSCALE(58)); Surface.SelectObject(hfOld2); Surface.SetBkMode(TRANSPARENT); Surface.SelectObject(hfOld); Surface.SetTextColor(GROUND_TEXT_COLOUR); if(bInvCol) if(sDia.fYMin > GC_SEA_LEVEL_TOLERANCE) Surface.SetTextColor(INV_GROUND_TEXT_COLOUR); /****************************************************************************************************/ /****************************************************************************************************/ /**************************************************************************************************** * draw distances to next airspace ****************************************************************************************************/ /****************************************************************************************************/ /****************************************************************************************************/ if (bValid) { /**************************************************************************************************** * draw horizontal distance to next airspace ****************************************************************************************************/ Surface.SetTextColor(Sideview_TextColor); Surface.SetBkMode(OPAQUE); LKFont hfOldU = Surface.SelectObject(LK8InfoNormalFont); // horizontal distance line[0].x = CalcDistanceCoordinat(0, &sDia); line[0].y = CalcHeightCoordinat( GPSalt, &sDia ); line[1].x = CalcDistanceCoordinat(iABS_AS_HorDistance, &sDia); line[1].y = line[0].y; Surface.DrawDashLine(THICK_LINE, line[0], line[1], Sideview_TextColor, rc); if(iAS_HorDistance < 0) { line[0].y = CalcHeightCoordinat( GPSalt - (double)iAS_VertDistance, &sDia ); line[1].y = line[0].y; Surface.DrawDashLine(THICK_LINE, line[0], line[1], Sideview_TextColor, rc); } bool bLeft = false; if( line[0].x < line[1].x) bLeft = false; else bLeft = true; Units::FormatUserDistance(iABS_AS_HorDistance, buffer, 7); _stprintf(text,_T(" %s"),buffer); Surface.GetTextSize(text, _tcslen(text), &tsize); if((GPSalt- sDia.fYMin /*-calc_terrainalt */) < 300) TxXPt.y = CalcHeightCoordinat( GPSalt, &sDia ) - tsize.cy; else TxXPt.y = CalcHeightCoordinat( GPSalt, &sDia ) + NIBLSCALE(3); if(tsize.cx > (line[1].x - line[0].x) ) TxXPt.x = CalcDistanceCoordinat( iABS_AS_HorDistance ,&sDia) -tsize.cx- NIBLSCALE(3); else TxXPt.x = CalcDistanceCoordinat( iABS_AS_HorDistance / 2.0, &sDia) -tsize.cx/2; Surface.DrawText(TxXPt.x, TxXPt.y, text, _tcslen(text)); /**************************************************************************************************** * draw vertical distance to next airspace ****************************************************************************************************/ line[0].x = CalcDistanceCoordinat( iABS_AS_HorDistance , &sDia); line[0].y = CalcHeightCoordinat( GPSalt, &sDia ); line[1].x = line[0].x; line[1].y = CalcHeightCoordinat( GPSalt - (double)iAS_VertDistance, &sDia ); Surface.DrawDashLine(THICK_LINE, line[0], line[1], Sideview_TextColor, rc); Units::FormatUserAltitude( (double)abs(iAS_VertDistance), buffer, 7); _stprintf(text,_T(" %s"),buffer); Surface.GetTextSize(text, _tcslen(text), &tsize); if ( bLeft ) TxYPt.x = CalcDistanceCoordinat(iABS_AS_HorDistance, &sDia)- tsize.cx - NIBLSCALE(3); else TxYPt.x = CalcDistanceCoordinat(iABS_AS_HorDistance, &sDia)+ NIBLSCALE(5); if( abs( line[0].y - line[1].y) > tsize.cy) TxYPt.y = CalcHeightCoordinat( GPSalt - (double)iAS_VertDistance/2.0, &sDia) -tsize.cy/2 ; else TxYPt.y = min( line[0].y , line[1].y) - tsize.cy ; Surface.DrawText(TxYPt.x, TxYPt.y , text, _tcslen(text)); Surface.SelectObject(hfOldU); } /**************************************************************************************************** * draw plane sideview at least ****************************************************************************************************/ RenderPlaneSideview(Surface, 0.0 , GPSalt,wpt_brg, &sDia ); hfOldFnt = Surface.SelectObject(LK8InfoNormalFont/* Sender->GetFont()*/); DrawMultimap_SideTopSeparator(Surface,rct); /**************************************************************************************************** * draw selection frame ****************************************************************************************************/ if(bHeightScale) DrawSelectionFrame(Surface, rc); #ifdef TOP_SELECTION_FRAME else DrawSelectionFrame(hdc, rci); #endif Surface.SelectObject(hfOldFnt/* Sender->GetFont()*/); Surface.SetBkMode(TRANSPARENT); Surface.SelectObject(hfOldFnt/* Sender->GetFont()*/); }
void Statistics::RenderTemperature(LKSurface& Surface, const RECT& rc) { ResetScale(); int i; float hmin= 10000; float hmax= -10000; float tmin= (float)CuSonde::maxGroundTemperature; float tmax= (float)CuSonde::maxGroundTemperature; // find range for scaling of graph for (i=0; i<CUSONDE_NUMLEVELS-1; i++) { if (CuSonde::cslevels[i].nmeasurements) { hmin = min(hmin, (float)i); hmax = max(hmax, (float)i); tmin = min(tmin, (float)min(CuSonde::cslevels[i].tempDry, (double)min(CuSonde::cslevels[i].airTemp, (double)CuSonde::cslevels[i].dewpoint))); tmax = max(tmax, (float)max(CuSonde::cslevels[i].tempDry, (double)max(CuSonde::cslevels[i].airTemp, (double)CuSonde::cslevels[i].dewpoint))); } } if (hmin>= hmax) { DrawNoData(Surface, rc); return; } ScaleYFromValue(rc, hmin); ScaleYFromValue(rc, hmax); ScaleXFromValue(rc, tmin); ScaleXFromValue(rc, tmax); bool labelDry = false; bool labelAir = false; bool labelDew = false; int ipos = 0; for (i=0; i<CUSONDE_NUMLEVELS-1; i++) { if (CuSonde::cslevels[i].nmeasurements && CuSonde::cslevels[i+1].nmeasurements) { ipos++; DrawLine(Surface, rc, CuSonde::cslevels[i].tempDry, i, CuSonde::cslevels[i+1].tempDry, (i+1), STYLE_REDTHICK); DrawLine(Surface, rc, CuSonde::cslevels[i].airTemp, i, CuSonde::cslevels[i+1].airTemp, (i+1), STYLE_MEDIUMBLACK); DrawLine(Surface, rc, CuSonde::cslevels[i].dewpoint, i, CuSonde::cslevels[i+1].dewpoint, i+1, STYLE_BLUETHIN); if (ipos> 2) { if (!labelDry) { DrawLabel(Surface, rc, TEXT("DALR"), CuSonde::cslevels[i+1].tempDry, i); labelDry = true; } else { if (!labelAir) { DrawLabel(Surface, rc, TEXT("Air"), CuSonde::cslevels[i+1].airTemp, i); labelAir = true; } else { if (!labelDew) { DrawLabel(Surface, rc, TEXT("Dew"), CuSonde::cslevels[i+1].dewpoint, i); labelDew = true; } } } } } } if(INVERTCOLORS) Surface.SetTextColor(RGB_DARKGREEN); else Surface.SetTextColor(RGB_GREEN); #if (WINDOWSPC>0) Surface.SetBackgroundOpaque(); #endif TCHAR text[80]; _stprintf(text,TEXT(" T/%sC "), gettext(_T("_@M2179_"))); DrawXLabel(Surface, rc, text); _stprintf(text,TEXT(" h/%s "),Units::GetAltitudeName()); DrawYLabel(Surface, rc, text); // DrawXLabel(hdc, rc, TEXT("T")TEXT(DEG)); // DrawYLabel(hdc, rc, TEXT("h")); }
/***************************************************************** * Alpha Lima splitted RenderContest from Render Task for CC * adding FAI Sector display ****************************************************************/ void Statistics::RenderContest(LKSurface& Surface, const RECT& rc) { if(contestType == CContestMgr::TYPE_FAI_TRIANGLE) RenderFAIOptimizer(Surface, rc); else { unsigned int ui; double fXY_Scale = 1.0; double lat1 = 0; double lon1 = 0; double lat2 = 0; double lon2 = 0; double x1, y1, x2=0, y2=0; double lat_c, lon_c; ResetScale(); CContestMgr::CResult result = CContestMgr::Instance().Result(contestType, true); const CPointGPSArray &points = result.PointArray(); // find center CPointGPSArray trace; CContestMgr::Instance().Trace(trace); for(ui=0; ui<trace.size(); ui++) { lat1 = trace[ui].Latitude(); lon1 = trace[ui].Longitude(); ScaleYFromValue(rc, lat1); ScaleXFromValue(rc, lon1); } const auto hfOldU = Surface.SelectObject(LK8PanelUnitFont); lat_c = (y_max+y_min)/2; lon_c = (x_max+x_min)/2; // find scale ResetScale(); lat1 = GPS_INFO.Latitude; lon1 = GPS_INFO.Longitude; x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); ScaleXFromValue(rc, x1*fXY_Scale); ScaleYFromValue(rc, y1*fXY_Scale); for(ui=0; ui<trace.size(); ui++) { lat1 = trace[ui].Latitude(); lon1 = trace[ui].Longitude(); x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); ScaleXFromValue(rc, x1*fXY_Scale); ScaleYFromValue(rc, y1*fXY_Scale); } ScaleMakeSquare(rc); // draw track for(ui=0; trace.size() && ui<trace.size()-1; ui++) { lat1 = trace[ui].Latitude(); lon1 = trace[ui].Longitude(); lat2 = trace[ui+1].Latitude(); lon2 = trace[ui+1].Longitude(); x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); x2 = (lon2-lon_c)*fastcosine(lat2); y2 = (lat2-lat_c); DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_MEDIUMBLACK); } // Draw aircraft on top double lat_p = GPS_INFO.Latitude; double lon_p = GPS_INFO.Longitude; double xp = (lon_p-lon_c)*fastcosine(lat_p); double yp = (lat_p-lat_c); if(result.Type() == contestType) { for(ui=0; ui<points.size()-1; ui++) { lat1 = points[ui].Latitude(); lon1 = points[ui].Longitude(); lat2 = points[ui+1].Latitude(); lon2 = points[ui+1].Longitude(); x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); x2 = (lon2-lon_c)*fastcosine(lat2); y2 = (lat2-lat_c); int style = STYLE_REDTHICK; if((result.Type() == CContestMgr::TYPE_OLC_FAI || result.Type() == CContestMgr::TYPE_OLC_FAI_PREDICTED) && (ui==0 || ui==3)) { // triangle start and finish style = STYLE_DASHGREEN; } else if(result.Predicted() && (result.Type() == CContestMgr::TYPE_OLC_FAI_PREDICTED || ui == points.size() - 2)) { // predicted edge style = STYLE_BLUETHIN; } if((result.Type() == CContestMgr::TYPE_FAI_3_TPS) ||// TYPE_FAI_3_TPS_PREDICTED (result.Type() == CContestMgr::TYPE_FAI_3_TPS_PREDICTED) ) { } if((contestType != CContestMgr::TYPE_FAI_TRIANGLE) ) DrawLine(Surface, rc, x1, y1, x2, y2, style); } if(result.Type() == CContestMgr::TYPE_OLC_FAI || result.Type() == CContestMgr::TYPE_OLC_FAI_PREDICTED) { // draw the last edge of a triangle lat1 = points[1].Latitude(); lon1 = points[1].Longitude(); lat2 = points[3].Latitude(); lon2 = points[3].Longitude(); x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); x2 = (lon2-lon_c)*fastcosine(lat2); y2 = (lat2-lat_c); DrawLine(Surface, rc, x1, y1, x2, y2, result.Predicted() ? STYLE_BLUETHIN : STYLE_REDTHICK); } DrawXGrid(Surface, rc, 1.0, 0, STYLE_THINDASHPAPER, 1.0, false); DrawYGrid(Surface, rc, 1.0, 0, STYLE_THINDASHPAPER, 1.0, false); Surface.SelectObject(hfOldU); #ifndef UNDITHER Surface.SetTextColor(RGB_MAGENTA); #else Surface.SetTextColor(RGB_BLACK); #endif Surface.SetBackgroundTransparent(); DrawLabel(Surface, rc, TEXT("O"), xp, yp); } } }
static void OnTaskPaintListItem(WindowControl * Sender, LKSurface& Surface){ (void)Sender; int n = UpLimit - LowLimit; TCHAR sTmp[120]; TCHAR wpName[120]; TCHAR landableStr[5] = TEXT(" [X]"); // LKTOKEN _@M1238_ "L" landableStr[2] = gettext(TEXT("_@M1238_"))[0]; LockTaskData(); int w0 = Sender->GetWidth()-1; int w1 = Surface.GetTextWidth(TEXT(" 000km")); _stprintf(sTmp, _T(" 000%s"), gettext(_T("_@M2179_"))); int w2 = Surface.GetTextWidth(sTmp); int TextMargin = (Sender->GetHeight() - Surface.GetTextHeight(TEXT("A"))) / 2; int p1 = w0-w1-w2- Sender->GetHeight()-2; int p2 = w0-w2- Sender->GetHeight()-2; RECT rc = {0*ScreenScale, 0*ScreenScale, Sender->GetHeight(), Sender->GetHeight()}; if (DrawListIndex < n){ int i = LowLimit + DrawListIndex; // if ((WayPointList[Task[i].Index].Flags & LANDPOINT) >0) // MapWindow::DrawRunway(hDC, &WayPointList[Task[i].Index], rc, 3000,true); MapWindow::DrawTaskPicto(Surface, DrawListIndex, rc, 2500); if (Task[i].Index>=0) { _stprintf(wpName, TEXT("%s%s"), WayPointList[Task[i].Index].Name, (WayPointList[Task[i].Index].Flags & LANDPOINT) ? landableStr : TEXT("")); if (AATEnabled && ValidTaskPoint(i+1) && (i>0)) { if (Task[i].AATType==0) { _stprintf(sTmp, TEXT("%s %.1f"), wpName, Task[i].AATCircleRadius*DISTANCEMODIFY); } else { if(Task[i].AATType==2 && DoOptimizeRoute()) { _stprintf(sTmp, TEXT("%s %.1f/1"), wpName, Task[i].PGConeSlope); } else { _stprintf(sTmp, TEXT("%s %.1f"), wpName, Task[i].AATSectorRadius*DISTANCEMODIFY); } } } else { _stprintf(sTmp, TEXT("%s"), wpName); } Surface.SetBackgroundTransparent(); Surface.SetTextColor(RGB_BLACK); Surface.DrawTextClip(Sender->GetHeight()+2*ScreenScale, TextMargin, sTmp, p1-4*ScreenScale); _stprintf(sTmp, TEXT("%.0f %s"), Task[i].Leg*DISTANCEMODIFY, Units::GetDistanceName()); Surface.DrawText(Sender->GetHeight()+p1+w1-Surface.GetTextWidth(sTmp), TextMargin, sTmp, _tcslen(sTmp)); _stprintf(sTmp, TEXT("%d%s"), iround(Task[i].InBound),gettext(_T("_@M2179_"))); Surface.DrawText(Sender->GetHeight()+p2+w2-Surface.GetTextWidth(sTmp), TextMargin, sTmp, _tcslen(sTmp)); } } else { Surface.SetTextColor(RGB_BLACK); // if (DrawListIndex==n) { // patchout 091126 if (DrawListIndex==n && UpLimit < MAXTASKPOINTS) { // patch 091126 // LKTOKEN _@M832_ = "add waypoint" _stprintf(sTmp, TEXT(" (%s)"), gettext(TEXT("_@M832_"))); Surface.DrawText(Sender->GetHeight()+2*ScreenScale, TextMargin, sTmp, _tcslen(sTmp)); } else if ((DrawListIndex==n+1) && ValidTaskPoint(0)) { if (!AATEnabled || ISPARAGLIDER) { // LKTOKEN _@M735_ = "Total:" _tcscpy(sTmp, gettext(TEXT("_@M735_"))); Surface.DrawText(Sender->GetHeight()+2*ScreenScale, TextMargin, sTmp, _tcslen(sTmp)); if (fai_ok) { _stprintf(sTmp, TEXT("%.0f %s FAI"), lengthtotal*DISTANCEMODIFY, Units::GetDistanceName()); } else { _stprintf(sTmp, TEXT("%.0f %s"), lengthtotal*DISTANCEMODIFY, Units::GetDistanceName()); } Surface.DrawText(Sender->GetHeight()+p1+w1-Surface.GetTextWidth(sTmp), TextMargin, sTmp, _tcslen(sTmp)); } else { double d1 = CALCULATED_INFO.TaskDistanceToGo; if ((CALCULATED_INFO.TaskStartTime>0.0) && (CALCULATED_INFO.Flying) && (ActiveWayPoint>0)) { d1 += CALCULATED_INFO.TaskDistanceCovered; } if (d1==0.0) { d1 = CALCULATED_INFO.AATTargetDistance; } _stprintf(sTmp, TEXT("%s %.0f min %.0f (%.0f) %s"), // LKTOKEN _@M735_ = "Total:" gettext(TEXT("_@M735_")), AATTaskLength*1.0, DISTANCEMODIFY*lengthtotal, DISTANCEMODIFY*d1, Units::GetDistanceName()); Surface.DrawText(Sender->GetHeight()+2*ScreenScale, TextMargin, sTmp, _tcslen(sTmp)); } } } UnlockTaskData(); }
static void OnTaskPaintListItem(WindowControl * Sender, LKSurface& Surface){ int n = UpLimit - LowLimit; TCHAR sTmp[120]; TCHAR wpName[120]; TCHAR landableStr[5] = TEXT(" [X]"); // LKTOKEN _@M1238_ "L" landableStr[2] = MsgToken(1238)[0]; LockTaskData(); const PixelRect rcClient(Sender->GetClientRect()); const int w0 = rcClient.GetSize().cx - DLGSCALE(1); const int w1 = Surface.GetTextWidth(TEXT(" 000km")); _stprintf(sTmp, _T(" 000%s"), MsgToken(2179)); const int w2 = Surface.GetTextWidth(sTmp); const int TextMargin = (rcClient.GetSize().cy - Surface.GetTextHeight(TEXT("A"))) / 2; const int p1 = w0-w1-w2- rcClient.GetSize().cy - DLGSCALE(2); const int p2 = w0-w2- rcClient.GetSize().cy - DLGSCALE(2); const PixelRect rc = { 0, 0, rcClient.GetSize().cy, rcClient.GetSize().cy }; if (DrawListIndex < n){ int i = LowLimit + DrawListIndex; // if ((WayPointList[Task[i].Index].Flags & LANDPOINT) >0) // MapWindow::DrawRunway(hDC, &WayPointList[Task[i].Index], rc, 3000,true); MapWindow::DrawTaskPicto(Surface, DrawListIndex, rc, 2500); if (Task[i].Index>=0) { _stprintf(wpName, TEXT("%s%s"), WayPointList[Task[i].Index].Name, (WayPointList[Task[i].Index].Flags & LANDPOINT) ? landableStr : TEXT("")); if (AATEnabled && ValidTaskPoint(i+1) && (i>0)) { if (Task[i].AATType==0 || Task[i].AATType==3) { _stprintf(sTmp, TEXT("%s %.1f"), wpName, Task[i].AATCircleRadius*DISTANCEMODIFY); } else { if(Task[i].AATType==2 && DoOptimizeRoute()) { _stprintf(sTmp, TEXT("%s %.1f/1"), wpName, Task[i].PGConeSlope); } else { _stprintf(sTmp, TEXT("%s %.1f"), wpName, Task[i].AATSectorRadius*DISTANCEMODIFY); } } } else { _stprintf(sTmp, TEXT("%s"), wpName); } Surface.SetBackgroundTransparent(); Surface.SetTextColor(RGB_BLACK); Surface.DrawTextClip(rc.right + DLGSCALE(2), TextMargin, sTmp, p1-DLGSCALE(4)); _stprintf(sTmp, TEXT("%.0f %s"),Task[i].Leg*DISTANCEMODIFY,Units::GetDistanceName()); Surface.DrawText(rc.right+p1+w1-Surface.GetTextWidth(sTmp), TextMargin, sTmp); _stprintf(sTmp, TEXT("%d%s"), iround(Task[i].InBound),MsgToken(2179)); Surface.DrawText(rc.right +p2+w2-Surface.GetTextWidth(sTmp), TextMargin, sTmp); } } else { Surface.SetTextColor(RGB_BLACK); // if (DrawListIndex==n) { // patchout 091126 if (DrawListIndex==n && UpLimit < MAXTASKPOINTS) { // patch 091126 // LKTOKEN _@M832_ = "add waypoint" _stprintf(sTmp, TEXT(" (%s)"), MsgToken(832)); Surface.DrawText(rc.right +DLGSCALE(2), TextMargin, sTmp); } else if ((DrawListIndex==n+1) && ValidTaskPoint(0)) { if (!AATEnabled || ISPARAGLIDER) { // LKTOKEN _@M735_ = "Total:" Surface.DrawText(rc.right +DLGSCALE(2), TextMargin, MsgToken(735)); _stprintf(sTmp, TEXT("%.0f %s%s"), lengthtotal*DISTANCEMODIFY, Units::GetDistanceName(), fai_ok?_T(" FAI"):_T("")); Surface.DrawText(rc.right +p1+w1-Surface.GetTextWidth(sTmp), TextMargin, sTmp); } else { double d1 = CALCULATED_INFO.TaskDistanceToGo; if ((CALCULATED_INFO.TaskStartTime>0.0) && (CALCULATED_INFO.Flying) && (ActiveTaskPoint>0)) { d1 += CALCULATED_INFO.TaskDistanceCovered; } if (d1==0.0) { d1 = CALCULATED_INFO.AATTargetDistance; } _stprintf(sTmp, TEXT("%s %.0f min %.0f (%.0f) %s"), // LKTOKEN _@M735_ = "Total:" MsgToken(735), AATTaskLength*1.0, DISTANCEMODIFY*lengthtotal, DISTANCEMODIFY*d1, Units::GetDistanceName()); Surface.DrawText(rc.right +DLGSCALE(2), TextMargin, sTmp); } } } UnlockTaskData(); }
/***************************************************************** * Alpha Lima splitted RenderContest from Render Task for CC * adding FAI Sector display ****************************************************************/ void Statistics::RenderFAIOptimizer(LKSurface& Surface, const RECT& rc) { unsigned int ui; double fXY_Scale = 1.0; double lat0 = 0; double lon0 = 0; double lat1 = 0; double lon1 = 0; double lat2 = 0; double lon2 = 0; double x0, y0, x1, y1, x2=0, y2=0; double lat_c, lon_c; double lat_p = GPS_INFO.Latitude; double lon_p = GPS_INFO.Longitude; BOOL bFlat = false; #define DRAWPERCENT #ifdef DRAWPERCENT double fTotalPercent = 1.0; #endif ResetScale(); CContestMgr::CResult result = CContestMgr::Instance().Result(contestType, true); const CPointGPSArray &points = result.PointArray(); if(contestType == CContestMgr::TYPE_FAI_TRIANGLE) fXY_Scale = 1.5; // find center double fTotalDistance = result.Distance(); if (fTotalDistance < 1) fTotalDistance =1; CPointGPSArray trace; CContestMgr::Instance().Trace(trace); for(ui=0; ui<trace.size(); ui++) { lat1 = trace[ui].Latitude(); lon1 = trace[ui].Longitude(); ScaleYFromValue(rc, lat1); ScaleXFromValue(rc, lon1); } const auto hfOldU = Surface.SelectObject(LK8PanelUnitFont); BOOL bFAITri = CContestMgr::Instance().FAI(); double fDist, fAngle; lat_c = (y_max+y_min)/2; lon_c = (x_max+x_min)/2; double xp = (lon_p-lon_c)*fastcosine(lat_p); double yp = (lat_p-lat_c); // find scale ResetScale(); lat1 = GPS_INFO.Latitude; lon1 = GPS_INFO.Longitude; x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); ScaleXFromValue(rc, x1*fXY_Scale); ScaleYFromValue(rc, y1*fXY_Scale); for(ui=0; ui<trace.size(); ui++) { lat1 = trace[ui].Latitude(); lon1 = trace[ui].Longitude(); x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); ScaleXFromValue(rc, x1*fXY_Scale); ScaleYFromValue(rc, y1*fXY_Scale); } ScaleMakeSquare(rc); if(result.Type() == contestType) { for(ui=0; ui<points.size()-1; ui++) { lat1 = points[ui].Latitude(); lon1 = points[ui].Longitude(); lat2 = points[ui+1].Latitude(); lon2 = points[ui+1].Longitude(); x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); x2 = (lon2-lon_c)*fastcosine(lat2); y2 = (lat2-lat_c); DistanceBearing(lat1, lon1, lat2, lon2, &fDist, &fAngle); if( (ui <points.size()-2) && !bFlat && ((fDist / fTotalDistance ) > 0.05) ) { if(fDist > 5000) { #ifndef UNDITHER LKColor rgbCol = RGB_BLUE; switch(ui) { case 0: rgbCol = RGB_LIGHTYELLOW; break; case 1: rgbCol = RGB_LIGHTCYAN ; break; case 2: rgbCol = RGB_LIGHTGREEN ; break; default: break; } #else LKColor rgbCol = RGB_DARKBLUE; switch(ui) { case 0: rgbCol = RGB_LIGHTGREY; break; case 1: rgbCol = RGB_GREY ; break; case 2: rgbCol = RGB_MIDDLEGREY ; break; default: break; } #endif RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,1, rgbCol ); RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,0, rgbCol ); } } if((fDist / fTotalDistance ) > 0.45) /* prevent drawing almost same sectors */ bFlat = true; } // draw track for(ui=0; trace.size() && ui<trace.size()-1; ui++) { lat1 = trace[ui].Latitude(); lon1 = trace[ui].Longitude(); lat2 = trace[ui+1].Latitude(); lon2 = trace[ui+1].Longitude(); x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); x2 = (lon2-lon_c)*fastcosine(lat2); y2 = (lat2-lat_c); DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_MEDIUMBLACK); } for(ui=0; ui<points.size()-1; ui++) { lat1 = points[ui].Latitude(); lon1 = points[ui].Longitude(); lat2 = points[ui+1].Latitude(); lon2 = points[ui+1].Longitude(); x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); x2 = (lon2-lon_c)*fastcosine(lat2); y2 = (lat2-lat_c); int style = STYLE_REDTHICK; if((ui > 0) && (ui < 3)) { style = STYLE_BLUETHIN; DistanceBearing(lat1, lon1, lat2, lon2, &fDist, &fAngle); #ifdef DRAWPERCENT if((result.Distance()> 5000) && bFAITri) { TCHAR text[180]; SIZE tsize; fTotalPercent -= fDist/result.Distance(); _stprintf(text, TEXT("%3.1f%%"), (fDist/result.Distance()*100.0)); Surface.GetTextSize(text, _tcslen(text), &tsize); #ifndef UNDITHER Surface.SetTextColor(RGB_BLUE); #else Surface.SetTextColor(RGB_BLACK); #endif Surface.DrawText(ScaleX(rc, x1 +( x2-x1)/2)-tsize.cx/2, ScaleY(rc,y1 + (y2-y1)/2), text, _tcslen(text)); } #endif DrawLine(Surface, rc, x1, y1, x2, y2, style); } } if(bFAITri) { if(points.size() >3) { if(ISPARAGLIDER) { lat0 = CContestMgr::Instance().GetBestNearClosingPoint().Latitude(); lon0 = CContestMgr::Instance().GetBestNearClosingPoint().Longitude(); lat1 = CContestMgr::Instance().GetBestClosingPoint().Latitude(); lon1 = CContestMgr::Instance().GetBestClosingPoint().Longitude(); x1 = (lon0-lon_c)*fastcosine(lat0); y1 = (lat0-lat_c); x2 = (lon1-lon_c)*fastcosine(lat1); y2 = (lat1-lat_c); DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_ORANGETHIN ); //result.Predicted() ? STYLE_BLUETHIN : STYLE_REDTHICK); } lat1 = points[1].Latitude(); lon1 = points[1].Longitude(); lat2 = points[3].Latitude(); lon2 = points[3].Longitude(); x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); x2 = (lon2-lon_c)*fastcosine(lat2); y2 = (lat2-lat_c); DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_THINDASHPAPER ); //result.Predicted() ? STYLE_BLUETHIN : STYLE_REDTHICK); #ifdef DRAWPERCENT TCHAR text[180]; SIZE tsize; _stprintf(text, TEXT("%3.1f%%"), (fTotalPercent*100.0)); Surface.GetTextSize(text, _tcslen(text), &tsize); #ifndef UNDITHER Surface.SetTextColor(RGB_LIGHTBLUE); #else Surface.SetTextColor(RGB_RED); #endif Surface.DrawText(ScaleX(rc, x1 +( x2-x1)/2)-tsize.cx/2, ScaleY(rc,y1 + (y2-y1)/2), text, _tcslen(text)); #endif lat0 = CContestMgr::Instance().GetClosingPoint().Latitude(); lon0 = CContestMgr::Instance().GetClosingPoint().Longitude(); x0 = (lon0-lon_c)*fastcosine(lat0); y0 = (lat0-lat_c); DrawLine(Surface, rc, xp, yp, x0, y0, STYLE_REDTHICK); } } } DrawXGrid(Surface, rc, 1.0, 0, STYLE_THINDASHPAPER, 1.0, false); DrawYGrid(Surface, rc, 1.0, 0, STYLE_THINDASHPAPER, 1.0, false); Surface.SetBackgroundTransparent(); #ifndef UNDITHER Surface.SetTextColor(RGB_MAGENTA); #else Surface.SetTextColor(RGB_BLACK); #endif DrawLabel(Surface, rc, TEXT("O"), xp, yp); Surface.SelectObject(hfOldU); }
static void OnMultiSelectListPaintListItem(WindowControl * Sender, LKSurface& Surface) { #define PICTO_WIDTH 50 Surface.SetTextColor(RGB_BLACK); if ((DrawListIndex < iNO_ELEMENTS) &&(DrawListIndex >= 0)) { int j; static CAirspaceBase airspace_copy; int i = DrawListIndex; LKASSERT(i < MAX_LIST_ITEMS); PixelRect rc = { 0, 0, DLGSCALE(PICTO_WIDTH), static_cast<PixelScalar>(Sender->GetHeight()) }; const CAirspace* pAS = NULL; int HorDist, Bearing, VertDist; double Distance; unsigned int idx = 0; TCHAR text1[180] = {TEXT("empty")}; TCHAR text2[180] = {TEXT("empty")}; TCHAR Comment[80] = {TEXT("")}; TCHAR Comment1[80] = {TEXT("")}; Surface.SetBkColor(LKColor(0xFF, 0xFF, 0xFF)); LKASSERT(i < MAX_LIST_ITEMS); switch (Elements[i].type) { case IM_AIRSPACE: pAS = (CAirspace*) Elements[i].ptr; if (pAS) { /*********************************************************************** * here we use a local copy of the airspace, only common property exists ***********************************************************************/ airspace_copy = CAirspaceManager::Instance().GetAirspaceCopy(pAS); // airspace type already in name? if (_tcsnicmp(airspace_copy.Name(), airspace_copy.TypeName(), _tcslen(airspace_copy.TypeName())) == 0) { _stprintf(text1, TEXT("%s"), airspace_copy.Name()); // yes, take name only } else { // fixed strings max. 20 NAME_SIZE 30 => max. 30 char _stprintf(text1, TEXT("%s %s"), airspace_copy.TypeName(), airspace_copy.Name()); } CAirspaceManager::Instance().GetSimpleAirspaceAltText(Comment, sizeof (Comment) / sizeof (Comment[0]), airspace_copy.Top()); CAirspaceManager::Instance().GetSimpleAirspaceAltText(Comment1, sizeof (Comment1) / sizeof (Comment1[0]), airspace_copy.Base()); CAirspaceManager::Instance().AirspaceCalculateDistance((CAirspace*) pAS, &HorDist, &Bearing, &VertDist); _stprintf(text2, TEXT("%3.1f%s (%s - %s)"), (double) HorDist*DISTANCEMODIFY, Units::GetDistanceName(), Comment1, Comment); //8 + 8+3 21 /**************************************************************** * for drawing the airspace pictorial, we need the original data. * copy contain only base class property, not geo data, * original data are shared ressources ! * for that we need to grant all called methods are thread safe ****************************************************************/ pAS->DrawPicto(Surface, rc); } break; case IM_TASK_PT: case IM_WAYPOINT: idx = -1; LockTaskData(); // protect from external task changes if (Elements[i].type == IM_TASK_PT) { if(ValidTaskPointFast(Elements[i].iIdx)) { idx = Task[Elements[i].iIdx].Index; } } else { if(ValidWayPointFast(Elements[i].iIdx)) { idx = Elements[i].iIdx; } } // This is not a solution. It will avoid a crash but the solution is to understand // why we are getting a wrong idx, eventually. If ever we got a wrong idx! // And then this "fix" should be changed to something more useful, instead of // adopting a totally wrong waypoint for task. assert(idx < WayPointList.size()); if(idx < WayPointList.size()) { if (WayPointList[idx].Comment != NULL) { LK_tcsncpy(Comment, WayPointList[idx].Comment, 30); } else { _tcscpy(Comment, TEXT("")); } DistanceBearing(GPS_INFO.Latitude, GPS_INFO.Longitude, WayPointList[idx].Latitude, WayPointList[idx].Longitude, &Distance, NULL); if (Elements[i].type != IM_TASK_PT) { if (WayPointCalc[idx].IsLandable) { MapWindow::DrawRunway(Surface, &WayPointList[idx], rc, nullptr, 1.5, true); if (WayPointCalc[idx].IsAirport) { // remove spaces from frequency for (j = 1; j < (CUPSIZE_FREQ); j++) if (WayPointList[idx].Freq[CUPSIZE_FREQ - j] == ' ') WayPointList[idx].Freq[CUPSIZE_FREQ - j] = '\0'; if (_tcslen(WayPointList[idx].Freq) > 2) _stprintf(text1, TEXT("%s %s MHz"), WayPointList[idx].Name, WayPointList[idx].Freq); else _stprintf(text1, TEXT("%s"), WayPointList[idx].Name); } else { if (WayPointList[idx].Comment != NULL) _stprintf(text1, TEXT("%s %s"), WayPointList[idx].Name, Comment); else _stprintf(text1, TEXT("%s"), WayPointList[idx].Name); } if ((WayPointList[idx].RunwayLen >= 10) || (WayPointList[idx].RunwayDir > 0)) { _stprintf(text2, TEXT("%3.1f%s (%i%s %02i/%02i %i%s)"), Distance * DISTANCEMODIFY, Units::GetDistanceName(), (int) (WayPointList[idx].Altitude * ALTITUDEMODIFY), Units::GetAltitudeName(), (int) (WayPointList[idx].RunwayDir / 10.0 + 0.5), (int) (AngleLimit360(WayPointList[idx].RunwayDir + 180.0) / 10.0 + 0.5), (int) ((double) WayPointList[idx].RunwayLen * ALTITUDEMODIFY), Units::GetAltitudeName()); } else { _stprintf(text2, TEXT("%3.1f%s (%i%s) "), Distance * DISTANCEMODIFY, Units::GetDistanceName(), (int) (WayPointList[idx].Altitude * ALTITUDEMODIFY), Units::GetAltitudeName()); } }// waypoint isLandable else { MapWindow::DrawWaypointPicto(Surface, rc, &WayPointList[idx]); _stprintf(text1, TEXT("%s %s"), WayPointList[idx].Name, Comment); _stprintf(text2, TEXT("%3.1f%s (%i%s)"), Distance * DISTANCEMODIFY, Units::GetDistanceName(), (int) (WayPointList[idx].Altitude * ALTITUDEMODIFY), Units::GetAltitudeName()); } }// Elements IM_TASK else { int iTaskIdx = Elements[i].iIdx; MapWindow::DrawTaskPicto(Surface, iTaskIdx, rc, 3000); int iLastTaskPoint = 0; while (ValidTaskPoint(iLastTaskPoint)) iLastTaskPoint++; iLastTaskPoint--; if (iTaskIdx == 0) { // _@M2301_ "S" # S = Start Task point _stprintf(text1, TEXT("%s: (%s)"), MsgToken(2301), WayPointList[idx].Name); _stprintf(text2, TEXT("Radius %3.1f%s (%i%s)"), StartRadius * DISTANCEMODIFY, Units::GetDistanceName(), (int) (WayPointList[idx].Altitude * ALTITUDEMODIFY), Units::GetAltitudeName()); } else { if (iTaskIdx == iLastTaskPoint) { // _@M2303_ "F" // max 30 30 => max 60 char _stprintf(text1, TEXT("%s: (%s) "), MsgToken(2303), WayPointList[idx].Name); _stprintf(text2, TEXT("Radius %3.1f%s (%i%s)"), FinishRadius * DISTANCEMODIFY, Units::GetDistanceName(), (int) (WayPointList[idx].Altitude * ALTITUDEMODIFY), Units::GetAltitudeName()); } else { // _@M2302_ "T" # F = Finish point // max 30 30 => max 60 char _stprintf(text1, TEXT("%s%i: (%s) "), MsgToken(2302), iTaskIdx, WayPointList[idx].Name); double SecRadius = 0; SecRadius = SectorRadius; if (AATEnabled) { if (Task[iTaskIdx].AATType == SECTOR) SecRadius = Task[iTaskIdx].AATSectorRadius; else SecRadius = Task[iTaskIdx].AATCircleRadius; } _stprintf(text2, TEXT("Radius %3.1f%s (%i%s)"), SecRadius * DISTANCEMODIFY, Units::GetDistanceName(), (int) (WayPointList[idx].Altitude * ALTITUDEMODIFY), Units::GetAltitudeName()); } } } } UnlockTaskData(); // protect from external task changes break; } /******************** * show text ********************/ Surface.SetBackgroundTransparent(); Surface.SetTextColor(RGB_BLACK); Surface.DrawText(rc.right + DLGSCALE(2), DLGSCALE(2), text1); int ytext2 = Surface.GetTextHeight(text1); Surface.SetTextColor(RGB_DARKBLUE); Surface.DrawText(rc.right + DLGSCALE(2), ytext2, text2); } }
void Statistics::RenderTask(LKSurface& Surface, const RECT& rc, const bool olcmode) { int i, j; unsigned int ui; double fXY_Scale = 1.5; double lat1 = 0; double lon1 = 0; double lat2 = 0; double lon2 = 0; double x1, y1, x2=0, y2=0; double lat_c, lon_c; double aatradius[MAXTASKPOINTS]; // find center ResetScale(); if ( (!ValidTaskPoint(0) || !ValidTaskPoint(1)) && !olcmode) { DrawNoData(Surface,rc); return; } for (i=0; i<MAXTASKPOINTS; i++) { aatradius[i]=0; } bool nowaypoints = true; for (i=0; i<MAXTASKPOINTS; i++) { if (ValidTaskPoint(i)) { lat1 = WayPointList[Task[i].Index].Latitude; lon1 = WayPointList[Task[i].Index].Longitude; ScaleYFromValue(rc, lat1); ScaleXFromValue(rc, lon1); nowaypoints = false; } } if (nowaypoints ) { DrawNoData(Surface, rc); return; } CPointGPSArray trace; CContestMgr::Instance().Trace(trace); for(ui=0; ui<trace.size(); ui++) { lat1 = trace[ui].Latitude(); lon1 = trace[ui].Longitude(); ScaleYFromValue(rc, lat1); ScaleXFromValue(rc, lon1); } const auto hfOldU = Surface.SelectObject(LK8InfoNormalFont); lat_c = (y_max+y_min)/2; lon_c = (x_max+x_min)/2; int nwps = 0; // find scale ResetScale(); lat1 = GPS_INFO.Latitude; lon1 = GPS_INFO.Longitude; x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); ScaleXFromValue(rc, x1*fXY_Scale); ScaleYFromValue(rc, y1*fXY_Scale); for (i=0; i<MAXTASKPOINTS; i++) { if (ValidTaskPoint(i)) { nwps++; lat1 = WayPointList[Task[i].Index].Latitude; lon1 = WayPointList[Task[i].Index].Longitude; x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); ScaleXFromValue(rc, x1*fXY_Scale); ScaleYFromValue(rc, y1*fXY_Scale); if (AATEnabled) { double aatlat; double aatlon; double bearing; double radius; if (ValidTaskPoint(i+1)) { if (Task[i].AATType == SECTOR) radius = Task[i].AATSectorRadius; else radius = Task[i].AATCircleRadius; for (j=0; j<4; j++) { bearing = j*360.0/4; FindLatitudeLongitude(WayPointList[Task[i].Index].Latitude, WayPointList[Task[i].Index].Longitude, bearing, radius, &aatlat, &aatlon); x1 = (aatlon-lon_c)*fastcosine(aatlat); y1 = (aatlat-lat_c); ScaleXFromValue(rc, x1); ScaleYFromValue(rc, y1); if (j==0) { aatradius[i] = fabs(aatlat-WayPointList[Task[i].Index].Latitude); } } } else { aatradius[i] = 0; } } } } for(ui=0; ui<trace.size(); ui++) { lat1 = trace[ui].Latitude(); lon1 = trace[ui].Longitude(); x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); ScaleXFromValue(rc, x1*fXY_Scale); ScaleYFromValue(rc, y1*fXY_Scale); } ScaleMakeSquare(rc); // draw aat areas if (AATEnabled) { for (i=MAXTASKPOINTS-1; i>0; i--) { if (ValidTaskPoint(i)) { lat1 = WayPointList[Task[i-1].Index].Latitude; lon1 = WayPointList[Task[i-1].Index].Longitude; lat2 = WayPointList[Task[i].Index].Latitude; lon2 = WayPointList[Task[i].Index].Longitude; x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); x2 = (lon2-lon_c)*fastcosine(lat2); y2 = (lat2-lat_c); #ifdef HAVE_HATCHED_BRUSH Surface.SelectObject(MapWindow::GetAirspaceBrushByClass(AATASK)); #else Surface.SelectObject(LKBrush_Yellow); #endif Surface.SelectObject(LK_WHITE_PEN); if (Task[i].AATType == SECTOR) { Surface.Segment((long)((x2-x_min)*xscale+rc.left+BORDER_X),(long)((y_max-y2)*yscale+rc.top),(long)(aatradius[i]*yscale),rc, Task[i].AATStartRadial, Task[i].AATFinishRadial); } else { Surface.DrawCircle((long)((x2-x_min)*xscale+rc.left+BORDER_X), (long)((y_max-y2)*yscale+rc.top), (long)(aatradius[i]*yscale), true); } } } } if (!AATEnabled) { for (i=MAXTASKPOINTS-1; i>0; i--) { if (ValidTaskPoint(i) && ValidTaskPoint(i-1)) { lat1 = WayPointList[Task[i-1].Index].Latitude; lon1 = WayPointList[Task[i-1].Index].Longitude; if (!ValidTaskPoint(1) ) { lat2 = GPS_INFO.Latitude; lon2 = GPS_INFO.Longitude; } else { lat2 = WayPointList[Task[i].Index].Latitude; lon2 = WayPointList[Task[i].Index].Longitude; } x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); x2 = (lon2-lon_c)*fastcosine(lat2); y2 = (lat2-lat_c); // DrawLine(hdc, rc, x1, y1, x2, y2, STYLE_DASHGREEN); if( ValidTaskPoint(4) && i <2) goto skip_FAI; #ifndef UNDITHER RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,1, RGB_LIGHTYELLOW ); RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,0, RGB_LIGHTCYAN ); #else RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,1, RGB_LIGHTGREY ); RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,0, RGB_GREY ); #endif skip_FAI: DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_DASHGREEN); Surface.Segment((long)((x2-x_min)*xscale+rc.left+BORDER_X),(long)((y_max-y2)*yscale+rc.top),(long)(aatradius[i]*yscale),rc, Task[i].AATStartRadial, Task[i].AATFinishRadial); } } if( ValidTaskPoint(1) && ValidTaskPoint(3)) { lat1 = WayPointList[Task[3].Index].Latitude; lon1 = WayPointList[Task[3].Index].Longitude; lat2 = WayPointList[Task[1].Index].Latitude; lon2 = WayPointList[Task[1].Index].Longitude; #ifndef UNDITHER RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,1, RGB_LIGHTYELLOW ); RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,0, RGB_LIGHTCYAN ); #else RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,1, RGB_LIGHTGREY ); RenderFAISector ( Surface, rc, lat1, lon1, lat2, lon2, lat_c, lon_c,0, RGB_GREY ); #endif } } // draw task lines and label for (i=MAXTASKPOINTS-1; i>0; i--) { if (ValidTaskPoint(i) && ValidTaskPoint(i-1)) { lat1 = WayPointList[Task[i-1].Index].Latitude; lon1 = WayPointList[Task[i-1].Index].Longitude; if (!ValidTaskPoint(1) ) { lat2 = GPS_INFO.Latitude; lon2 = GPS_INFO.Longitude; } else { lat2 = WayPointList[Task[i].Index].Latitude; lon2 = WayPointList[Task[i].Index].Longitude; } x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); x2 = (lon2-lon_c)*fastcosine(lat2); y2 = (lat2-lat_c); DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_BLUETHIN); #if (WINDOWSPC>0) Surface.SetBackgroundOpaque(); #endif TCHAR text[100]; Surface.SetTextColor(RGB_BLUE); /* if ((i==nwps-1) && (Task[i].Index == Task[0].Index)) { _stprintf(text,TEXT("%0d"),1); DrawLabel(hdc, rc, text, x1+(x2-x1)/2, y1+(y2-y1)/2); } else */ { _stprintf(text,TEXT("%0d"),i); DrawLabel(Surface, rc, text, x1+(x2-x1)/2, y1+(y2-y1)/2); } if ((i==ActiveTaskPoint)&&(!AATEnabled)) { lat1 = GPS_INFO.Latitude; lon1 = GPS_INFO.Longitude; x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_REDTHICK); } } } // draw aat task line if (AATEnabled) { for (i=MAXTASKPOINTS-1; i>0; i--) { if (ValidTaskPoint(i) && ValidTaskPoint(i-1)) { if (i==1) { lat1 = WayPointList[Task[i-1].Index].Latitude; lon1 = WayPointList[Task[i-1].Index].Longitude; } else { lat1 = Task[i-1].AATTargetLat; lon1 = Task[i-1].AATTargetLon; } lat2 = Task[i].AATTargetLat; lon2 = Task[i].AATTargetLon; x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); x2 = (lon2-lon_c)*fastcosine(lat2); y2 = (lat2-lat_c); DrawLine(Surface, rc, x1, y1, x2, y2, STYLE_REDTHICK); } } } DrawXGrid(Surface, rc, 1.0, 0, STYLE_THINDASHPAPER, 1.0, false); DrawYGrid(Surface, rc, 1.0, 0, STYLE_THINDASHPAPER, 1.0, false); Surface.SelectObject(hfOldU); // Draw aircraft on top lat1 = GPS_INFO.Latitude; lon1 = GPS_INFO.Longitude; x1 = (lon1-lon_c)*fastcosine(lat1); y1 = (lat1-lat_c); Surface.SetBackgroundTransparent(); DrawLabel(Surface, rc, TEXT("+"), x1, y1); }
void RenderAirspaceTerrain(LKSurface& Surface, double PosLat, double PosLon, double brg, DiagrammStruct* psDiag) { RECT rc = psDiag->rc; //rc.bottom +=BORDER_Y; double range = psDiag->fXMax - psDiag->fXMin; // km double hmax = psDiag->fYMax; double lat, lon; int i, j; if (!IsDithered() && IsMultimapTerrain()) { RenderSky(Surface, rc, SKY_HORIZON_COL, SKY_SPACE_COL, GC_NO_COLOR_STEPS); } else { Surface.FillRect(&rc, MapWindow::hInvBackgroundBrush[BgMapColor]); } FindLatitudeLongitude(PosLat, PosLon, brg, psDiag->fXMin, &lat, &lon); POINT apTerrainPolygon[AIRSPACE_SCANSIZE_X + 4] = {}; double d_lat[AIRSPACE_SCANSIZE_X] = {}; double d_lon[AIRSPACE_SCANSIZE_X] = {}; double d_h[AIRSPACE_SCANSIZE_X] = {}; #define FRAMEWIDTH 2 RasterTerrain::Lock(); // want most accurate rounding here RasterTerrain::SetTerrainRounding(0, 0); double fj; for (j = 0; j < AIRSPACE_SCANSIZE_X; j++) { // scan range fj = (double) j * 1.0 / (double) (AIRSPACE_SCANSIZE_X - 1); FindLatitudeLongitude(lat, lon, brg, range*fj, &d_lat[j], &d_lon[j]); d_h[j] = RasterTerrain::GetTerrainHeight(d_lat[j], d_lon[j]); if (d_h[j] == TERRAIN_INVALID) d_h[j] = 0; //@ 101027 BUGFIX hmax = max(hmax, d_h[j]); } RasterTerrain::Unlock(); /******************************************************************************** * scan line ********************************************************************************/ if (IsMultimapAirspace()) Sideview_iNoHandeldSpaces = CAirspaceManager::Instance().ScanAirspaceLineList(d_lat, d_lon, d_h, Sideview_pHandeled, MAX_NO_SIDE_AS); // Sideview_pHandeled[GC_MAX_NO]; else Sideview_iNoHandeldSpaces = 0; #if BUGSTOP LKASSERT(Sideview_iNoHandeldSpaces < MAX_NO_SIDE_AS); #endif if (Sideview_iNoHandeldSpaces >= MAX_NO_SIDE_AS) Sideview_iNoHandeldSpaces = MAX_NO_SIDE_AS - 1; /******************************************************************************** * bubble sort to start with biggest airspaces ********************************************************************************/ int iSizeLookupTable[MAX_NO_SIDE_AS]; for (i = 0; i < Sideview_iNoHandeldSpaces; i++) iSizeLookupTable[i] = i; for (i = 0; i < Sideview_iNoHandeldSpaces; i++) { #if BUGSTOP LKASSERT(iSizeLookupTable[i] < MAX_NO_SIDE_AS); #endif for (j = i; j < Sideview_iNoHandeldSpaces; j++) { #if BUGSTOP LKASSERT(iSizeLookupTable[j] < MAX_NO_SIDE_AS); #endif if (iSizeLookupTable[i] >= MAX_NO_SIDE_AS) continue; if (iSizeLookupTable[j] >= MAX_NO_SIDE_AS) continue; if (Sideview_pHandeled[iSizeLookupTable[i]].iAreaSize < Sideview_pHandeled[iSizeLookupTable[j]].iAreaSize) { int iTmp = iSizeLookupTable[i]; iSizeLookupTable[i] = iSizeLookupTable[j]; iSizeLookupTable[j] = iTmp; } } } /********************************************************************************** * transform into diagram coordinates **********************************************************************************/ double dx1 = (double) (rc.right) / (double) (AIRSPACE_SCANSIZE_X - 1); int x0 = rc.left; LKASSERT(Sideview_iNoHandeldSpaces < MAX_NO_SIDE_AS); for (i = 0; i < Sideview_iNoHandeldSpaces; i++) { Sideview_pHandeled[i].rc.left = (long) ((Sideview_pHandeled[i].rc.left) * dx1) + x0 - FRAMEWIDTH / 2; Sideview_pHandeled[i].rc.right = (long) ((Sideview_pHandeled[i].rc.right) * dx1) + x0 + FRAMEWIDTH / 2; Sideview_pHandeled[i].rc.bottom = CalcHeightCoordinat((double) Sideview_pHandeled[i].rc.bottom, psDiag) + FRAMEWIDTH / 2; Sideview_pHandeled[i].rc.top = CalcHeightCoordinat((double) Sideview_pHandeled[i].rc.top, psDiag) - FRAMEWIDTH / 2; Sideview_pHandeled[i].iMaxBase = Sideview_pHandeled[i].rc.bottom; Sideview_pHandeled[i].iMinTop = Sideview_pHandeled[i].rc.top; int iN = Sideview_pHandeled[i].iNoPolyPts; #if BUGSTOP LKASSERT(iN < GC_MAX_POLYGON_PTS); #endif if (iN >= GC_MAX_POLYGON_PTS) iN = GC_MAX_POLYGON_PTS - 1; if (Sideview_pHandeled[i].bRectAllowed == false) { for (j = 0; j < iN; j++) { Sideview_pHandeled[i].apPolygon[j].x = (long) (((Sideview_pHandeled[i].apPolygon[j].x) * dx1) + x0); Sideview_pHandeled[i].apPolygon[j].y = CalcHeightCoordinat((double) Sideview_pHandeled[i].apPolygon[j].y, psDiag); if (j != iN - 1) { if ((j < iN / 2)) { Sideview_pHandeled[i].iMaxBase = min((long) Sideview_pHandeled[i].iMaxBase, (long) Sideview_pHandeled[i].apPolygon[j].y); } else { Sideview_pHandeled[i].iMinTop = max((long) Sideview_pHandeled[i].iMinTop, (long) Sideview_pHandeled[i].apPolygon[j].y); } } } } } /********************************************************************************** * draw airspaces **********************************************************************************/ const auto oldpen = Surface.SelectObject(LK_NULL_PEN); _TCHAR text [80]; LKASSERT(Sideview_iNoHandeldSpaces < MAX_NO_SIDE_AS); for (int m = 0; m < Sideview_iNoHandeldSpaces; m++) { int iSizeIdx = iSizeLookupTable[m]; #if BUGSTOP LKASSERT(iSizeIdx < MAX_NO_SIDE_AS && iSizeIdx >= 0); #endif if (iSizeIdx >= MAX_NO_SIDE_AS) iSizeIdx = MAX_NO_SIDE_AS - 1; int type = Sideview_pHandeled[iSizeIdx].iType; RECT rcd = Sideview_pHandeled[iSizeIdx].rc; LKColor FrameColor; double fFrameColFact; if (Sideview_pHandeled[iSizeIdx].bEnabled) { Surface.SelectObject(MapWindow::GetAirspaceBrushByClass(type)); Surface.SetTextColor(MapWindow::GetAirspaceColourByClass(type)); fFrameColFact = 0.8; FrameColor = MapWindow::GetAirspaceColourByClass(type); } else { Surface.SelectObject(LKBrush_Hollow); Surface.SetTextColor(RGB_GGREY); FrameColor = RGB_GGREY; fFrameColFact = 1.2; } if (INVERTCOLORS) fFrameColFact *= 0.8; else fFrameColFact *= 1.2; LKColor Color = FrameColor.ChangeBrightness(fFrameColFact); LKPen mpen2(PEN_SOLID, FRAMEWIDTH, Color); const auto oldpen2 = Surface.SelectObject(mpen2); if (Sideview_pHandeled[iSizeIdx].bRectAllowed == true) Surface.Rectangle(rcd.left + 1, rcd.top, rcd.right, rcd.bottom); else Surface.Polygon(Sideview_pHandeled[iSizeIdx].apPolygon, Sideview_pHandeled[iSizeIdx].iNoPolyPts); Surface.SelectObject(oldpen2); if (Sideview_pHandeled[iSizeIdx].bEnabled) Surface.SetTextColor(Sideview_TextColor); // RGB_MENUTITLEFG else Surface.SetTextColor(RGB_GGREY); /*********************************************** * build view overlap for centering text ***********************************************/ rcd.bottom = min(rcd.bottom, Sideview_pHandeled[iSizeIdx].iMaxBase); rcd.top = max(rcd.top, Sideview_pHandeled[iSizeIdx].iMinTop); rcd.left = max(rcd.left, rc.left); rcd.right = min(rcd.right, rc.right); rcd.bottom = min(rcd.bottom, rc.bottom); rcd.top = max(rcd.top, rc.top); SIZE textsize; SIZE aispacesize = {rcd.right - rcd.left, rcd.bottom - rcd.top}; LK_tcsncpy(text, Sideview_pHandeled[iSizeIdx].szAS_Name, NAME_SIZE - 1/* sizeof(text)/sizeof(text[0])*/); Surface.GetTextSize(text, &textsize); int x = rcd.left + aispacesize.cx / 2; ; int y = rcd.top + aispacesize.cy / 2; // int iTextheight = tsize.cy; int iOffset = 0; BOOL blongtext = false; if (aispacesize.cy > (2 * textsize.cy) && (textsize.cx < aispacesize.cx)) { iOffset = textsize.cy / 2; } if ((textsize.cx < aispacesize.cx) && (textsize.cy < aispacesize.cy)) { Surface.DrawText(x - textsize.cx / 2, y - iOffset - textsize.cy / 2, text); blongtext = true; } LK_tcsncpy(text, CAirspaceManager::Instance().GetAirspaceTypeShortText(Sideview_pHandeled[iSizeIdx].iType), NAME_SIZE); Surface.GetTextSize(text, &textsize); if (textsize.cx < aispacesize.cx) { if (2 * textsize.cy < aispacesize.cy) { Surface.DrawText(x - textsize.cx / 2, y + iOffset - textsize.cy / 2, text); } else { if ((textsize.cy < aispacesize.cy) && (!blongtext)) Surface.DrawText(x - textsize.cx / 2, y - iOffset - textsize.cy / 2, text); } } } Surface.SelectObject(oldpen); /********************************************************************************** * draw airspace frames in reversed order **********************************************************************************/ #ifdef OUTLINE_2ND for (int m = 0; m < Sideview_iNoHandeldSpaces; m++) { int iSizeIdx = iSizeLookupTable[Sideview_iNoHandeldSpaces - m - 1]; if (Sideview_pHandeled[iSizeIdx].bEnabled) { #if BUGSTOP LKASSERT(iSizeIdx < MAX_NO_SIDE_AS); #endif if (iSizeIdx >= MAX_NO_SIDE_AS) iSizeIdx = MAX_NO_SIDE_AS - 1; int type = Sideview_pHandeled[iSizeIdx].iType; RECT rcd = Sideview_pHandeled[iSizeIdx].rc; LKColor FrameColor = MapWindow::GetAirspaceColourByClass(type); double fFrameColFact; Surface.SelectObject(LKBrush_Hollow); if (Sideview_pHandeled[iSizeIdx].bEnabled) { // Surface.SelectObject(MapWindow::GetAirspaceBrushByClass(type)); Surface.SetTextColor(MapWindow::GetAirspaceColourByClass(type)); fFrameColFact = 0.8; } else { Surface.SetTextColor(RGB_GGREY); FrameColor = RGB_GGREY; fFrameColFact = 1.2; } if (INVERTCOLORS) fFrameColFact *= 0.8; else fFrameColFact *= 1.2; LKColor lColor = FrameColor.ChangeBrightness(fFrameColFact); LKPen mpen2(PEN_SOLID, FRAMEWIDTH, lColor); const auto oldpen2 = Surface.SelectObject(mpen2); if (Sideview_pHandeled[iSizeIdx].bRectAllowed == true) Surface.Rectangle(rcd.left + 1, rcd.top, rcd.right, rcd.bottom); else Surface.Polygon(Sideview_pHandeled[iSizeIdx].apPolygon, Sideview_pHandeled[iSizeIdx].iNoPolyPts); Surface.SelectObject(oldpen2); } } #endif /************************************************************* * draw ground *************************************************************/ // draw ground /********************************************************************* * draw terrain *********************************************************************/ LKPen hpHorizonGround(PEN_SOLID, IBLSCALE(1) + 1, LKColor(126, 62, 50)); LKBrush hbHorizonGround(GROUND_COLOUR); const auto oldPen = Surface.SelectObject(hpHorizonGround); const auto oldBrush = Surface.SelectObject(hbHorizonGround); for (j = 0; j < AIRSPACE_SCANSIZE_X; j++) { // scan range apTerrainPolygon[j].x = iround(j * dx1) + x0; apTerrainPolygon[j].y = CalcHeightCoordinat(d_h[j], psDiag); } apTerrainPolygon[AIRSPACE_SCANSIZE_X].x = iround(AIRSPACE_SCANSIZE_X * dx1) + x0; ; // x0; apTerrainPolygon[AIRSPACE_SCANSIZE_X].y = CalcHeightCoordinat(0, psDiag); //iBottom; apTerrainPolygon[AIRSPACE_SCANSIZE_X + 1].x = iround(0 * dx1) + x0; //iround(j*dx1)+x0; apTerrainPolygon[AIRSPACE_SCANSIZE_X + 1].y = CalcHeightCoordinat(0, psDiag); //iBottom; apTerrainPolygon[AIRSPACE_SCANSIZE_X + 2] = apTerrainPolygon[0]; static_assert(array_size(apTerrainPolygon) >= AIRSPACE_SCANSIZE_X + 3, "wrong array size"); Surface.Polygon(apTerrainPolygon, AIRSPACE_SCANSIZE_X + 3); Surface.SelectObject(oldPen); Surface.SelectObject(oldBrush); /********************************************************************* * draw sea *********************************************************************/ #ifdef MSL_SEA_DRAW // draw sea if (psDiag->fYMin < GC_SEA_LEVEL_TOLERANCE) { RECT sea = {rc.left, rc.bottom, rc.right, rc.bottom + SV_BORDER_Y}; #ifndef UNDITHER RenderSky(Surface, sea, RGB_STEEL_BLUE, RGB_ROYAL_BLUE, 7); #else RenderSky(Surface, sea, RGB_BLACK, RGB_BLACK, 2); #endif } #else if (psDiag->fYMin < GC_SEA_LEVEL_TOLERANCE) Rectangle(hdc, rc.left, rc.bottom, rc.right, rc.bottom + BORDER_Y); #endif Surface.SetTextColor(Sideview_TextColor); // RGB_MENUTITLEFG }