Example #1
1
void
ThermalAssistantWindow::PaintRadarBackground(Canvas &canvas, fixed max_lift) const
{
  canvas.Clear(look.background_color);
  canvas.SelectHollowBrush();

  canvas.Select(look.inner_circle_pen);
  canvas.DrawCircle(mid.x, mid.y, radius / 2);
  canvas.Select(look.outer_circle_pen);
  canvas.DrawCircle(mid.x, mid.y, radius);

  if (small)
    return;

  canvas.SetTextColor(COLOR_BLACK);
  canvas.Select(look.circle_label_font);
  canvas.SetBackgroundColor(look.background_color);
  canvas.SetBackgroundOpaque();

  TCHAR lift_string[10];
  FormatUserVerticalSpeed(max_lift, lift_string, ARRAY_SIZE(lift_string));
  PixelSize s = canvas.CalcTextSize(lift_string);
  canvas.text(mid.x - s.cx / 2,
              mid.y + radius - s.cy * 0.75, lift_string);

  FormatUserVerticalSpeed(fixed_zero, lift_string, ARRAY_SIZE(lift_string));
  s = canvas.CalcTextSize(lift_string);
  canvas.text(mid.x - s.cx / 2,
              mid.y + radius / 2 - s.cy * 0.75, lift_string);

  canvas.SetBackgroundTransparent();
}
void
ThermalAssistantWindow::PaintRadarBackground(Canvas &canvas) const
{
  canvas.clear(hbBackground);
  canvas.SelectHollowBrush();

  canvas.Select(hpInnerCircle);
  canvas.circle(mid.x, mid.y, radius / 2);
  canvas.Select(hpOuterCircle);
  canvas.circle(mid.x, mid.y, radius);

  if (small)
    return;

  canvas.SetTextColor(COLOR_BLACK);
  canvas.Select(hfLabels);
  canvas.SetBackgroundColor(hcBackground);
  canvas.SetBackgroundOpaque();

  TCHAR lift_string[10];
  Units::FormatUserVerticalSpeed(max_lift, lift_string, ARRAY_SIZE(lift_string));
  PixelSize s = canvas.CalcTextSize(lift_string);
  canvas.text(mid.x - s.cx / 2,
              mid.y + radius - s.cy * 0.75, lift_string);

  Units::FormatUserVerticalSpeed(fixed_zero, lift_string, ARRAY_SIZE(lift_string));
  s = canvas.CalcTextSize(lift_string);
  canvas.text(mid.x - s.cx / 2,
              mid.y + radius / 2 - s.cy * 0.75, lift_string);

  canvas.SetBackgroundTransparent();
}
Example #3
0
void
FlarmTrafficControl::PaintRelativeAltitude(Canvas &canvas, PixelRect rc,
                                           fixed relative_altitude) const
{
  // Format relative altitude
  TCHAR buffer[20];
  Unit unit = Units::GetUserAltitudeUnit();
  FormatRelativeUserAltitude(relative_altitude, buffer, false);

  // Calculate unit size
  canvas.Select(look.info_units_font);
  const unsigned unit_width = UnitSymbolRenderer::GetSize(canvas, unit).cx;
  const unsigned unit_height =
      UnitSymbolRenderer::GetAscentHeight(look.info_units_font, unit);

  const unsigned space_width = unit_width / 3;

  // Calculate value size
  canvas.Select(look.info_values_font);
  const unsigned value_height = look.info_values_font.GetAscentHeight();
  const unsigned value_width = canvas.CalcTextSize(buffer).cx;

  // Calculate positions
  const unsigned max_height = std::max(unit_height, value_height);

  // Paint value
  canvas.DrawText(rc.right - unit_width - space_width - value_width,
                  rc.bottom - value_height,
                  buffer);

  // Paint unit
  canvas.Select(look.info_units_font);
  UnitSymbolRenderer::Draw(canvas,
                           RasterPoint(rc.right - unit_width,
                                       rc.bottom - unit_height),
                           unit, look.unit_fraction_pen);


  // Paint label
  canvas.Select(look.info_labels_font);
  const unsigned label_width = canvas.CalcTextSize(_("Rel. Alt.")).cx;
  canvas.DrawText(rc.right - label_width,
                  rc.bottom - max_height - look.info_labels_font.GetHeight(),
                  _("Rel. Alt."));
}
void
MapWindow::DrawTaskOffTrackIndicator(Canvas &canvas)
{
  if (Calculated().circling 
      || !Basic().location_available
      || !Basic().track_available
      || !GetMapSettings().detour_cost_markers_enabled)
    return;

  const TaskStats &task_stats = Calculated().task_stats;
  const ElementStat &current_leg = task_stats.current_leg;

  if (!task_stats.task_valid || !current_leg.location_remaining.IsValid())
    return;

  const GeoPoint target = current_leg.location_remaining;
  GeoVector vec(Basic().location, target);

  if ((Basic().track - vec.bearing).AsDelta().AbsoluteDegrees() < fixed(10))
    // insignificant error
    return;

  fixed distance_max =
    std::min(vec.distance,
             render_projection.GetScreenDistanceMeters() * fixed(0.7));

  // too short to bother
  if (distance_max < fixed(5000))
    return;

  GeoPoint start = Basic().location;
  
  canvas.Select(*look.overlay_font);
  canvas.SetTextColor(COLOR_BLACK);
  canvas.SetBackgroundTransparent();
  
  GeoPoint dloc;
  int ilast = 0;
  for (fixed d = fixed(1) / 4; d <= fixed(1); d += fixed(1) / 4) {
    dloc = FindLatitudeLongitude(start, Basic().track, distance_max * d);
    
    fixed distance0 = start.Distance(dloc);
    fixed distance1 = target.Distance(dloc);
    fixed distance = fixed(distance0 + distance1) / vec.distance;
    int idist = iround((distance - fixed(1)) * 100);
    
    if ((idist != ilast) && (idist > 0) && (idist < 1000)) {
      TCHAR Buffer[5];
      _stprintf(Buffer, _T("%d"), idist);
      RasterPoint sc = render_projection.GeoToScreen(dloc);
      PixelSize tsize = canvas.CalcTextSize(Buffer);
      canvas.DrawText(sc.x - tsize.cx / 2, sc.y - tsize.cy / 2, Buffer);
      ilast = idist;
    }
  }
}
Example #5
0
static void
Draw(Canvas &canvas)
{
  PixelRect rc = canvas.GetRect();
  rc.Grow(-0.2 * rc.GetSize().cx);
  
  /* draw the banner text with a large font */
  Font small_font;
  small_font.LoadFile("/opt/LK8000/share/fonts/DejaVuSansCondensed.ttf", (rc.GetSize().cy / 25));
  canvas.Select(small_font);
  canvas.SetTextColor(COLOR_BLACK);
  canvas.SetBackgroundTransparent();

  const TCHAR *const text = _T("Powered Off");
  const PixelSize text_size = canvas.CalcTextSize(text);
  const RasterPoint text_pos = {
      rc.left + 16,
      rc.bottom - 16 - text_size.cy
  };
  canvas.DrawText(text_pos.x, text_pos.y, text);
  
  Font big_font;
  big_font.LoadFile("/opt/LK8000/share/fonts/DejaVuSansCondensed-Bold.ttf", (rc.GetSize().cy / 10));
  canvas.Select(big_font);
  
  const TCHAR *const text2 = _T("LK8000");
  const PixelSize text2_size = canvas.CalcTextSize(text2);
  const RasterPoint text2_pos = {
      (rc.left + rc.GetSize().cx + text2_size.cx) / 2,
      (rc.top + (rc.GetSize().cy / 10))
  };
  canvas.DrawText(text2_pos.x, text2_pos.y, text2);
  
  const double Scale = (double)rc.GetSize().cx / (double)bird_size.cx;
  
  RasterPoint polygon[array_size(bird_polygon)] = {};
  std::transform(std::begin(bird_polygon), std::end(bird_polygon), std::begin(polygon), [Scale, rc, text2_size, text2_pos]( const RasterPoint& pt ) {
      return RasterPoint(pt.x*Scale + rc.left, pt.y*Scale + text2_pos.y + text2_size.cy);
  });
  
  canvas.SelectBlackBrush();
  canvas.DrawPolygon(polygon, array_size(polygon));
}
Example #6
0
void
FlarmTrafficControl::PaintClimbRate(Canvas &canvas, PixelRect rc,
                                    fixed climb_rate) const
{
  // Paint label
  canvas.Select(look.info_labels_font);
  const unsigned label_width = canvas.CalcTextSize(_("Vario")).cx;
  canvas.DrawText(rc.right - label_width, rc.top, _("Vario"));

  // Format climb rate
  TCHAR buffer[20];
  Unit unit = Units::GetUserVerticalSpeedUnit();
  FormatUserVerticalSpeed(climb_rate, buffer, false);

  // Calculate unit size
  canvas.Select(look.info_units_font);
  const unsigned unit_width = UnitSymbolRenderer::GetSize(canvas, unit).cx;
  const unsigned unit_height =
      UnitSymbolRenderer::GetAscentHeight(look.info_units_font, unit);

  UPixelScalar space_width = unit_width / 3;

  // Calculate value size
  canvas.Select(look.info_values_font);
  const unsigned value_height = look.info_values_font.GetAscentHeight();
  const unsigned value_width = canvas.CalcTextSize(buffer).cx;

  // Calculate positions
  const int max_height = std::max(unit_height, value_height);
  const int y = rc.top + look.info_units_font.GetHeight() + max_height;

  // Paint value
  canvas.DrawText(rc.right - unit_width - space_width - value_width,
                  y - value_height,
                  buffer);

  // Paint unit
  canvas.Select(look.info_units_font);
  UnitSymbolRenderer::Draw(canvas,
                           RasterPoint(rc.right - unit_width, y - unit_height),
                           unit, look.unit_fraction_pen);
}
Example #7
0
void
InfoBoxWindow::PaintValue(Canvas &canvas, Color background_color)
{
  if (data.value.empty())
    return;

  canvas.SetTextColor(look.GetValueColor(data.value_color));

  canvas.Select(look.unit_font);
  int unit_width =
    UnitSymbolRenderer::GetSize(canvas, data.value_unit).cx;

  canvas.Select(look.value_font);
  int ascent_height = look.value_font.GetAscentHeight();

  PixelSize value_size = canvas.CalcTextSize(data.value);
  if (unsigned(value_size.cx + unit_width) > value_rect.GetWidth()) {
    canvas.Select(look.small_value_font);
    ascent_height = look.small_value_font.GetAscentHeight();
    value_size = canvas.CalcTextSize(data.value);
  }

  int x = std::max(0,
                   (value_rect.left + value_rect.right
                    - value_size.cx - unit_width) / 2);

  int y = (value_rect.top + value_rect.bottom - value_size.cy) / 2;

  canvas.TextAutoClipped(x, y, data.value);

  if (unit_width != 0) {
    const int unit_height =
      UnitSymbolRenderer::GetAscentHeight(look.unit_font, data.value_unit);

    canvas.Select(look.unit_font);
    UnitSymbolRenderer::Draw(canvas,
                             { x + value_size.cx,
                                 y + ascent_height - unit_height },
                             data.value_unit, look.unit_fraction_pen);
  }
}
Example #8
0
/**
 * Paints a "No Traffic" sign on the given canvas
 * @param canvas The canvas to paint on
 */
void
FlarmTrafficWindow::PaintRadarNoTraffic(Canvas &canvas) const
{
  if (small)
    return;

  const TCHAR* str = _("No Traffic");
  canvas.Select(look.no_traffic_font);
  PixelSize ts = canvas.CalcTextSize(str);
  canvas.SetTextColor(look.default_color);
  canvas.text(radar_mid.x - (ts.cx / 2), radar_mid.y - (radius / 2), str);
}
void
ThermalAssistantWindow::PaintNotCircling(Canvas &canvas) const
{
  if (small)
    return;

  const TCHAR* str = _("Not Circling");
  canvas.Select(hfNoTraffic);
  PixelSize ts = canvas.CalcTextSize(str);
  canvas.SetTextColor(hcStandard);
  canvas.text(mid.x - (ts.cx / 2), mid.y - (radius / 2), str);
}
Example #10
0
void
ThermalAssistantWindow::PaintNotCircling(Canvas &canvas) const
{
  if (small)
    return;

  const TCHAR* str = _("Not Circling");
  canvas.Select(look.overlay_font);
  PixelSize ts = canvas.CalcTextSize(str);
  canvas.SetTextColor(look.text_color);
  canvas.text(mid.x - (ts.cx / 2), mid.y - (radius / 2), str);
}
Example #11
0
void
TabDisplay::PaintButton(Canvas &canvas, unsigned CaptionStyle,
                        const TCHAR *caption, const PixelRect &rc,
                        const Bitmap *bmp, const bool isDown, bool inverse)
{
  PixelRect rcTextFinal = rc;
  const UPixelScalar buttonheight = rc.bottom - rc.top;
  const PixelSize text_size = canvas.CalcTextSize(caption);
  const int textwidth = text_size.cx;
  const int textheight = text_size.cy;
  UPixelScalar textheightoffset = 0;

  if (textwidth > (rc.right - rc.left)) // assume 2 lines
    textheightoffset = std::max(0, (int)(buttonheight - textheight * 2) / 2);
  else
    textheightoffset = std::max(0, (int)(buttonheight - textheight) / 2);

  rcTextFinal.top += textheightoffset;

  canvas.DrawFilledRectangle(rc, canvas.GetBackgroundColor());

  if (bmp != NULL) {
    const PixelSize bitmap_size = bmp->GetSize();
    const int offsetx = (rc.right - rc.left - bitmap_size.cx / 2) / 2;
    const int offsety = (rc.bottom - rc.top - bitmap_size.cy) / 2;

    if (inverse) // black background
      canvas.CopyNotOr(rc.left + offsetx,
                       rc.top + offsety,
                       bitmap_size.cx / 2,
                       bitmap_size.cy,
                       *bmp,
                       bitmap_size.cx / 2, 0);

    else
      canvas.CopyAnd(rc.left + offsetx,
                      rc.top + offsety,
                      bitmap_size.cx / 2,
                      bitmap_size.cy,
                      *bmp,
                      bitmap_size.cx / 2, 0);

  } else {
#ifndef USE_GDI
    if (IsDithered())
      CaptionStyle |= DT_UNDERLINE;
#endif

    canvas.DrawFormattedText(&rcTextFinal, caption, CaptionStyle);
  }
}
Example #12
0
void
KnobTextEntryWindow::OnPaint(Canvas &canvas)
{
  const PixelRect rc = GetClientRect();

  canvas.Clear(Color(0x40, 0x40, 0x00));

  // Do the actual painting of the text
  const DialogLook &look = UIGlobals::GetDialogLook();
  canvas.Select(look.text_font);

  PixelSize tsize = canvas.CalcTextSize(buffer);
  PixelSize tsizec = canvas.CalcTextSize(buffer, cursor);
  PixelSize tsizea = canvas.CalcTextSize(buffer, cursor + 1);

  BulkPixelPoint p[5];
  p[0].x = 10;
  p[0].y = (rc.GetHeight() - tsize.cy - 5) / 2;

  p[2].x = p[0].x + tsizec.cx;
  p[2].y = p[0].y + tsize.cy + 5;

  p[3].x = p[0].x + tsizea.cx;
  p[3].y = p[0].y + tsize.cy + 5;

  p[1].x = p[2].x;
  p[1].y = p[2].y - 2;

  p[4].x = p[3].x;
  p[4].y = p[3].y - 2;

  canvas.SelectWhitePen();
  canvas.DrawPolyline(p + 1, 4);

  canvas.SetBackgroundTransparent();
  canvas.SetTextColor(COLOR_WHITE);
  canvas.DrawText(p[0].x, p[0].y, buffer);
}
Example #13
0
/**
 * Paints the radar circle on the given canvas
 * @param canvas The canvas to paint on
 */
void
FlarmTrafficWindow::PaintRadarBackground(Canvas &canvas) const
{
  canvas.SelectHollowBrush();
  canvas.Select(look.radar_pen);
  canvas.SetTextColor(look.radar_color);

  // Paint circles
  canvas.circle(radar_mid.x, radar_mid.y, radius);
  canvas.circle(radar_mid.x, radar_mid.y, radius / 2);

  PaintRadarPlane(canvas);

  if (small)
    return;

  // Paint zoom strings
  canvas.Select(look.label_font);
  canvas.SetBackgroundOpaque();
  canvas.SetBackgroundColor(look.background_color);

  TCHAR distance_string[10];
  FormatUserDistanceSmart(distance, distance_string,
                            ARRAY_SIZE(distance_string));
  PixelSize s = canvas.CalcTextSize(distance_string);
  canvas.text(radar_mid.x - s.cx / 2,
              radar_mid.y + radius - s.cy * 0.75, distance_string);

  FormatUserDistanceSmart(distance / 2, distance_string,
                            ARRAY_SIZE(distance_string));
  s = canvas.CalcTextSize(distance_string);
  canvas.text(radar_mid.x - s.cx / 2,
              radar_mid.y + radius / 2 - s.cy * 0.75, distance_string);

  canvas.SetBackgroundTransparent();

  PaintNorth(canvas);
}
Example #14
0
static void
OnTextPaint(gcc_unused WndOwnerDrawFrame *Sender, Canvas &canvas)
{
    const PixelRect rc = Sender->GetClientRect();

    canvas.Clear(Color(0x40, 0x40, 0x00));

    // Do the actual painting of the text
    const DialogLook &look = UIGlobals::GetDialogLook();
    canvas.Select(*look.text_font);

    PixelSize tsize = canvas.CalcTextSize(edittext);
    PixelSize tsizec = canvas.CalcTextSize(edittext, cursor);
    PixelSize tsizea = canvas.CalcTextSize(edittext, cursor + 1);

    RasterPoint p[5];
    p[0].x = 10;
    p[0].y = (rc.bottom - rc.top - tsize.cy - 5) / 2;

    p[2].x = p[0].x + tsizec.cx;
    p[2].y = p[0].y + tsize.cy + 5;

    p[3].x = p[0].x + tsizea.cx;
    p[3].y = p[0].y + tsize.cy + 5;

    p[1].x = p[2].x;
    p[1].y = p[2].y - 2;

    p[4].x = p[3].x;
    p[4].y = p[3].y - 2;

    canvas.SelectWhitePen();
    canvas.DrawPolyline(p + 1, 4);

    canvas.SetBackgroundTransparent();
    canvas.SetTextColor(COLOR_WHITE);
    canvas.DrawText(p[0].x, p[0].y, edittext);
}
Example #15
0
void
WndProperty::OnPaint(Canvas &canvas)
{
  const bool focused = edit.HasFocus();

  /* background and selector */
  if (focused) {
    canvas.Clear(look.focused.background_color);
  } else {
    /* don't need to erase the background when it has been done by the
       parent window already */
    if (HaveClipping())
      canvas.Clear(look.background_color);
  }

  WindowControl::OnPaint(canvas);

  /* kludge: don't draw caption if width is too small (but not 0),
     used by the polar configuration panel.  This concept needs to be
     redesigned. */
  if (caption_width != 0 && !caption.empty()) {
    canvas.SetTextColor(focused
                          ? look.focused.text_color
                          : look.text_color);
    canvas.SetBackgroundTransparent();
    canvas.Select(*look.text_font);

    PixelSize tsize = canvas.CalcTextSize(caption.c_str());

    RasterPoint org;
    if (caption_width < 0) {
      org.x = edit_rc.left;
      org.y = edit_rc.top - tsize.cy;
    } else {
      org.x = caption_width - tsize.cx - Layout::FastScale(3);
      org.y = (GetHeight() - tsize.cy) / 2;
    }

    if (org.x < 1)
      org.x = 1;

    if (HaveClipping())
      canvas.text(org.x, org.y, caption.c_str());
    else
      canvas.text_clipped(org.x, org.y, caption_width - org.x,
                          caption.c_str());
  }
}
Example #16
0
void
InfoBoxWindow::PaintTitle(Canvas &canvas)
{
  if (data.title.empty())
    return;

  if (!pressed && !HasFocus() && !dragging && !force_draw_selector &&
      settings.border_style == InfoBoxSettings::BorderStyle::SHADED)
    canvas.DrawFilledRectangle(title_rect, look.caption_background_color);

  canvas.SetTextColor(look.GetTitleColor(data.title_color));

  const Font &font = look.title_font;
  canvas.Select(font);

  PixelSize tsize = canvas.CalcTextSize(data.title);

  PixelScalar halftextwidth = (title_rect.left + title_rect.right - tsize.cx) / 2;
  PixelScalar x = std::max(PixelScalar(1),
                           PixelScalar(title_rect.left + halftextwidth));
  PixelScalar y = title_rect.top;

  canvas.TextAutoClipped(x, y, data.title);

  if (settings.border_style == InfoBoxSettings::BorderStyle::TAB &&
      halftextwidth > Layout::Scale(3)) {
    PixelScalar ytop = title_rect.top + font.GetCapitalHeight() / 2;
    PixelScalar ytopedge = ytop + Layout::GetTextPadding();
    PixelScalar ybottom = title_rect.top + Layout::Scale(6)
      + font.GetCapitalHeight();

    canvas.Select(look.border_pen);

    RasterPoint tab[8];
    tab[0].x = tab[1].x = title_rect.left;
    tab[0].y = tab[7].y = ybottom;
    tab[2].x = title_rect.left + Layout::GetTextPadding();
    tab[2].y = tab[5].y = tab[3].y = tab[4].y = ytop;
    tab[1].y = tab[6].y = ytopedge;
    tab[5].x = title_rect.right - Layout::GetTextPadding();
    tab[6].x = tab[7].x = title_rect.right;
    tab[3].x = title_rect.left + halftextwidth - Layout::Scale(1);
    tab[4].x = title_rect.right - halftextwidth + Layout::Scale(1);

    canvas.DrawPolyline(tab, 4);
    canvas.DrawPolyline(tab + 4, 4);
  }
}
Example #17
0
  virtual void OnPaint(Canvas &canvas) {
    canvas.SelectWhiteBrush();
    if (has_focus())
      canvas.SelectBlackPen();
    else
      canvas.SelectWhitePen();
    canvas.clear();

    unsigned text_height = canvas.CalcTextSize(_T("W")).cy;
    for (int i = num_events - 1, y = 4; i >= 0; --i, y += text_height) {
      const struct key_event &event = events[i];
      TCHAR buffer[64];
      _stprintf(buffer, _T("key %s = 0x%x"),
                event.down ? _T("down") : _T("up"), event.code);
      canvas.text(4, y, buffer);
    }
  }
Example #18
0
void
InfoBoxWindow::PaintTitle(Canvas &canvas)
{
  if (data.title.empty())
    return;

  canvas.SetTextColor(look.GetTitleColor(data.title_color));

  const Font &font = *look.title.font;
  canvas.Select(font);

  PixelSize tsize = canvas.CalcTextSize(data.title);

  PixelScalar halftextwidth = (title_rect.left + title_rect.right - tsize.cx) / 2;
  PixelScalar x = max(PixelScalar(1),
                      PixelScalar(title_rect.left + halftextwidth));
  PixelScalar y = title_rect.top + 1 + font.GetCapitalHeight() -
    font.GetAscentHeight();

  canvas.TextAutoClipped(x, y, data.title);

  if (settings.border_style == apIbTab && halftextwidth > Layout::Scale(3)) {
    PixelScalar ytop = title_rect.top + font.GetCapitalHeight() / 2;
    PixelScalar ytopedge = ytop + Layout::Scale(2);
    PixelScalar ybottom = title_rect.top + Layout::Scale(6)
      + font.GetCapitalHeight();

    canvas.Select(look.border_pen);

    RasterPoint tab[8];
    tab[0].x = tab[1].x = title_rect.left;
    tab[0].y = tab[7].y = ybottom;
    tab[2].x = title_rect.left + Layout::Scale(2);
    tab[2].y = tab[5].y = tab[3].y = tab[4].y = ytop;
    tab[1].y = tab[6].y = ytopedge;
    tab[5].x = title_rect.right - Layout::Scale(2);
    tab[6].x = tab[7].x = title_rect.right;
    tab[3].x = title_rect.left + halftextwidth - Layout::Scale(1);
    tab[4].x = title_rect.right - halftextwidth + Layout::Scale(1);

    canvas.DrawPolyline(tab, 4);
    canvas.DrawPolyline(tab + 4, 4);
  }
}
Example #19
0
void
InfoBoxWindow::PaintComment(Canvas &canvas)
{
  if (data.comment.empty())
    return;

  canvas.SetTextColor(look.GetCommentColor(data.comment_color));

  const Font &font = look.title_font;
  canvas.Select(font);

  PixelSize tsize = canvas.CalcTextSize(data.comment);

  int x = std::max(1,
                   (comment_rect.left + comment_rect.right - tsize.cx) / 2);
  int y = comment_rect.top;

  canvas.TextAutoClipped(x, y, data.comment);
}
Example #20
0
/**
 * Paints the radar circle on the given canvas
 * @param canvas The canvas to paint on
 */
void
FlarmTrafficWindow::PaintNorth(Canvas &canvas) const
{
  DoublePoint2D p(0, -1);
  if (!enable_north_up) {
    p = fr.Rotate(p);
  }

  canvas.SetTextColor(look.background_color);
  canvas.Select(look.radar_pen);
  canvas.Select(look.radar_brush);
  canvas.SetBackgroundTransparent();
  canvas.Select(look.label_font);

  PixelSize s = canvas.CalcTextSize(_T("N"));
  canvas.DrawCircle(radar_mid.x + iround(p.x * radius),
                radar_mid.y + iround(p.y * radius), s.cy * 0.65);
  canvas.DrawText(radar_mid.x + iround(p.x * radius) - s.cx / 2,
                  radar_mid.y + iround(p.y * radius) - s.cy / 2, _T("N"));
}
Example #21
0
void
FlarmTrafficControl::PaintDistance(Canvas &canvas, PixelRect rc,
                                   fixed distance) const
{
  // Format distance
  TCHAR buffer[20];
  Unit unit = FormatUserDistanceSmart(distance, buffer, false, fixed(1000));

  // Calculate unit size
  canvas.Select(look.info_units_font);
  const unsigned unit_width = UnitSymbolRenderer::GetSize(canvas, unit).cx;
  const unsigned unit_height =
      UnitSymbolRenderer::GetAscentHeight(look.info_units_font, unit);

  const unsigned space_width = unit_width / 3;

  // Calculate value size
  canvas.Select(look.info_values_font);
  const unsigned value_height = look.info_values_font.GetAscentHeight();
  const unsigned value_width = canvas.CalcTextSize(buffer).cx;

  // Calculate positions
  const unsigned max_height = std::max(unit_height, value_height);

  // Paint value
  canvas.DrawText(rc.left, rc.bottom - value_height, buffer);

  // Paint unit
  canvas.Select(look.info_units_font);
  UnitSymbolRenderer::Draw(canvas,
                           RasterPoint(rc.left + value_width + space_width,
                                       rc.bottom - unit_height),
                           unit, look.unit_fraction_pen);


  // Paint label
  canvas.Select(look.info_labels_font);
  canvas.DrawText(rc.left,
                  rc.bottom - max_height - look.info_labels_font.GetHeight(),
                  _("Distance"));
}
Example #22
0
void
InfoBoxWindow::PaintComment(Canvas &canvas)
{
  if (data.comment.empty())
    return;

  canvas.SetTextColor(look.GetCommentColor(data.comment_color));

  const Font &font = *look.comment.font;
  canvas.Select(font);

  PixelSize tsize = canvas.CalcTextSize(data.comment);

  PixelScalar x = max(PixelScalar(1),
                      PixelScalar((comment_rect.left + comment_rect.right
                                   - tsize.cx) / 2));
  PixelScalar y = comment_rect.top + 1 + font.GetCapitalHeight()
    - font.GetAscentHeight();

  canvas.TextAutoClipped(x, y, data.comment);
}
Example #23
0
/**
 * Paints the radar circle on the given canvas
 * @param canvas The canvas to paint on
 */
void
FlarmTrafficWindow::PaintNorth(Canvas &canvas) const
{
  fixed x = fixed_zero, y = fixed_minus_one;
  if (!enable_north_up) {
    FastRotation::Pair p = fr.Rotate(x, y);
    x = p.first;
    y = p.second;
  }

  canvas.SetTextColor(look.background_color);
  canvas.Select(look.radar_pen);
  canvas.Select(look.radar_brush);
  canvas.SetBackgroundTransparent();
  canvas.Select(look.label_font);

  PixelSize s = canvas.CalcTextSize(_T("N"));
  canvas.circle(radar_mid.x + iround(x * radius),
                radar_mid.y + iround(y * radius), s.cy * 0.65);
  canvas.text(radar_mid.x + iround(x * radius) - s.cx / 2,
              radar_mid.y + iround(y * radius) - s.cy / 2, _T("N"));
}
Example #24
0
//------------------------------------------------------------------------------
int
main(int argc, char *argv[])
  {
  QApplication app(argc, argv);
  Canvas c;
  Pen(Pen::SOLID, 1, Color(0, 0, 0));
    {
    c.Select(Brush(Color(128, 128, 0, Color::TRANSPARENT)));
    c.DrawKeyhole(200, 100, 50, 100, Angle::Degrees(-20), Angle::Degrees(20));
    c.DrawKeyhole(400, 100, 50, 100, Angle::Degrees(70), Angle::Degrees(110));
    c.DrawKeyhole(200, 300, 50, 100, Angle::Degrees(160), Angle::Degrees(200));
    c.DrawKeyhole(400, 300, 50, 100, Angle::Degrees(-110), Angle::Degrees(-70));
    c.show();
    app.exec();
    }
    {
    c.Clear();
    c.DrawKeyhole(200, 100, 50, 100, Angle::Degrees(35), Angle::Degrees(55));
    c.DrawKeyhole(400, 100, 50, 100, Angle::Degrees(125), Angle::Degrees(145));
    c.DrawKeyhole(200, 300, 50, 100, Angle::Degrees(215), Angle::Degrees(235));
    c.DrawKeyhole(400, 300, 50, 100, Angle::Degrees(305), Angle::Degrees(325));
    c.show();
    app.exec();
    }
    {
    c.Clear();
    c.DrawFilledRectangle(0, 0, 100, 100, Color(128, 128, 128,
                                                Color::TRANSPARENT));
    c.DrawFilledRectangle(100, 100, 200, 200, Color(128, 0, 0,
                                                    Color::TRANSPARENT));
    c.DrawFilledRectangle(150, 150, 250, 250, Color(0, 128, 0,
                                                    Color::TRANSPARENT));
    c.DrawFilledRectangle(200, 200, 300, 300, Color(0, 0, 128,
                                                    Color::TRANSPARENT));
    c.DrawTransparentText(0, 0, "0");
    c.DrawTransparentText(0, 100, "100");
    c.DrawTransparentText(0, 200, "200");
    c.DrawTransparentText(0, 300, "300");
    c.DrawTransparentText(0, 400, "400");
    c.DrawTransparentText(0, 500, "500");
    c.DrawTransparentText(100, c.GetFontHeight(), "100");
    c.DrawTransparentText(200, c.GetFontHeight(), "200");
    c.DrawTransparentText(300, c.GetFontHeight(), "300");
    c.DrawTransparentText(400, c.GetFontHeight(), "400");
    c.DrawTransparentText(500, c.GetFontHeight(), "500");
    c.show();
    app.exec();
    }
    {
    c.Clear();
    c.DrawOutlineRectangle(100, 100, 200, 200, Color(255, 0, 0));
    c.show();
    app.exec();
    }
    {
    c.Clear();
    c.DrawRoundRectangle(100, 100, 200, 200, 10, 10);
    c.DrawRoundRectangle(200, 200, 300, 300, 100, 100);
    c.DrawRoundRectangle(300, 300, 400, 400, 50, 50);
    c.show();
    app.exec();
    }
    {
    c.Clear();
    PixelRect rc;
    rc.left   = 100;
    rc.top    = 100;
    rc.right  = 200;
    rc.bottom = 200;
    c.DrawRaisedEdge(rc);
    c.show();
    app.exec();
    }
    {
    c.Clear();
    RasterPoint rp[4];
    rp[0] = {100, 100};
    rp[1] = {200, 200};
    rp[2] = {200, 300};
    rp[3] = {300, 400};
    c.DrawPolyline(rp, 4);
    c.show();
    app.exec();
    }
    {
    c.Clear();
    RasterPoint rp[6];
    rp[0] = {100, 100};
    rp[1] = {150,  50};
    rp[2] = {200, 100};
    rp[3] = {200, 200};
    rp[4] = {150, 200};
    rp[5] = {100, 100};
    c.DrawPolygon(rp, 6);
    c.show();
    app.exec();
    }
    {
    c.Clear();
    RasterPoint rp[4];
    rp[0] = {100, 100};
    rp[1] = {200,  50};
    rp[2] = {200, 150};
    rp[3] = {150, 200};
    c.DrawTriangleFan(rp, 4);
    c.show();
    app.exec();
    }
    {
    c.Clear();
    c.DrawHLine(100, 200, 100, Color(255, 0, 0));
    c.DrawHLine(100, 200, 200, Color(0, 255, 0));
    c.DrawHLine(100, 200, 300, Color(0, 0, 255));
    c.show();
    app.exec();
    }
    {
    c.Clear();
    c.DrawLine(100, 100, 200, 200);
    c.DrawCircle(250, 250, 50);
    c.DrawSegment(100, 250, 50, Angle::Degrees(10), Angle::Degrees(30), false);
    c.show();
    app.exec();
    }
    {
    c.Clear();
    c.DrawAnnulus(100, 100, 50, 100, Angle::Degrees(10), Angle::Degrees(60));
    c.DrawAnnulus(300, 100, 50, 100, Angle::Degrees(0),  Angle::Degrees(360));
    c.DrawAnnulus(100, 300, 50, 100, Angle::Degrees(0),  Angle::Degrees(0));
    c.show();
    app.exec();
    }
    {
    PixelSize rc = c.CalcTextSize("Hello");
    std::cout << "Size of \"Hello\": " << rc.cx << ", " << rc.cy << std::endl;
    c.DrawClippedText(100, 100, rc.cx / 2, "Hello");
    c.show();
    app.exec();
    }
    {
    std::cout << "Height of font: " << c.GetFontHeight() << std::endl;
    }
    {
    c.Clear();
    c.DrawText(0, 50, "50");
    c.Clear();
    c.show();
    return app.exec();
    }
  }
Example #25
0
void
FinalGlideBarRenderer::Draw(Canvas &canvas, const PixelRect &rc,
                            const DerivedInfo &calculated,
                            const GlideSettings &glide_settings,
                            const bool final_glide_bar_mc0_enabled) const
{
#ifdef ENABLE_OPENGL
  const ScopeAlphaBlend alpha_blend;
#endif

  BulkPixelPoint GlideBar[6] = {
      { 0, 0 }, { 9, -9 }, { 18, 0 }, { 18, 0 }, { 9, 0 }, { 0, 0 }
  };
  BulkPixelPoint GlideBar0[4] = {
      { 0, 0 }, { 9, -9 }, { 9, 0 }, { 0, 0 }
  };
  BulkPixelPoint clipping_arrow[6] = {
      { 0, 0 }, { 9, 9 }, { 18, 0 }, { 18, 6 }, { 9, 15 }, { 0, 6 }
  };
  BulkPixelPoint clipping_arrow0[4] = {
      { 0, 0 }, { 9, 9 }, { 9, 15 }, { 0, 6 }
  };

  TCHAR Value[10];

  const TaskStats &task_stats = calculated.task_stats;
  const ElementStat &total = task_stats.total;
  const GlideResult &solution = total.solution_remaining;
  const GlideResult &solution_mc0 = total.solution_mc0;

  if (!task_stats.task_valid || !solution.IsOk() || !solution_mc0.IsDefined())
    return;

  const int y0 = (rc.bottom + rc.top) / 2;

  /* NOTE: size_divisor replaces the fixed value 9 that was used throughout
   * the code below which caused fixed size rendering regardless of
   * map size (except the effects of Layout::Scale()). This method
   * is not usable with variable map sizes (e.g. because of the cross-section
   * area). size_divisor is used to introduce a screen size dependent scaling.
   * That workaround is an ugly hack and needs a rework. */
  const int size_divisor =
    std::max(Layout::Scale(3000u / rc.GetHeight()), 4u);

  int dy_glidebar = 0;
  int dy_glidebar0 = 0;

  FormatUserAltitude(solution.SelectAltitudeDifference(glide_settings),
                            Value, false);
  canvas.Select(*look.font);
  const PixelSize text_size = canvas.CalcTextSize(Value);

  int clipping_arrow_offset = Layout::Scale(4);
  int clipping_arrow0_offset = Layout::Scale(4);

  // 468 meters is it's size. Will be divided by 9 to fit screen resolution.
  int altitude_difference = (int)
    solution.SelectAltitudeDifference(glide_settings);
  int altitude_difference0 = (int)
    solution_mc0.SelectAltitudeDifference(glide_settings);
  // TODO feature: should be an angle if in final glide mode

  // cut altitude_difference at +- 468 meters (55 units)
  if (altitude_difference > 468)
    altitude_difference = 468;
  if (altitude_difference < -468)
    altitude_difference = -468;

  // 55 units is size, 468 meters div by 9 means 55.
  int Offset = altitude_difference / size_divisor;
  
  Offset = Layout::Scale(Offset);
  if (altitude_difference <= 0) {
    GlideBar[1].y = Layout::Scale(9);
    dy_glidebar = text_size.cy + 2;
  } else {
    GlideBar[1].y = -Layout::Scale(9);
    clipping_arrow[1].y = -clipping_arrow[1].y;
    clipping_arrow[3].y = -clipping_arrow[3].y;
    clipping_arrow[4].y = -clipping_arrow[4].y;
    clipping_arrow[5].y = -clipping_arrow[5].y;
    clipping_arrow_offset = -clipping_arrow_offset;
    dy_glidebar = -1;
  }

  // cut altitude_difference0 at +- 468 meters (55 units)
  if (altitude_difference0 > 468)
    altitude_difference0 = 468;
  if (altitude_difference0 < -468)
    altitude_difference0 = -468;

  // 55 units is size, therefore div by 9.
  int Offset0 = altitude_difference0 / size_divisor;
  
  Offset0 = Layout::Scale(Offset0);
  if (altitude_difference0 <= 0) {
    GlideBar0[1].y = Layout::Scale(9);
    dy_glidebar0 = text_size.cy + 2;
  } else {
    GlideBar0[1].y = -Layout::Scale(9);
    clipping_arrow0[1].y = -clipping_arrow0[1].y;
    clipping_arrow0[2].y = -clipping_arrow0[2].y;
    clipping_arrow0[3].y = -clipping_arrow0[3].y;
    clipping_arrow0_offset = -clipping_arrow0_offset;
    dy_glidebar0 = -1;
  }

  for (unsigned i = 0; i < 6; i++) {
    GlideBar[i].y += y0 + dy_glidebar;
    GlideBar[i].x = Layout::Scale(GlideBar[i].x) + rc.left;
  }

  GlideBar[0].y -= Offset;
  GlideBar[1].y -= Offset;
  GlideBar[2].y -= Offset;

  for (unsigned i = 0; i < 4; i++) {
    GlideBar0[i].y += y0 + dy_glidebar0;
    GlideBar0[i].x = Layout::Scale(GlideBar0[i].x) + rc.left;
  }

  GlideBar0[0].y -= Offset0;
  GlideBar0[1].y -= Offset0;

  if ((altitude_difference0 >= altitude_difference) && (altitude_difference > 0)) {
    // both above and mc0 arrow larger than mc arrow
    GlideBar0[2].y = GlideBar[1].y;    // both below
    GlideBar0[3].y = GlideBar[0].y;
  }

  // prepare clipping arrow
  for (unsigned i = 0; i < 6; i++) {
    clipping_arrow[i].y = Layout::Scale(clipping_arrow[i].y) + y0 - Offset
      + clipping_arrow_offset + dy_glidebar;
    clipping_arrow[i].x = Layout::Scale(clipping_arrow[i].x) + rc.left;
  }

  // prepare clipping arrow mc0
  for (unsigned i = 0; i < 4; i++) {
    clipping_arrow0[i].y = Layout::Scale(clipping_arrow0[i].y) + y0 - Offset0
      + clipping_arrow0_offset + dy_glidebar0;
    clipping_arrow0[i].x = Layout::Scale(clipping_arrow0[i].x) + rc.left;
  }

  // draw actual glide bar
  if (altitude_difference <= 0) {
    if (calculated.common_stats.landable_reachable) {
      canvas.Select(look.pen_below_landable);
      canvas.Select(look.brush_below_landable);
    } else {
      canvas.Select(look.pen_below);
      canvas.Select(look.brush_below);
    }
  } else {
    canvas.Select(look.pen_above);
    canvas.Select(look.brush_above);
  }
  canvas.DrawPolygon(GlideBar, 6);

  // draw clipping arrow
  if ((altitude_difference <= -468 ) || (altitude_difference >= 468))
    canvas.DrawPolygon(clipping_arrow, 6);

  // draw glide bar at mc 0
  if (altitude_difference0 <= 0 && final_glide_bar_mc0_enabled) {
    if (calculated.common_stats.landable_reachable) {
      canvas.Select(look.pen_below_landable);
      canvas.Select(look.brush_below_landable_mc0);
    } else {
      canvas.Select(look.pen_below);
      canvas.Select(look.brush_below_mc0);
    }
  } else {
    canvas.Select(look.pen_above);
    canvas.Select(look.brush_above_mc0);
  }

  if ( ( (altitude_difference != altitude_difference0) || (altitude_difference0 < 0) )
      && final_glide_bar_mc0_enabled) {
    canvas.DrawPolygon(GlideBar0, 4);

    if ((altitude_difference0 <= -468 ) || (altitude_difference0 >= 468))
      canvas.DrawPolygon(clipping_arrow0, 4);
  }

  // draw cross (x) on final glide bar if unreachable at current Mc
  // or above final glide but impeded by obstacle
  int cross_sign = 0;

  if (!total.IsAchievable())
    cross_sign = 1;
  if (calculated.terrain_warning_location.IsValid() &&
      altitude_difference > 0 )
    cross_sign = -1;

  if (cross_sign != 0) {
    canvas.Select(task_look.bearing_pen);
    canvas.DrawLine(Layout::Scale(9 - 5), y0 + cross_sign * Layout::Scale(9 - 5),
                Layout::Scale(9 + 5), y0 + cross_sign * Layout::Scale(9 + 5));
    canvas.DrawLine(Layout::Scale(9 - 5), y0 + cross_sign * Layout::Scale(9 + 5),
                Layout::Scale(9 + 5), y0 + cross_sign * Layout::Scale(9 - 5));
  }

  canvas.SetTextColor(COLOR_BLACK);
  canvas.SetBackgroundColor(COLOR_WHITE);

  TextInBoxMode style;
  style.shape = LabelShape::ROUNDED_BLACK;
  style.move_in_view = true;

  if (text_size.cx < Layout::Scale(18)) {
    style.align = TextInBoxMode::Alignment::RIGHT;
    TextInBox(canvas, Value, Layout::Scale(18), y0, style, rc);
  } else
    TextInBox(canvas, Value, 0, y0, style, rc);

}
Example #26
0
void
GaugeVario::RenderBugs(Canvas &canvas)
{
  static int last_bugs = -1;
  static PixelRect label_rect = {-1,-1,-1,-1};
  static PixelRect value_rect = {-1,-1,-1,-1};
  static RasterPoint label_pos = {-1,-1};
  static RasterPoint value_pos = {-1,-1};

  if (!bugs_initialised) {
    const PixelRect rc = GetClientRect();
    PixelSize tSize;

    label_pos.x = 1;
    label_pos.y = rc.bottom - 2
      - look.text_font->GetCapitalHeight()
      - look.text_font->GetAscentHeight();

    value_pos.x = 1;
    value_pos.y = rc.bottom - 1
      - look.text_font->GetAscentHeight();

    label_rect.left = label_pos.x;
    label_rect.top = label_pos.y
      + look.text_font->GetAscentHeight()
      - look.text_font->GetCapitalHeight();
    value_rect.left = value_pos.x;
    value_rect.top = value_pos.y
      + look.text_font->GetAscentHeight()
      - look.text_font->GetCapitalHeight();

    canvas.Select(*look.text_font);
    tSize = canvas.CalcTextSize(TEXT_BUG);

    label_rect.right = label_rect.left + tSize.cx;
    label_rect.bottom = label_rect.top
      + look.text_font->GetCapitalHeight()
      + look.text_font->GetHeight()
      - look.text_font->GetAscentHeight();

    tSize = canvas.CalcTextSize(_T("100%"));

    value_rect.right = value_rect.left + tSize.cx;
    value_rect.bottom = value_rect.top +
      look.text_font->GetCapitalHeight();

    bugs_initialised = true;
  }

  int bugs = iround((fixed(1) - GetComputerSettings().polar.bugs) * 100);
  if (!IsPersistent() || bugs != last_bugs) {

    canvas.Select(*look.text_font);

    if (IsPersistent())
      canvas.SetBackgroundColor(look.background_color);
    else
      canvas.SetBackgroundTransparent();

    if (IsPersistent() || last_bugs < 1 || bugs < 1) {
      if (bugs > 0) {
        canvas.SetTextColor(look.dimmed_text_color);
        if (IsPersistent())
          canvas.DrawOpaqueText(label_pos.x, label_pos.y, label_rect, TEXT_BUG);
        else
          canvas.DrawText(label_pos.x, label_pos.y, TEXT_BUG);
      } else if (IsPersistent())
        canvas.DrawFilledRectangle(label_rect, look.background_color);
    }

    if (bugs > 0) {
      TCHAR buffer[18];
      _stprintf(buffer, _T("%d%%"), bugs);
      canvas.SetTextColor(look.text_color);
      if (IsPersistent())
        canvas.DrawOpaqueText(value_pos.x, value_pos.y, value_rect, buffer);
      else 
        canvas.DrawText(value_pos.x, value_pos.y, buffer);
    } else if (IsPersistent())
      canvas.DrawFilledRectangle(value_rect, look.background_color);

    if (IsPersistent())
      last_bugs = bugs;
  }
}
Example #27
0
void
GaugeVario::RenderBallast(Canvas &canvas)
{
  static int last_ballast = -1;
  static PixelRect label_rect = {-1,-1,-1,-1};
  static PixelRect value_rect = {-1,-1,-1,-1};
  static RasterPoint label_pos = {-1,-1};
  static RasterPoint value_pos = {-1,-1};

  if (!ballast_initialised) { // ontime init, origin and background rect
    const PixelRect rc = GetClientRect();

    PixelSize tSize;

    // position of ballast label
    label_pos.x = 1;
    label_pos.y = rc.top + 2
      + look.text_font->GetCapitalHeight() * 2
      - look.text_font->GetAscentHeight();

    // position of ballast value
    value_pos.x = 1;
    value_pos.y = rc.top + 1
      + look.text_font->GetCapitalHeight()
      - look.text_font->GetAscentHeight();

    // set upper left corner
    label_rect.left = label_pos.x;
    label_rect.top = label_pos.y
      + look.text_font->GetAscentHeight()
      - look.text_font->GetCapitalHeight();

    // set upper left corner
    value_rect.left = value_pos.x;
    value_rect.top = value_pos.y
      + look.text_font->GetAscentHeight()
      - look.text_font->GetCapitalHeight();

    // get max label size
    canvas.Select(*look.text_font);
    tSize = canvas.CalcTextSize(TEXT_BALLAST);

    // update back rect with max label size
    label_rect.right = label_rect.left + tSize.cx;
    label_rect.bottom = label_rect.top +
      look.text_font->GetCapitalHeight();

    // get max value size
    tSize = canvas.CalcTextSize(_T("100%"));

    value_rect.right = value_rect.left + tSize.cx;
    // update back rect with max label size
    value_rect.bottom = value_rect.top +
      look.text_font->GetCapitalHeight();

    ballast_initialised = true;
  }

  int ballast = iround(GetGlidePolar().GetBallast() * 100);

  if (!IsPersistent() || ballast != last_ballast) {
    // ballast hase been changed

    canvas.Select(*look.text_font);

    if (IsPersistent())
      canvas.SetBackgroundColor(look.background_color);
    else
      canvas.SetBackgroundTransparent();

    if (IsPersistent() || last_ballast < 1 || ballast < 1) {
      // new ballast is 0, hide label
      if (ballast > 0) {
        canvas.SetTextColor(look.dimmed_text_color);
        // ols ballast was 0, show label
        if (IsPersistent())
          canvas.DrawOpaqueText(label_pos.x, label_pos.y, label_rect, TEXT_BALLAST);
        else
          canvas.DrawText(label_pos.x, label_pos.y, TEXT_BALLAST);
      } else if (IsPersistent())
        canvas.DrawFilledRectangle(label_rect, look.background_color);
    }

    // new ballast 0, hide value
    if (ballast > 0) {
      TCHAR buffer[18];
      _stprintf(buffer, _T("%u%%"), ballast);
      canvas.SetTextColor(look.text_color);

      if (IsPersistent())
        canvas.DrawOpaqueText(value_pos.x, value_pos.y, value_rect, buffer);
      else
        canvas.DrawText(value_pos.x, value_pos.y, buffer);
    } else if (IsPersistent())
      canvas.DrawFilledRectangle(value_rect, look.background_color);

    if (IsPersistent())
      last_ballast = ballast;
  }
}
Example #28
0
// TODO code: Optimise vario rendering, this is slow
void
GaugeVario::RenderValue(Canvas &canvas, int x, int y,
                        DrawInfo *value_info, DrawInfo *label_info,
                        fixed value, const TCHAR *label)
{
  PixelSize tsize;

#ifndef FIXED_MATH
  value = (double)iround(value * 10) / 10; // prevent the -0.0 case
#endif

  if (!value_info->initialised) {

    value_info->rc.right = x - Layout::Scale(5);
    value_info->rc.top = y + Layout::Scale(3)
      + look.text_font->GetCapitalHeight();

    value_info->rc.left = value_info->rc.right;
    // update back rect with max label size
    value_info->rc.bottom = value_info->rc.top + look.value_font->GetCapitalHeight();

    value_info->text_position.x = value_info->rc.left;
    value_info->text_position.y = value_info->rc.top
                         + look.value_font->GetCapitalHeight()
                         - look.value_font->GetAscentHeight();

    value_info->last_value = fixed(-9999);
    value_info->last_text[0] = '\0';
    value_info->last_unit = Unit::UNDEFINED;
    value_info->initialised = true;
  }

  if (!label_info->initialised) {

    label_info->rc.right = x;
    label_info->rc.top = y + Layout::Scale(1);

    label_info->rc.left = label_info->rc.right;
    // update back rect with max label size
    label_info->rc.bottom = label_info->rc.top
      + look.text_font->GetCapitalHeight();

    label_info->text_position.x = label_info->rc.left;
    label_info->text_position.y = label_info->rc.top
      + look.text_font->GetCapitalHeight()
      - look.text_font->GetAscentHeight();

    label_info->last_value = fixed(-9999);
    label_info->last_text[0] = '\0';
    label_info->initialised = true;
  }

  canvas.SetBackgroundTransparent();

  if (!IsPersistent() || (dirty && !StringIsEqual(label_info->last_text, label))) {
    canvas.SetTextColor(look.dimmed_text_color);
    canvas.Select(*look.text_font);
    tsize = canvas.CalcTextSize(label);
    label_info->text_position.x = label_info->rc.right - tsize.cx;

    if (IsPersistent()) {
      canvas.SetBackgroundColor(look.background_color);
      canvas.DrawOpaqueText(label_info->text_position.x, label_info->text_position.y,
                            label_info->rc, label);
      label_info->rc.left = label_info->text_position.x;
      _tcscpy(label_info->last_text, label);
    } else {
      canvas.DrawText(label_info->text_position.x, label_info->text_position.y,
                      label);
    }
  }

  if (!IsPersistent() || (dirty && value_info->last_value != value)) {
    TCHAR buffer[18];
    canvas.SetBackgroundColor(look.background_color);
    canvas.SetTextColor(look.text_color);
    _stprintf(buffer, _T("%.1f"), (double)value);
    canvas.Select(*look.value_font);
    tsize = canvas.CalcTextSize(buffer);
    value_info->text_position.x = value_info->rc.right - tsize.cx;

    if (IsPersistent()) {
      canvas.DrawOpaqueText(value_info->text_position.x,
                            value_info->text_position.y,
                            value_info->rc, buffer);

      value_info->rc.left = value_info->text_position.x;
      value_info->last_value = value;
    } else {
      canvas.DrawText(value_info->text_position.x, value_info->text_position.y,
                      buffer);
    }
  }

  if (!IsPersistent() ||
      value_info->last_unit != Units::current.vertical_speed_unit) {
    value_info->last_unit = Units::current.vertical_speed_unit;
    const UnitSymbol *unit_symbol = units_look.GetSymbol(value_info->last_unit);
    unit_symbol->Draw(canvas, x - Layout::Scale(5), value_info->rc.top,
                      look.background_color, COLOR_GRAY);
  }
}
void
TabDisplay::PaintButton(Canvas &canvas, unsigned CaptionStyle,
                        const TCHAR *caption, const PixelRect &rc,
                        const Bitmap *bmp, const bool isDown, bool inverse)
{
  PixelRect rcTextFinal = rc;
  const UPixelScalar buttonheight = rc.bottom - rc.top;
  const PixelSize text_size = canvas.CalcTextSize(caption);
  const int textwidth = text_size.cx;
  const int textheight = text_size.cy;
  UPixelScalar textheightoffset = 0;

  if (textwidth > (rc.right - rc.left)) // assume 2 lines
    textheightoffset = std::max(0, (int)(buttonheight - textheight * 2) / 2);
  else
    textheightoffset = std::max(0, (int)(buttonheight - textheight) / 2);

  rcTextFinal.top += textheightoffset;

  canvas.DrawFilledRectangle(rc, canvas.GetBackgroundColor());

  if (bmp != nullptr) {
    const PixelSize bitmap_size = bmp->GetSize();
    const int offsetx = (rc.right - rc.left - bitmap_size.cx / 2) / 2;
    const int offsety = (rc.bottom - rc.top - bitmap_size.cy) / 2;

#ifdef ENABLE_OPENGL

    if (inverse) {
      OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);

      /* invert the texture color */
      OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_REPLACE);
      OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_RGB, GL_TEXTURE);
      OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_ONE_MINUS_SRC_COLOR);

      /* copy the texture alpha */
      OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
      OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_TEXTURE);
      OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA);
    } else
      /* simple copy */
      OpenGL::glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);

    const GLEnable scope(GL_TEXTURE_2D);
    const GLBlend blend(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    GLTexture &texture = *bmp->GetNative();
    texture.Bind();
    texture.Draw(rc.left + offsetx, rc.top + offsety);

#else
    if (inverse) // black background
      canvas.CopyNotOr(rc.left + offsetx,
                       rc.top + offsety,
                       bitmap_size.cx / 2,
                       bitmap_size.cy,
                       *bmp,
                       bitmap_size.cx / 2, 0);

    else
      canvas.CopyAnd(rc.left + offsetx,
                      rc.top + offsety,
                      bitmap_size.cx / 2,
                      bitmap_size.cy,
                      *bmp,
                      bitmap_size.cx / 2, 0);
#endif

  } else {
#ifndef USE_GDI
    if (IsDithered())
      CaptionStyle |= DT_UNDERLINE;
#endif

    canvas.DrawFormattedText(&rcTextFinal, caption, CaptionStyle);
  }
}
Example #30
0
void
VarioBarRenderer::Draw(Canvas &canvas, const PixelRect &rc,
                            const MoreData &basic,
                            const DerivedInfo &calculated,
                            const GlidePolar &glide_polar,
                            const bool vario_bar_avg_enabled) const
{
#ifdef ENABLE_OPENGL
  const ScopeAlphaBlend alpha_blend;
#endif

  RasterPoint VarioBar[6] = {
      { 0, 0 }, { 9, -9 }, { 18, 0 }, { 18, 0 }, { 9, 0 }, { 0, 0 }
  };
  RasterPoint VarioBarAvg[4] = {
      { 0, 0 }, { 9, -9 }, { 9, 0 }, { 0, 0 }
  };
  RasterPoint clipping_arrow[6] = {
      { 0, 0 }, { 9, 9 }, { 18, 0 }, { 18, 6 }, { 9, 15 }, { 0, 6 }
  };
  RasterPoint clipping_arrow_av[4] = {
      { 0, 0 }, { 9, 9 }, { 9, 15 }, { 0, 6 }
  };
  RasterPoint mc_arrow[6] = {
      { 0, 0 }, { 9, -9 }, { 18, 0 }, { 18, -2 }, { 9, -11 }, { 0, -2 }
  };

  TCHAR Value[10];

  const int y0 = (rc.bottom + rc.top) / 2;

  /* NOTE: size_divisor replaces the fixed value 9 that was used throughout
   * the code sink which caused fixed size rendering regardless of
   * map size (except the effects of Layout::Scale()). This method
   * is not usable with variable map sizes (e.g. because of the cross-section
   * area). size_divisor is used to introduce a screen size dependent scaling.
   * That workaround is an ugly hack and needs a rework. */
  const auto size_divisor =
    std::max((fixed) Layout::Scale(70 / (rc.bottom - rc.top)), fixed(0.15));

  PixelScalar dy_variobar = 0;
  PixelScalar dy_variobar_av = 0;
  PixelScalar dy_variobar_mc = 0;

  PixelScalar clipping_arrow_offset = Layout::Scale(4);
  PixelScalar clipping_arrow_av_offset = Layout::Scale(4);
//  PixelScalar clipping_arrow_mc_offset = Layout::Scale(4);

  auto vario_gross = basic.brutto_vario;

  FormatUserVerticalSpeed(vario_gross, Value, false, true);
  canvas.Select(*look.font);
  const PixelSize text_size = canvas.CalcTextSize(Value);

  auto vario_avg = calculated.average;

  // cut vario_gross at +- 5 meters/s
  if (vario_gross > fixed(5))
    vario_gross = fixed(5);
  if (vario_gross < fixed(-5))
    vario_gross = fixed(-5);

  int Offset = (int)(vario_gross / size_divisor);

  Offset = Layout::Scale(Offset);
  if (!positive(vario_gross)) {
    VarioBar[1].y = Layout::Scale(9);
    dy_variobar = text_size.cy + 2;
  } else {
    VarioBar[1].y = -Layout::Scale(9);
    clipping_arrow[1].y = -clipping_arrow[1].y;
    clipping_arrow[3].y = -clipping_arrow[3].y;
    clipping_arrow[4].y = -clipping_arrow[4].y;
    clipping_arrow[5].y = -clipping_arrow[5].y;
    clipping_arrow_offset = -clipping_arrow_offset;
    dy_variobar = -1;
  }

  // cut vario_avg at +- 5 meters/s
  if (vario_avg > fixed(5))
    vario_avg = fixed(5);
  if (vario_avg < fixed(-5))
    vario_avg = fixed(-5);

  int OffsetAvg = int(vario_avg / size_divisor);

  OffsetAvg = Layout::Scale(OffsetAvg);
  if (!positive(vario_avg)) {
    VarioBarAvg[1].y = Layout::Scale(9);
    dy_variobar_av = text_size.cy + 2;
  } else {
    VarioBarAvg[1].y = -Layout::Scale(9);
    clipping_arrow_av[1].y = -clipping_arrow_av[1].y;
    clipping_arrow_av[2].y = -clipping_arrow_av[2].y;
    clipping_arrow_av[3].y = -clipping_arrow_av[3].y;
    clipping_arrow_av_offset = -clipping_arrow_av_offset;
    dy_variobar_av = -1;
  }


  //clip MC Value
  auto mc_val = glide_polar.GetMC();
  if (mc_val > fixed(5))
    mc_val = fixed(5);
  if (!positive(mc_val)) {
    dy_variobar_mc = text_size.cy + 2;
  }else{
    dy_variobar_mc = -1;
  }

  int OffsetMC = int(mc_val / size_divisor);
  OffsetMC = Layout::Scale(OffsetMC);

  for (unsigned i = 0; i < 6; i++) {
    VarioBar[i].y += y0 + dy_variobar;
    VarioBar[i].x = rc.right - Layout::Scale(VarioBar[i].x);
  }

  VarioBar[0].y -= Offset;
  VarioBar[1].y -= Offset;
  VarioBar[2].y -= Offset;

  for (unsigned i = 0; i < 4; i++) {
    VarioBarAvg[i].y += y0 + dy_variobar_av;
    VarioBarAvg[i].x = rc.right-Layout::Scale(VarioBarAvg[i].x);
  }

  VarioBarAvg[0].y -= OffsetAvg;
  VarioBarAvg[1].y -= OffsetAvg;

  // prepare mc arrow
  for (unsigned i = 0; i < 6; i++) {
    mc_arrow[i].y = Layout::Scale(mc_arrow[i].y) + y0
      - OffsetMC + dy_variobar_mc;
    mc_arrow[i].x = rc.right - Layout::Scale(mc_arrow[i].x);
  }

  // prepare clipping arrow
  for (unsigned i = 0; i < 6; i++) {
    clipping_arrow[i].y = Layout::Scale(clipping_arrow[i].y) + y0 - Offset
      + clipping_arrow_offset + dy_variobar;
    clipping_arrow[i].x = rc.right - Layout::Scale(clipping_arrow[i].x);
  }

  // prepare clipping avg
  for (unsigned i = 0; i < 4; i++) {
    clipping_arrow_av[i].y = Layout::Scale(clipping_arrow_av[i].y) + y0 - OffsetAvg
      + clipping_arrow_av_offset + dy_variobar_av;
    clipping_arrow_av[i].x = rc.right-Layout::Scale(clipping_arrow_av[i].x);
  }

  // draw actual vario bar
  if (!positive(vario_gross)) {
    canvas.Select(look.pen_sink);
    canvas.Select(look.brush_sink);
  } else {
    canvas.Select(look.pen_climb);
    canvas.Select(look.brush_climb);
  }

  canvas.DrawPolygon(VarioBar, 6);

  // draw clipping arrow
  if (vario_gross <= fixed(-5) || vario_gross >= fixed(5))
    canvas.DrawPolygon(clipping_arrow, 6);

  // draw avg vario bar
  if (!positive(vario_avg) && vario_bar_avg_enabled) {
      canvas.Select(look.pen_sink);
      canvas.Select(look.brush_sink_avg);
  } else {
    canvas.Select(look.pen_climb);
    canvas.Select(look.brush_climb_avg);
  }

  canvas.DrawPolygon(VarioBarAvg, 4);

  if (vario_avg <= fixed(-5.0) || vario_avg >= fixed(5.0))
      canvas.DrawPolygon(clipping_arrow_av, 4);

  //draw MC arrow
  canvas.Select(look.pen_mc);
  canvas.Select(look.brush_mc);

  canvas.DrawPolygon(mc_arrow, 6);

  //draw text
  canvas.SetTextColor(COLOR_BLACK);
  canvas.SetBackgroundColor(COLOR_WHITE);

  TextInBoxMode style;
  style.shape = LabelShape::ROUNDED_BLACK;
  style.move_in_view = true;

  if (text_size.cx < Layout::Scale(18)) {
    style.align = TextInBoxMode::Alignment::RIGHT;
    TextInBox(canvas, Value, rc.right, y0, style, rc);
  } else
    TextInBox(canvas, Value, rc.right-Layout::Scale(18), y0, style, rc);
}