예제 #1
0
파일: Weather.cpp 프로젝트: damianob/xcsoar
void
InfoBoxContentWindArrow::OnCustomPaint(InfoBoxWindow &infobox, Canvas &canvas)
{
  const auto &info = CommonInterface::Calculated();

  auto rc = infobox.GetValueRect();
  RasterPoint pt = {
    PixelScalar((rc.left + rc.right) / 2),
    PixelScalar((rc.top + rc.bottom) / 2),
  };

  UPixelScalar padding = Layout::FastScale(5);
  UPixelScalar size = std::min(rc.right - rc.left, rc.bottom - rc.top);

  if (size > padding)
    size -= padding;

  auto angle = info.wind.bearing - info.heading;
  auto length = std::min(size, (UPixelScalar)std::max(10, iround(info.wind.norm * 4)));

  auto offset = -length / 2;

  auto style = CommonInterface::GetMapSettings().wind_arrow_style;

  WindArrowRenderer renderer(UIGlobals::GetMapLook().wind);
  renderer.DrawArrow(canvas, pt, angle, length, style, offset);
}
예제 #2
0
PixelRect
ButtonPanel::VerticalRange(PixelRect rc, unsigned start, unsigned end)
{
  const unsigned n = end - start;
  assert(n > 0);

  const UPixelScalar width = RangeMaxWidth(start, end);
  const UPixelScalar total_height = rc.bottom - rc.top;
  const UPixelScalar max_height = n * Layout::GetMaximumControlHeight();
  const UPixelScalar row_height = std::min(total_height, max_height) / n;

  PixelRect button_rc = {
    rc.left, rc.top, PixelScalar(rc.left + width),
    PixelScalar(rc.top + row_height),
  };
  rc.left += width;

  for (unsigned i = start; i < end; ++i) {
    buttons[i]->Move(button_rc);

    button_rc.top = button_rc.bottom;
    button_rc.bottom += row_height;
  }

  return rc;
}
예제 #3
0
void
TerminalWindow::OnPaint(Canvas &canvas, const PixelRect &p_dirty)
{
  canvas.SetBackgroundTransparent();
  canvas.SetTextColor(look.text_color);
  canvas.Select(look.font);

  const PixelRect cell_dirty = {
    p_dirty.left / cell_size.cx,
    p_dirty.top / cell_size.cy,
    std::min(PixelScalar(p_dirty.right / cell_size.cx + 1),
             PixelScalar(data.GetWidth())),
    std::min(PixelScalar(p_dirty.bottom / cell_size.cy + 1),
             PixelScalar(data.GetHeight())),
  };

  const PixelScalar x(cell_dirty.left * cell_size.cx);
  const size_t length = cell_dirty.right - cell_dirty.left;

  auto text = data.GetPointerAt(cell_dirty.left, cell_dirty.top);
  for (int cell_y = cell_dirty.top, p_y = cell_y * cell_size.cy;
       cell_y < cell_dirty.bottom;
       ++cell_y, p_y += cell_size.cy, text += data.GetWidth()) {
    canvas.DrawFilledRectangle(p_dirty.left, p_y,
                          p_dirty.right, p_y + cell_size.cy,
                          look.background_color);
    canvas.DrawText(x, p_y, text, length);
  }

  PixelScalar cell_bottom_y(cell_dirty.bottom * cell_size.cy);
  if (cell_bottom_y < p_dirty.bottom)
    canvas.DrawFilledRectangle(p_dirty.left, cell_bottom_y,
                          p_dirty.right, p_dirty.bottom,
                          look.background_color);
}
예제 #4
0
PixelRect
ButtonPanel::HorizontalRange(PixelRect rc, unsigned start, unsigned end)
{
  const unsigned n = end - start;
  assert(n > 0);

  const UPixelScalar total_width = rc.right - rc.left;
  const UPixelScalar row_height = Layout::GetMaximumControlHeight();
  const UPixelScalar width = total_width / n;

  PixelRect button_rc = {
    rc.left, PixelScalar(rc.bottom - row_height),
    PixelScalar(rc.left + width), rc.bottom,
  };
  rc.bottom -= row_height;

  for (unsigned i = start; i < end; ++i) {
    buttons[i]->Move(button_rc);

    button_rc.left = button_rc.right;
    button_rc.right += width;
  }

  return rc;
}
예제 #5
0
void
MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                          const MarkerMapItem &item,
                          const DialogLook &dialog_look,
                          const MarkerLook &look)
{
  const PixelScalar line_height = rc.bottom - rc.top;

  const Markers::Marker &marker = item.marker;

  RasterPoint pt = { PixelScalar(rc.left + line_height / 2),
                     PixelScalar(rc.top + line_height / 2) };

  look.icon.Draw(canvas, pt);

  const Font &name_font = *dialog_look.list.font;
  const Font &small_font = *dialog_look.small_font;

  PixelScalar left = rc.left + line_height + Layout::FastScale(2);

  StaticString<256> buffer;
  buffer.Format(_T("%s #%d"), _("Marker"), item.id + 1);
  canvas.Select(name_font);
  canvas.text_clipped(left, rc.top + Layout::FastScale(2), rc, buffer);

  TCHAR time_buffer[32], timespan_buffer[32];
  FormatSignedTimeHHMM(time_buffer, TimeLocal(marker.time.GetSecondOfDay()));
  FormatTimespanSmart(timespan_buffer, BrokenDateTime::NowUTC() - marker.time);
  buffer.Format(_("dropped %s ago"), timespan_buffer);
  buffer.AppendFormat(_T(" (%s)"), time_buffer);
  canvas.Select(small_font);
  canvas.text_clipped(left,
                      rc.top + name_font.GetHeight() + Layout::FastScale(4),
                      rc, buffer);
}
예제 #6
0
  void set(const DialogLook &look, PixelRect _rc) {
    SingleWindow::set(_T("RunRenderOZ"), _T("RunRenderOZ"), _rc);

    const PixelRect rc = get_client_rect();

    WindowStyle with_border;
    with_border.Border();

    oz.set(*this, rc.right / 2, 0, rc.right - (rc.right / 2), rc.bottom,
           with_border);
    oz_window = &oz;

    const PixelRect list_rc = {
      0, 0, PixelScalar(rc.right / 2), PixelScalar(rc.bottom - 30),
    };

    type_list = new ListControl(*this, look, list_rc,
                                with_border, 25);
    type_list->SetPaintItemCallback(paint_oz_type_name);
    type_list->SetCursorCallback(oz_type_cursor_callback);
    type_list->SetLength(NUM_OZ_TYPES);

    PixelRect button_rc = rc;
    button_rc.right = (rc.left + rc.right) / 2;
    button_rc.top = button_rc.bottom - 30;
    close_button.set(*this, _T("Close"), ID_CLOSE, button_rc);

    oz.set_shape(ObservationZonePoint::LINE);

    type_list->SetFocus();
  }
예제 #7
0
constexpr
static PixelRect
ToOrigin(PixelRect rc)
{
  return {
    0, 0, PixelScalar(rc.right - rc.left), PixelScalar(rc.bottom - rc.top)
  };
}
예제 #8
0
파일: Bitmap.cpp 프로젝트: damianob/xcsoar
const PixelSize
Bitmap::GetSize() const
{
  assert(IsDefined());

#ifndef ENABLE_OPENGL
  const PixelSize size = { PixelScalar(surface->w), PixelScalar(surface->h) };
#endif
  return size;
}
예제 #9
0
  gcc_pure
  const PixelSize GetSize() const
  {
#ifdef USE_GDI
    PixelRect rc = GetClientRect();
    PixelSize s;
    s.cx = rc.right;
    s.cy = rc.bottom;
    return s;
#else
    return { PixelScalar(GetWidth()), PixelScalar(GetHeight()) };
#endif
  }
예제 #10
0
void
WaypointListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                           const Waypoint &waypoint, fixed distance,
                           fixed arrival_altitude,
                           const DialogLook &dialog_look,
                           const WaypointLook &look,
                           const WaypointRendererSettings &settings)
{
  const PixelScalar line_height = rc.bottom - rc.top;

  const Font &name_font = *dialog_look.list.font;
  const Font &small_font = *dialog_look.small_font;

  // Y-Coordinate of the second row
  PixelScalar top2 = rc.top + name_font.GetHeight() + Layout::FastScale(4);

  // Use small font for details
  canvas.Select(small_font);

  // Draw distance and arrival altitude
  StaticString<256> buffer;
  TCHAR dist[20], alt[20], radio[20];
  FormatUserDistanceSmart(distance, dist, true);
  FormatRelativeUserAltitude(arrival_altitude, alt, true);
  buffer.Format(_T("%s: %s - %s: %s"), _("Distance"), dist,
                _("Arrival Alt"), alt);

  if (waypoint.radio_frequency.IsDefined()) {
    waypoint.radio_frequency.Format(radio, ARRAY_SIZE(radio));
    buffer.AppendFormat(_T(" - %s MHz"), radio);
  }

  UPixelScalar left = rc.left + line_height + Layout::FastScale(2);
  canvas.text_clipped(left, top2, rc, buffer);

  // Draw waypoint name
  canvas.Select(name_font);
  canvas.text_clipped(left, rc.top + Layout::FastScale(2), rc,
                      waypoint.name.c_str());

  // Draw icon
  RasterPoint pt = { PixelScalar(rc.left + line_height / 2),
                     PixelScalar(rc.top + line_height / 2) };

  WaypointIconRenderer::Reachability reachable =
      positive(arrival_altitude) ?
      WaypointIconRenderer::ReachableTerrain : WaypointIconRenderer::Unreachable;

  WaypointIconRenderer wir(settings, look, canvas);
  wir.Draw(waypoint, pt, reachable);
}
예제 #11
0
파일: Button.cpp 프로젝트: damianob/xcsoar
void
WndButton::OnPaint(Canvas &canvas)
{
  PixelRect rc = {
    PixelScalar(0), PixelScalar(0), PixelScalar(canvas.get_width()),
    PixelScalar(canvas.get_height())
  };

  const bool focused = HasFocus();
  const bool pressed = is_down();

  renderer.DrawButton(canvas, rc, focused, pressed);

  // If button has text on it
  tstring caption = get_text();
  if (caption.empty())
    return;

  rc = renderer.GetDrawingRect(rc, pressed);

  canvas.SetBackgroundTransparent();
  if (!IsEnabled())
    canvas.SetTextColor(look.button.disabled.color);
  else if (focused)
    canvas.SetTextColor(look.button.focused.foreground_color);
  else
    canvas.SetTextColor(look.button.standard.foreground_color);

#ifndef USE_GDI
  canvas.formatted_text(&rc, caption.c_str(), GetTextStyle());
#else
  unsigned style = DT_CENTER | DT_NOCLIP | DT_WORDBREAK;
  canvas.Select(*(look.button.font));

  PixelRect text_rc = rc;
  canvas.formatted_text(&text_rc, caption.c_str(), style | DT_CALCRECT);
  text_rc.right = rc.right;

  PixelScalar offset = rc.bottom - text_rc.bottom;
  if (offset > 0) {
    offset /= 2;
    text_rc.top += offset;
    text_rc.bottom += offset;
  }

  canvas.formatted_text(&text_rc, caption.c_str(), style);
#endif
}
예제 #12
0
파일: Canvas.cpp 프로젝트: mobotics/XCSoar
void
Canvas::copy(PixelScalar dest_x, PixelScalar dest_y,
             UPixelScalar dest_width, UPixelScalar dest_height,
             SDL_Surface *src_surface, PixelScalar src_x, PixelScalar src_y)
{
  assert(src_surface != NULL);

  if (!clip(dest_x, dest_width, width, src_x) ||
      !clip(dest_y, dest_height, height, src_y))
    return;

  SDL_Rect src_rect = { src_x, src_y, dest_width, dest_height };
  SDL_Rect dest_rect = { PixelScalar(x_offset + dest_x),
                         PixelScalar(y_offset + dest_y) };

  ::SDL_BlitSurface(src_surface, &src_rect, surface, &dest_rect);
}
예제 #13
0
void
MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                          const AirspaceMapItem &item,
                          const DialogLook &dialog_look,
                          const AirspaceLook &look,
                          const AirspaceRendererSettings &renderer_settings)
{
  const PixelScalar line_height = rc.bottom - rc.top;

  const AbstractAirspace &airspace = *item.airspace;

  RasterPoint pt = { PixelScalar(rc.left + line_height / 2),
                     PixelScalar(rc.top + line_height / 2) };
  PixelScalar radius = std::min(PixelScalar(line_height / 2
                                            - Layout::FastScale(4)),
                                Layout::FastScale(10));
  AirspacePreviewRenderer::Draw(canvas, airspace, pt, radius,
                                renderer_settings, look);

  const Font &name_font = *dialog_look.list.font;
  const Font &small_font = *dialog_look.small_font;
  canvas.SetTextColor(COLOR_BLACK);

  PixelScalar left = rc.left + line_height + Layout::FastScale(2);
  canvas.Select(name_font);
  canvas.text_clipped(left, rc.top + Layout::FastScale(2), rc,
                      airspace.GetName());

  canvas.Select(small_font);
  canvas.text_clipped(left,
                      rc.top + name_font.GetHeight() + Layout::FastScale(4),
                      rc, airspace.GetTypeText(false));

  PixelScalar altitude_width =
    canvas.CalcTextWidth(airspace.GetTopText(true).c_str());
  canvas.text_clipped(rc.right - altitude_width - Layout::FastScale(4),
                      rc.top + name_font.GetHeight() -
                      small_font.GetHeight() + Layout::FastScale(2), rc,
                      airspace.GetTopText(true).c_str());

  altitude_width = canvas.CalcTextWidth(airspace.GetBaseText(true).c_str());
  canvas.text_clipped(rc.right - altitude_width - Layout::FastScale(4),
                      rc.top + name_font.GetHeight() + Layout::FastScale(4),
                      rc, airspace.GetBaseText(true).c_str());
}
예제 #14
0
void
AirspaceListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                           const AbstractAirspace &airspace,
                           const TCHAR *comment, const DialogLook &dialog_look,
                           const AirspaceLook &look,
                           const AirspaceRendererSettings &renderer_settings)
{
  const PixelScalar line_height = rc.bottom - rc.top;

  const Font &name_font = *dialog_look.list.font;
  const Font &small_font = *dialog_look.small_font;

  PixelScalar left = rc.left + line_height + Layout::FastScale(2);
  canvas.Select(name_font);
  canvas.text_clipped(left, rc.top + Layout::FastScale(2), rc,
                      airspace.GetName());

  canvas.Select(small_font);
  canvas.text_clipped(left,
                      rc.top + name_font.GetHeight() + Layout::FastScale(4),
                      rc, comment);

  tstring top = AirspaceFormatter::GetTopShort(airspace);
  PixelScalar altitude_width =
    canvas.CalcTextWidth(top.c_str());
  canvas.text_clipped(rc.right - altitude_width - Layout::FastScale(4),
                      rc.top + name_font.GetHeight() -
                      small_font.GetHeight() + Layout::FastScale(2), rc,
                      top.c_str());

  tstring base = AirspaceFormatter::GetBaseShort(airspace);
  altitude_width = canvas.CalcTextWidth(base.c_str());

  canvas.text_clipped(rc.right - altitude_width - Layout::FastScale(4),
                      rc.top + name_font.GetHeight() + Layout::FastScale(4),
                      rc, base.c_str());

  RasterPoint pt = { PixelScalar(rc.left + line_height / 2),
                     PixelScalar(rc.top + line_height / 2) };
  PixelScalar radius = std::min(PixelScalar(line_height / 2
                                            - Layout::FastScale(4)),
                                Layout::FastScale(10));
  AirspacePreviewRenderer::Draw(canvas, airspace, pt, radius,
                                renderer_settings, look);
}
예제 #15
0
void
MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                          const TaskOZMapItem &item,
                          const DialogLook &dialog_look,
                          const TaskLook &look, const AirspaceLook &airspace_look,
                          const AirspaceRendererSettings &airspace_settings)
{
  const PixelScalar line_height = rc.bottom - rc.top;

  const ObservationZonePoint &oz = *item.oz;
  const Waypoint &waypoint = item.waypoint;

  RasterPoint pt = { PixelScalar(rc.left + line_height / 2),
                     PixelScalar(rc.top + line_height / 2) };
  PixelScalar radius = std::min(PixelScalar(line_height / 2
                                            - Layout::FastScale(4)),
                                Layout::FastScale(10));
  OZPreviewRenderer::Draw(canvas, oz, pt, radius, look,
                          airspace_settings, airspace_look);

  const Font &name_font = *dialog_look.list.font;
  const Font &small_font = *dialog_look.small_font;
  canvas.SetTextColor(COLOR_BLACK);

  TCHAR buffer[256];

  // Y-Coordinate of the second row
  UPixelScalar top2 = rc.top + name_font.GetHeight() + Layout::FastScale(4);

  // Use small font for details
  canvas.Select(small_font);

  // Draw details line
  UPixelScalar left = rc.left + line_height + Layout::FastScale(2);
  OrderedTaskPointRadiusLabel(*item.oz, buffer);
  if (!StringIsEmpty(buffer))
    canvas.text_clipped(left, top2, rc.right - left, buffer);

  // Draw waypoint name
  canvas.Select(name_font);
  OrderedTaskPointLabel(item.tp_type, waypoint.name.c_str(),
                        item.index, buffer);
  canvas.text_clipped(left, rc.top + Layout::FastScale(2),
                      rc.right - left, buffer);
}
예제 #16
0
void
MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc,
                          const ThermalMapItem &item,
                          const DialogLook &dialog_look,
                          const MapLook &look)
{
  const PixelScalar line_height = rc.bottom - rc.top;

  const ThermalSource &thermal = item.thermal;

  RasterPoint pt = { PixelScalar(rc.left + line_height / 2),
                     PixelScalar(rc.top + line_height / 2) };

  look.thermal_source_icon.Draw(canvas, pt);

  const Font &name_font = *dialog_look.list.font;
  const Font &small_font = *dialog_look.small_font;
  canvas.SetTextColor(COLOR_BLACK);

  PixelScalar left = rc.left + line_height + Layout::FastScale(2);

  canvas.Select(name_font);
  canvas.text_clipped(left, rc.top + Layout::FastScale(2), rc, _("Thermal"));

  StaticString<256> buffer;
  TCHAR lift_buffer[32], time_buffer[32], timespan_buffer[32];
  FormatUserVerticalSpeed(thermal.lift_rate, lift_buffer, 32);
  FormatSignedTimeHHMM(time_buffer, TimeLocal((int)thermal.time));

  int timespan = BrokenDateTime::NowUTC().GetSecondOfDay() - (int)thermal.time;
  if (timespan < 0)
    timespan += 24 * 60 * 60;

  FormatTimespanSmart(timespan_buffer, timespan);

  buffer.Format(_T("%s: %s"), _("Avg. lift"), lift_buffer);
  buffer.append(_T(" - "));
  buffer.AppendFormat(_("left %s ago"), timespan_buffer);
  buffer.AppendFormat(_T(" (%s)"), time_buffer);
  canvas.Select(small_font);
  canvas.text_clipped(left,
                      rc.top + name_font.GetHeight() + Layout::FastScale(4),
                      rc, buffer);
}
예제 #17
0
PixelSize
RowFormWidget::GetMaximumSize() const
{
  const UPixelScalar value_width =
    look.text_font->TextSize(_T("Foo Bar Foo Bar")).cx * 2;

  PixelSize size{ PixelScalar(GetRecommendedCaptionWidth() + value_width), 0 };
  for (auto i = rows.begin(), end = rows.end(); i != end; ++i)
    size.cy += i->GetMaximumHeight();

  return size;
}
예제 #18
0
PixelSize
RowFormWidget::GetMinimumSize() const
{
  const UPixelScalar value_width =
    look.text_font->TextSize(_T("Foo Bar Foo Bar")).cx;

  const bool expert = UIGlobals::GetDialogSettings().expert;

  PixelSize size{ PixelScalar(GetRecommendedCaptionWidth() + value_width), 0 };
  for (auto i = rows.begin(), end = rows.end(); i != end; ++i)
    if (i->available && (!i->expert || expert))
      size.cy += i->GetMinimumHeight();

  return size;
}
예제 #19
0
void
WindArrowRenderer::DrawArrow(Canvas &canvas, RasterPoint pos, Angle angle,
                             PixelScalar length, WindArrowStyle arrow_style,
                             PixelScalar offset)
{
  // Draw arrow

  RasterPoint arrow[] = {
    { 0, (PixelScalar)(-offset + 3) },
    { -6, (PixelScalar)(-offset - 3 - length) },
    { 0, (PixelScalar)(-offset + 3 - length) },
    { 6, (PixelScalar)(-offset - 3 - length) },
  };

  // Rotate the arrow
  PolygonRotateShift(arrow, ARRAY_SIZE(arrow), pos.x, pos.y, angle);

  canvas.Select(look.arrow_pen);
  canvas.Select(look.arrow_brush);
  canvas.DrawPolygon(arrow, ARRAY_SIZE(arrow));

  // Draw arrow tail

  if (arrow_style == WindArrowStyle::FULL_ARROW) {
    RasterPoint tail[] = {
      { 0, (PixelScalar)(-offset + 3) },
      { 0, -offset - 3 - std::min(PixelScalar(20), length) * 3 },
    };

    PolygonRotateShift(tail, ARRAY_SIZE(tail),
                       pos.x, pos.y, angle);

    canvas.Select(look.tail_pen);
    canvas.DrawLine(tail[0], tail[1]);
  }
}
예제 #20
0
void
TrailLook::Initialise(const TrailSettings &settings)
{
  PixelScalar iwidth;
  PixelScalar minwidth = Layout::ScalePenWidth(2);

  for (unsigned i = 0; i < NUMSNAILCOLORS; ++i) {
    short ih = i * 200 / (NUMSNAILCOLORS - 1);
    Color color = GetColor(settings.type, ih);

    if (i < NUMSNAILCOLORS / 2 ||
        !settings.scaling_enabled)
      iwidth = minwidth;
    else
      iwidth = max(minwidth,
                   PixelScalar((i - NUMSNAILCOLORS / 2) *
                               Layout::ScalePenWidth(16) / NUMSNAILCOLORS));

    trail_pens[i].Set(minwidth, color);
    scaled_trail_pens[i].Set(iwidth, color);
  }

  trace_pen.Set(2, Color(50, 243, 45));
}
예제 #21
0
 gcc_pure
 RasterPoint Rotate(PixelScalar x, PixelScalar y) const {
   auto result = rotation.Rotate(x, y);
   return RasterPoint{ PixelScalar(result.first), PixelScalar(result.second) };
 }
void
GlueMapWindow::UpdateProjection()
{
  const PixelRect rc = GetClientRect();

  /* not using MapWindowBlackboard here because these methods are
     called by the main thread */
  const NMEAInfo &basic = CommonInterface::Basic();
  const DerivedInfo &calculated = CommonInterface::Calculated();
  const MapSettings &settings_map = CommonInterface::GetMapSettings();
  const bool circling =
    CommonInterface::GetUIState().display_mode == DisplayMode::CIRCLING;

  const RasterPoint center = rc.GetCenter();

  if (circling || !IsNearSelf())
    visible_projection.SetScreenOrigin(center.x, center.y);
  else if (settings_map.cruise_orientation == DisplayOrientation::NORTH_UP ||
           settings_map.cruise_orientation == DisplayOrientation::WIND_UP) {
    RasterPoint offset{0, 0};
    if (settings_map.glider_screen_position != 50 &&
        settings_map.map_shift_bias != MapShiftBias::NONE) {
      fixed x = fixed(0);
      fixed y = fixed(0);
      if (settings_map.map_shift_bias == MapShiftBias::TRACK) {
        if (basic.track_available &&
            basic.ground_speed_available &&
             /* 8 m/s ~ 30 km/h */
            basic.ground_speed > fixed(8)) {
          auto angle = basic.track.Reciprocal() - visible_projection.GetScreenAngle();

          const auto sc = angle.SinCos();
          x = sc.first;
          y = sc.second;
        }
      } else if (settings_map.map_shift_bias == MapShiftBias::TARGET) {
        if (calculated.task_stats.current_leg.solution_remaining.IsDefined()) {
          auto angle = calculated.task_stats.current_leg.solution_remaining
              .vector.bearing.Reciprocal() - visible_projection.GetScreenAngle();

          const auto sc = angle.SinCos();
          x = sc.first;
          y = sc.second;
        }
      }
      fixed position_factor = fixed(50 - settings_map.glider_screen_position) / 100;
      offset.x = PixelScalar(x * (rc.right - rc.left) * position_factor);
      offset.y = PixelScalar(y * (rc.top - rc.bottom) * position_factor);
      offset_history.Add(offset);
      offset = offset_history.GetAverage();
    }
    visible_projection.SetScreenOrigin(center.x + offset.x, center.y + offset.y);
  } else
    visible_projection.SetScreenOrigin(center.x,
        ((rc.top - rc.bottom) * settings_map.glider_screen_position / 100) + rc.bottom);

  if (!IsNearSelf()) {
    /* no-op - the Projection's location is updated manually */
  } else if (circling && calculated.thermal_locator.estimate_valid) {
    const fixed d_t = calculated.thermal_locator.estimate_location.Distance(basic.location);
    if (!positive(d_t)) {
      SetLocationLazy(basic.location);
    } else {
      const fixed d_max = Double(visible_projection.GetMapScale());
      const fixed t = std::min(d_t, d_max)/d_t;
      SetLocation(basic.location.Interpolate(calculated.thermal_locator.estimate_location,
                                               t));
    }
  } else if (basic.location_available)
    // Pan is off
    SetLocationLazy(basic.location);
  else if (!visible_projection.IsValid() && terrain != nullptr)
    /* if there's no GPS fix yet and no home waypoint, start at the
       map center, to avoid showing a fully white map, which confuses
       users */
    SetLocation(terrain->GetTerrainCenter());

  visible_projection.UpdateScreenBounds();
}
예제 #23
0
void
GlueMapWindow::UpdateProjection()
{
  const PixelRect rc = GetClientRect();

  /* not using MapWindowBlackboard here because these methods are
     called by the main thread */
  const NMEAInfo &basic = CommonInterface::Basic();
  const DerivedInfo &calculated = CommonInterface::Calculated();
  const MapSettings &settings_map = CommonInterface::GetMapSettings();

  RasterPoint center;
  center.x = (rc.left + rc.right) / 2;
  center.y = (rc.top + rc.bottom) / 2;

  if (InCirclingMode() || !IsNearSelf())
    visible_projection.SetScreenOrigin(center.x, center.y);
  else if (settings_map.cruise_orientation == NORTHUP) {
    RasterPoint offset{0, 0};
    if (settings_map.glider_screen_position != 50 &&
        settings_map.map_shift_bias != MAP_SHIFT_BIAS_NONE) {
      fixed x = fixed_zero;
      fixed y = fixed_zero;
      if (settings_map.map_shift_bias == MAP_SHIFT_BIAS_TRACK) {
        if (basic.track_available &&
            basic.ground_speed_available &&
             /* 8 m/s ~ 30 km/h */
            basic.ground_speed > fixed_int_constant(8)) {
          const auto sc = basic.track.Reciprocal().SinCos();
          x = sc.first;
          y = sc.second;
        }
      } else if (settings_map.map_shift_bias == MAP_SHIFT_BIAS_TARGET) {
        if (calculated.task_stats.current_leg.solution_remaining.IsDefined()) {
          const auto sc =calculated.task_stats.current_leg.solution_remaining
            .vector.bearing.Reciprocal().SinCos();
          x = sc.first;
          y = sc.second;
        }
      }
      fixed position_factor = fixed(50 - settings_map.glider_screen_position) / 100;
      offset.x = PixelScalar(x * (rc.right - rc.left) * position_factor);
      offset.y = PixelScalar(y * (rc.top - rc.bottom) * position_factor);
      offset_history.Add(offset);
      offset = offset_history.GetAverage();
    }
    visible_projection.SetScreenOrigin(center.x + offset.x, center.y + offset.y);
  } else
    visible_projection.SetScreenOrigin(center.x,
        ((rc.top - rc.bottom) * settings_map.glider_screen_position / 100) + rc.bottom);

  if (!IsNearSelf()) {
    /* no-op - the Projection's location is updated manually */
  } else if (InCirclingMode() && calculated.thermal_locator.estimate_valid) {
    const fixed d_t = calculated.thermal_locator.estimate_location.Distance(basic.location);
    if (!positive(d_t)) {
      SetLocationLazy(basic.location);
    } else {
      const fixed d_max = Double(visible_projection.GetMapScale());
      const fixed t = std::min(d_t, d_max)/d_t;
      SetLocation(basic.location.Interpolate(calculated.thermal_locator.estimate_location,
                                               t));
    }
  } else if (basic.location_available)
    // Pan is off
    SetLocationLazy(basic.location);

  visible_projection.UpdateScreenBounds();
}
예제 #24
0
파일: Canvas.hpp 프로젝트: StefanL74/XCSoar
 gcc_pure
 PixelRect GetRect() const {
   return PixelRect{0, 0, PixelScalar(GetWidth()), PixelScalar(GetHeight())};
 }
예제 #25
0
bool
TopWindow::OnEvent(const SDL_Event &event)
{
  switch (event.type) {
    Window *w;

  case SDL_VIDEOEXPOSE:
    Invalidated_lock.Lock();
    Invalidated = false;
    Invalidated_lock.Unlock();

    Expose();
    return true;

  case SDL_KEYDOWN:
    w = GetFocusedWindow();
    if (w == NULL)
      w = this;

    if (!w->IsEnabled())
      return false;

    return w->OnKeyDown(event.key.keysym.sym);

  case SDL_KEYUP:
    w = GetFocusedWindow();
    if (w == NULL)
      w = this;

    if (!w->IsEnabled())
      return false;

    return w->OnKeyUp(event.key.keysym.sym);

  case SDL_MOUSEMOTION:
    // XXX keys
    return OnMouseMove(event.motion.x, event.motion.y, 0);

  case SDL_MOUSEBUTTONDOWN:
    if (event.button.button == SDL_BUTTON_WHEELUP)
      return OnMouseWheel(event.button.x, event.button.y, 1);
    else if (event.button.button == SDL_BUTTON_WHEELDOWN)
      return OnMouseWheel(event.button.x, event.button.y, -1);

    return double_click.Check(RasterPoint{PixelScalar(event.button.x),
                                          PixelScalar(event.button.y)})
      ? OnMouseDouble(event.button.x, event.button.y)
      : OnMouseDown(event.button.x, event.button.y);

  case SDL_MOUSEBUTTONUP:
    if (event.button.button == SDL_BUTTON_WHEELUP ||
        event.button.button == SDL_BUTTON_WHEELDOWN)
      /* the wheel has already been handled in SDL_MOUSEBUTTONDOWN */
      return false;

    double_click.Moved(RasterPoint{PixelScalar(event.button.x),
                                   PixelScalar(event.button.y)});

    return OnMouseUp(event.button.x, event.button.y);

  case SDL_QUIT:
    return OnClose();

  case SDL_VIDEORESIZE:
    Resize(event.resize.w, event.resize.h);
    return true;
  }

  return false;
}
예제 #26
0
void
TaskEditPanel::OnPaintItem(Canvas &canvas, const PixelRect rc,
                           unsigned DrawListIndex)
{
  assert(DrawListIndex <= ordered_task->TaskSize());

  const PixelScalar line_height = rc.bottom - rc.top;

  TCHAR buffer[120];

  const Font &name_font = *dialog.GetLook().list.font_bold;
  const Font &small_font = *dialog.GetLook().small_font;

  // Draw "Add turnpoint" label
  if (DrawListIndex == ordered_task->TaskSize()) {
    canvas.Select(name_font);
    canvas.SetTextColor(COLOR_BLACK);
    _stprintf(buffer, _T("  (%s)"), _("Add Turnpoint"));
    canvas.DrawText(rc.left + line_height + Layout::FastScale(2),
                    rc.top + line_height / 2 - name_font.GetHeight() / 2,
                    buffer);
    return;
  }

  const OrderedTaskPoint &tp = ordered_task->GetTaskPoint(DrawListIndex);
  GeoVector leg = tp.GetNominalLegVector();
  bool show_leg_info = leg.distance > fixed(0.01);

  // Draw icon
  const RasterPoint pt(rc.left + line_height / 2,
                       rc.top + line_height / 2);

  PixelScalar radius = std::min(PixelScalar(line_height / 2
                                            - Layout::FastScale(4)),
                                Layout::FastScale(10));

  OZPreviewRenderer::Draw(canvas, tp.GetObservationZone(),
                          pt, radius, task_look,
                          CommonInterface::GetMapSettings().airspace,
                          airspace_look);

  // Y-Coordinate of the second row
  PixelScalar top2 = rc.top + name_font.GetHeight() + Layout::FastScale(4);

  // Use small font for details
  canvas.Select(small_font);
  canvas.SetTextColor(COLOR_BLACK);

  UPixelScalar leg_info_width = 0;
  if (show_leg_info) {
    // Draw leg distance
    FormatUserDistanceSmart(leg.distance, buffer, true);
    UPixelScalar width = leg_info_width = canvas.CalcTextWidth(buffer);
    canvas.DrawText(rc.right - Layout::FastScale(2) - width,
                    rc.top + Layout::FastScale(2) +
                    (name_font.GetHeight() - small_font.GetHeight()) / 2,
                    buffer);

    // Draw leg bearing
    FormatBearing(buffer, ARRAY_SIZE(buffer), leg.bearing);
    width = canvas.CalcTextWidth(buffer);
    canvas.DrawText(rc.right - Layout::FastScale(2) - width, top2, buffer);

    if (width > leg_info_width)
      leg_info_width = width;

    leg_info_width += Layout::FastScale(2);
  }

  // Draw details line
  PixelScalar left = rc.left + line_height + Layout::FastScale(2);
  OrderedTaskPointRadiusLabel(tp.GetObservationZone(), buffer);
  if (!StringIsEmpty(buffer))
    canvas.DrawClippedText(left, top2, rc.right - leg_info_width - left,
                           buffer);

  // Draw turnpoint name
  canvas.Select(name_font);
  OrderedTaskPointLabel(tp.GetType(), tp.GetWaypoint().name.c_str(),
                        DrawListIndex, buffer);
  canvas.DrawClippedText(left, rc.top + Layout::FastScale(2),
                         rc.right - leg_info_width - left, buffer);
}
예제 #27
0
 virtual PixelSize GetMaximumSize() const override {
   return { ::Layout::Scale(400),
       PixelScalar(::Layout::GetMaximumControlHeight()) };
 }
예제 #28
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));
  }
}