void WaypointListRenderer::Draw(Canvas &canvas, const PixelRect rc, const Waypoint &waypoint, const GeoVector *vector, 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; Buffer buffer; // 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 leg distance UPixelScalar leg_info_width = 0; if (vector) { FormatUserDistanceSmart(vector->distance, buffer.buffer(), true); UPixelScalar width = leg_info_width = canvas.CalcTextWidth(buffer.c_str()); canvas.text(rc.right - Layout::FastScale(2) - width, rc.top + Layout::FastScale(2) + (name_font.GetHeight() - small_font.GetHeight()) / 2, buffer.c_str()); // Draw leg bearing FormatBearing(buffer.buffer(), buffer.MAX_SIZE, vector->bearing); width = canvas.CalcTextWidth(buffer.c_str()); canvas.text(rc.right - Layout::FastScale(2) - width, top2, buffer.c_str()); if (width > leg_info_width) leg_info_width = width; leg_info_width += Layout::FastScale(2); } // Draw details line FormatWaypointDetails(buffer, waypoint); PixelScalar left = rc.left + line_height + Layout::FastScale(2); canvas.text_clipped(left, top2, rc.right - leg_info_width - left, buffer.c_str()); // Draw waypoint name canvas.Select(name_font); canvas.text_clipped(left, rc.top + Layout::FastScale(2), rc.right - leg_info_width - left, waypoint.name.c_str()); // Draw icon RasterPoint pt = { (PixelScalar)(rc.left + line_height / 2), (PixelScalar)(rc.top + line_height / 2) }; WaypointIconRenderer wir(settings, look, canvas); wir.Draw(waypoint, pt); }
static TCHAR * GetDirectionData(TCHAR *buffer, size_t size, int direction_filter_index) { if (direction_filter_index == 0) _tcscpy(buffer, _T("*")); else if (direction_filter_index == 1) { TCHAR bearing[8]; FormatBearing(bearing, ARRAY_SIZE(bearing), last_heading); _stprintf(buffer, _T("HDG(%s)"), bearing); } else FormatBearing(buffer, size, direction_filter_items[direction_filter_index]); return buffer; }
void FlightStatusPanel::Refresh() { const NMEAInfo &basic = CommonInterface::Basic(); const DerivedInfo &calculated = CommonInterface::Calculated(); if (basic.location_available) SetText(Location, FormatGeoPoint(basic.location)); else ClearText(Location); if (basic.gps_altitude_available) SetText(Altitude, FormatUserAltitude(basic.gps_altitude)); else ClearText(Altitude); SetText(MaxHeightGain, FormatUserAltitude(calculated.max_height_gain)); if (nearest_waypoint) { GeoVector vec(basic.location, nearest_waypoint->location); SetText(Near, nearest_waypoint->name.c_str()); SetText(Bearing, FormatBearing(vec.bearing).c_str()); SetText(Distance, FormatUserDistanceSmart(vec.distance)); } else { SetText(Near, _T("-")); SetText(Bearing, _T("-")); SetText(Distance, _T("-")); } }
void InfoBoxData::SetComment(Angle _value, const TCHAR *suffix) { assert(suffix != NULL); FormatBearing(comment.buffer(), comment.MAX_SIZE, _value, suffix); }
void TeamCodeWidget::Update(const MoreData &basic, const DerivedInfo &calculated) { const TeamInfo &teamcode_info = calculated; const TeamCodeSettings &settings = CommonInterface::GetComputerSettings().team_code; SetText(RELATIVE_BEARING, teamcode_info.teammate_available && basic.track_available ? FormatAngleDelta(teamcode_info.teammate_vector.bearing - basic.track).c_str() : _T("---")); if (teamcode_info.teammate_available) { SetText(BEARING, FormatBearing(teamcode_info.teammate_vector.bearing).c_str()); SetText(RANGE, FormatUserDistanceSmart(teamcode_info.teammate_vector.distance)); } SetText(OWN_CODE, teamcode_info.own_teammate_code.GetCode()); SetText(MATE_CODE, settings.team_code.GetCode()); SetText(FLARM_LOCK, settings.team_flarm_id.IsDefined() ? settings.team_flarm_callsign.c_str() : _T("")); }
void InfoBoxData::SetValue(Angle _value, const TCHAR *suffix) { assert(suffix != NULL); FormatBearing(value.buffer(), value.MAX_SIZE, _value, suffix); }
gcc_const static inline StringBuffer<TCHAR, 16> FormatBearing(Angle value) { StringBuffer<TCHAR, 16> buffer; FormatBearing(buffer.data(), buffer.capacity(), value); return buffer; }
gcc_const static inline StringBuffer<TCHAR, 16> FormatBearing(unsigned degrees_value) { StringBuffer<TCHAR, 16> buffer; FormatBearing(buffer.data(), buffer.capacity(), degrees_value); return buffer; }
static TCHAR * GetDirectionData(int direction_filter_index) { static TCHAR buffer[12]; if (direction_filter_index == 0) _stprintf(buffer, _T("%c"), '*'); else if (direction_filter_index == 1) { TCHAR bearing[8]; FormatBearing(bearing, ARRAY_SIZE(bearing), last_heading); _stprintf(buffer, _T("HDG(%s)"), bearing); } else FormatBearing(buffer, ARRAY_SIZE(buffer), direction_filter_items[direction_filter_index]); return buffer; }
void TaskEditPanel::OnPaintItem(Canvas &canvas, const PixelRect rc, unsigned DrawListIndex) { assert(DrawListIndex <= ordered_task->TaskSize()); const unsigned padding = Layout::GetTextPadding(); const unsigned line_height = rc.bottom - rc.top; TCHAR buffer[120]; // Draw "Add turnpoint" label if (DrawListIndex == ordered_task->TaskSize()) { row_renderer.DrawFirstRow(canvas, rc, _("Add Turnpoint")); return; } const OrderedTaskPoint &tp = ordered_task->GetTaskPoint(DrawListIndex); GeoVector leg = tp.GetNominalLegVector(); bool show_leg_info = leg.distance > fixed(0.01); PixelRect text_rc = rc; text_rc.left += line_height + padding; if (show_leg_info) { // Draw leg distance FormatUserDistanceSmart(leg.distance, buffer, true); const int x1 = row_renderer.DrawRightFirstRow(canvas, rc, buffer); // Draw leg bearing FormatBearing(buffer, ARRAY_SIZE(buffer), leg.bearing); const int x2 = row_renderer.DrawRightSecondRow(canvas, rc, buffer); text_rc.right = std::min(x1, x2); } // Draw details line OrderedTaskPointRadiusLabel(tp.GetObservationZone(), buffer); if (!StringIsEmpty(buffer)) row_renderer.DrawSecondRow(canvas, text_rc, buffer); // Draw turnpoint name OrderedTaskPointLabel(tp.GetType(), tp.GetWaypoint().name.c_str(), DrawListIndex, buffer); row_renderer.DrawFirstRow(canvas, text_rc, buffer); // Draw icon const RasterPoint pt(rc.left + line_height / 2, rc.top + line_height / 2); const unsigned radius = line_height / 2 - padding; OZPreviewRenderer::Draw(canvas, tp.GetObservationZone(), pt, radius, task_look, CommonInterface::GetMapSettings().airspace, airspace_look); }
gcc_pure static const TCHAR * GetHeadingString(TCHAR *buffer) { TCHAR heading[32]; FormatBearing(heading, ARRAY_SIZE(heading), CommonInterface::Basic().attitude.heading); _stprintf(buffer, _T("%s (%s)"), _("Heading"), heading); return buffer; }
static void FillDirectionEnum(DataFieldEnum &df) { TCHAR buffer[64]; df.AddChoice(WILDCARD, _T("*")); df.AddChoice(0, GetHeadingString(buffer)); static constexpr unsigned directions[] = { 360, 30, 60, 90, 120, 150, 180, 210, 240, 270, 300, 330 }; for (unsigned i = 0; i < ARRAY_SIZE(directions); ++i) df.AddChoice(directions[i], FormatBearing(directions[i]).c_str()); df.Set(WILDCARD); }
static void OnPaintListItem(Canvas &canvas, const PixelRect rc, unsigned i) { if (AirspaceSelectInfo.empty()) { assert(i == 0); canvas.text(rc.left + Layout::FastScale(2), rc.top + Layout::FastScale(2), _("No Match!")); return; } assert(i < AirspaceSelectInfo.size()); const AbstractAirspace &airspace = *AirspaceSelectInfo[i].airspace; int w0, w1, w2, w3, x1, x2, x3; w0 = rc.right - rc.left - Layout::FastScale(4); w1 = canvas.CalcTextWidth(_T("XXX")); w2 = canvas.CalcTextWidth(_T(" 000km")); w3 = canvas.CalcTextWidth(_T(" 000")_T(DEG)); x1 = w0-w1-w2-w3; canvas.text_clipped(rc.left + Layout::FastScale(2), rc.top + Layout::FastScale(2), x1 - Layout::FastScale(5), airspace.GetNameText().c_str()); // left justified canvas.text(rc.left + x1, rc.top + Layout::FastScale(2), airspace.GetTypeText(true)); StaticString<12> sTmp; // right justified after airspace type sTmp.Format(_T("%d%s"), (int)AirspaceSelectInfo[i].Distance, Units::GetDistanceName()); x2 = w0 - w3 - canvas.CalcTextWidth(sTmp); canvas.text(rc.left + x2, rc.top + Layout::FastScale(2), sTmp); // right justified after distance FormatBearing(sTmp.buffer(), sTmp.MAX_SIZE, AirspaceSelectInfo[i].Direction); x3 = w0 - canvas.CalcTextWidth(sTmp); canvas.text(rc.left + x3, rc.top + Layout::FastScale(2), sTmp); }
void AirspaceListRenderer::Draw(Canvas &canvas, const PixelRect rc, const AbstractAirspace &airspace, const GeoVector &vector, const DialogLook &dialog_look, const AirspaceLook &look, const AirspaceRendererSettings &renderer_settings) { StaticString<256> comment(AirspaceFormatter::GetClass(airspace)); TCHAR dist[20], bearing[20]; FormatUserDistanceSmart(vector.distance, dist, true); FormatBearing(bearing, ARRAY_SIZE(bearing), vector.bearing); comment.AppendFormat(_T(" - %s - %s"), dist, bearing); Draw(canvas, rc, airspace, comment, dialog_look, look, renderer_settings); }
void InfoBoxContentWindArrow::Update(InfoBoxData &data) { const DerivedInfo &info = CommonInterface::Calculated(); if (!info.wind_available || info.wind.IsZero()) { data.SetInvalid(); return; } data.SetCustom(); TCHAR speed_buffer[16], bearing_buffer[16]; FormatUserWindSpeed(info.wind.norm, speed_buffer, true, false); FormatBearing(bearing_buffer, ARRAY_SIZE(bearing_buffer), info.wind.bearing); StaticString<32> buffer; buffer.Format(_T("%s / %s"), bearing_buffer, speed_buffer); data.SetComment(buffer); }
void FlightStatusPanel::Refresh() { const NMEAInfo &basic = CommonInterface::Basic(); const DerivedInfo &calculated = CommonInterface::Calculated(); StaticString<32> buffer; if (basic.location_available) { FormatGeoPoint(basic.location, buffer.buffer(), buffer.MAX_SIZE); SetText(Location, buffer); } else SetText(Location, _T("")); if (basic.gps_altitude_available) { FormatUserAltitude(basic.gps_altitude, buffer.buffer(), buffer.MAX_SIZE); SetText(Altitude, buffer); } else SetText(Altitude, _T("")); FormatUserAltitude(calculated.max_height_gain, buffer.buffer(), buffer.MAX_SIZE); SetText(MaxHeightGain, buffer); if (nearest_waypoint) { GeoVector vec(basic.location, nearest_waypoint->location); SetText(Near, nearest_waypoint->name.c_str()); FormatBearing(buffer.buffer(), buffer.MAX_SIZE, vec.bearing, _T("")); SetText(Bearing, buffer); FormatUserDistanceSmart(vec.distance, buffer.buffer(), buffer.MAX_SIZE); SetText(Distance, buffer); } else { SetText(Near, _T("-")); SetText(Bearing, _T("-")); SetText(Distance, _T("-")); } }
void MapItemListRenderer::Draw(Canvas &canvas, const PixelRect rc, const LocationMapItem &item, const DialogLook &dialog_look) { const Font &name_font = *dialog_look.list.font_bold; const Font &small_font = *dialog_look.small_font; PixelScalar left = rc.left + Layout::FastScale(2); TCHAR info_buffer[256], distance_buffer[32], direction_buffer[32]; if (item.vector.IsValid()) { FormatUserDistanceSmart(item.vector.distance, distance_buffer, 32); FormatBearing(direction_buffer, ARRAY_SIZE(direction_buffer), item.vector.bearing); _stprintf(info_buffer, _T("%s: %s, %s: %s"), _("Distance"), distance_buffer, _("Direction"), direction_buffer); } else { _stprintf(info_buffer, _T("%s: %s, %s: %s"), _("Distance"), _T("???"), _("Direction"), _T("???")); } canvas.Select(name_font); canvas.DrawClippedText(left, rc.top + Layout::FastScale(2), rc, info_buffer); TCHAR elevation_buffer[32]; if (!RasterBuffer::IsSpecial(item.elevation)) { FormatUserAltitude(fixed(item.elevation), elevation_buffer, 32); _stprintf(info_buffer, _T("%s: %s"), _("Elevation"), elevation_buffer); } else { _stprintf(info_buffer, _T("%s: %s"), _("Elevation"), _T("???")); } canvas.Select(small_font); canvas.DrawClippedText(left, rc.top + name_font.GetHeight() + Layout::FastScale(4), rc, info_buffer); }
static void Draw(Canvas &canvas, const PixelRect rc, const LocationMapItem &item, const TwoTextRowsRenderer &row_renderer) { TCHAR info_buffer[256]; if (item.vector.IsValid()) StringFormatUnsafe(info_buffer, _T("%s: %s, %s: %s"), _("Distance"), FormatUserDistanceSmart(item.vector.distance).c_str(), _("Direction"), FormatBearing(item.vector.bearing).c_str()); else StringFormatUnsafe(info_buffer, _T("%s: %s, %s: %s"), _("Distance"), _T("???"), _("Direction"), _T("???")); row_renderer.DrawFirstRow(canvas, rc, info_buffer); StringFormatUnsafe(info_buffer, _T("%s: %s"), _("Elevation"), item.HasElevation() ? FormatUserAltitude(item.elevation).c_str() : _T("???")); row_renderer.DrawSecondRow(canvas, rc, info_buffer); }
void WaypointInfoWidget::Prepare(ContainerWindow &parent, const PixelRect &rc) { RowFormWidget::Prepare(parent, rc); const MoreData &basic = CommonInterface::Basic(); const DerivedInfo &calculated = CommonInterface::Calculated(); const ComputerSettings &settings = CommonInterface::GetComputerSettings(); StaticString<64> buffer; if (!waypoint.comment.empty()) AddMultiLine(waypoint.comment.c_str()); if (waypoint.radio_frequency.IsDefined() && waypoint.radio_frequency.Format(buffer.buffer(), buffer.MAX_SIZE) != NULL) { buffer += _T(" MHz"); AddReadOnly(_("Radio frequency"), NULL, buffer); } if (waypoint.runway.IsDirectionDefined()) buffer.UnsafeFormat(_T("%02u"), waypoint.runway.GetDirectionName()); else buffer.clear(); if (waypoint.runway.IsLengthDefined()) { if (!buffer.empty()) buffer += _T("; "); TCHAR length_buffer[16]; FormatSmallUserDistance(length_buffer, fixed(waypoint.runway.GetLength())); buffer += length_buffer; } if (!buffer.empty()) AddReadOnly(_("Runway"), NULL, buffer); if (FormatGeoPoint(waypoint.location, buffer.buffer(), buffer.MAX_SIZE) != NULL) AddReadOnly(_("Location"), NULL, buffer); FormatUserAltitude(waypoint.elevation, buffer.buffer(), buffer.MAX_SIZE); AddReadOnly(_("Elevation"), NULL, buffer); if (basic.time_available) { const SunEphemeris::Result sun = SunEphemeris::CalcSunTimes(waypoint.location, basic.date_time_utc, fixed(GetUTCOffset()) / 3600); const unsigned sunrisehours = (int)sun.time_of_sunrise; const unsigned sunrisemins = (int)((sun.time_of_sunrise - fixed(sunrisehours)) * 60); const unsigned sunset_hour = (int)sun.time_of_sunset; const unsigned sunset_minute = (int)((sun.time_of_sunset - fixed(sunset_hour)) * 60); buffer.UnsafeFormat(_T("%02u:%02u - %02u:%02u"), sunrisehours, sunrisemins, sunset_hour, sunset_minute); AddReadOnly(_("Daylight time"), NULL, buffer); } if (basic.location_available) { const GeoVector vector = basic.location.DistanceBearing(waypoint.location); TCHAR distance_buffer[32]; FormatUserDistanceSmart(vector.distance, distance_buffer, ARRAY_SIZE(distance_buffer)); FormatBearing(buffer.buffer(), buffer.MAX_SIZE, vector.bearing, distance_buffer); AddReadOnly(_("Bearing and Distance"), NULL, buffer); } if (basic.location_available && basic.NavAltitudeAvailable() && settings.polar.glide_polar_task.IsValid()) { const GlideState glide_state(basic.location.DistanceBearing(waypoint.location), waypoint.elevation + settings.task.safety_height_arrival, basic.nav_altitude, calculated.GetWindOrZero()); GlidePolar gp0 = settings.polar.glide_polar_task; gp0.SetMC(fixed(0)); AddGlideResult(_("Alt. diff. MC 0"), MacCready::Solve(settings.task.glide, gp0, glide_state)); AddGlideResult(_("Alt. diff. MC safety"), MacCready::Solve(settings.task.glide, calculated.glide_polar_safety, glide_state)); AddGlideResult(_("Alt. diff. MC current"), MacCready::Solve(settings.task.glide, settings.polar.glide_polar_task, glide_state)); } }
static int ShowMapItemListDialog(SingleWindow &parent) { unsigned num_items = list->size(); UPixelScalar item_height = Fonts::map_bold.GetHeight() + Layout::Scale(6) + Fonts::map_label.GetHeight(); assert(num_items <= 0x7fffffff); assert(item_height > 0); wf = LoadDialog(CallBackTable, parent, Layout::landscape ? _T("IDR_XML_MAPITEMLIST_L") : _T("IDR_XML_MAPITEMLIST")); assert(wf != NULL); details_button = (WndButton *)wf->FindByName(_T("cmdDetails")); assert(details_button); WndListFrame *list_control = (WndListFrame *)wf->FindByName(_T("frmComboPopupList")); assert(list_control != NULL); list_control->SetItemHeight(item_height); list_control->SetLength(num_items); list_control->SetCursorIndex(0); list_control->SetActivateCallback(OnComboPopupListEnter); list_control->SetPaintItemCallback(PaintListItem); list_control->SetCursorCallback(OnListIndexChange); OnListIndexChange(0); WndFrame *info_label = (WndFrame *)wf->FindByName(_T("lblInfo")); assert(info_label); info_label->SetAlignCenter(); info_label->SetVAlignCenter(); TCHAR info_buffer[256], distance_buffer[32], direction_buffer[32]; if (vector.IsValid()) { Units::FormatUserDistance(vector.distance, distance_buffer, 32); FormatBearing(direction_buffer, ARRAY_SIZE(direction_buffer), vector.bearing, _T("T")); _stprintf(info_buffer, _T("%s: %s - %s: %s"), _("Distance"), distance_buffer, _("Direction"), direction_buffer); } else { _stprintf(info_buffer, _T("%s: %s - %s: %s"), _("Distance"), _T("???"), _("Direction"), _T("???")); } TCHAR elevation_buffer[32]; if (elevation != RasterBuffer::TERRAIN_INVALID) { Units::FormatUserAltitude(fixed(elevation), elevation_buffer, 32); _stprintf(info_buffer + _tcslen(info_buffer), _T(" - %s: %s"), _("Elevation"), elevation_buffer); } AnyCanvas canvas; canvas.Select(info_label->GetFont()); UPixelScalar text_width = canvas.CalcTextWidth(info_buffer); if (text_width > info_label->get_width()) { if (vector.IsValid()) _stprintf(info_buffer, _T("%s - %s"), distance_buffer, direction_buffer); else _stprintf(info_buffer, _T("%s - %s"), _T("???"), _T("???")); if (elevation != RasterBuffer::TERRAIN_INVALID) _stprintf(info_buffer + _tcslen(info_buffer), _T(" - %s"), elevation_buffer); } info_label->SetCaption(info_buffer); int result = wf->ShowModal() == mrOK ? (int)list_control->GetCursorIndex() : -1; delete wf; return result; }
void FormatBearing(TCHAR *buffer, size_t size, Angle value, const TCHAR *suffix) { FormatBearing(buffer, size, lround(value.AsBearing().Degrees()), suffix); }
void TrafficListWidget::OnPaintItem(Canvas &canvas, const PixelRect rc, unsigned index) { assert(index < items.size()); Item &item = items[index]; assert(item.IsFlarm() #ifdef HAVE_SKYLINES_TRACKING_HANDLER || item.IsSkyLines() #endif ); item.AutoLoad(); const FlarmNetRecord *record = item.record; const TCHAR *callsign = item.callsign; const DialogLook &look = UIGlobals::GetDialogLook(); const Font &name_font = *look.list.font_bold; const Font &small_font = *look.small_font; const unsigned text_padding = Layout::GetTextPadding(); const unsigned frame_padding = text_padding / 2; TCHAR tmp_id[10]; item.id.Format(tmp_id); canvas.Select(name_font); StaticString<256> tmp; if (item.IsFlarm()) { if (record != NULL) tmp.Format(_T("%s - %s - %s"), callsign, record->registration.c_str(), tmp_id); else if (callsign != NULL) tmp.Format(_T("%s - %s"), callsign, tmp_id); else tmp.Format(_T("%s"), tmp_id); #ifdef HAVE_SKYLINES_TRACKING_HANDLER } else if (item.IsSkyLines()) { tmp.UnsafeFormat(_T("SkyLines %u"), item.skylines_id); #endif } else { tmp = _T("?"); } const int name_x = rc.left + text_padding, name_y = rc.top + text_padding; if (item.color != FlarmColor::NONE) { const TrafficLook &traffic_look = UIGlobals::GetLook().traffic; switch (item.color) { case FlarmColor::NONE: case FlarmColor::COUNT: gcc_unreachable(); case FlarmColor::GREEN: canvas.Select(traffic_look.team_pen_green); break; case FlarmColor::BLUE: canvas.Select(traffic_look.team_pen_blue); break; case FlarmColor::YELLOW: canvas.Select(traffic_look.team_pen_yellow); break; case FlarmColor::MAGENTA: canvas.Select(traffic_look.team_pen_magenta); break; } canvas.SelectHollowBrush(); const PixelSize size = canvas.CalcTextSize(tmp); canvas.Rectangle(name_x - frame_padding, name_y - frame_padding, name_x + size.cx + frame_padding, name_y + size.cy + frame_padding); } canvas.DrawText(name_x, name_y, tmp); if (record != NULL) { tmp.clear(); if (!record->pilot.empty()) tmp = record->pilot.c_str(); if (!record->plane_type.empty()) { if (!tmp.empty()) tmp.append(_T(" - ")); tmp.append(record->plane_type); } if (!record->airfield.empty()) { if (!tmp.empty()) tmp.append(_T(" - ")); tmp.append(record->airfield); } if (!tmp.empty()) { canvas.Select(small_font); canvas.DrawText(rc.left + text_padding, rc.bottom - small_font.GetHeight() - text_padding, tmp); } } /* draw bearing and distance on the right */ if (item.vector.IsValid()) { FormatUserDistanceSmart(item.vector.distance, tmp.buffer(), true); unsigned width = canvas.CalcTextWidth(tmp.c_str()); canvas.DrawText(rc.right - text_padding - width, name_y + (name_font.GetHeight() - small_font.GetHeight()) / 2, tmp.c_str()); // Draw leg bearing FormatBearing(tmp.buffer(), tmp.MAX_SIZE, item.vector.bearing); width = canvas.CalcTextWidth(tmp.c_str()); canvas.DrawText(rc.right - text_padding - width, rc.bottom - small_font.GetHeight() - text_padding, tmp.c_str()); } }
void TrafficListWidget::OnPaintItem(Canvas &canvas, PixelRect rc, unsigned index) { assert(index < items.size()); Item &item = items[index]; assert(item.IsFlarm() #ifdef HAVE_SKYLINES_TRACKING_HANDLER || item.IsSkyLines() #endif ); item.AutoLoad(); const FlarmNetRecord *record = item.record; const TCHAR *callsign = item.callsign; const DialogLook &look = UIGlobals::GetDialogLook(); const Font &name_font = *look.list.font_bold; const Font &small_font = look.small_font; const unsigned text_padding = Layout::GetTextPadding(); const unsigned frame_padding = text_padding / 2; TCHAR tmp_id[10]; item.id.Format(tmp_id); canvas.Select(name_font); StaticString<256> tmp; if (item.IsFlarm()) { if (record != nullptr) tmp.Format(_T("%s - %s - %s"), callsign, record->registration.c_str(), tmp_id); else if (callsign != nullptr) tmp.Format(_T("%s - %s"), callsign, tmp_id); else tmp.Format(_T("%s"), tmp_id); #ifdef HAVE_SKYLINES_TRACKING_HANDLER } else if (item.IsSkyLines()) { if (!item.name.empty()) tmp = item.name.c_str(); else tmp.UnsafeFormat(_T("SkyLines %u"), item.skylines_id); #endif } else { tmp = _T("?"); } if (item.color != FlarmColor::NONE) { const TrafficLook &traffic_look = UIGlobals::GetLook().traffic; switch (item.color) { case FlarmColor::NONE: case FlarmColor::COUNT: gcc_unreachable(); case FlarmColor::GREEN: canvas.Select(traffic_look.team_pen_green); break; case FlarmColor::BLUE: canvas.Select(traffic_look.team_pen_blue); break; case FlarmColor::YELLOW: canvas.Select(traffic_look.team_pen_yellow); break; case FlarmColor::MAGENTA: canvas.Select(traffic_look.team_pen_magenta); break; } canvas.SelectHollowBrush(); const PixelSize size = canvas.CalcTextSize(tmp); canvas.Rectangle(rc.left + row_renderer.GetX() - frame_padding, rc.top + row_renderer.GetFirstY() - frame_padding, rc.left + row_renderer.GetX() + size.cx + frame_padding, rc.top + row_renderer.GetFirstY() + size.cy + frame_padding); } row_renderer.DrawFirstRow(canvas, rc, tmp); canvas.Select(small_font); /* draw bearing and distance on the right */ if (item.vector.IsValid()) { row_renderer.DrawRightFirstRow(canvas, rc, FormatUserDistanceSmart(item.vector.distance).c_str()); // Draw leg bearing rc.right = row_renderer.DrawRightSecondRow(canvas, rc, FormatBearing(item.vector.bearing).c_str()); } if (record != nullptr) { tmp.clear(); if (!record->pilot.empty()) tmp = record->pilot.c_str(); if (!record->plane_type.empty()) { if (!tmp.empty()) tmp.append(_T(" - ")); tmp.append(record->plane_type); } if (!record->airfield.empty()) { if (!tmp.empty()) tmp.append(_T(" - ")); tmp.append(record->airfield); } if (!tmp.empty()) row_renderer.DrawSecondRow(canvas, rc, tmp); #ifdef HAVE_SKYLINES_TRACKING_HANDLER } else if (item.IsSkyLines()) { if (CommonInterface::Basic().time_available) { tmp.UnsafeFormat(_("%u minutes ago"), SinceInMinutes(CommonInterface::Basic().time, item.time_of_day_ms)); } else tmp.clear(); if (!item.near_name.empty()) tmp.AppendFormat(_T(" near %s (%s)"), item.near_name.c_str(), FormatUserDistanceSmart(item.near_distance).c_str()); if (!tmp.empty()) tmp.append(_T("; ")); tmp.append(FormatUserAltitude(item.altitude)); if (!tmp.empty()) row_renderer.DrawSecondRow(canvas, rc, tmp); #endif } }
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); }
void WaypointInfoWidget::Prepare(ContainerWindow &parent, const PixelRect &rc) { RowFormWidget::Prepare(parent, rc); const MoreData &basic = CommonInterface::Basic(); const DerivedInfo &calculated = CommonInterface::Calculated(); const ComputerSettings &settings = CommonInterface::GetComputerSettings(); StaticString<64> buffer; if (!waypoint.comment.empty()) AddMultiLine(waypoint.comment.c_str()); if (waypoint.radio_frequency.IsDefined() && waypoint.radio_frequency.Format(buffer.buffer(), buffer.MAX_SIZE) != nullptr) { buffer += _T(" MHz"); AddReadOnly(_("Radio frequency"), nullptr, buffer); } if (waypoint.runway.IsDirectionDefined()) buffer.UnsafeFormat(_T("%02u"), waypoint.runway.GetDirectionName()); else buffer.clear(); if (waypoint.runway.IsLengthDefined()) { if (!buffer.empty()) buffer += _T("; "); TCHAR length_buffer[16]; FormatSmallUserDistance(length_buffer, fixed(waypoint.runway.GetLength())); buffer += length_buffer; } if (!buffer.empty()) AddReadOnly(_("Runway"), nullptr, buffer); if (FormatGeoPoint(waypoint.location, buffer.buffer(), buffer.MAX_SIZE) != nullptr) AddReadOnly(_("Location"), nullptr, buffer); FormatUserAltitude(waypoint.elevation, buffer.buffer(), buffer.MAX_SIZE); AddReadOnly(_("Elevation"), nullptr, buffer); if (basic.time_available && basic.date_time_utc.IsDatePlausible()) { const SunEphemeris::Result sun = SunEphemeris::CalcSunTimes(waypoint.location, basic.date_time_utc, settings.utc_offset); const BrokenTime sunrise = BreakHourOfDay(sun.time_of_sunrise); const BrokenTime sunset = BreakHourOfDay(sun.time_of_sunset); buffer.UnsafeFormat(_T("%02u:%02u - %02u:%02u"), sunrise.hour, sunrise.minute, sunset.hour, sunset.minute); AddReadOnly(_("Daylight time"), nullptr, buffer); } if (basic.location_available) { const GeoVector vector = basic.location.DistanceBearing(waypoint.location); TCHAR distance_buffer[32]; FormatUserDistanceSmart(vector.distance, distance_buffer, ARRAY_SIZE(distance_buffer)); FormatBearing(buffer.buffer(), buffer.MAX_SIZE, vector.bearing, distance_buffer); AddReadOnly(_("Bearing and Distance"), nullptr, buffer); } if (basic.location_available && basic.NavAltitudeAvailable() && settings.polar.glide_polar_task.IsValid()) { const GlideState glide_state(basic.location.DistanceBearing(waypoint.location), waypoint.elevation + settings.task.safety_height_arrival, basic.nav_altitude, calculated.GetWindOrZero()); GlidePolar gp0 = settings.polar.glide_polar_task; gp0.SetMC(fixed(0)); AddGlideResult(_("Alt. diff. MC 0"), MacCready::Solve(settings.task.glide, gp0, glide_state)); AddGlideResult(_("Alt. diff. MC safety"), MacCready::Solve(settings.task.glide, calculated.glide_polar_safety, glide_state)); AddGlideResult(_("Alt. diff. MC current"), MacCready::Solve(settings.task.glide, settings.polar.glide_polar_task, glide_state)); } if (basic.location_available && basic.NavAltitudeAvailable()) { const TaskBehaviour &task_behaviour = CommonInterface::GetComputerSettings().task; const fixed safety_height = task_behaviour.safety_height_arrival; const fixed target_altitude = waypoint.elevation + safety_height; const fixed delta_h = basic.nav_altitude - target_altitude; if (positive(delta_h)) { const fixed distance = basic.location.Distance(waypoint.location); const fixed gr = distance / delta_h; if (GradientValid(gr)) { buffer.UnsafeFormat(_T("%.1f"), (double)gr); AddReadOnly(_("Required glide ratio"), nullptr, buffer); } } } }