def paint(self, painter, option, widget): painter.setPen(new_pen(settings.colour('nav_aid'))) painter.drawEllipse(QPointF(0, 0), .33, .33) painter.drawPolygon( QPolygonF([ QPointF(-8, 0), QPointF(-3, -6), QPointF(3, -6), QPointF(8, 0), QPointF(3, 6), QPointF(-3, 6) ])) if self.navpoint.tacan: painter.setBrush(QBrush(settings.colour('nav_aid'))) poly = QPolygonF( [QPointF(-3, 6), QPointF(3, 6), QPointF(3, 8), QPointF(-3, 8)]) rot = QTransform() painter.drawPolygon(poly) rot.rotate(120) painter.drawPolygon(rot.map(poly)) rot.rotate(120) painter.drawPolygon(rot.map(poly)) elif self.navpoint.dme: painter.drawRect(-8, -6, 16, 12)
def paint(self, painter, option, widget): painter.setPen(new_pen(settings.colour('nav_aid'))) painter.drawEllipse(QPointF(0, 0), .33, .33) brush = QBrush(Qt.Dense6Pattern) brush.setColor(settings.colour('nav_aid')) painter.setPen(QPen(Qt.NoPen)) painter.setBrush(brush) painter.drawEllipse(QPointF(0, 0), 7, 7)
def paint(self, painter, option, widget): # 0,0 is threshold of first DirRunway col = runway_border_colours[self.occupation_indication] w = 0 if self.occupation_indication == 0 else 3 painter.setPen(new_pen(settings.colour(col), width=w)) if self.paved: painter.setBrush(QBrush(settings.colour('runway'))) painter.drawRect(self.rect)
def paint(self, painter, option, widget): # 0,0 is RWY THR and drawing down ILS_colour = settings.colour('LDG_guide_ILS') noILS_colour = settings.colour('LDG_guide_noILS') ILS_pen = new_pen(ILS_colour) noILS_pen = new_pen(noILS_colour) ILS_brush = QBrush(ILS_colour) noILS_brush = QBrush(noILS_colour) ## Centre line painter.setPen(noILS_pen if self.runway.LOC_range == None else ILS_pen) painter.drawLine(QPointF(0, LOC_line_RWY_sep_dist), QPointF(0, self.runway.param_disp_line_length)) ## GS altitude marks if self.scene().show_slope_altitudes: alt_step = self.GS_init_step dthr_dist = self.GS_init_dist while dthr_dist <= self.runway.param_disp_line_length: if dthr_dist < self.draw_GS_up_to: painter.setPen(ILS_pen) painter.setBrush(ILS_brush) else: painter.setPen(noILS_pen) painter.setBrush(noILS_brush) y = dthr_dist - self.dthr_NM for i in range(alt_step % 5): painter.drawLine(QPointF(-.12, y), QPointF(.12, y)) y += slope_tick_spacing hw = .6 * slope_tick_spacing # slope diamond half width for i in range(alt_step // 5): painter.drawPolygon(QPointF(-.15, y), QPointF(0, y - hw), QPointF(.15, y), QPointF(0, y + hw)) y += slope_tick_spacing alt_step += 1 dthr_dist += self.GS_step_dist ## Interception cone if self.runway.LOC_range != None and self.scene().show_interception_cones: cone_gradient = QConicalGradient(QPointF(0, 0), 270 - 2 * intercept_cone_half_angle) r = intercept_cone_half_angle / 180 cone_gradient.setColorAt(0, ILS_colour) cone_gradient.setColorAt(.9 * r, Qt.transparent) cone_gradient.setColorAt(1.1 * r, Qt.transparent) cone_gradient.setColorAt(2 * r, ILS_colour) cone_brush = QBrush(cone_gradient) painter.setPen(Qt.NoPen) painter.setBrush(cone_brush) p1 = QPointF(-self.draw_cone_half_width, self.runway.LOC_range) p2 = QPointF(self.draw_cone_half_width, self.runway.LOC_range) painter.drawPolygon(p1, QPointF(0, 0), p2) ## Marker beacons for md, ls, hl in (self.draw_OM, Qt.DashLine, .4), (self.draw_MM, Qt.DashDotLine, .25), (self.draw_IM, Qt.DotLine, .1): if md != None: painter.setPen(new_pen(ILS_colour, width=2, style=ls)) painter.drawLine(QPointF(-hl, md), QPointF(hl, md))
def paint(self, painter, option, widget): # Draw measuring line; the text box draws itslef painter.setPen(new_pen(settings.colour('measuring_tool'))) if self.altMode(): painter.drawLine(QPointF(0, 0), QPointF(0, self.mouseXY.y())) else: # Speed mode painter.drawLine(QPointF(0, 0), QPointF(self.mouseXY.x(), 0))
def paint(self, painter, option, widget): if self.mouse_highlight or self.scene().show_ground_networks: painter.setPen(QPen(Qt.NoPen)) brushcol = settings.colour(self.colour_name) brushcol.setAlpha(96 if self.mouse_highlight else 64) painter.setBrush(QBrush(brushcol)) painter.drawPath(self.shape)
def paint(self, painter, option, widget): # Draw taxi route; the text box draws itslef painter.setPen( new_pen( settings.colour('measuring_tool' if self. snapped_OK else 'assignment_bad'))) for p1, p2 in self.lines: painter.drawLine(p1, p2)
def ACFT_pen_colour(radar_contact): if radar_contact.ignored: return settings.colour('ACFT_ignored') strip = env.linkedStrip(radar_contact) if strip != None: # look for strip position colour (rack colour, overrides range colour) rack = strip.lookup(rack_detail) if rack != None and rack in settings.rack_colours: return settings.rack_colours[rack] sq = radar_contact.xpdrCode() if sq != None: # look for a range colour try: return next(rng for rng in settings.XPDR_assignment_ranges if rng.lo <= sq <= rng.hi and rng.col != None).col except StopIteration: pass # no range colour available return settings.colour( 'ACFT_unlinked') if strip == None else settings.colour('ACFT_linked')
def paint(self, painter, option, widget): coloured_pen = new_pen(ACFT_pen_colour(self.radar_contact)) # 1. Write info text painter.setPen(coloured_pen) painter.drawText(self.rectangle, Qt.AlignLeft | Qt.AlignVCenter, self.info_text) # 2. Draw container box? if self.paint_border: pen = coloured_pen if self.radar_contact is selection.acft else new_pen( settings.colour('radar_tag_line')) if self.radar_contact.individual_cheat: pen.setStyle(Qt.DashLine) painter.setPen(pen) painter.drawRect(self.rectangle)
def paint(self, painter, option, widget): if self.strip is selection.strip: painter.save() painter.setPen( new_pen(settings.colour('selection_indicator'), width=2)) painter.drawRect(self.boundingRect()) painter.restore() painter.save() painter.translate(option.rect.topLeft()) painter.translate(loose_strip_margin, loose_strip_margin) doc_rect = QRectF(0, 0, option.rect.width() - 2 * loose_strip_margin, option.rect.height() - 2 * loose_strip_margin) paint_strip_box(widget, painter, self.strip, doc_rect) painter.restore()
def paint_strip_box(parent_widget, painter, strip, rect): acft = strip.linkedAircraft() ### LINE 1 scs = strip.callsign(fpl=True) acs = None if acft == None else acft.xpdrCallsign() cs = some(scs, acs) if settings.strip_CPDLC_integration and cs != None and (acs == None or acs == scs): sdl = env.cpdlc.currentDataLink(cs) else: sdl = None ## Decorated callsign section callsign_section = '' # handover from fromATC = strip.lookup(received_from_detail) if fromATC != None: callsign_section += fromATC + ' >> ' # callsign(s) if sdl != None: callsign_section += '⚡ ' if sdl.status( ) == ConnectionStatus.OK else '[⚡] ' callsign_section += '<strong>%s</strong>' % some(cs, '?') if scs != None and acs != None and scs != acs: # callsign conflict with XPDR callsign_section += ' <strong>(%s)</strong>' % acs if strip.lookup(FPL.COMMENTS) != None: callsign_section += '*' # handover to toATC = strip.lookup(sent_to_detail) if toATC != None: callsign_section += ' >> ' + toATC if strip.lookup(duplicate_callsign_detail): # duplicate callsign warning callsign_section += ' !!dup' line1_sections = [callsign_section] ## Wake turb. cat. / aircraft type atyp = None if acft == None else acft.xpdrAcftType() typesec = some(strip.lookup(FPL.ACFT_TYPE, fpl=True), some(atyp, '')) wtc = strip.lookup(FPL.WTC, fpl=True) if wtc != None: typesec += '/%s' % wtc line1_sections.append(typesec) ## Optional sections # transponder code assSQ = strip.lookup(assigned_SQ_detail) if assSQ != None: if acft == None: # no ACFT linked line1_sections.append('sq=%04o' % assSQ) else: sq = acft.xpdrCode() if sq != None and sq != assSQ: line1_sections.append('sq=%04o (%04o)' % (assSQ, sq)) # conflicts conflicts = [] alert_lvl_hi = alert_lvl_lo = False if strip.transponderConflictList() != []: conflicts.append('!!XPDR') alert_lvl_hi = True if sdl != None and sdl.status() != ConnectionStatus.OK: conflicts.append('!!CPDLC') if sdl.status() == ConnectionStatus.PROBLEM: alert_lvl_hi = True else: alert_lvl_lo = True if settings.strip_route_vect_warnings: if len(strip.vectoringConflicts(env.QNH())) != 0: conflicts.append('!!vect') alert_lvl_lo = True elif strip.routeConflict(): conflicts.append('!!route') alert_lvl_lo = True if len(conflicts) > 0: line1_sections.append(' '.join(conflicts)) ### LINE 2 line2_sections = [] if settings.APP_spacing_hints: prev = env.strips.previousInSequence(strip) if prev != None: hint = spacing_hint(strip, prev) if hint != None: line2_sections.append('%s ' % hint) parsed_route = strip.lookup(parsed_route_detail) if parsed_route == None: arr = strip.lookup(FPL.ICAO_ARR, fpl=True) if arr != None: line2_sections.append(arr) elif acft == None: line2_sections.append(str(parsed_route)) else: line2_sections.append(parsed_route.toGoStr(acft.coords())) ## MAKE DOCUMENT html_line1 = ' '.join(line1_sections) html_line2 = ' '.join(line2_sections) doc = QTextDocument(parent_widget) doc.setHtml('<html><body><p>%s<br> %s</p></body></html>' % (html_line1, html_line2)) ## PAINT painter.save() ## Background and borders if acft == None: if strip.lookup(soft_link_detail) == None: bgcol = 'strip_unlinked' else: bgcol = 'strip_unlinked_identified' else: # an aircraft is linked if alert_lvl_hi: bgcol = 'strip_linked_alert' elif alert_lvl_lo: bgcol = 'strip_linked_warning' else: bgcol = 'strip_linked_OK' if strip is selection.strip: painter.setPen(new_pen(Qt.black, width=2)) else: painter.setPen(new_pen(Qt.darkGray)) painter.setBrush(QBrush(settings.colour(bgcol))) painter.drawRect(rect) painter.translate(rect.topLeft()) rules = strip.lookup(FPL.FLIGHT_RULES, fpl=True) if rules != None: # add a border along bottom edge of strip painter.setPen(Qt.NoPen) painter.setBrush( QBrush(Qt.black, style={ 'IFR': Qt.SolidPattern, 'VFR': Qt.BDiagPattern }.get(rules, Qt.NoBrush))) painter.drawRect(0, rect.height() - strip_IFR_border_width, rect.width(), strip_IFR_border_width) ## Text contents doc.drawContents( painter, QRectF(0, 0, rect.width(), rect.height() - strip_IFR_border_width)) painter.restore()
def paint(self, painter, option, widget): painter.setPen(new_pen(settings.colour('nav_fix'))) painter.drawPolygon( QPolygonF([QPointF(-3, 0), QPointF(0, -3), QPointF(3, 0)]))
def data(self, index, role): fpl = self.FPL_list[index.row()] col = index.column() if role == Qt.DisplayRole: if col == 0: if fpl.existsOnline() and fpl.needsUpload(): # not in sync with online version return '!!' elif col == 1: return some(fpl[FPL.CALLSIGN], '?') elif col == 2: return fpl.shortDescr_AD() elif col == 3: return fpl.shortDescr_time() elif role == Qt.DecorationRole: if col == 0: if fpl.existsOnline(): status = fpl.status() if status == FPL.FILED: dep = fpl[FPL.TIME_OF_DEP] if dep != None and now() > dep + FPL_outdated_delay: # outdated colour = settings.colour('FPL_filed_outdated') else: colour = settings.colour('FPL_filed') elif status == FPL.OPEN: eta = fpl.ETA() if eta == None: # warning colour = settings.colour('FPL_open_noETA') elif now() > eta: # overdue colour = settings.colour('FPL_open_overdue') else: colour = settings.colour('FPL_open') elif status == FPL.CLOSED: colour = settings.colour('FPL_closed') return coloured_square_icon(colour) elif role == Qt.ToolTipRole: if col == 0: if fpl.existsOnline(): status = fpl.status() if status == FPL.FILED: dep = fpl[FPL.TIME_OF_DEP] txt = 'Outdated' if dep != None and now() > dep + FPL_outdated_delay else 'Filed' elif status == FPL.OPEN: eta = fpl.ETA() if eta == None: # warning txt = 'Open, ETA unknown' else: txt = 'Open' minutes_overtime = int(round((now() - eta).total_seconds())) // 60 if minutes_overtime >= 1: txt += ', arrival overdue by %d h %02d min' % (minutes_overtime // 60, minutes_overtime % 60) elif status == FPL.CLOSED: txt = 'Closed' else: txt = 'Status N/A' if fpl.needsUpload(): txt += '\n(local changes)' return txt else: return 'Not online'
def paint(self, painter, option, widget): painter.setPen(new_pen(settings.colour('runway'))) painter.drawText(RunwayNameItem.brect, Qt.AlignHCenter | Qt.AlignTop, self.text)
def paint(self, painter, option, widget): painter.setPen(new_pen(settings.colour('runway'))) if self.paved: painter.setBrush(QBrush(settings.colour('runway'))) painter.drawRect(self.rect)
def paint(self, painter, option, widget): painter.setPen(new_pen(settings.colour('measuring_tool'))) painter.drawText(ToolTextItem.rectangle, Qt.AlignCenter, self.display_text)
def paint(self, painter, option, widget): painter.setPen(new_pen(settings.colour('ground_route_taxiway' if self.text != '' else 'ground_route_apron'))) painter.drawText(TaxiwayLabelItem.brect, Qt.AlignCenter, self.text)
def paint(self, painter, option, widget): painter.setPen( new_pen(settings.colour(self.colour_name), style=self.pen_style)) painter.drawEllipse(self.boundingRect())
def paint(self, painter, option, widget): painter.setPen(new_pen(settings.colour('AD_tarmac'))) painter.setBrush(QBrush(settings.colour('AD_tarmac')) if self.paved else QBrush()) painter.drawPath(self.path)
def __init__(self, parent): QGraphicsScene.__init__(self, parent) if TextBoxItem.txt_rect_2lines.isNull( ) or TextBoxItem.txt_rect_3lines.isNull(): TextBoxItem.setRectanglesFromFont(self.font()) self.prevent_mouse_release_deselect = False # CAUTION set by view on panning self.show_unlinked_tags = True self.show_all_vectors = False self.show_all_routes = False self.show_separation_rings = False self.show_selected_ACFT_assignments = False self.show_slope_altitudes = True self.show_interception_cones = False self.show_ground_networks = False self.show_taxiway_names = False self.show_GND_modes = True self.show_RDF_line = True self.lock_pan_zoom = False self.runway_names_always_visible = False self.speed_mark_count = init_speed_mark_count self.mouseover_highlights_groundnet_edges = False self.rdf_line_item = RdfLineItem() # radio direction finding self.point_indicator = PointIndicatorItem() self.measuring_tool = MeasuringToolItem() self.using_special_tool = False # Makes the difference between normal measuring and "special" tool self.setBackgroundBrush(settings.colour('radar_background')) self.additional_AD_items = [] # Create layers self.layers = {l: EmptyGraphicsItem() for l in Layer.radar_layer_names} for layer in self.layers.values(): self.addItem(layer) self.pinned_navpoints_layer = EmptyGraphicsItem() self.addItem(self.pinned_navpoints_layer) self.pinned_pkpos_layer = EmptyGraphicsItem() self.addItem(self.pinned_pkpos_layer) self.replaced_AD_items_layer = EmptyGraphicsItem() self.addItem(self.replaced_AD_items_layer) self.replaced_AD_items_layer.setVisible(False) # Populate radar back- and fore-ground if env.airport_data != None: for n in range(1, int(settings.map_range / bg_radar_circle_step) + 1): dist = n * bg_radar_circle_step self.addToLayer( Layer.RADAR_BACKGROUND, RadarCircleItem(dist, 'radar_circle', Qt.SolidLine)) self.radar_range_item = RadarCircleItem(settings.radar_range, 'radar_range_limit', Qt.DotLine) self.addToLayer(Layer.RADAR_BACKGROUND, self.radar_range_item) self.addToLayer(Layer.RADAR_FOREGROUND, self.point_indicator) self.addToLayer(Layer.RADAR_FOREGROUND, self.measuring_tool) self.addToLayer(Layer.RADAR_FOREGROUND, self.rdf_line_item) # Populate background images self.redrawBackgroundImages() # Populate airport objects if env.airport_data != None: self._drawAirportData( env.airport_data, False ) # things that are drawn for additional airports, but these do not reset # Populate navpoints for p in env.navpoints.findAll(types=navpoint_layers.keys()): if p.type == Navpoint.AD and p.code == settings.location_code: continue # do not draw base airport navpoint if p.type == Navpoint.VOR: base_item = NavVORItem(p) elif p.type == Navpoint.NDB: base_item = NavNDBItem(p) elif p.type == Navpoint.FIX: base_item = NavFixItem(p) elif p.type == Navpoint.RNAV: base_item = RnavItem(p) elif p.type == Navpoint.AD: base_item = NavAirfieldItem(p) label = '%s\n%s' % (p.code, p.frequency) if p.type in [ Navpoint.VOR, Navpoint.NDB ] else p.code item = MouseOverLabelledItem(base_item, navpoint_colours[p.type], self.pinned_navpoints_layer) item.setMouseOverText(label) item.setPos(p.coordinates.toQPointF()) self.addToLayer(navpoint_layers[p.type], item) # Populate aircraft already in contact for acft in env.radar.contacts(): self.addAircraftItem(acft) # External signal connections below. CAUTION: these must all be disconnected on widget deletion env.radar.blip.connect(self.updateAfterRadarBlip) env.radar.newContact.connect(self.addAircraftItem) env.radar.lostContact.connect(self.removeAircraftItem) env.strips.rwyBoxFilled.connect(self.updateRunways) env.strips.rwyBoxFreed.connect(self.updateRunways) env.rdf.signalChanged.connect(self.updateRdfLine) signals.aircraftKilled.connect(self.removeAircraftItem) signals.stripInfoChanged.connect(self.updateContacts) signals.selectionChanged.connect(self.updateAfterSelectionChanged) signals.runwayUseChanged.connect(self.updateRunwayNamesVisibility) signals.generalSettingsChanged.connect( self.updateAfterGeneralSettingsChanged ) # in case e.g. interpret XPDR FL toggle signals.localSettingsChanged.connect( self.updateAfterLocalSettingsChanged ) # in case e.g. RWY param changed signals.backgroundImagesReloaded.connect(self.redrawBackgroundImages) signals.colourConfigReloaded.connect(self.updateBgColours) signals.sessionEnded.connect(self.clearAircraftItems)
def paint(self, painter, option, widget): # Draw callout line; child text box draws itself pen = new_pen(settings.colour('radar_tag_line')) painter.setPen(pen) painter.drawLine(self.callout_line_start, self.callout_line_end)
def paint(self, painter, option, widget): if self.path != None: painter.setPen(new_pen(settings.colour(self.colour_name), width=self.width)) painter.drawPath(self.path)
def fillBackground(self): self.setBackgroundBrush(settings.colour('loose_strip_bay_background'))
def paint(self, painter, option, widget): # Draw measuring line; the text box draws itslef painter.setPen(new_pen(settings.colour('measuring_tool'))) painter.drawLine(QPointF(0, 0), self.mousePos)
def paint(self, painter, option, widget): painter.setPen(new_pen(settings.colour('RDF_line'), width=2)) painter.drawLine(0, 0, 0, -self.length)
def paint(self, painter, option, widget): painter.setPen(new_pen(settings.colour('AD_parking_position'))) painter.drawLine(QPointF(-.01, -.01), QPointF(.01, -.01)) painter.drawLine(QPointF(0, -.01), QPointF(0, .015))
def updateBgColours(self): self.setBackgroundBrush(settings.colour('radar_background'))
def paint(self, painter, option, widget): painter.setPen(new_pen(settings.colour(self.colour_name))) painter.drawText(self.boundingRect(), Qt.AlignCenter, self.text)
def paint(self, painter, option, widget): painter.setPen(new_pen(settings.colour('point_indicator'), width=2)) painter.drawEllipse(QPointF(0, 0), 12, 6) painter.drawEllipse(QPointF(0, 0), 6, 12)
def paint(self, painter, option, widget): painter.setPen(new_pen(settings.colour('measuring_tool'))) painter.drawText(self.boundingRect(), Qt.AlignCenter, self.display_text) #STYLE text bounding rect