void TargetMapWindow::RenderTopographyLabels(Canvas &canvas) { if (topography_renderer != NULL && SettingsMap().EnableTopography) topography_renderer->DrawLabels(canvas, projection, label_block, SettingsMap()); }
/** * Determine whether vario gauge, FLARM radar and infoboxes should be drawn */ void ActionInterface::DisplayModes() { // Determine whether the vario gauge should be drawn SetSettingsMap().EnableVarioGauge = vario_visible() && !SettingsMap().FullScreen; if (main_window.vario) { if (!SettingsMap().ScreenBlanked && SettingsMap().EnableVarioGauge) { main_window.vario->show(); } else { main_window.vario->hide(); } } if (Basic().NewTraffic) { // TODO bug: JMW: broken, currently won't work very well, needs to be reworked GaugeFLARM *gauge_flarm = main_window.flarm; if (gauge_flarm != NULL) gauge_flarm->Suppress = false; } if (SettingsMap().FullScreen) { InfoBoxManager::Hide(); } else { InfoBoxManager::Show(); } }
void GlueMapWindow::RenderTrail(Canvas &canvas, const RasterPoint aircraft_pos) const { unsigned min_time = 0; if (GetDisplayMode() == DM_CIRCLING) { min_time = max(0, (int)Basic().time - 600); } else { switch(SettingsMap().trail_length) { case TRAIL_OFF: return; case TRAIL_LONG: min_time = max(0, (int)Basic().time - 3600); break; case TRAIL_SHORT: min_time = max(0, (int)Basic().time - 600); break; case TRAIL_FULL: min_time = 0; // full break; } } DrawTrail(canvas, aircraft_pos, min_time, SettingsMap().EnableTrailDrift && GetDisplayMode() == DM_CIRCLING); }
void MapWindow::DrawCDI() { bool dodrawcdi = Calculated().Circling ? SettingsMap().EnableCDICircling : SettingsMap().EnableCDICruise; if (dodrawcdi) { cdi->show(); cdi->Update(Basic().TrackBearing, Calculated().WaypointBearing); } else { cdi->hide(); } }
void TargetMapWindow::RenderAirspace(Canvas &canvas) { if (SettingsMap().airspace.enable) airspace_renderer.Draw(canvas, #ifndef ENABLE_OPENGL buffer_canvas, stencil_canvas, #endif projection, Basic(), Calculated(), SettingsComputer(), SettingsMap()); }
void MapWindow::RenderTerrain(Canvas &canvas) { if (SettingsMap().terrain.slope_shading == sstWind) m_background.sun_from_wind(render_projection, Calculated().wind); else m_background.set_sun_angle(render_projection, SettingsMap().terrain.slope_shading == sstSun ? Calculated().SunAzimuth : Angle::degrees(fixed(-45.0))); m_background.Draw(canvas, render_projection, SettingsMap().terrain); }
void TargetMapWindow::RenderTerrain(Canvas &canvas) { if (SettingsMap().terrain.slope_shading == sstWind) background.sun_from_wind(projection, Calculated().wind); else background.set_sun_angle(projection, (Basic().location_available && SettingsMap().terrain.slope_shading == sstSun) ? Calculated().sun_azimuth : Angle::degrees(fixed(-45.0))); background.Draw(canvas, projection, SettingsMap().terrain); }
void MapWindow::DrawTask(Canvas &canvas) { if (task == NULL) return; ProtectedTaskManager::Lease task_manager(*task); const AbstractTask *task = task_manager->get_active_task(); if (task == NULL || !task->check_task()) return; /* RLD bearing is invalid if GPS not connected and in non-sim mode, but we can still draw targets */ const bool draw_bearing = Basic().gps.Connected; RenderObservationZone ozv; RenderTaskPointMap tpv(canvas, #ifdef ENABLE_OPENGL /* OpenGL doesn't have the BufferCanvas class */ NULL, #else &buffer_canvas, #endif render_projection, SettingsMap(), /* we're accessing the OrderedTask here, which may be invalid at this point, but it will be used only if active, so it's ok */ task_manager->get_ordered_task().get_task_projection(), ozv, draw_bearing, Basic().Location); RenderTask dv(tpv, render_projection.GetScreenBounds()); ((TaskVisitor &)dv).Visit(*task); }
/** * Render the AAT areas and airspace * @param canvas The drawing canvas * @param rc The area to draw in */ void MapWindow::RenderAreas(Canvas &canvas, const RECT &rc) { // Draw airspace on top if (SettingsMap().OnAirSpace > 0) DrawAirspace(canvas, buffer_canvas); }
/** * Send the own SettingsMap to the DeviceBlackboard * @param trigger_draw Triggers the draw event after sending if true */ void ActionInterface::SendSettingsMap(const bool trigger_draw) { // trigger_draw: asks for an immediate exchange of blackboard data // (via ProcessTimer()) rather than waiting for the idle timer every 500ms if (trigger_draw) { DisplayModes(); InfoBoxManager::ProcessTimer(); } // Copy InterfaceBlackboard.SettingsMap to the DeviceBlackboard ScopeLock protect(mutexBlackboard); device_blackboard.ReadSettingsMap(SettingsMap()); #ifdef ENABLE_OPENGL if (trigger_draw) main_window.map.invalidate(); #else if (trigger_draw) draw_thread->trigger_redraw(); #endif // TODO: trigger refresh if the settings are changed }
void TargetMapWindow::DrawTask(Canvas &canvas) { if (task == NULL) return; ProtectedTaskManager::Lease task_manager(*task); const AbstractTask *task = task_manager->get_active_task(); if (task && task->check_task()) { RenderObservationZone ozv(task_look, airspace_renderer.GetLook()); RenderTaskPointMap tpv(canvas, #ifdef ENABLE_OPENGL /* OpenGL doesn't have the BufferCanvas class */ NULL, #else &buffer_canvas, #endif projection, SettingsMap(), task_look, /* we're accessing the OrderedTask here, which may be invalid at this point, but it will be used only if active, so it's ok */ task_manager->get_ordered_task().get_task_projection(), ozv, false, true, Basic().location); RenderTask dv(tpv, projection.GetScreenBounds()); ((TaskVisitor &)dv).Visit(*task); } }
void MapWindow::DrawTrail(Canvas &canvas, const RasterPoint aircraft_pos, unsigned min_time, bool enable_traildrift) const { if (glide_computer) TrailRenderer::Draw(canvas, *glide_computer, render_projection, min_time, enable_traildrift, aircraft_pos, Basic(), Calculated(), SettingsMap()); }
void MapWindow::DrawProjectedTrack(Canvas &canvas) { if (task == NULL || !task->Valid() || !task->getSettings().AATEnabled || task->getActiveIndex() ==0) return; if (Calculated().Circling || task->TaskIsTemporary()) { // don't display in various modes return; } // TODO feature: maybe have this work even if no task? // TODO feature: draw this also when in target pan mode GEOPOINT start = Basic().Location; GEOPOINT previous_loc = task->getTargetLocation(task->getActiveIndex() - 1); double distance_from_previous, bearing; DistanceBearing(previous_loc, start, &distance_from_previous, &bearing); if (distance_from_previous < 100.0) { bearing = Basic().TrackBearing; // too short to have valid data } POINT pt[2] = {{0,-75},{0,-400}}; if (SettingsMap().TargetPan) { double screen_range = GetScreenDistanceMeters(); double f_low = 0.4; double f_high = 1.5; screen_range = max(screen_range, Calculated().WaypointDistance); GEOPOINT p1, p2; FindLatitudeLongitude(start, bearing, f_low*screen_range, &p1); FindLatitudeLongitude(start, bearing, f_high*screen_range, &p2); LonLat2Screen(p1, pt[0]); LonLat2Screen(p2, pt[1]); } else if (fabs(bearing-Calculated().WaypointBearing)<10) { // too small an error to bother return; } else { pt[1].y = (long)(-max(MapRectBig.right-MapRectBig.left, MapRectBig.bottom-MapRectBig.top)*1.2); PolygonRotateShift(pt, 2, Orig_Aircraft.x, Orig_Aircraft.y, bearing-DisplayAngle); } Pen dash_pen(Pen::DASH, IBLSCALE(2), Color(0, 0, 0)); canvas.select(dash_pen); canvas.line(pt[0], pt[1]); }
/** * Renders the aircraft, the FLARM targets and the wind arrow * @param canvas The drawing canvas * @param rc The area to draw in */ void MapWindow::RenderAirborne(Canvas &canvas, const RECT &rc) { // Draw wind vector at aircraft if (!SettingsMap().EnablePan) DrawWindAtAircraft2(canvas, projection.GetOrigAircraft(), rc); else if (SettingsMap().TargetPan) DrawWindAtAircraft2(canvas, projection.GetOrigScreen(), rc); // Draw traffic DrawTeammate(canvas); DrawFLARMTraffic(canvas); // Draw center screen cross hair in pan mode if (SettingsMap().EnablePan && !SettingsMap().TargetPan) DrawCrossHairs(canvas); // Finally, draw you! if (Basic().gps.Connected) DrawAircraft(canvas); }
/** * Determine whether vario gauge, FLARM radar and infoboxes should be drawn */ void ActionInterface::DisplayModes() { bool full_screen = main_window.GetFullScreen(); // Determine whether the vario gauge should be drawn SetSettingsMap().EnableVarioGauge = vario_visible() && !full_screen; if (main_window.vario) { if (!SettingsMap().ScreenBlanked && SettingsMap().EnableVarioGauge) main_window.vario->show(); else main_window.vario->hide(); } if (Basic().flarm.NewTraffic) { GaugeFLARM *gauge_flarm = main_window.flarm; if (gauge_flarm != NULL) gauge_flarm->Suppress = false; } }
void TargetMapWindow::DrawWaypoints(Canvas &canvas) { const SETTINGS_MAP &settings_map = SettingsMap(); WaypointRendererSettings settings = settings_map.waypoint; settings.display_text_type = DISPLAYNAME; way_point_renderer.render(canvas, label_block, projection, settings, SettingsComputer().task, task, NULL); }
void MapWindow::DrawWaypoints(Canvas &canvas) { GlidePolar polar = get_glide_polar(); polar.set_mc(min(Calculated().common_stats.current_risk_mc, SettingsComputer().safety_mc)); way_point_renderer.render(canvas, label_block, render_projection, SettingsMap(), SettingsComputer(), polar, ToAircraftState(Basic()), task); }
/** * Renders the terrain background, the groundline and the topology * @param canvas The drawing canvas * @param rc The area to draw in */ void MapWindow::RenderMapLayer(Canvas &canvas) { m_background.sun_from_wind(projection, Basic().wind); m_background.Draw(canvas, projection, SettingsMap()); // Select black brush/pen and the MapWindowFont canvas.black_brush(); canvas.black_pen(); canvas.select(Fonts::Map); if (terrain != NULL) { if ((SettingsComputer().FinalGlideTerrain == 2) && Calculated().TerrainValid) // Draw the groundline (and shading) DrawTerrainAbove(canvas, buffer_canvas); } if (topology != NULL && SettingsMap().EnableTopology) // Draw the topology topology->Draw(canvas, bitmap_canvas, projection); }
void GlueMapWindow::QuickRedraw(const SETTINGS_MAP &_settings_map) { assert(&_settings_map != &SettingsMap()); ReadSettingsMap(_settings_map); /* update the Projection */ visible_projection.CalculateOrigin(get_client_rect(), Basic(), Calculated(), SettingsComputer(), SettingsMap()); visible_projection.ExchangeBlackboard(Calculated(), SettingsMap()); ++ui_generation; /* quickly stretch the existing buffer into the window */ scale_buffer = 2; invalidate(); }
/** * Draw the AAT areas to the buffer and copy the buffer to the drawing canvas * @param canvas The drawing canvas * @param rc The area to draw in * @param buffer The drawing buffer */ void MapWindow::DrawTaskAAT(Canvas &canvas, const RECT rc, Canvas &buffer) { if (way_points == NULL || task == NULL) return; if (task->getSettings().AATEnabled) { DrawTaskAATVisitor dv(canvas, rc, buffer, task->getActiveIndex(), task_screen, *this, SettingsMap(), *way_points); task->scan_point_forward(dv, false); // read lock // TODO, reverse canvas.copy_transparent_white(buffer, rc); } }
bool XCSoarInterface::Debounce(void) { static PeriodClock fps_last; ResetDisplayTimeOut(); InterfaceTimeoutReset(); if (SettingsMap().ScreenBlanked) { // prevent key presses working if screen is blanked, // so a key press just triggers turning the display on again return false; } return fps_last.check_update(debounceTimeout); }
/** * Calculates the screen positions of all important features * @param canvas The drawing canvas * @param rc The area to draw in */ void MapWindow::RenderStart(Canvas &canvas, const RECT &rc) { // Calculate screen position of the aircraft projection.CalculateOrigin(rc, Basic(), Calculated(), SettingsComputer(), SettingsMap()); // Calculate screen positions of the thermal sources CalculateScreenPositionsThermalSources(); // Calculate screen positions of the final glide groundline CalculateScreenPositionsGroundline(); // reset label over-write preventer label_block.reset(); }
/** * Send the own SettingsMap to the DeviceBlackboard * @param trigger_draw Triggers the draw event after sending if true */ void ActionInterface::SendSettingsMap(const bool trigger_draw) { // QUESTION TB: what is trigger_draw? ScopeLock protect(mutexBlackboard); if (trigger_draw) { DisplayModes(); InfoBoxManager::ProcessTimer(); } // Copy InterfaceBlackboard.SettingsMap to the DeviceBlackboard device_blackboard.ReadSettingsMap(SettingsMap()); if (trigger_draw) { drawTriggerEvent.trigger(); } // TODO: trigger refresh if the settings are changed }
// Debounce input buttons (does not matter which button is pressed) bool XCSoarInterface::Debounce(void) { #if defined(GNAV) || defined(PCGNAV) return true; #else static PeriodClock fps_last; ResetDisplayTimeOut(); if (SettingsMap().ScreenBlanked) // prevent key presses working if screen is blanked, // so a key press just triggers turning the display on again return false; return fps_last.check_update(debounceTimeout); #endif }
/** * Draw the final glide groundline (and shading) to the buffer * and copy the transparent buffer to the canvas * @param canvas The drawing canvas * @param rc The area to draw in * @param buffer The drawing buffer */ void MapWindow::DrawTerrainAbove(Canvas &canvas) { if (!Basic().flight.Flying || SettingsMap().EnablePan) return; #ifdef ENABLE_OPENGL glClearStencil(0); glClear(GL_STENCIL_BUFFER_BIT); glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE); glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); canvas.polygon(Groundline, TERRAIN_ALT_INFO::NUMTERRAINSWEEPS); glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); glStencilFunc(GL_NOTEQUAL, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glColor4f(1.0, 1.0, 1.0, 0.3); GLFillRectangle(0, 0, canvas.get_width(), canvas.get_height()); glDisable(GL_BLEND); glDisable(GL_STENCIL_TEST); #else Canvas &buffer = buffer_canvas; buffer.set_background_color(Color::WHITE); buffer.set_text_color(Color(0xf0,0xf0,0xf0)); buffer.clear(Graphics::hAboveTerrainBrush); buffer.null_pen(); buffer.white_brush(); buffer.polygon(Groundline, TERRAIN_ALT_INFO::NUMTERRAINSWEEPS); canvas.copy_transparent_white(buffer); #endif }
void MapWindow::DrawGlideThroughTerrain(Canvas &canvas) { canvas.select(MapGfx.hpTerrainLineBg); canvas.polyline(Groundline, NUMTERRAINSWEEPS + 1); if ((SettingsComputer().FinalGlideTerrain==1) || ((!SettingsMap().EnableTerrain || !Calculated().Flying) && (SettingsComputer().FinalGlideTerrain==2))) { canvas.select(MapGfx.hpTerrainLine); canvas.polyline(Groundline, NUMTERRAINSWEEPS + 1); } if (Calculated().Flying && task.Valid()) { if ((Calculated().TerrainWarningLocation.Latitude != 0.0) &&(Calculated().TerrainWarningLocation.Longitude != 0.0)) { draw_masked_bitmap_if_visible(canvas, MapGfx.hTerrainWarning, Calculated().TerrainWarningLocation, 10, 10); } } }
void TargetMapWindow::on_paint_buffer(Canvas &canvas) { #ifdef ENABLE_OPENGL /* enable clipping */ GLCanvasScissor scissor(canvas); #endif // Calculate screen position of the aircraft const RasterPoint aircraft_pos = projection.GeoToScreen(Basic().location); // reset label over-write preventer label_block.reset(); // Render terrain, groundline and topography RenderTerrain(canvas); RenderTopography(canvas); // Render airspace RenderAirspace(canvas); // Render task, waypoints DrawTask(canvas); DrawWaypoints(canvas); // Render the snail trail RenderTrail(canvas); // Render topography on top of airspace, to keep the text readable RenderTopographyLabels(canvas); // Finally, draw you! if (Basic().connected) AircraftRenderer::Draw(canvas, SettingsMap(), aircraft_look, Calculated().heading - projection.GetScreenAngle(), aircraft_pos); }
void MapWindow::DrawWaypoints(Canvas &canvas) { if (way_points == NULL) return; TCHAR Buffer[32]; TCHAR Buffer2[32]; TCHAR sAltUnit[4]; TextInBoxMode_t TextDisplayMode; // if pan mode, show full names int pDisplayTextType = SettingsMap().DisplayTextType; if (SettingsMap().EnablePan) { pDisplayTextType = DISPLAYNAME; } _tcscpy(sAltUnit, Units::GetAltitudeName()); MapWaypointLabelClear(); for (unsigned i = 0; way_points->verify_index(i); ++i) { const WAYPOINT &way_point = way_points->get(i); const WPCALC &wpcalc = way_points->get_calc(i); if (wpcalc.Visible) { bool irange = false; bool islandable = false; bool dowrite; dowrite = wpcalc.InTask; TextDisplayMode.AsInt = 0; irange = WaypointInScaleFilter(way_point); Bitmap *wp_bmp = &MapGfx.hSmall; if(GetMapScaleKM() > 20) { wp_bmp = &MapGfx.hSmall; } else if( ((way_point.Flags & AIRPORT) == AIRPORT) || ((way_point.Flags & LANDPOINT) == LANDPOINT) ) { islandable = true; // so we can always draw them if (wpcalc.Reachable) { TextDisplayMode.AsFlag.Reachable = 1; if ((SettingsMap().DeclutterLabels<2)||wpcalc.InTask) { if (wpcalc.InTask || (SettingsMap().DeclutterLabels<1)) { TextDisplayMode.AsFlag.Border = 1; } // show all reachable landing fields unless we want a decluttered // screen. dowrite = true; } if ((way_point.Flags & AIRPORT) == AIRPORT) wp_bmp = &MapGfx.hBmpAirportReachable; else wp_bmp = &MapGfx.hBmpFieldReachable; } else { if ((way_point.Flags & AIRPORT) == AIRPORT) wp_bmp = &MapGfx.hBmpAirportUnReachable; else wp_bmp = &MapGfx.hBmpFieldUnReachable; } } else { if (GetMapScaleKM()>4) { wp_bmp = &MapGfx.hTurnPoint; } else { wp_bmp = &MapGfx.hSmall; } } if (wpcalc.InTask) { // VNT TextDisplayMode.AsFlag.WhiteBold = 1; } if(irange || wpcalc.InTask || islandable || dowrite) { draw_masked_bitmap(canvas, *wp_bmp, wpcalc.Screen.x, wpcalc.Screen.y, 20, 20); } if(wpcalc.InTask || irange || dowrite) { bool draw_alt = TextDisplayMode.AsFlag.Reachable && ((SettingsMap().DeclutterLabels<1) || wpcalc.InTask); switch(pDisplayTextType) { case DISPLAYNAMEIFINTASK: dowrite = wpcalc.InTask; if (wpcalc.InTask) { if (draw_alt) _stprintf(Buffer, TEXT("%s:%d%s"), way_point.Name, (int)(wpcalc.AltArrivalAGL*ALTITUDEMODIFY), sAltUnit); else _stprintf(Buffer, TEXT("%s"),way_point.Name); } break; case DISPLAYNAME: dowrite = (SettingsMap().DeclutterLabels<2) || wpcalc.InTask; if (draw_alt) _stprintf(Buffer, TEXT("%s:%d%s"), way_point.Name, (int)(wpcalc.AltArrivalAGL*ALTITUDEMODIFY), sAltUnit); else _stprintf(Buffer, TEXT("%s"),way_point.Name); break; case DISPLAYNUMBER: dowrite = (SettingsMap().DeclutterLabels<2) || wpcalc.InTask; if (draw_alt) _stprintf(Buffer, TEXT("%d:%d%s"), way_point.Number, (int)(wpcalc.AltArrivalAGL*ALTITUDEMODIFY), sAltUnit); else _stprintf(Buffer, TEXT("%d"),way_point.Number); break; case DISPLAYFIRSTFIVE: dowrite = (SettingsMap().DeclutterLabels<2) || wpcalc.InTask; _tcsncpy(Buffer2, way_point.Name, 5); Buffer2[5] = '\0'; if (draw_alt) _stprintf(Buffer, TEXT("%s:%d%s"), Buffer2, (int)(wpcalc.AltArrivalAGL*ALTITUDEMODIFY), sAltUnit); else _stprintf(Buffer, TEXT("%s"),Buffer2); break; case DISPLAYFIRSTTHREE: dowrite = (SettingsMap().DeclutterLabels<2) || wpcalc.InTask; _tcsncpy(Buffer2, way_point.Name, 3); Buffer2[3] = '\0'; if (draw_alt) _stprintf(Buffer, TEXT("%s:%d%s"), Buffer2, (int)(wpcalc.AltArrivalAGL*ALTITUDEMODIFY), sAltUnit); else _stprintf(Buffer, TEXT("%s"),Buffer2); break; case DISPLAYNONE: dowrite = (SettingsMap().DeclutterLabels<2) || wpcalc.InTask; if (draw_alt) _stprintf(Buffer, TEXT("%d%s"), (int)(wpcalc.AltArrivalAGL*ALTITUDEMODIFY), sAltUnit); else Buffer[0]= '\0'; break; default: assert(0); break; } if (dowrite) { MapWaypointLabelAdd( Buffer, wpcalc.Screen.x + 5, wpcalc.Screen.y, TextDisplayMode, (int)(wpcalc.AltArrivalAGL*ALTITUDEMODIFY), wpcalc.InTask,false,false,false, MapRect); } } } } MapWaypointLabelSortAndRender(canvas); }
void MapWindow::DrawCompass(Canvas &canvas, const RECT rc) { POINT Start; if (Appearance.CompassAppearance == apCompassDefault){ Start.y = IBLSCALE(19)+rc.top; Start.x = rc.right - IBLSCALE(19); if (SettingsMap().EnableVarioGauge && MapRectBig.right == rc.right) Start.x -= InfoBoxLayout::ControlWidth; POINT Arrow[5] = { {0,-18}, {-6,10}, {0,0}, {6,10}, {0,-18}}; canvas.select(MapGfx.hpCompass); canvas.select(MapGfx.hbCompass); // North arrow PolygonRotateShift(Arrow, 5, Start.x, Start.y, -DisplayAngle); canvas.polygon(Arrow, 5); } else if (Appearance.CompassAppearance == apCompassAltA) { static double lastDisplayAngle = 9999.9; static int lastRcRight = 0; static POINT Arrow[5] = { {0,-11}, {-5,9}, {0,3}, {5,9}, {0,-11}}; if (lastDisplayAngle != DisplayAngle || lastRcRight != rc.right){ Arrow[0].x = 0; Arrow[0].y = -11; Arrow[1].x = -5; Arrow[1].y = 9; Arrow[2].x = 0; Arrow[2].y = 3; Arrow[3].x = 5; Arrow[3].y = 9; Arrow[4].x = 0; Arrow[4].y = -11; Start.y = rc.top + IBLSCALE(10); Start.x = rc.right - IBLSCALE(11); if (SettingsMap().EnableVarioGauge && MapRectBig.right == rc.right) { Start.x -= InfoBoxLayout::ControlWidth; } // North arrow PolygonRotateShift(Arrow, 5, Start.x, Start.y, -DisplayAngle); lastDisplayAngle = DisplayAngle; lastRcRight = rc.right; } canvas.polygon(Arrow, 5); canvas.select(MapGfx.hpCompass); canvas.polygon(Arrow, 5); } }
void MapWindow::DrawHorizon(Canvas &canvas, const RECT rc) { POINT Start; Start.y = IBLSCALE(55)+rc.top; Start.x = rc.right - IBLSCALE(19); if (SettingsMap().EnableVarioGauge && MapRectBig.right == rc.right) Start.x -= InfoBoxLayout::ControlWidth; Pen hpHorizonSky(IBLSCALE(1), Color(0x40,0x40,0xff)); Brush hbHorizonSky(Color(0xA0,0xA0,0xff)); Pen hpHorizonGround(IBLSCALE(1), Color(106,55,12)); Brush hbHorizonGround(Color(157,101,60)); int radius = IBLSCALE(17); double phi = max(-89,min(89,Calculated().BankAngle)); double alpha = RAD_TO_DEG *acos(max(-1.0,min(1.0,Calculated().PitchAngle/50.0))); double alpha1 = 180-alpha-phi; double alpha2 = 180+alpha-phi; canvas.select(hpHorizonSky); canvas.select(hbHorizonSky); canvas.segment(Start.x, Start.y, radius, rc, alpha2, alpha1, true); canvas.select(hpHorizonGround); canvas.select(hbHorizonGround); canvas.segment(Start.x, Start.y, radius, rc, alpha1, alpha2, true); /* POINT a1, a2; a1.x = Start.x + fastsine(alpha1)*radius; a1.y = Start.y - fastcosine(alpha1)*radius; a2.x = Start.x + fastsine(alpha2)*radius; a2.y = Start.y - fastcosine(alpha2)*radius; ClipDrawLine(hDC, PS_SOLID, IBLSCALE(1), a1, a2, RGB(0,0,0)); */ Pen dash_pen(Pen::DASH, 2, Color(0, 0, 0)); canvas.select(dash_pen); canvas.line(Start.x + radius / 2, Start.y, Start.x - radius / 2, Start.y); canvas.line(Start.x, Start.y - radius / 4, Start.x - radius / 2, Start.y); // #define ROOT2 0.70711 int rr2p = lround(radius*ROOT2+IBLSCALE(1)); int rr2n = lround(radius*ROOT2); Pen penb1(Pen::SOLID, 1, Color(0,0,0)); canvas.select(penb1); canvas.line(Start.x + rr2p, Start.y - rr2p, Start.x + rr2n, Start.y - rr2n); canvas.line(Start.x - rr2p, Start.y - rr2p, Start.x - rr2n, Start.y - rr2n); // JMW experimental, display stall sensor double s = max(0.0,min(1.0,Basic().StallRatio)); long m = (long)((rc.bottom-rc.top)*s*s); Pen penr2(Pen::SOLID, 1, Color(0,0,0)); canvas.select(penr2); canvas.line(rc.right - 1, rc.bottom - m, rc.right - 11, rc.bottom - m); }