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); }
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; }
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); }
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; }
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); }
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(); }
constexpr static PixelRect ToOrigin(PixelRect rc) { return { 0, 0, PixelScalar(rc.right - rc.left), PixelScalar(rc.bottom - rc.top) }; }
const PixelSize Bitmap::GetSize() const { assert(IsDefined()); #ifndef ENABLE_OPENGL const PixelSize size = { PixelScalar(surface->w), PixelScalar(surface->h) }; #endif return size; }
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 }
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); }
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 }
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); }
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()); }
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); }
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); }
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); }
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; }
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; }
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]); } }
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)); }
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(); }
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(); }
gcc_pure PixelRect GetRect() const { return PixelRect{0, 0, PixelScalar(GetWidth()), PixelScalar(GetHeight())}; }
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; }
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); }
virtual PixelSize GetMaximumSize() const override { return { ::Layout::Scale(400), PixelScalar(::Layout::GetMaximumControlHeight()) }; }
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)); } }