Exemple #1
0
void
ButtonFrameRenderer::DrawButton(Canvas &canvas, PixelRect rc,
                                bool focused, bool pressed) const
{
  const ButtonLook::StateLook &_look = focused ? look.focused : look.standard;

  canvas.DrawFilledRectangle(rc, _look.background_color);

  const unsigned margin = GetMargin();

  if (margin < 4) {
    /* draw 1-pixel lines */

    canvas.Select(pressed ? _look.dark_border_pen : _look.light_border_pen);
    for (unsigned i = 0; i < margin; ++i)
      canvas.DrawTwoLinesExact(rc.left + i, rc.bottom - 2 - i,
                               rc.left + i, rc.top + i,
                               rc.right - 2 - i, rc.top + i);

    canvas.Select(pressed ? _look.light_border_pen : _look.dark_border_pen);
    for (unsigned i = 0; i < margin; ++i)
      canvas.DrawTwoLinesExact(rc.left + 1 + i, rc.bottom - 1 - i,
                               rc.right - 1 - i, rc.bottom - 1 - i,
                               rc.right - 1 - i, rc.top + 1 + i);
  } else {
    /* at 4 pixels or more, it's more efficient to draw a filled
       polygon */

    const RasterPoint p1[] = {
      RasterPoint(rc.left, rc.top),
      RasterPoint(rc.right, rc.top),
      RasterPoint(rc.right - margin, rc.top + margin),
      RasterPoint(rc.left + margin, rc.top + margin),
      RasterPoint(rc.left + margin, rc.bottom - margin),
      RasterPoint(rc.left, rc.bottom),
    };

    canvas.SelectNullPen();
    canvas.Select(pressed
                  ? _look.dark_border_brush
                  : _look.light_border_brush);
    canvas.DrawTriangleFan(p1, ARRAY_SIZE(p1));

    const RasterPoint p2[] = {
      RasterPoint(rc.right, rc.bottom),
      RasterPoint(rc.right, rc.top),
      RasterPoint(rc.right - margin, rc.top + margin),
      RasterPoint(rc.right - margin, rc.bottom - margin),
      RasterPoint(rc.left + margin, rc.bottom - margin),
      RasterPoint(rc.left, rc.bottom),
    };

    canvas.Select(pressed
                  ? _look.light_border_brush
                  : _look.dark_border_brush);
    canvas.DrawTriangleFan(p2, ARRAY_SIZE(p2));
}
}
Exemple #2
0
void
SymbolRenderer::DrawArrow(Canvas &canvas, PixelRect rc, Direction direction)
{
  assert(direction == UP || direction == DOWN ||
         direction == LEFT || direction == RIGHT);

  PixelScalar size = std::min(rc.right - rc.left, rc.bottom - rc.top) / 5;
  RasterPoint center = rc.GetCenter();
  RasterPoint arrow[3];

  if (direction == LEFT || direction == RIGHT) {
    arrow[0].x = center.x + (direction == LEFT ? size : -size);
    arrow[0].y = center.y + size;
    arrow[1].x = center.x + (direction == LEFT ? -size : size);
    arrow[1].y = center.y;
    arrow[2].x = center.x + (direction == LEFT ? size : -size);
    arrow[2].y = center.y - size;
  } else if (direction == UP || direction == DOWN) {
    arrow[0].x = center.x + size;
    arrow[0].y = center.y + (direction == UP ? size : -size);
    arrow[1].x = center.x;
    arrow[1].y = center.y + (direction == UP ? -size : size);
    arrow[2].x = center.x - size;
    arrow[2].y = center.y + (direction == UP ? size : -size);
  }

  canvas.DrawTriangleFan(arrow, 3);
}
Exemple #3
0
bool
Segment(Canvas &canvas, PixelScalar x, PixelScalar y, UPixelScalar radius,
        Angle start, Angle end, bool horizon)
{
  // dont draw if out of view
  PixelRect rc, bounds;
  SetRect(&rc, 0, 0, canvas.get_width(), canvas.get_height());
  SetRect(&bounds, x - radius, y - radius, x + radius, y + radius);
  if (!IntersectRect(&bounds, &bounds, &rc))
    return false;

  const int istart = NATIVE_TO_INT(start.Native());
  const int iend = NATIVE_TO_INT(end.Native());

  int npoly = 0;
  RasterPoint pt[66];

  // add center point
  if (!horizon) {
    pt[0].x = x;
    pt[0].y = y;
    npoly = 1;
  }

  segment_poly(pt, x, y, radius, istart, iend, npoly);

  assert(npoly <= 66);
  if (npoly)
    canvas.DrawTriangleFan(pt, npoly);

  return true;
}
Exemple #4
0
void
RoundRect(Canvas &canvas, int left, int top,
          int right, int bottom, unsigned radius)
{
  unsigned npoly = 0;
  BulkPixelPoint pt[66*4];

  segment_poly(pt, PixelPoint(left + radius, top + radius), radius,
               INT_ANGLE_RANGE * 3 / 4,
               INT_ANGLE_RANGE - 1,
               npoly);
  segment_poly(pt, PixelPoint(right - radius, top + radius), radius,
               0, INT_ANGLE_RANGE / 4 - 1,
               npoly);
  segment_poly(pt, PixelPoint(right - radius, bottom - radius), radius,
               INT_ANGLE_RANGE / 4,
               INT_ANGLE_RANGE / 2 - 1,
               npoly);
  segment_poly(pt, PixelPoint(left + radius, bottom - radius), radius,
               INT_ANGLE_RANGE / 2,
               INT_ANGLE_RANGE * 3 / 4 - 1,
               npoly);

  assert(npoly <= ARRAY_SIZE(pt));
  if (npoly)
    canvas.DrawTriangleFan(pt, npoly);
}
Exemple #5
0
void
GaugeVario::RenderVarioLine(Canvas &canvas, int i, int sink, bool clear)
{
  dirty = true;
  if (i == sink)
    return;

  canvas.Select(clear
                ? look.thick_background_pen
                : (i > sink ? look.thick_lift_pen : look.thick_sink_pen));

  if (i > sink)
    canvas.DrawPolyline(lines + gmax + sink, i - sink);
  else
    canvas.DrawPolyline(lines + gmax + i, sink - i);

  if (!clear) {
    canvas.SelectNullPen();

    // clear up naked (sink) edge of polygon, this gives it a nice
    // taper look
    if (look.inverse) {
      canvas.SelectBlackBrush();
    } else {
      canvas.SelectWhiteBrush();
    }
    canvas.DrawTriangleFan(getPolygon(sink), 3);
  }
}
Exemple #6
0
void
SymbolRenderer::DrawArrow(Canvas &canvas, PixelRect rc, Direction direction)
{
  assert(direction == UP || direction == DOWN ||
         direction == LEFT || direction == RIGHT);

  auto size = std::min(rc.GetWidth(), rc.GetHeight()) / 5;
  auto center = rc.GetCenter();
  BulkPixelPoint arrow[3];

  if (direction == LEFT || direction == RIGHT) {
    arrow[0].x = center.x + (direction == LEFT ? size : -size);
    arrow[0].y = center.y + size;
    arrow[1].x = center.x + (direction == LEFT ? -size : size);
    arrow[1].y = center.y;
    arrow[2].x = center.x + (direction == LEFT ? size : -size);
    arrow[2].y = center.y - size;
  } else if (direction == UP || direction == DOWN) {
    arrow[0].x = center.x + size;
    arrow[0].y = center.y + (direction == UP ? size : -size);
    arrow[1].x = center.x;
    arrow[1].y = center.y + (direction == UP ? -size : size);
    arrow[2].x = center.x - size;
    arrow[2].y = center.y + (direction == UP ? size : -size);
  }

  canvas.DrawTriangleFan(arrow, 3);
}
static void
DrawLandableRunway(Canvas &canvas, const PixelPoint &pt,
                   const Angle angle, double radius, double width)
{
    if (radius <= 0)
        return;

    const auto sc = angle.SinCos();
    const auto x = sc.first, y = sc.second;
    int lx = iround(2 * x * radius) & ~0x1;  // make it a even number
    int ly = iround(2 * y * radius) & ~0x1;
    int wx = iround(-y * width);
    int wy = iround(x * width);

    BulkPixelPoint runway[4];
    runway[0].x = pt.x        - (lx / 2) + (wx / 2);
    runway[0].y = pt.y        + (ly / 2) - (wy / 2);
    runway[1].x = runway[0].x            - wx;
    runway[1].y = runway[0].y            + wy;
    runway[2].x = runway[1].x + lx;
    runway[2].y = runway[1].y - ly;
    runway[3].x = runway[2].x            + wx;
    runway[3].y = runway[2].y            - wy;
    canvas.DrawTriangleFan(runway, ARRAY_SIZE(runway));
}
Exemple #8
0
bool
Segment(Canvas &canvas, int x, int y, unsigned radius,
        Angle start, Angle end, bool horizon)
{
  // dont draw if out of view
  if (!IsCircleVisible(canvas, x, y, radius))
    return false;

  const int istart = NATIVE_TO_INT(start.Native());
  const int iend = NATIVE_TO_INT(end.Native());

  unsigned npoly = 0;
  RasterPoint pt[67];

  // add center point
  if (!horizon) {
    pt[0].x = x;
    pt[0].y = y;
    npoly = 1;
  }

  segment_poly(pt, x, y, radius, istart, iend, npoly);

  assert(npoly <= ARRAY_SIZE(pt));
  if (npoly)
    canvas.DrawTriangleFan(pt, npoly);

  return true;
}
Exemple #9
0
void
TopWindow::OnPaint(Canvas &canvas)
{
  ContainerWindow::OnPaint(canvas);

  /* draw the mouse cursor */

  const RasterPoint m = event_queue->GetMousePosition();
  const RasterPoint p[] = {
    { m.x, m.y },
    { m.x + Layout::Scale(4), m.y + Layout::Scale(4) },
    { m.x, m.y + Layout::Scale(6) },
  };

  canvas.SelectBlackPen();
  canvas.SelectWhiteBrush();
  canvas.DrawTriangleFan(p, ARRAY_SIZE(p));
}
void
CrossSectionWindow::PaintAircraft(Canvas &canvas, const Chart &chart,
                                  const PixelRect rc)
{
  canvas.Select(look.aircraft_brush);
  canvas.SelectNullPen();

  RasterPoint line[4];
  line[0].x = chart.screenX(fixed_zero);
  line[0].y = chart.screenY(gps_info.nav_altitude);
  line[1].x = rc.left;
  line[1].y = line[0].y;
  line[2].x = line[1].x;
  line[2].y = line[0].y - (line[0].x - line[1].x) / 2;
  line[3].x = (line[1].x + line[0].x) / 2;
  line[3].y = line[0].y;
  canvas.DrawTriangleFan(line, 4);
}
Exemple #11
0
void
GaugeVario::RenderNeedle(Canvas &canvas, int i, bool average, bool clear)
{
  dirty = true;

  canvas.SelectNullPen();

  // legacy behaviour
  if (clear ^ look.inverse) {
    canvas.SelectWhiteBrush();
  } else {
    canvas.SelectBlackBrush();
  }

  if (average)
    canvas.DrawPolyline(getPolygon(i), 3);
  else
    canvas.DrawTriangleFan(getPolygon(i), 3);
}
static void
DrawLandableBase(Canvas &canvas, const PixelPoint &pt, bool airport,
                 const double radius)
{
    int iradius = iround(radius);
    if (airport)
        canvas.DrawCircle(pt.x, pt.y, iradius);
    else {
        BulkPixelPoint diamond[4];
        diamond[0].x = pt.x + 0;
        diamond[0].y = pt.y - iradius;
        diamond[1].x = pt.x + iradius;
        diamond[1].y = pt.y + 0;
        diamond[2].x = pt.x + 0;
        diamond[2].y = pt.y + iradius;
        diamond[3].x = pt.x - iradius;
        diamond[3].y = pt.y - 0;
        canvas.DrawTriangleFan(diamond, ARRAY_SIZE(diamond));
    }
}
Exemple #13
0
void
CrossSectionRenderer::PaintAircraft(Canvas &canvas, const ChartRenderer &chart,
                                    const PixelRect rc) const
{
  if (!gps_info.NavAltitudeAvailable())
    return;

  canvas.Select(look.aircraft_brush);
  canvas.SelectNullPen();

  RasterPoint line[4];
  line[0] = chart.ToScreen(fixed(0), gps_info.nav_altitude);
  line[1].x = rc.left;
  line[1].y = line[0].y;
  line[2].x = line[1].x;
  line[2].y = line[0].y - (line[0].x - line[1].x) / 2;
  line[3].x = (line[1].x + line[0].x) / 2;
  line[3].y = line[0].y;
  canvas.DrawTriangleFan(line, 4);
}
Exemple #14
0
void
GaugeVario::RenderSpeedToFly(Canvas &canvas, int x, int y)
{
  if (!Basic().airspeed_available ||
      !Basic().total_energy_vario_available)
    return;

  static fixed last_v_diff;
  fixed v_diff;

  const unsigned arrow_y_size = Layout::Scale(3);
  const unsigned arrow_x_size = Layout::Scale(7);

  const PixelRect rc = GetClientRect();

  int nary = NARROWS * arrow_y_size;
  int ytop = rc.top + YOFFSET + nary; // JMW
  int ybottom = rc.bottom - YOFFSET - nary - Layout::FastScale(1);

  ytop += Layout::Scale(14);
  ybottom -= Layout::Scale(14);

  x = rc.right - 2 * arrow_x_size;

  // only draw speed command if flying and vario is not circling
  if ((Calculated().flight.flying)
      && (!Basic().gps.simulator || !Calculated().circling)) {
    v_diff = Calculated().V_stf - Basic().indicated_airspeed;
    v_diff = Clamp(v_diff, -DELTA_V_LIMIT, DELTA_V_LIMIT); // limit it
    v_diff = iround(v_diff/DELTA_V_STEP) * DELTA_V_STEP;
  } else
    v_diff = fixed(0);

  if (!IsPersistent() || last_v_diff != v_diff || dirty) {
    last_v_diff = v_diff;

    if (IsPersistent()) {
      // bottom (too slow)
      canvas.DrawFilledRectangle(x, ybottom + YOFFSET,
                                 x + arrow_x_size * 2 + 1,
                                 ybottom + YOFFSET + nary + arrow_y_size +
                                 Layout::FastScale(2),
                                 look.background_color);

      // top (too fast)
      canvas.DrawFilledRectangle(x, ytop - YOFFSET + 1,
                                 x + arrow_x_size * 2  +1,
                                 ytop - YOFFSET - nary + 1 - arrow_y_size -
                                 Layout::FastScale(2),
                                 look.background_color);
    }

    RenderClimb(canvas);

    canvas.SelectNullPen();

    if (look.colors) {
      if (positive(v_diff)) {
        // too slow
        canvas.Select(look.sink_brush);
      } else {
        canvas.Select(look.lift_brush);
      }
    } else {
      if (look.inverse)
        canvas.SelectWhiteBrush();
      else
        canvas.SelectBlackBrush();
    }

    if (positive(v_diff)) {
      // too slow
      y = ybottom;
      y += YOFFSET;

      while (positive(v_diff)) {
        if (v_diff > DELTA_V_STEP) {
          canvas.Rectangle(x, y,
                           x + arrow_x_size * 2 + 1, y + arrow_y_size - 1);
        } else {
          RasterPoint arrow[3];
          arrow[0].x = x;
          arrow[0].y = y;
          arrow[1].x = x + arrow_x_size;
          arrow[1].y = y + arrow_y_size - 1;
          arrow[2].x = x + 2 * arrow_x_size;
          arrow[2].y = y;
          canvas.DrawTriangleFan(arrow, 3);
        }
        v_diff -= DELTA_V_STEP;
        y += arrow_y_size;
      }
    } else if (negative(v_diff)) {
      // too fast
      y = ytop;
      y -= YOFFSET;

      while (negative(v_diff)) {
        if (v_diff < -DELTA_V_STEP) {
          canvas.Rectangle(x, y + 1,
                           x + arrow_x_size * 2 + 1, y - arrow_y_size + 2);
        } else {
          RasterPoint arrow[3];
          arrow[0].x = x;
          arrow[0].y = y;
          arrow[1].x = x + arrow_x_size;
          arrow[1].y = y - arrow_y_size + 1;
          arrow[2].x = x + 2 * arrow_x_size;
          arrow[2].y = y;
          canvas.DrawTriangleFan(arrow, 3);
        }
        v_diff += DELTA_V_STEP;
        y -= arrow_y_size;
      }
    }
  }
}
Exemple #15
0
void
GaugeVario::RenderSpeedToFly(Canvas &canvas, PixelScalar x, PixelScalar y)
{
    if (!Basic().airspeed_available ||
            !Basic().total_energy_vario_available)
        return;

    static fixed lastVdiff;
    fixed vdiff;

    const UPixelScalar arrow_y_size = Layout::Scale(3);
    const UPixelScalar arrow_x_size = Layout::Scale(7);

    const PixelRect rc = get_client_rect();

    PixelScalar nary = NARROWS * arrow_y_size;
    PixelScalar ytop = rc.top + YOFFSET + nary; // JMW
    PixelScalar ybottom = rc.bottom - YOFFSET - nary - Layout::FastScale(1);

    ytop += Layout::Scale(14);
    ybottom -= Layout::Scale(14);

    x = rc.right - 2 * arrow_x_size;

    // only draw speed command if flying and vario is not circling
    if ((Calculated().flight.flying)
            && (!Basic().gps.simulator || !Calculated().circling)) {
        vdiff = Calculated().V_stf - Basic().indicated_airspeed;
        vdiff = max(-DeltaVlimit, min(DeltaVlimit, vdiff)); // limit it
        vdiff = iround(vdiff/DeltaVstep) * DeltaVstep;
    } else
        vdiff = fixed_zero;

    if (!is_persistent() || lastVdiff != vdiff || dirty) {
        lastVdiff = vdiff;

        if (is_persistent()) {
            // bottom (too slow)
            canvas.DrawFilledRectangle(x, ybottom + YOFFSET,
                                       x + arrow_x_size * 2 + 1,
                                       ybottom + YOFFSET + nary + arrow_y_size +
                                       Layout::FastScale(2),
                                       look.background_color);

            // top (too fast)
            canvas.DrawFilledRectangle(x, ytop - YOFFSET + 1,
                                       x + arrow_x_size * 2  +1,
                                       ytop - YOFFSET - nary + 1 - arrow_y_size -
                                       Layout::FastScale(2),
                                       look.background_color);
        }

        RenderClimb(canvas);

        canvas.SelectNullPen();

        if (look.colors) {
            if (positive(vdiff)) {
                // too slow
                canvas.Select(look.sink_brush);
            } else {
                canvas.Select(look.lift_brush);
            }
        } else {
            if (look.inverse)
                canvas.SelectWhiteBrush();
            else
                canvas.SelectBlackBrush();
        }

        if (positive(vdiff)) {
            // too slow
            y = ybottom;
            y += YOFFSET;

            while (positive(vdiff)) {
                if (vdiff > DeltaVstep) {
                    canvas.Rectangle(x, y,
                                     x + arrow_x_size * 2 + 1, y + arrow_y_size - 1);
                } else {
                    RasterPoint arrow[3];
                    arrow[0].x = x;
                    arrow[0].y = y;
                    arrow[1].x = x + arrow_x_size;
                    arrow[1].y = y + arrow_y_size - 1;
                    arrow[2].x = x + 2 * arrow_x_size;
                    arrow[2].y = y;
                    canvas.DrawTriangleFan(arrow, 3);
                }
                vdiff -= DeltaVstep;
                y += arrow_y_size;
            }
        } else if (negative(vdiff)) {
            // too fast
            y = ytop;
            y -= YOFFSET;

            while (negative(vdiff)) {
                if (vdiff < -DeltaVstep) {
                    canvas.Rectangle(x, y + 1,
                                     x + arrow_x_size * 2 + 1, y - arrow_y_size + 2);
                } else {
                    RasterPoint arrow[3];
                    arrow[0].x = x;
                    arrow[0].y = y;
                    arrow[1].x = x + arrow_x_size;
                    arrow[1].y = y - arrow_y_size + 1;
                    arrow[2].x = x + 2 * arrow_x_size;
                    arrow[2].y = y;
                    canvas.DrawTriangleFan(arrow, 3);
                }
                vdiff += DeltaVstep;
                y -= arrow_y_size;
            }
        }
    }
}
Exemple #16
0
void
ScrollBar::Paint(Canvas &canvas) const
{
  // ###################
  // #### ScrollBar ####
  // ###################

  // draw rectangle around entire scrollbar area
  canvas.SelectBlackPen();
  canvas.SelectHollowBrush();
  canvas.Rectangle(rc.left, rc.top, rc.right, rc.bottom);

  // ###################
  // ####  Buttons  ####
  // ###################

  const int arrow_padding = std::max(GetWidth() / 4, 4);

  PixelRect up_arrow_rect = rc;
  ++up_arrow_rect.left;
  up_arrow_rect.bottom = up_arrow_rect.top + GetWidth();

  PixelRect down_arrow_rect = rc;
  ++down_arrow_rect.left;
  down_arrow_rect.top = down_arrow_rect.bottom - GetWidth();

  canvas.DrawExactLine(up_arrow_rect.left, up_arrow_rect.bottom,
                       up_arrow_rect.right, up_arrow_rect.bottom);
  canvas.DrawExactLine(down_arrow_rect.left, down_arrow_rect.top - 1,
                       down_arrow_rect.right, down_arrow_rect.top - 1);

  button_renderer.DrawButton(canvas, up_arrow_rect, false, false);
  button_renderer.DrawButton(canvas, down_arrow_rect, false, false);

  canvas.SelectNullPen();
  canvas.SelectBlackBrush();

  const RasterPoint up_arrow[3] = {
    { (up_arrow_rect.left + rc.right) / 2,
      up_arrow_rect.top + arrow_padding },
    { up_arrow_rect.left + arrow_padding,
      up_arrow_rect.bottom - arrow_padding },
    { rc.right - arrow_padding,
      up_arrow_rect.bottom - arrow_padding },
  };
  canvas.DrawTriangleFan(up_arrow, ARRAY_SIZE(up_arrow));

  const RasterPoint down_arrow[3] = {
    { (down_arrow_rect.left + rc.right) / 2,
      down_arrow_rect.bottom - arrow_padding },
    { down_arrow_rect.left + arrow_padding,
      down_arrow_rect.top + arrow_padding },
    { rc.right - arrow_padding,
      down_arrow_rect.top + arrow_padding },
  };
  canvas.DrawTriangleFan(down_arrow, ARRAY_SIZE(down_arrow));

  // ###################
  // ####  Slider   ####
  // ###################

  if (rc_slider.top + 4 < rc_slider.bottom) {
    canvas.SelectBlackPen();
    canvas.DrawExactLine(rc_slider.left, rc_slider.top,
                         rc_slider.right, rc_slider.top);
    canvas.DrawExactLine(rc_slider.left, rc_slider.bottom,
                         rc_slider.right, rc_slider.bottom);

    PixelRect rc_slider2 = rc_slider;
    ++rc_slider2.left;
    ++rc_slider2.top;
    button_renderer.DrawButton(canvas, rc_slider2, dragging, dragging);
  }

  // fill the rest with darker gray
  const Color background_color = IsDithered() ? COLOR_BLACK : COLOR_GRAY;

  if (up_arrow_rect.bottom + 1 < rc_slider.top)
    canvas.DrawFilledRectangle(rc.left + 1, up_arrow_rect.bottom + 1,
                               rc.right, rc_slider.top,
                               background_color);

  if (rc_slider.bottom + 1 < down_arrow_rect.top - 1)
    canvas.DrawFilledRectangle(rc.left + 1, rc_slider.bottom + 1,
                               rc.right, down_arrow_rect.top - 1,
                               background_color);
}
/**
 * Paints the traffic symbols on the given canvas
 * @param canvas The canvas to paint on
 */
void
FlarmTrafficWindow::PaintRadarTarget(Canvas &canvas,
                                     const FlarmTraffic &traffic,
                                     unsigned i)
{
  // Save relative East/North
  fixed x = traffic.relative_east;
  fixed y = -traffic.relative_north;

  // Calculate the distance in pixels
  fixed scale = RangeScale(traffic.distance);

  // Don't display distracting, far away targets in WarningMode
  if (WarningMode() && !traffic.HasAlarm() && scale == fixed(radius))
    return;

  // x and y are not between 0 and 1 (distance will be handled via scale)
  if (!traffic.distance.IsZero()) {
    x /= traffic.distance;
    y /= traffic.distance;
  } else {
    x = fixed_zero;
    y = fixed_zero;
  }

  if (!enable_north_up) {
    // Rotate x and y to have a track up display
    FastRotation::Pair p = fr.Rotate(x, y);
    x = fixed(p.first);
    y = fixed(p.second);
  }

  // Calculate screen coordinates
  sc[i].x = radar_mid.x + iround(x * scale);
  sc[i].y = radar_mid.y + iround(y * scale);

  const Color *text_color;
  const Pen *target_pen, *circle_pen;
  const Brush *target_brush, *arrow_brush;
  bool hollow_brush = false;
  unsigned circles = 0;

  // Set the arrow color depending on alarm level
  switch (traffic.alarm_level) {
  case FlarmTraffic::AlarmType::LOW:
    text_color = &look.default_color;
    target_pen = circle_pen = &look.warning_pen;
    target_brush = &look.warning_brush;
    arrow_brush = &look.default_brush;
    circles = 1;
    break;
  case FlarmTraffic::AlarmType::IMPORTANT:
  case FlarmTraffic::AlarmType::URGENT:
    text_color = &look.default_color;
    target_pen = circle_pen = &look.alarm_pen;
    target_brush = &look.alarm_brush;
    arrow_brush = &look.default_brush;
    circles = 2;
    break;
  case FlarmTraffic::AlarmType::NONE:
    if (WarningMode()) {
      text_color = &look.passive_color;
      target_pen = &look.passive_pen;
      arrow_brush = &look.passive_brush;
      hollow_brush = true;
    } else {
      // Search for team color
      FlarmFriends::Color team_color = FlarmFriends::GetFriendColor(traffic.id);

      // If no color found but target is teammate
      if (team_color == FlarmFriends::NONE &&
          settings.team_flarm_tracking &&
          traffic.id == settings.team_flarm_id)
        // .. use yellow color
        team_color = FlarmFriends::GREEN;

      // If team color found -> draw a colored circle around the target
      if (team_color != FlarmFriends::NONE) {
        switch (team_color) {
        case FlarmFriends::GREEN:
          circle_pen = &look.team_pen_green;
          break;
        case FlarmFriends::BLUE:
          circle_pen = &look.team_pen_blue;
          break;
        case FlarmFriends::YELLOW:
          circle_pen = &look.team_pen_yellow;
          break;
        case FlarmFriends::MAGENTA:
          circle_pen = &look.team_pen_magenta;
          break;
        default:
          break;
        }

        circles = 1;
      }

      if (!small && static_cast<unsigned> (selection) == i) {
        text_color = &look.selection_color;
        target_brush = arrow_brush = &look.selection_brush;
        target_pen = &look.selection_pen;
      } else {
        hollow_brush = true;
        if (traffic.IsPassive()) {
          text_color = &look.passive_color;
          target_pen = &look.passive_pen;
          arrow_brush = &look.passive_brush;
        } else {
          text_color = &look.default_color;
          target_pen = &look.default_pen;
          arrow_brush = &look.default_brush;
        }
      }
    }
    break;
  }

  if (circles > 0) {
    canvas.SelectHollowBrush();
    canvas.Select(*circle_pen);
    canvas.circle(sc[i].x, sc[i].y, Layout::FastScale(small ? 8 : 16));
    if (circles == 2)
      canvas.circle(sc[i].x, sc[i].y, Layout::FastScale(small ? 10 : 19));
  }

  // Create an arrow polygon
  RasterPoint Arrow[5];
  if (small) {
    Arrow[0].x = -3;
    Arrow[0].y = 4;
    Arrow[1].x = 0;
    Arrow[1].y = -5;
    Arrow[2].x = 3;
    Arrow[2].y = 4;
    Arrow[3].x = 0;
    Arrow[3].y = 2;
    Arrow[4].x = -3;
    Arrow[4].y = 4;
  } else {
    Arrow[0].x = -6;
    Arrow[0].y = 8;
    Arrow[1].x = 0;
    Arrow[1].y = -10;
    Arrow[2].x = 6;
    Arrow[2].y = 8;
    Arrow[3].x = 0;
    Arrow[3].y = 5;
    Arrow[4].x = -6;
    Arrow[4].y = 8;
  }

  // Rotate and shift the arrow
  PolygonRotateShift(Arrow, 5, sc[i].x, sc[i].y,
                     traffic.track - (enable_north_up ?
                                             Angle::Zero() : heading));

  // Select pen and brush
  canvas.Select(*target_pen);
  if (hollow_brush)
    canvas.SelectHollowBrush();
  else
    canvas.Select(*target_brush);

  // Draw the polygon
  canvas.polygon(Arrow, 5);

  if (small) {
    if (WarningMode() && !traffic.HasAlarm())
      return;

    const short relalt =
        iround(Units::ToUserAltitude(traffic.relative_altitude) / 100);

    // if (relative altitude is other than zero)
    if (relalt == 0)
      return;

    // Write the relativ altitude devided by 100 to the Buffer
    StaticString<10> buffer;
    buffer.Format(_T("%d"), abs(relalt));

    // Select font
    canvas.SetBackgroundTransparent();
    canvas.Select(look.side_info_font);
    canvas.SetTextColor(*text_color);

    // Calculate size of the output string
    PixelSize tsize = canvas.CalcTextSize(buffer);

    UPixelScalar dist = Layout::FastScale(traffic.HasAlarm() ? 12 : 8);

    // Draw string
    canvas.text(sc[i].x + dist, sc[i].y - tsize.cy / 2, buffer);

    // Set target_brush for the up/down arrow
    canvas.Select(*arrow_brush);
    canvas.SelectNullPen();

    // Prepare the triangular polygon
    RasterPoint triangle[4];
    triangle[0].x = 0;
    triangle[0].y = -4;
    triangle[1].x = 3;
    triangle[1].y = 0;
    triangle[2].x = -3;
    triangle[2].y = 0;

    // Flip = -1 for arrow pointing downwards
    short flip = 1;
    if (relalt < 0)
      flip = -1;

    // Shift the arrow to the right position
    for (int j = 0; j < 3; j++) {
      triangle[j].x = Layout::FastScale(triangle[j].x);
      triangle[j].y = Layout::FastScale(triangle[j].y);

      triangle[j].x = sc[i].x + dist + triangle[j].x + tsize.cx / 2;
      triangle[j].y = sc[i].y + flip * (triangle[j].y  - tsize.cy / 2);
    }
    triangle[3].x = triangle[0].x;
    triangle[3].y = triangle[0].y;

    // Draw the arrow
    canvas.DrawTriangleFan(triangle, 4);

    return;
  }

  // if warning exists -> don't draw vertical speeds
  if (WarningMode())
    return;

  // if vertical speed to small or negative -> skip this one
  if (side_display_type == 1 &&
      (!traffic.climb_rate_avg30s_available ||
       traffic.climb_rate_avg30s < fixed(0.5) ||
       traffic.IsPowered()))
      return;

  // Select font
  canvas.SetBackgroundTransparent();
  canvas.Select(look.side_info_font);

  // Format string
  TCHAR tmp[10];

  if (side_display_type == 1)
    FormatUserVerticalSpeed(traffic.climb_rate_avg30s, tmp, false);
  else
    FormatRelativeUserAltitude(traffic.relative_altitude, tmp, true);

  PixelSize sz = canvas.CalcTextSize(tmp);

  // Draw vertical speed shadow
  canvas.SetTextColor(COLOR_WHITE);
  canvas.text(sc[i].x + Layout::FastScale(11) + 1,
              sc[i].y - sz.cy / 2 + 1, tmp);
  canvas.text(sc[i].x + Layout::FastScale(11) - 1,
              sc[i].y - sz.cy / 2 - 1, tmp);

  // Select color
  canvas.SetTextColor(*text_color);

  // Draw vertical speed
  canvas.text(sc[i].x + Layout::FastScale(11), sc[i].y - sz.cy / 2, tmp);
}
Exemple #18
0
void
FlarmTrafficWindow::PaintTargetInfoSmall(
    Canvas &canvas, const FlarmTraffic &traffic, unsigned i,
    const Color &text_color, const Brush &arrow_brush)
{
  const short relalt =
      iround(Units::ToUserAltitude(traffic.relative_altitude) / 100);

  // if (relative altitude is other than zero)
  if (relalt == 0)
    return;

  // Write the relativ altitude devided by 100 to the Buffer
  StaticString<10> buffer;
  buffer.Format(_T("%d"), abs(relalt));

  // Select font
  canvas.SetBackgroundTransparent();
  canvas.Select(look.side_info_font);
  canvas.SetTextColor(text_color);

  // Calculate size of the output string
  PixelSize tsize = canvas.CalcTextSize(buffer);

  UPixelScalar dist = Layout::FastScale(traffic.HasAlarm() ? 12 : 8);

  // Draw string
  canvas.DrawText(sc[i].x + dist, sc[i].y - tsize.cy / 2, buffer);

  // Set target_brush for the up/down arrow
  canvas.Select(arrow_brush);
  canvas.SelectNullPen();

  // Prepare the triangular polygon
  RasterPoint triangle[4];
  triangle[0].x = 0;
  triangle[0].y = -4;
  triangle[1].x = 3;
  triangle[1].y = 0;
  triangle[2].x = -3;
  triangle[2].y = 0;

  // Flip = -1 for arrow pointing downwards
  short flip = 1;
  if (relalt < 0)
    flip = -1;

  // Shift the arrow to the right position
  for (int j = 0; j < 3; j++) {
    triangle[j].x = Layout::FastScale(triangle[j].x);
    triangle[j].y = Layout::FastScale(triangle[j].y);

    triangle[j].x = sc[i].x + dist + triangle[j].x + tsize.cx / 2;
    triangle[j].y = sc[i].y + flip * (triangle[j].y  - tsize.cy / 2);
  }
  triangle[3].x = triangle[0].x;
  triangle[3].y = triangle[0].y;

  // Draw the arrow
  canvas.DrawTriangleFan(triangle, 4);

}
Exemple #19
0
void
ScrollBar::Paint(Canvas &canvas) const
{
  // Prepare Pen
  canvas.SelectBlackPen();

  // ###################
  // #### ScrollBar ####
  // ###################

  // draw rectangle around entire scrollbar area
  canvas.DrawTwoLines(rc.left, rc.top, rc.left, rc.bottom,
                   rc.right, rc.bottom);
  canvas.DrawTwoLines(rc.right, rc.bottom, rc.right, rc.top,
                   rc.left, rc.top);

  // ###################
  // ####  Buttons  ####
  // ###################

  UPixelScalar arrow_padding = max(UPixelScalar(GetWidth() / 4),
                                   UPixelScalar(4));
  canvas.SelectBlackBrush();

  PixelRect up_arrow_rect = rc;
  ++up_arrow_rect.left;
  up_arrow_rect.bottom = up_arrow_rect.top + GetWidth();
  canvas.DrawLine(up_arrow_rect.left, up_arrow_rect.bottom,
              up_arrow_rect.right, up_arrow_rect.bottom);
  canvas.DrawButton(up_arrow_rect, false);

  RasterPoint up_arrow[3] = {
    { PixelScalar((up_arrow_rect.left + rc.right) / 2),
      PixelScalar(up_arrow_rect.top + arrow_padding) },
    { PixelScalar(up_arrow_rect.left + arrow_padding),
      PixelScalar(up_arrow_rect.bottom - arrow_padding) },
    { PixelScalar(rc.right - arrow_padding),
      PixelScalar(up_arrow_rect.bottom - arrow_padding) },
  };
  canvas.DrawTriangleFan(up_arrow, ARRAY_SIZE(up_arrow));

  PixelRect down_arrow_rect = rc;
  ++down_arrow_rect.left;
  down_arrow_rect.top = down_arrow_rect.bottom - GetWidth();
  canvas.DrawLine(down_arrow_rect.left, down_arrow_rect.top - 1,
              down_arrow_rect.right, down_arrow_rect.top - 1);
  canvas.DrawButton(down_arrow_rect, false);

  RasterPoint down_arrow[3] = {
    { PixelScalar((down_arrow_rect.left + rc.right) / 2),
      PixelScalar(down_arrow_rect.bottom - arrow_padding) },
    { PixelScalar(down_arrow_rect.left + arrow_padding),
      PixelScalar(down_arrow_rect.top + arrow_padding) },
    { PixelScalar(rc.right - arrow_padding),
      PixelScalar(down_arrow_rect.top + arrow_padding) },
  };
  canvas.DrawTriangleFan(down_arrow, ARRAY_SIZE(down_arrow));

  // ###################
  // ####  Slider   ####
  // ###################

  if (rc_slider.top + 4 < rc_slider.bottom) {
    canvas.DrawLine(rc_slider.left, rc_slider.top,
                rc_slider.right, rc_slider.top);
    canvas.DrawLine(rc_slider.left, rc_slider.bottom,
                rc_slider.right, rc_slider.bottom);

    PixelRect rc_slider2 = rc_slider;
    ++rc_slider2.left;
    ++rc_slider2.top;
    canvas.DrawButton(rc_slider2, false);
  }

  // fill the rest with darker gray
  if (up_arrow_rect.bottom + 1 < rc_slider.top)
    canvas.DrawFilledRectangle(rc.left + 1, up_arrow_rect.bottom + 1,
                               rc.right, rc_slider.top, COLOR_GRAY);

  if (rc_slider.bottom < down_arrow_rect.top)
    canvas.DrawFilledRectangle(rc.left + 1, rc_slider.bottom,
                               rc.right, down_arrow_rect.top, COLOR_GRAY);
}
Exemple #20
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();
    }
  }
Exemple #21
0
void
WndSymbolButton::OnPaint(Canvas &canvas)
{
  PixelRect rc = {
    PixelScalar(0), PixelScalar(0), PixelScalar(canvas.get_width()),
    PixelScalar(canvas.get_height())
  };

  bool pressed = is_down();

  renderer.DrawButton(canvas, rc, HasFocus(), pressed);
  // If button has text on it
  tstring caption = get_text();
  if (caption.empty())
    return;

  rc = renderer.GetDrawingRect(rc, pressed);

  canvas.SelectNullPen();
  if (!IsEnabled())
    canvas.Select(look.button.disabled.brush);
  else if (HasFocus())
    canvas.Select(look.button.focused.foreground_brush);
  else
    canvas.Select(look.button.standard.foreground_brush);

  const char ch = (char)caption[0];

  // Draw arrow symbols instead of < and >
  if (ch == '<' || ch == '>') {
    int size = min(rc.right - rc.left, rc.bottom - rc.top) / 5;

    RasterPoint Arrow[3];
    Arrow[0].x = (rc.left + rc.right) / 2 + (ch == '<' ? size : -size);
    Arrow[0].y = (rc.top + rc.bottom) / 2 + size;
    Arrow[1].x = (rc.left + rc.right) / 2 + (ch == '<' ? -size : size);
    Arrow[1].y = (rc.top + rc.bottom) / 2;
    Arrow[2].x = (rc.left + rc.right) / 2 + (ch == '<' ? size : -size);
    Arrow[2].y = (rc.top + rc.bottom) / 2 - size;

    canvas.DrawTriangleFan(Arrow, 3);
  }

  // Draw arrow symbols instead of v and ^
  else if (ch == '^' || ch == 'v') {
    int size = min(rc.right - rc.left, rc.bottom - rc.top) / 5;

    RasterPoint Arrow[3];
    Arrow[0].x = (rc.left + rc.right) / 2 +
                 size;
    Arrow[0].y = (rc.top + rc.bottom) / 2 +
                 (ch == '^' ? size : -size);
    Arrow[1].x = (rc.left + rc.right) / 2;
    Arrow[1].y = (rc.top + rc.bottom) / 2 +
                 (ch == '^' ? -size : size);
    Arrow[2].x = (rc.left + rc.right) / 2 - size;
    Arrow[2].y = (rc.top + rc.bottom) / 2 +
                 (ch == '^' ? size : -size);

    canvas.DrawTriangleFan(Arrow, 3);
  }

  // Draw symbols instead of + and -
  else if (ch == '+' || ch == '-') {
    int size = min(rc.right - rc.left, rc.bottom - rc.top) / 5;

    canvas.Rectangle((rc.left + rc.right) / 2 - size,
                     (rc.top + rc.bottom) / 2 - size / 3,
                     (rc.left + rc.right) / 2 + size,
                     (rc.top + rc.bottom) / 2 + size / 3);

    if (ch == '+')
      canvas.Rectangle((rc.left + rc.right) / 2 - size / 3,
                       (rc.top + rc.bottom) / 2 - size,
                       (rc.left + rc.right) / 2 + size / 3,
                       (rc.top + rc.bottom) / 2 + size);
  }

  // Draw Fly bitmap
  else if (caption == _T("Fly")) {
    Bitmap launcher1_bitmap(IDB_LAUNCHER1);
    canvas.ClearWhite();
    if (is_down())
      canvas.invert_stretch_transparent(launcher1_bitmap, COLOR_YELLOW);
    else
      canvas.stretch_transparent(launcher1_bitmap, COLOR_BLUE);
  }

  // Draw Simulator bitmap
  else if (caption == _T("Simulator")) {
    Bitmap launcher2_bitmap(IDB_LAUNCHER2);
    canvas.ClearWhite();
    if (is_down())
      canvas.invert_stretch_transparent(launcher2_bitmap, COLOR_YELLOW);
    else
      canvas.stretch_transparent(launcher2_bitmap, COLOR_BLUE);
  }

  else if (caption == _T("Green")) {
    InflateRect(&rc, -3, -3);
    canvas.DrawFilledRectangle(rc, Color(0x74, 0xFF, 0));
  } else if (caption == _T("Blue")) {
    InflateRect(&rc, -3, -3);
    canvas.DrawFilledRectangle(rc, Color(0, 0x90, 0xFF));
  } else if (caption == _T("Magenta")) {
    InflateRect(&rc, -3, -3);
    canvas.DrawFilledRectangle(rc, Color(0xFF, 0, 0xCB));
  } else if (caption == _T("Yellow")) {
    InflateRect(&rc, -3, -3);
    canvas.DrawFilledRectangle(rc, Color(0xFF, 0xE8, 0));
  }
}