示例#1
0
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);
        }
    }
}
示例#2
0
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;
}
示例#3
0
void DrawSelectionFrame(LKSurface& Surface, const RECT& rc) {
    Surface.SetBackgroundTransparent();
    RECT rci = rc;
#define SHRINK 1
    rci.left += 1;
    rci.top -= 1;
    rci.right -= 2;
    rci.bottom -= 2;
    int iSize = NIBLSCALE(2);
    LKColor col = RGB_BLACK;

    Surface.DrawLine(PEN_SOLID, iSize, (POINT) {
        rci.left, rci.top}, (POINT) {
        rci.left, rci.bottom
    }, col, rci);

    Surface.DrawLine(PEN_SOLID, iSize, (POINT) {
        rci.left, rci.bottom}, (POINT) {
        rci.right, rci.bottom
    }, col, rci);

    Surface.DrawLine(PEN_SOLID, iSize, (POINT) {
        rci.right, rci.bottom}, (POINT) {
        rci.right, rci.top
    }, col, rci);

    Surface.DrawLine(PEN_SOLID, iSize, (POINT) {
        rci.right, rci.top}, (POINT) {
        rci.left, rci.top
    }, col, rci);

    col = RGB_YELLOW;

    Surface.DrawDashLine(iSize, (POINT) {
        rci.left, rci.top}, (POINT) {
        rci.left, rci.bottom
    }, col, rci);

    Surface.DrawDashLine(iSize, (POINT) {
        rci.left, rci.bottom}, (POINT) {
        rci.right, rci.bottom
    }, col, rci);

    Surface.DrawDashLine(iSize, (POINT) {
        rci.right, rci.bottom}, (POINT) {
        rci.right, rci.top
    }, col, rci);

    Surface.DrawDashLine(iSize, (POINT) {
        rci.right, rci.top}, (POINT) {
        rci.left, rci.top
    }, col, rci);


}
示例#4
0
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);
  }
}
void Statistics::DrawLabel(LKSurface& Surface, const RECT& rc, const TCHAR *text,
			   const double xv, const double yv) {

  SIZE tsize;
  Surface.GetTextSize(text, _tcslen(text), &tsize);
  int x = (int)((xv-x_min)*xscale)+rc.left-tsize.cx/2+BORDER_X;
  int y = (int)((y_max-yv)*yscale)+rc.top-tsize.cy/2;
//  SetBkMode(hdc, OPAQUE);
  if(INVERTCOLORS)
    Surface.SelectObject(LK_BLACK_PEN);


  Surface.DrawText(x, y, text, _tcslen(text));
  Surface.SetBackgroundTransparent();
}
void Statistics::DrawNoData(LKSurface& Surface, const RECT& rc) {

  SIZE tsize;
  TCHAR text[80];
	// LKTOKEN  _@M470_ = "No data" 
  _stprintf(text,TEXT("%s"), gettext(TEXT("_@M470_")));
  Surface.GetTextSize(text, _tcslen(text), &tsize);
  int x = (int)(rc.left+rc.right-tsize.cx)/2;
  int y = (int)(rc.top+rc.bottom-tsize.cy)/2;
  #if (WINDOWSPC>0)
  Surface.SetBackgroundOpaque();
  #endif
  Surface.DrawText(x, y, text, _tcslen(text));
  Surface.SetBackgroundTransparent();
}
示例#7
0
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);
   
}
示例#8
0
void RawWrite(LKSurface& Surface, const TCHAR *text, int line, short fsize, const LKColor& rgbcolor, int wtmode) {
    const auto oldfont = Surface.SelectObject(MapWindowFont);
    switch (fsize) {
        case 0:
            Surface.SelectObject(TitleWindowFont);
            break;
        case 1:
            Surface.SelectObject(LK8MapFont);
            break;
        case 2:
            Surface.SelectObject(LK8MediumFont);
            break;
        case 3:
            Surface.SelectObject(LK8BigFont);
            break;
    }
    Surface.SetBackgroundTransparent();
    SIZE tsize;
    Surface.GetTextSize(text, &tsize);
    const int y = tsize.cy * (line - 1) + (tsize.cy / 2);

    MapWindow::LKWriteText(Surface, text, ScreenSizeX / 2, y, wtmode, WTALIGN_CENTER, rgbcolor, false);
    Surface.SelectObject(oldfont);
}
示例#9
0
void Statistics::DrawXGrid(LKSurface& Surface, const RECT& rc,
			   const double tic_step,
			   const double zero,
                           const int Style,
			   const double unit_step, bool draw_units) {

  if(INVERTCOLORS || IsDithered())
    Surface.SelectObject(LK_BLACK_PEN);


  POINT line[2];

  double xval;
  SIZE tsize;

  int xmin, ymin, xmax, ymax;
  if (!tic_step) return;
  LKASSERT(tic_step!=0);

  //  bool do_units = ((x_max-zero)/tic_step)<10;

  for (xval=zero; xval<= x_max; xval+= tic_step) {

    xmin = (int)((xval-x_min)*xscale)+rc.left+BORDER_X;
    ymin = rc.top;
    xmax = xmin;
    ymax = rc.bottom;
    line[0].x = xmin;
    line[0].y = ymin;
    line[1].x = xmax;
    line[1].y = ymax-BORDER_Y;

    // STYLE_THINDASHPAPER
    if ((xval< x_max)
        && (xmin>=rc.left+BORDER_X) && (xmin<=rc.right)) {
      StyleLine(Surface, line[0], line[1], Style, rc);

      if (draw_units) {
	TCHAR unit_text[MAX_PATH];
	FormatTicText(unit_text, xval*unit_step/tic_step, unit_step);

//	SetBkMode(hdc, OPAQUE);
	Surface.GetTextSize(unit_text, &tsize);
	Surface.SetBackgroundOpaque();
	Surface.DrawText(xmin-tsize.cx/2, ymax-tsize.cy, unit_text);
	Surface.SetBackgroundTransparent();
      }
    }

  }

  for (xval=zero-tic_step; xval>= x_min; xval-= tic_step) {

    xmin = (int)((xval-x_min)*xscale)+rc.left+BORDER_X;
    ymin = rc.top;
    xmax = xmin;
    ymax = rc.bottom;
    line[0].x = xmin;
    line[0].y = ymin;
    line[1].x = xmax;
    line[1].y = ymax-BORDER_Y;

    // STYLE_THINDASHPAPER

    if ((xval> x_min)
        && (xmin>=rc.left+BORDER_X) && (xmin<=rc.right)) {

      StyleLine(Surface, line[0], line[1], Style, rc);

      if (draw_units) {
	TCHAR unit_text[MAX_PATH];
	FormatTicText(unit_text, xval*unit_step/tic_step, unit_step);
//	SetBkMode(hdc, OPAQUE);
	Surface.GetTextSize(unit_text, &tsize);
	Surface.SetBackgroundOpaque();
	Surface.DrawText(xmin-tsize.cx/2, ymax-tsize.cy, unit_text);
	Surface.SetBackgroundTransparent();
      }
    }

  }

}
示例#10
0
void MapWindow::DrawVisualGlide(LKSurface& Surface, const DiagrammStruct& sDia) {

    const RECT& rci = sDia.rc;

    unsigned short numboxrows = 1;

#if BUGSTOP
    LKASSERT(Current_Multimap_SizeY < SIZE4);
#endif
    switch (Current_Multimap_SizeY) {
        case SIZE0:
        case SIZE1:
            numboxrows = 3;
            break;
        case SIZE2:
            numboxrows = 2;
            break;
        case SIZE3:
            numboxrows = 1;
            break;
        case SIZE4:
            return;
        default:
            LKASSERT(0);
            break;
    }

    if (!ScreenLandscape) {
        numboxrows++;
        if (numboxrows > 3) numboxrows = 3;
    }

    TCHAR tmpT[30];

    line1Font = LK8VisualTopFont;
    line2Font = LK8VisualBotFont;
    SIZE textSizeTop, textSizeBot;
    Surface.SelectObject(line1Font);
    _stprintf(tmpT, _T("MMMM"));
    Surface.GetTextSize(tmpT, &textSizeTop);
    Surface.SelectObject(line2Font);
    _stprintf(tmpT, _T("55.5%s 79%s%s "), Units::GetDistanceName(), MsgToken(2179), MsgToken(2183));
    Surface.GetTextSize(tmpT, &textSizeBot);

    // we can cut the waypoint name, but not the value data, so we use the second row of data
    // to size the box for everything.
    maxtSizeX = textSizeBot.cx;

    int a = (rci.right-rci.left) / (textSizeBot.cx+BOXINTERVAL);
    int b = (rci.right-rci.left) - a * (textSizeBot.cx)-(BOXINTERVAL * (a + 1));

    boxSizeX = textSizeBot.cx + (b / (a + 1));
    boxSizeY = textSizeTop.cy + 1; // single line (wp name) + distance from bottombar

    if (numboxrows > 1) {
        boxSizeY += (textSizeBot.cy * (numboxrows - 1)) - NIBLSCALE(2);
        if (numboxrows > 2) boxSizeY -= NIBLSCALE(1);
    }

#if DEBUG_SCR
    StartupStore(_T("boxX=%d boxY=%d  \n"), boxSizeX, boxSizeY);
#endif

#if DEBUG_SCR
    StartupStore(_T("VG AREA LTRB: %d,%d %d,%d\n"), rci.left, rci.top, rci.right, rci.bottom);
#endif

    const auto oldBrush = Surface.SelectObject(LKBrush_White);
    const auto oldPen = Surface.SelectObject(LK_BLACK_PEN);

    BrushReference brush_back;
    if (!INVERTCOLORS) {
        brush_back = LKBrush_Black;
    } else {
        brush_back = LKBrush_Nlight;
    }

    Surface.FillRect(&rci, brush_back);

    POINT center, p1, p2;
    center.y = rci.top + (rci.bottom - rci.top) / 2;
    center.x = rci.left + (rci.right - rci.left) / 2;

    // numSlotX is the number items we can print horizontally.
    unsigned short numSlotX = (rci.right - rci.left) / (boxSizeX + BOXINTERVAL);
    if (numSlotX > MAXBSLOT) numSlotX = MAXBSLOT;
#if BUGSTOP
    LKASSERT(numSlotX > 0);
#endif
    if (numSlotX == 0) return;

    unsigned short boxInterval = ((rci.right - rci.left)-(boxSizeX * numSlotX)) / (numSlotX + 1);
    unsigned short oddoffset = ( (rci.right-rci.left) - (boxSizeX * numSlotX) - boxInterval * (numSlotX + 1)) / 2;

    /*
    #if BUGSTOP
    // not really harmful
    LKASSERT(oddoffset<=boxInterval);
    #endif
     */

#if DEBUG_SCR
    StartupStore(_T("numSlotX=%d ScreenSizeX=%d boxSizeX=%d interval=%d offset=%d\n"), numSlotX, ScreenSizeX, boxSizeX, boxInterval, oddoffset);
#endif

    unsigned int t;

    // The horizontal grid
    unsigned int slotCenterX[MAXBSLOT + 1];
    for (t = 0; t < numSlotX; t++) {
        slotCenterX[t] = (t * boxSizeX) + boxInterval * (t + 1)+(boxSizeX / 2) + oddoffset+rci.left;
#if DEBUG_SCR
        StartupStore(_T("slotCenterX[%d]=%d\n"), t, slotCenterX[t]);
#endif
    }

    // Vertical coordinates of each up/down subwindow, excluding center line
    int upYtop = rci.top;
#if MIDCENTER
    int upYbottom = center.y + (boxSizeY / 2);
    int downYtop = center.y - (boxSizeY / 2);
#else
    int upYbottom = center.y - CENTERYSPACE;
    int downYtop = center.y + CENTERYSPACE;
#endif
    int upSizeY = upYbottom - upYtop - (boxSizeY);
    ;
    int downYbottom = rci.bottom;
    int downSizeY = downYbottom - downYtop - (boxSizeY);
    ;

#if 0
    // Reassign dynamically the vertical scale for each subwindow size
    double vscale = 1000 * (100 - Current_Multimap_SizeY) / 100;
#else
    // Set the vertical range
    double vscale;
    if (Units::GetUserAltitudeUnit() == unFeet)
        vscale = (1000 / TOFEET);
    else
        vscale = 300.0;
#endif



    Surface.SetBackgroundTransparent();

    RECT trc = rci;

    // Top part of visual rect, target is over us=unreachable=red
    trc.top = rci.top;
    trc.bottom = center.y - 1;
    #ifndef DITHER
    RenderSky(Surface, trc, RGB_WHITE, LKColor(150, 255, 150), GC_NO_COLOR_STEPS / 2);
    #else
    RenderSky(Surface, trc, RGB_WHITE, RGB_WHITE, GC_NO_COLOR_STEPS / 2);
    #endif
    // Bottom part, target is below us=reachable=green
    trc.top = center.y + 1;
    trc.bottom = rci.bottom;
    #ifndef DITHER
    RenderSky(Surface, trc, LKColor(255, 150, 150), RGB_WHITE, GC_NO_COLOR_STEPS / 2);
    #else
    RenderSky(Surface, trc, RGB_WHITE, RGB_WHITE,GC_NO_COLOR_STEPS / 2);
    #endif

    // Draw center line
    p1.x = rci.left + 1;
    p1.y = center.y;
    p2.x = rci.right - 1;
    p2.y = center.y;
    Surface.SelectObject(LKPen_Black_N1);
    Surface.DrawSolidLine(p1, p2, rci);

#if DEBUG_SCR
    StartupStore(_T("... Center line: Y=%d\n"), center.y);
#endif

    Surface.SelectObject(line1Font);
    Surface.SelectObject(LKPen_Black_N0);

    ResetVisualGlideGlobals();

    short res = GetVisualGlidePoints(numSlotX);

    if (res == INVALID_VALUE) {
#if DEBUG_DVG
        StartupStore(_T("...... GVGP says not ready, wait..\n"));
#endif
        return;
    }
    if (res == 0) {
#if DEBUG_DVG
        StartupStore(_T("...... GVGP says no data available!\n"));
#endif
        return;
    }

    // Print them all!
    int offset = (boxSizeY / 2) + CENTERYSPACE;

    LKBrush bcolor;
    LKColor rgbcolor, textcolor;
    int wp;

    unsigned short zeroslot = 0;
    double minbrgdiff = 999.0;
    double minabrgdiff = 999.0; // absolute never negative
    for (unsigned short n = 0; n < numSlotX; n++) {
        wp = slotWpIndex[n];
        if (!ValidWayPoint(wp)) {
            // empty slot nothing to print
            continue;
        }
        double brgdiff = WayPointCalc[wp].Bearing - DrawInfo.TrackBearing;
        // this check is worthless
        if (brgdiff < -180.0) {
            brgdiff += 360.0;
        } else {
            if (brgdiff > 180.0) brgdiff -= 360.0;
        }
        double abrgdiff = brgdiff;
        if (abrgdiff < 0) abrgdiff *= -1;

        if (abrgdiff < minabrgdiff) {
            zeroslot = n;
            minabrgdiff = abrgdiff;
            minbrgdiff = brgdiff;
        }
    }

    // Draw vertical line
#define DEGRANGE 10	// degrees left and right to perfect target
    if (minabrgdiff < 1) {
        p1.x = slotCenterX[zeroslot];
    } else {
        // set fullscale range
        if (minabrgdiff > DEGRANGE) {
            minabrgdiff = DEGRANGE;
            if (minbrgdiff < 0)
                minbrgdiff = -1 * DEGRANGE;
            else
                minbrgdiff = DEGRANGE;
        }
        // we shift of course in the opposite direction
        p1.x = slotCenterX[zeroslot]-(int) ((boxSizeX / (DEGRANGE * 2)) * minbrgdiff);
    }
    p2.x = p1.x;

    p1.y = rci.top + 1;
    p2.y = rci.bottom - 1;
    Surface.SelectObject(LKPen_Black_N1);
    Surface.DrawSolidLine(p1, p2, rci);



    for (unsigned short n = 0; n < numSlotX; n++) {

        wp = slotWpIndex[n];
        if (!ValidWayPoint(wp)) {
            // empty slot nothing to print
            continue;
        }
#if DEBUG_DVG
        StartupStore(_T("... DVG PRINT [%d]=%d <%s>\n"), n, wp, WayPointList[wp].Name);
#endif

        Sideview_VGWpt[n] = wp;

        double altdiff = WayPointCalc[wp].AltArriv[AltArrivMode];
        int ty;
#if DEBUG_SCR
        StartupStore(_T("... wp=<%s>\n"), WayPointList[wp].Name);
#endif

        // Since terrain can be approximated due to low precision maps, or waypoint position or altitude error,
        // we have a common problem: we get an obstacle to get to the waypoint because it is
        // positioned "BELOW" the terrain itself. We try to reduce this problem here.
#define SAFETERRAIN	50

        // Positive arrival altitude for the waypoint, upper window
        if (altdiff >= 0) {
            if (altdiff == 0)altdiff = 1;
            double d = vscale / altdiff;
            if (d == 0) d = 1;
            ty = upYbottom - (int) ((double) upSizeY / d)-(boxSizeY / 2);
#if DEBUG_SCR
            StartupStore(_T("... upYbottom=%d upSizeY=%d / (vscale=%f/altdiff=%f = %f) =- %d  ty=%d  offset=%d\n"),
                    upYbottom, upSizeY, vscale, altdiff, d, (int) ((double) upSizeY / d), ty, offset);
#endif
            if ((ty - offset) < upYtop) ty = upYtop + offset;
            if ((ty + offset) > upYbottom) ty = upYbottom - offset;
#if DEBUG_SCR
            StartupStore(_T("... upYtop=%d upYbottom=%d final ty=%d\n"), upYtop, upYbottom, ty);
#endif


            //
            // This is too confusing. We want simple colors, not shaded
            // rgbcolor = MixColors( LKColor(50,255,50), LKColor(230,255,230),  altdiff/(vscale-50));
            //

            if (altdiff <= SAFETERRAIN) {
                rgbcolor = RGB_LIGHTYELLOW;
            } else {
                if (!CheckLandableReachableTerrainNew(&DrawInfo, &DerivedDrawInfo,
                        WayPointCalc[wp].Distance, WayPointCalc[wp].Bearing)) {
                    rgbcolor = RGB_LIGHTRED;
                } else {
#ifdef DITHER
                    rgbcolor = RGB_WHITE;
#else
                    rgbcolor = RGB_LIGHTGREEN;
#endif
                }
            }
            bcolor.Create(rgbcolor);

        } else {
            double d = vscale / altdiff;
            if (d == 0) d = -1;
            ty = downYtop - (int) ((double) downSizeY / d)+(boxSizeY / 2); // - because the left part is negative, we are really adding.
            if ((ty - offset) < downYtop) ty = downYtop + offset;
            if ((ty + offset) > downYbottom) ty = downYbottom - offset;

#ifdef DITHER
            rgbcolor = RGB_WHITE; // negative part, no need to render dark
#else
            rgbcolor = RGB_LIGHTRED;
#endif
            bcolor.Create(rgbcolor);
        }

        TCHAR line2[40], line3[40];
        TCHAR value[40], unit[30];
        TCHAR name[NAME_SIZE + 1];
        double ar = (WayPointCalc[wp].AltArriv[AltArrivMode] * ALTITUDEMODIFY);
        _tcscpy(name, WayPointList[wp].Name);
        CharUpper(name);

        if (IsSafetyAltitudeInUse(wp))
            textcolor = RGB_DARKBLUE;
        else
            textcolor = RGB_BLACK;

        switch (numboxrows) {
            case 0:
#if BUGSTOP
                LKASSERT(0);
#endif
                return;

            case 1:
                // 1 line: waypoint name
                VGTextInBox(Surface, n, 1, name, NULL, NULL, slotCenterX[n], ty, textcolor, bcolor);
                break;

            case 2:
                // 2 lines: waypoint name + altdiff
                LKFormatAltDiff(wp, false, value, unit);
                // Should we print also the GR?
                if ((ar >= -9999 && ar <= 9999) && (WayPointCalc[wp].GR < MAXEFFICIENCYSHOW)) {
                    if (ar >= -999 && ar <= 999)
                        _stprintf(line2, _T("%s   "), value);
                    else
                        _stprintf(line2, _T("%s  "), value);
                    LKFormatGR(wp, false, value, unit);
                    _tcscat(line2, value);
                } else {
                    _stprintf(line2, _T("%s   ---"), value);
                }

                VGTextInBox(Surface, n, 2, name, line2, NULL, slotCenterX[n], ty, textcolor, bcolor);
                break;

            case 3:
                // 3 lines: waypoint name + dist + altdiff
                LKFormatDist(wp, false, value, unit);
                _stprintf(line2, _T("%s%s"), value, unit);

                LKFormatBrgDiff(wp, false, value, unit);
                _stprintf(tmpT, _T(" %s%s"), value, unit);
                _tcscat(line2, tmpT);

                LKFormatAltDiff(wp, false, value, unit);
                // Should we print also the GR?
                if ((ar >= -9999 && ar <= 9999) && (WayPointCalc[wp].GR < MAXEFFICIENCYSHOW)) {
                    if (ar >= -999 && ar <= 999)
                        _stprintf(line3, _T("%s   "), value);
                    else
                        _stprintf(line3, _T("%s  "), value);
                    LKFormatGR(wp, false, value, unit);
                    _tcscat(line3, value);
                } else {
                    _stprintf(line3, _T("%s   ---"), value);
                }

                VGTextInBox(Surface, n, 3, name, line2, line3, slotCenterX[n], ty, textcolor, bcolor);
                break;
            default:
#if BUGSTOP
                LKASSERT(0);
#endif
                return;
        }

    } // for numSlotX



    // Cleanup and return
    Surface.SelectObject(oldBrush);
    Surface.SelectObject(oldPen);
    return;
}
示例#11
0
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);
      } 

      Surface.SetBackgroundTransparent();
      
#ifndef __linux__
      Surface.DrawText(x, y, Value);
#else
      Surface.DrawText(x, y+NIBLSCALE(1), Value);
#endif
      drawn=true;
    }


  } else if (Mode->FillBackground) {
示例#12
0
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();

}
示例#13
0
/*****************************************************************
 * 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);
}
}
}
示例#14
0
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;

}
示例#15
0
/*****************************************************************
 * 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);

}
示例#16
0
void Statistics::DrawYGrid(LKSurface& Surface, const RECT& rc,
			   const double tic_step,
			   const double zero,
                           const int Style,
			   const double unit_step, bool draw_units) {

  POINT line[2];
  SIZE tsize;
  double yval;

  if(INVERTCOLORS || IsDithered())
    Surface.SelectObject(LK_BLACK_PEN);


  int xmin, ymin, xmax, ymax;

  if (!tic_step) return;

  for (yval=zero; yval<= y_max; yval+= tic_step) {

    xmin = rc.left;
    ymin = (int)((y_max-yval)*yscale)+rc.top -BORDER_Y;
    xmax = rc.right;
    ymax = ymin;
    line[0].x = xmin+BORDER_X;
    line[0].y = ymin;
    line[1].x = xmax;
    line[1].y = ymax;

    // STYLE_THINDASHPAPER
    if ((yval< y_max) &&
        (ymin>=rc.top) && (ymin<=rc.bottom-BORDER_Y)) {

      StyleLine(Surface, line[0], line[1], Style, rc);

      if (draw_units) {
	TCHAR unit_text[MAX_PATH];
	FormatTicText(unit_text, yval*unit_step/tic_step, unit_step);
	Surface.GetTextSize(unit_text, &tsize);
	Surface.SetBackgroundOpaque();
	Surface.DrawText(xmin, ymin-tsize.cy/2, unit_text);
    Surface.SetBackgroundTransparent();
      }
    }
  }

  for (yval=zero-tic_step; yval>= y_min; yval-= tic_step) {

    xmin = rc.left;
    ymin = (int)((y_max-yval)*yscale)+rc.top-BORDER_Y;
    xmax = rc.right;
    ymax = ymin;
    line[0].x = xmin+BORDER_X;
    line[0].y = ymin;
    line[1].x = xmax;
    line[1].y = ymax;

    // STYLE_THINDASHPAPER
    if ((yval> y_min) &&
        (ymin>=rc.top) && (ymin<=rc.bottom-BORDER_Y)) {

      StyleLine(Surface, line[0], line[1], Style, rc);

      if (draw_units) {
	TCHAR unit_text[MAX_PATH];
	FormatTicText(unit_text, yval*unit_step/tic_step, unit_step);
	Surface.GetTextSize(unit_text, &tsize);
    Surface.SetBackgroundOpaque();
	Surface.DrawText(xmin, ymin-tsize.cy/2, unit_text);
    Surface.SetBackgroundTransparent();
      }
    }
  }
}
示例#17
0
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();

}
示例#18
0
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);

    }
}
示例#19
0
void MapWindow::DrawMapScale(LKSurface& Surface, const RECT& rc /* the Map Rect*/, 
                             const bool ScaleChangeFeedback)
{
    static short terrainwarning=0;
    static POINT lineOneStart, lineOneEnd,lineTwoStart,lineTwoEnd,lineThreeStart,lineThreeEnd;
    static POINT lineTwoStartB,lineThreeStartB;
    static int   ytext;
    static bool flipflop=true;

    if (DoInit[MDI_DRAWMAPSCALE]) {
	lineOneStart.x = MAPSCALE_RIGHTMARGIN;
	lineOneEnd.x   = MAPSCALE_RIGHTMARGIN;
	lineOneStart.y = MAPSCALE_BOTTOMMARGIN;
	lineOneEnd.y = lineOneStart.y - MAPSCALE_VSIZE;

	lineTwoStart.x = MAPSCALE_RIGHTMARGIN - MAPSCALE_HSIZE; 
	lineTwoEnd.x = MAPSCALE_RIGHTMARGIN;
	lineTwoEnd.y = lineOneStart.y;
	lineTwoStart.y = lineOneStart.y;

	lineThreeStart.y = lineTwoStart.y - MAPSCALE_VSIZE;
	lineThreeEnd.y = lineThreeStart.y;
	lineThreeStart.x = lineTwoStart.x;
	lineThreeEnd.x = lineTwoEnd.x;

	lineTwoStartB=lineTwoStart;
	lineTwoStartB.x++;
	lineThreeStartB=lineThreeStart;
	lineThreeStartB.x++;

        SIZE tsize;
        Surface.SelectObject(MapScaleFont);
        Surface.GetTextSize(_T("M"),1,&tsize);
        int ofs=(MAPSCALE_VSIZE - (tsize.cy + tsize.cy))/2;
        ytext=lineThreeStart.y+ofs;


	DoInit[MDI_DRAWMAPSCALE]=false;
    }

    TCHAR Scale[200];
    TCHAR Scale1[200];
    TCHAR Scale2[200];
    TCHAR TEMP[20];

    const auto hpOld = Surface.SelectObject(hpMapScale2);

    Surface.DrawSolidLine(lineOneStart,lineOneEnd, rc);
    Surface.DrawSolidLine(lineTwoStart,lineTwoEnd, rc);
    Surface.DrawSolidLine(lineThreeStart,lineThreeEnd, rc);

    Surface.SelectObject(LKPen_White_N0);
    Surface.DrawSolidLine(lineOneStart,lineOneEnd, rc);
    Surface.DrawSolidLine(lineTwoStartB,lineTwoEnd, rc);
    Surface.DrawSolidLine(lineThreeStartB,lineThreeEnd, rc);

    Surface.SelectObject(hpOld);

    flipflop=!flipflop;

    _tcscpy(Scale2,TEXT(""));

    bool inpanmode= (!mode.Is(Mode::MODE_TARGET_PAN) && mode.Is(Mode::MODE_PAN));

    if (inpanmode) {
	if (DerivedDrawInfo.TerrainValid) {
		double alt= ALTITUDEMODIFY*RasterTerrain::GetTerrainHeight(GetPanLatitude(), GetPanLongitude());
		if (alt==TERRAIN_INVALID) alt=0.0;
		_stprintf(Scale2, _T(" %.0f%s "),alt,
		Units::GetUnitName(Units::GetUserAltitudeUnit()));
	}
	double pandistance, panbearing;

    if(ValidTaskPoint(PanTaskEdit))
    {
    	  _stprintf(Scale, _T("Task %.1f%s"), CALCULATED_INFO.TaskDistanceToGo*DISTANCEMODIFY, Units::GetDistanceName()/*, panbearing,_T(DEG)*/ );

    }
    else
    {
	  DistanceBearing(DrawInfo.Latitude,DrawInfo.Longitude,GetPanLatitude(),GetPanLongitude(),&pandistance,&panbearing);
	  _stprintf(Scale, _T(" %.1f%s %.0f%s "), pandistance*DISTANCEMODIFY, Units::GetDistanceName(), panbearing, gettext(_T("_@M2179_")) );
    }


	_tcscat(Scale2,Scale);
	goto _skip1;
    }

    //
    // This stuff is not painted while panning, to save space on screen
    //

    // warn about missing terrain
    if (!DerivedDrawInfo.TerrainValid) {
	if (terrainwarning < 120) {
		// LKTOKEN _@M1335_ " TERRAIN?"
		_tcscat(Scale2, MsgToken(1335));
		terrainwarning++;
	} else  {
		// LKTOKEN _@M1336_ " T?"
		_tcscat(Scale2, MsgToken(1336));
		terrainwarning=120;
	}
    } else terrainwarning=0;

    if (UseTotalEnergy) {
      _tcscat(Scale2, TEXT("[TE]")); // Total Energy indicator
    }
    if (zoom.AutoZoom()) {
		// LKTOKEN _@M1337_ " AZM"
      _tcscat(Scale2, MsgToken(1337));
    }

_skip1:

    //
    // Back painting stuff even in PAN mode
    //

    if (mode.AnyPan()) {
		// LKTOKEN _@M1338_ " PAN"
      _tcscat(Scale2, MsgToken(1338));
    }

    if (DrawBottom) {
	switch(BottomMode) {
		case BM_TRM:
				// LKTOKEN _@M1340_ " TRM0"
      			_tcscat(Scale2, MsgToken(1340));
			break;
		case BM_CRU:
				// LKTOKEN _@M1341_ " NAV1"
      			_tcscat(Scale2, MsgToken(1341));
			break;
		case BM_HGH:
				// LKTOKEN _@M1342_ " ALT2"
      			_tcscat(Scale2, MsgToken(1342));
			break;
		case BM_AUX:
				// LKTOKEN _@M1343_ " STA3"
      			_tcscat(Scale2, MsgToken(1343));
			break;
		case BM_TSK:
				// LKTOKEN _@M1344_ " TSK4"
      			_tcscat(Scale2, MsgToken(1344));
			break;
		case BM_ALT:
				// LKTOKEN _@M1345_ " ATN5"
      			_tcscat(Scale2, MsgToken(1345));
			break;
		case BM_SYS:
				// LKTOKEN _@M1346_ " SYS6"
      			_tcscat(Scale2, MsgToken(1346));
			break;
		case BM_CUS2:
				// LKTOKEN _@M1347_ " CRU7"
      			_tcscat(Scale2, MsgToken(1347));
			break;
		case BM_CUS3:
				// LKTOKEN _@M1348_ " FIN8"
      			_tcscat(Scale2, MsgToken(1348));
			break;
		case BM_CUS:
				// LKTOKEN _@M1349_ " AUX9"
      			_tcscat(Scale2, MsgToken(1349));
			break;
		default:
			break;
	}
    }

    if (inpanmode) goto _skip2;

    if (ReplayLogger::IsEnabled()) {
	_stprintf(Scale,_T("%s %.0fX"),
		MsgToken(1350), // " REPLAY"
		ReplayLogger::TimeScale);
      _tcscat(Scale2, Scale);
    }
    if (BallastTimerActive) {
		// LKTOKEN _@M1351_ " BALLAST"
      _stprintf(TEMP,TEXT("%s %3.0fL"), MsgToken(1351), WEIGHTS[2]*BALLAST);
      _tcscat(Scale2, TEMP);
    }

_skip2:

    _tcscpy(Scale,TEXT(""));
    _tcscpy(Scale1,TEXT(""));

    //if (SIMMODE && (!mode.Is(Mode::MODE_TARGET_PAN) && mode.Is(Mode::MODE_PAN)) ) {
    if (inpanmode) {

	TCHAR sCoordinate[32]={0};
	Units::CoordinateToString(GetPanLongitude(), GetPanLatitude(), sCoordinate, array_size(sCoordinate)-1);
	_tcscat(Scale, sCoordinate);
	_tcscat(Scale, _T(" "));
    }
    double mapScale=Units::ToSysDistance(zoom.Scale()*1.4);	// 1.4 for mapscale symbol size on map screen
    // zoom.Scale() gives user units, but FormatUserMapScale() needs system distance units
    Units::FormatUserMapScale(NULL, mapScale, Scale1, sizeof(Scale1)/sizeof(Scale1[0]));
    _tcscat(Scale,Scale1);

    SIZE tsize;

    Surface.SetBackgroundTransparent();
    const auto oldFont = Surface.SelectObject(MapScaleFont);
    const auto oldPen = Surface.SelectObject(LK_BLACK_PEN);
    const auto oldBrush = Surface.SelectObject(LKBrush_Black);

    Surface.GetTextSize(Scale, _tcslen(Scale), &tsize);

    LKColor mapscalecolor = OverColorRef;
    if (OverColorRef==RGB_SBLACK) mapscalecolor=RGB_WHITE;

    LKWriteText(Surface, Scale, rc.right-NIBLSCALE(7)-tsize.cx, ytext, 0, WTMODE_OUTLINED, WTALIGN_LEFT, mapscalecolor, true);

    Surface.GetTextSize(Scale2, _tcslen(Scale2), &tsize);

    if (!DerivedDrawInfo.TerrainValid) {
	if (terrainwarning>0 && terrainwarning<120) mapscalecolor=RGB_RED;
    }

    LKWriteText(Surface, Scale2, rc.right-NIBLSCALE(7)-tsize.cx, ytext+tsize.cy, 0, WTMODE_OUTLINED, WTALIGN_LEFT, mapscalecolor, true);

    Surface.SelectObject(oldPen);
    Surface.SelectObject(oldBrush);
    Surface.SelectObject(oldFont);

}
示例#20
0
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);
}
示例#21
0
void MapWindow::RenderNearAirspace(LKSurface& Surface, const RECT& rci) {
    RECT rc = rci; /* rectangle for sideview */
    RECT rct = rc; /* rectangle for topview */

    rc.top = (int) ((double) (rci.bottom - rci.top) * fSplitFact);
    rct.bottom = rc.top;
    // Expose the topview rect size in use..
    Current_Multimap_TopRect = rct;

    auto hfOldFnt = Surface.SelectObject(LK8PanelUnitFont/* Sender->GetFont()*/);

    int *iSplit = &Multimap_SizeY[Get_Current_Multimap_Type()];

    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:
            if (Sideview_iNoHandeldSpaces) {
                bool bShow = false;
                for (int k = 0; k <= Sideview_iNoHandeldSpaces; k++) {
                    if (Sideview_pHandeled[k].psAS != NULL) {
                        if (PtInRect(&(Sideview_pHandeled[k].rc), startScreen)) {
                            dlgAddMultiSelectListItem((long*) Sideview_pHandeled[k].psAS, 0, IM_AIRSPACE, 0);
                            bShow = true;
                        }
                    }
                }
                if (bShow) {
                    /*
                     * we can't show dialog from Draw thread
                     * instead, new event is queued, dialog will be popup by main thread 
                     */
                    InputEvents::processGlideComputer(GCE_POPUP_MULTISELECT);

                    // reset event, otherwise Distance/height zoom mod are also triggered
                    LKevent = LKEVENT_NONE;
                }
            }

            if (LKevent != LKEVENT_NONE) {
                if (PtInRect(&rc, startScreen)) {
                    bHeightScale = !bHeightScale;
                } else 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);

    const auto 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, &tsize);
        TxYPt.x = (rc.right - rc.left - tsize.cx) / 2;
        TxYPt.y = (rc.bottom - rc.top) / 2;

        Surface.SetBackgroundTransparent();
        Surface.DrawText(TxYPt.x, TxYPt.y - 20, 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.SetBackgroundTransparent();
    Surface.SetTextColor(txtCol);
    Surface.SelectObject(LK8PanelUnitFont);
    _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);


    Surface.SetBkColor(RGB_WHITE);

    if (!bInvCol)
        Surface.SetBackgroundOpaque();
    /****************************************************************************************************
     * 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, &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);
        }
    }

    Surface.SetBackgroundTransparent();

    /****************************************************************************************************
     * 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, &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);
        }
    }


    /****************************************************************************************************
     * draw side elements
     ****************************************************************************************************/
    Surface.SetTextColor(Sideview_TextColor);
    Surface.SetBackgroundOpaque();
    const auto hfOld2 = Surface.SelectObject(LK8InfoNormalFont);

    //  DrawTelescope      ( hdc, iAS_Bearing-90.0, rc.right  - NIBLSCALE(13),  rc.top   + NIBLSCALE(58));

    Surface.SelectObject(hfOld2);
    Surface.SetBackgroundTransparent();

    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.SetBackgroundOpaque();
        const auto 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, &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);



        /****************************************************************************************************
         * 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, &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);
        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.SetBackgroundTransparent();
    Surface.SelectObject(hfOldFnt/* Sender->GetFont()*/);
}