def shape(self): path = QPainterPath() path.setFillRule(Qt.WindingFill) path.addRect(self.rect()) for handle in self.handles: path.addRect(handle.boundingRect()) return path
def __paint_title_background(self, painter: "QPainter"): """Paints a little background behind the title text, at the top of the node.""" title_rect = self.__graphics_title.boundingRect() path_title_background = QPainterPath() path_title_background.setFillRule(Qt.WindingFill) path_title_background.addRoundedRect( 0, 0, self.background_paint_area().width(), title_rect.height(), self.round_edge_size, self.round_edge_size, ) # (Drawing rects to hide the two botton round edges) path_title_background.addRect( 0, title_rect.height() - self.round_edge_size, self.round_edge_size, self.round_edge_size, ) path_title_background.addRect( self.background_paint_area().width() - self.round_edge_size, title_rect.height() - self.round_edge_size, self.round_edge_size, self.round_edge_size, ) painter.setPen(Qt.NoPen) painter.setBrush(self.__title_background_brush) painter.drawPath(path_title_background.simplified())
def shape(self): """ Returns the shape of this item as a QPainterPath in local coordinates. The shape could be used for many things, like collision detection. :return: Returns the shape of this item as a QPainterPath in local coordinates. :rtype: QPainterPath """ path = QPainterPath() path.addRect(self.boundingRect()) return path
def paint(self, painter, option, widget): # pylint: disable=unused-argument """ Draw the minimap outline and viewport box. """ # Minimap outline painter.setPen(QPen(Conf.palette_mid, self.PEN_WIDTH)) path = QPainterPath() path.addRect(self._scene_rect) painter.drawPath(path) # Viewport box painter.setPen( QPen(Conf.disasm_view_minimap_viewport_color, self.PEN_WIDTH)) path = QPainterPath() path.addRect(self._viewport_rect) painter.drawPath(path)
def paintPagesView(self): # This method paints the page layout, nothing more # It also paints the background at page breaks # The design is drawn only when the editor is in page mode. if (self.m_usePageMode): # Draw page breaks pageWidth = self.m_pageMetrics.pxPageSize().width() pageHeight = self.m_pageMetrics.pxPageSize().height() p = QPainter(self.viewport()) borderPen = QPen(self.palette().dark(), 1) curHeight = pageHeight - (self.verticalScrollBar().value() % pageHeight) # Horizontal offset if there is a scroll bar horizontalDelta = self.horizontalScrollBar().value() # Paint page views while there are remotely more visible pages while (curHeight < pageHeight + self.height()): p.setRenderHint(QPainter.Antialiasing) path = QPainterPath() # In painting page, height of the rect is (pageHeight - 10) # to give page break pageLayout = QRectF(0 - horizontalDelta, curHeight - pageHeight, pageWidth, pageHeight - 10) path.addRect(pageLayout) p.fillPath(path, Qt.white) p.setPen(borderPen) p.drawPath(path) # Go to next page curHeight += pageHeight
def shape(self): """Returns a shape containing the entire bounding rect, to work better with icon transparency.""" path = QPainterPath() path.addRect(self.boundingRect()) return path
class QBlock(QCachedGraphicsItem): TOP_PADDING = 5 BOTTOM_PADDING = 5 LEFT_PADDING = 10 RIGHT_PADDING = 10 SPACING = 0 def __init__(self, workspace, func_addr, disasm_view, disasm, infodock, addr, cfg_nodes, out_branches, parent=None): super().__init__(parent=parent) # initialization self.workspace = workspace self.func_addr = func_addr self.disasm_view = disasm_view self.disasm = disasm self.infodock = infodock self.variable_manager = infodock.variable_manager self.addr = addr self.cfg_nodes = cfg_nodes self.out_branches = out_branches self._config = Conf self.objects = [] # instructions and labels self._block_item = None # QPath self.addr_to_insns = {} self.addr_to_labels = {} self._init_widgets() self._objects_are_hidden = False self._create_block_item() # # Properties # @property def mode(self): raise NotImplementedError @property def width(self): return self.boundingRect().width() @property def height(self): return self.boundingRect().height() # # Public methods # def refresh_if_contains_addr(self, addr1, addr2): if addr1 in self.addr_to_insns or addr2 in self.addr_to_insns: self.refresh() def refresh(self): for obj in self.objects: obj.refresh() self.recalculate_size() self._create_block_item() self.update() def size(self): return self.width, self.height def instruction_position(self, insn_addr): if insn_addr in self.addr_to_insns: insn = self.addr_to_insns[insn_addr] pos = insn.pos() return pos.x(), pos.y() return None # # Initialization # def _create_block_item(self): """ Create the block background and border. """ self._block_item = QPainterPath() self._block_item.addRect(0, 0, self.width, self.height) def _init_widgets(self): self.objects.clear() block_objects = get_block_objects(self.disasm, self.cfg_nodes, self.func_addr) for obj in block_objects: if isinstance(obj, Instruction): out_branch = get_out_branches_for_insn(self.out_branches, obj.addr) insn = QInstruction(self.workspace, self.func_addr, self.disasm_view, self.disasm, self.infodock, obj, out_branch, self._config, parent=self) self.objects.append(insn) self.addr_to_insns[obj.addr] = insn elif isinstance(obj, Label): # label label = QBlockLabel(obj.addr, obj.text, self._config, self.disasm_view, self.workspace, parent=self) self.objects.append(label) self.addr_to_labels[obj.addr] = label elif isinstance(obj, PhiVariable): if not isinstance(obj.variable, SimRegisterVariable): phivariable = QPhiVariable(self.workspace, self.disasm_view, obj, self._config, parent=self) self.objects.append(phivariable) elif isinstance(obj, Variables): for var in obj.variables: variable = QVariable(self.workspace, self.disasm_view, var, self._config, parent=self) self.objects.append(variable) self.layout_widgets() def layout_widgets(self): raise NotImplementedError()
def shape(self) -> QPainterPath: path = QPainterPath() path.addRect(14, 14, 82, 82) return path
class QBlock(QCachedGraphicsItem): TOP_PADDING = 5 BOTTOM_PADDING = 5 LEFT_PADDING = 10 RIGHT_PADDING = 10 SPACING = 0 def __init__(self, workspace, func_addr, disasm_view, disasm, infodock, addr, cfg_nodes, out_branches, scene, parent=None, container=None): super().__init__(parent=parent, container=container) # initialization self.workspace = workspace self.func_addr = func_addr self.disasm_view = disasm_view self.disasm = disasm self.infodock = infodock self.variable_manager = infodock.variable_manager self.addr = addr self.cfg_nodes = cfg_nodes self.out_branches = out_branches self._scene = scene self.margins = QMarginsF(self.LEFT_PADDING, self.TOP_PADDING, self.RIGHT_PADDING, self.BOTTOM_PADDING) self._config = Conf self.objects = [] # instructions and labels self._block_item = None # type: QPainterPath self._block_item_obj = None # type: QGraphicsPathItem self.qblock_annotations = None self.addr_to_insns = {} self.addr_to_labels = {} self._init_widgets() self._objects_are_hidden = False self._create_block_item() self.setAcceptHoverEvents(True) # # Properties # @property def mode(self): raise NotImplementedError @property def width(self): return self.boundingRect().width() @property def height(self): return self.boundingRect().height() # # Public methods # def clear_cache(self): super().clear_cache() for obj in self.objects: obj.clear_cache() def refresh(self): for obj in self.objects: obj.refresh() self.layout_widgets() self.recalculate_size() self._create_block_item() self.update() def reload(self): self._init_widgets() self.refresh() def size(self): return self.width, self.height def instruction_position(self, insn_addr): if insn_addr in self.addr_to_insns: insn = self.addr_to_insns[insn_addr] pos = insn.pos() return pos.x(), pos.y() return None # # Initialization # def _create_block_item(self): """ Create the block background and border. """ if self._block_item_obj is not None and self._scene is not None: self._scene.removeItem(self._block_item_obj) self._block_item = None self._block_item_obj = None self._block_item = QPainterPath() self._block_item.addRect( self.block_object_group.childrenBoundingRect().marginsAdded( self.margins)) def _init_widgets(self): # TODO: hci: refactor: no need for self.objects anymore b/c of self.block_object_group. Using a # QGraphicsItemGroup is a more natural way to group/work with multiple GraphicItems if self._scene is not None: for obj in self.objects: self._scene.removeItem(obj) self.objects.clear() block_objects = get_block_objects(self.disasm, self.cfg_nodes, self.func_addr) self.block_object_group = QGraphicsItemGroup(parent=self) self.block_object_group.setHandlesChildEvents(False) for obj in block_objects: if isinstance(obj, Instruction): out_branch = get_out_branches_for_insn(self.out_branches, obj.addr) insn = QInstruction(self.workspace, self.func_addr, self.disasm_view, self.disasm, self.infodock, obj, out_branch, self._config, parent=self, container=self._container) self.objects.append(insn) self.block_object_group.addToGroup(insn) self.addr_to_insns[obj.addr] = insn elif isinstance(obj, Label): # label label = QBlockLabel(obj.addr, obj.text, self._config, self.disasm_view, self.workspace, self.infodock, parent=self, container=self._container) self.objects.append(label) self.block_object_group.addToGroup(label) self.addr_to_labels[obj.addr] = label elif isinstance(obj, PhiVariable): if not isinstance(obj.variable, SimRegisterVariable): phivariable = QPhiVariable(self.workspace, self.disasm_view, obj, self._config, parent=self, container=self._container) self.objects.append(phivariable) self.block_object_group.addToGroup(phivariable) elif isinstance(obj, Variables): for var in obj.variables: variable = QVariable(self.workspace, self.disasm_view, var, self._config, parent=self, container=self._container) self.objects.append(variable) self.block_object_group.addToGroup(variable) elif isinstance(obj, FunctionHeader): header = QFunctionHeader(self.func_addr, obj.name, obj.prototype, obj.args, self._config, self.disasm_view, self.workspace, self.infodock, parent=self, container=self._container) self.objects.append(header) self.block_object_group.addToGroup(header) self.layout_widgets() def layout_widgets(self): raise NotImplementedError()
def draw_game(self, painter): self.my_painters[ModelType.SHIP_MODEL].setup() self.my_painters[ModelType.BOLT_MODEL].setup() self.my_painters['background'].setup() painter.setBrush(QBrush(QColor('#20124d'))) painter.drawRect(0, 0, self.width(), self.height()) try: # DRAW BACKGROUND painter.setPen(QPen(QBrush(QColor(255, 255, 255)), 2, Qt.SolidLine)) self.my_painters['background'].paint(painter) # DRAW DEAD ZONE _dz_radius = self.controller.get_dead_zone_radius() _xy = self.controller.get_dead_zone_center().tolist() _point_center = self.transform_world_to_screen(*_xy, is_point=True) # GET MOBILE OBJECTS _model_ships = self.controller.get_data_from_players( enemy_only=False) _model_bolts = self.controller.get_data_from_bolts() _model_asteroids = self.controller.get_data_from_asteroids() # SET CAMERA PSOTOPM _ship_to_follow = None if self.camera_is_locked: _ship_to_follow = self.controller.get_player( self.controller.get_name()) if _ship_to_follow is not None and _ship_to_follow.is_alive: self.camera_pst = QPoint( -_ship_to_follow.x + self.width() // 2, _ship_to_follow.y + self.height() // 2) elif len(_model_ships): _ship_to_follow = _model_ships[self.camera_increment % len(_model_ships)] self.camera_pst = QPoint( -_ship_to_follow.x + self.width() // 2, _ship_to_follow.y + self.height() // 2) # DRAW MOBILE OBJECTS for _mob in _model_bolts + _model_ships + _model_asteroids: self.my_painters[_mob.type].paint(painter, model=_mob) # DRAW OVERLAY _brush_band = QBrush(QColor('#00284d')) _barre_height = 100 _rect_top_title = QRect(0, 0, self.width(), 50) _rect_band = QRect(0, (self.height() - _barre_height) // 2, self.width(), _barre_height) _rect_text1 = QRect(0, (self.height() - _barre_height) // 2, self.width(), _barre_height // 2) _rect_text2 = QRect(0, self.height() // 2, self.width(), _barre_height // 2) _rect_board_score_bg = QRect(self.width() // 2 - 250, 50, 500, self.height() - 200) _rect_board_title = QRect(0, 100, self.width(), 100) _rect_board_score = QRect(0, 200, self.width(), self.height() - 200) painter.setPen(QPen(QColor('#ffffff'), 10)) painter.setFont(QFont('Open Sans', weight=QFont.Bold, pointSize=20)) if self.controller.is_party_waiting(): painter.setPen(QPen(Qt.NoPen)) painter.setBrush(_brush_band) painter.setOpacity(.75) painter.drawRect(_rect_band) painter.setOpacity(1) painter.setPen(QPen(QColor('#ffffff'), 50)) painter.drawText(_rect_text1, Qt.AlignCenter, 'WAITING FOR PLAYERS') painter.drawText(_rect_text2, Qt.AlignCenter, '{}'.format(self.controller.get_time_left())) elif self.controller.is_party_ready_to_fight(): painter.setPen(QPen(Qt.NoPen)) painter.setBrush(_brush_band) painter.setOpacity(.75) painter.drawRect(_rect_band) painter.setOpacity(1) painter.setPen( QPen( QColor('#ffffff' if self.controller.get_time_left() > 5 else '#ff5555'), 50)) painter.drawText(_rect_text1, Qt.AlignCenter, 'READY TO FIGHT?') painter.drawText(_rect_text2, Qt.AlignCenter, '{}'.format(self.controller.get_time_left())) elif self.controller.has_party_winner(): painter.setPen(QPen(Qt.NoPen)) painter.setBrush(_brush_band) painter.setOpacity(.75) painter.drawRect(_rect_board_score_bg) painter.setOpacity(1) painter.setPen(QPen(QColor('#ffffff'), 50)) painter.drawText( _rect_board_title, Qt.AlignHCenter, 'Winner is: {} !'.format(self.controller.get_winner())) _text_score = [ '=========================', 'PARTY: {}'.format(self.controller.get_party_name()), '========= SCORE =========' ] painter.setPen(QPen(QColor('#8be9fd'), 50)) painter.setFont( QFont('Open Sans', weight=QFont.Bold, pointSize=15)) for _i, _player in enumerate( self.controller.get_rank_board()[::-1]): _text_score.append('> {: >2}. {: >35}'.format( _i + 1, _player)) painter.drawText(_rect_board_score, Qt.AlignHCenter, '\n'.join(_text_score)) elif self.controller.is_party_done(): painter.drawText(50, 50, 'PARTY DONE !') elif self.controller.is_party_in_progress(): painter.setPen(QPen(Qt.NoPen)) painter.setBrush(_brush_band) painter.setOpacity(.75) painter.drawRect(_rect_top_title) painter.setOpacity(1) painter.setPen(QPen(QColor('#8be9fd'), 50)) painter.setFont( QFont('Open Sans', weight=QFont.Bold, pointSize=10)) if _ship_to_follow is not None: painter.drawText( 50, 25, 'TimeLeft: {1} | Alive: {0} | Player: {2} |' ' Life: {3}%'.format( sum([_ship.is_alive for _ship in _model_ships]), self.controller.get_time_left(), _ship_to_follow.name, int(_ship_to_follow.life * 100))) else: painter.drawText( 50, 25, 'TimeLeft: {1} | Alive: {0}'.format( sum([_ship.is_alive for _ship in _model_ships]), self.controller.get_time_left())) # DRAW DEAD ZONE FILL _path = QPainterPath() _path.addRect( QRect(_point_center.x() - PartyConst.WIDTH, _point_center.y() - PartyConst.HEIGHT, PartyConst.WIDTH * 2, PartyConst.HEIGHT * 2)) _path.addEllipse(_point_center, _dz_radius, _dz_radius) painter.setPen(QPen(QColor('#00ffff'), 10, Qt.SolidLine)) painter.setBrush(QBrush(QColor('#00ffff'))) painter.setOpacity(.25) painter.drawPath(_path) painter.setOpacity(1.) painter.setBrush(QBrush(Qt.NoBrush)) painter.drawEllipse(_point_center, _dz_radius, _dz_radius) painter.setPen(QPen(QColor('#ffffff'), 5, Qt.SolidLine)) painter.drawEllipse(_point_center, _dz_radius, _dz_radius) except Exception as e: print('> [ERR] paintEvent: {}:{}'.format(type(e).__name__, e))
def getSymbolFromCmnd(self, symbolinfo): ''' Returns the SymbolPath for the symbol described in symbolinfo, which can either be a string or a dictionary. If symbolinfo is a string, it should be the name of a symbol that has already been defined, either as a pre-defined symbol or from a previous symbol definition. Current pre-defined symbol names are ones involving circles: 'dot': very small filled circle 'dotex': very small filled circle and outer lines of an ex mark 'dotplus': very small filled circle and outer lines of a plus mark 'circle': unfilled circle 'circfill': normal-sized filled circle 'circex': small unfilled circle and outer lines of an ex mark 'circplus': small unfilled circle and outer lines of a plus mark If symbolinfo is a dictionary, the following key/value pairs are recognized: 'name' : (string) symbol name (required) 'pts' : (sequence of pairs of floats) vertex coordinates 'fill' : (bool) color-fill symbol? If 'pts' is given, the value is coordinates that define the symbol as multiline subpaths in a [-50,50] square for typical size. The location of the point this symbol represents will be at the center of the square. A coordinate outside [-100,100] will terminate the current subpath, and the next valid coordinate will start a new subpath. This definition will replace an existing symbol with the given name. If 'pts' is not given, the symbol must already be defined, either as a pre-defined symbol (see above) or from a previous symbol definition. Raises: TypeError - if symbolinfo is neither a string nor a dictionary KeyError - if symbolinfo is a dictionary and the key 'name' is not given ValueError - if there are problems generating the symbol ''' # get the information about the symbol if isinstance(symbolinfo, str): symbol = symbolinfo pts = None fill = False elif isinstance(symbolinfo, dict): symbol = symbolinfo['name'] pts = symbolinfo.get('pts', None) fill = symbolinfo.get('fill', False) else: raise TypeError('symbolinfo must either be a dictionary or a string') if pts is None: # no path given; check if already defined sympath = self.__symbolpaths.get(symbol) if sympath is not None: return sympath # symbol not defined - if well known, create a SymbolPath for it if symbol == 'dot': path = QPainterPath() path.addEllipse(-10.0, -10.0, 20.0, 20.0) sympath = SymbolPath(path, True) elif symbol == 'dotplus': path = QPainterPath() path.addEllipse(-10.0, -10.0, 20.0, 20.0) # filled path, so need to draw "lines" as rectangles path.addRect( -4.0, -50.0, 8.0, 24.0) path.addRect( -4.0, 26.0, 8.0, 24.0) path.addRect(-50.0, -4.0, 24.0, 8.0) path.addRect( 26.0, -4.0, 24.0, 8.0) sympath = SymbolPath(path, True) elif symbol == 'dotex': path = QPainterPath() path.addEllipse(-10.0, -10.0, 20.0, 20.0) # filled path, so need to draw "lines" as rectangles path.moveTo(-38.18, -32.53) path.lineTo(-32.53, -38.18) path.lineTo(-15.56, -21.21) path.lineTo(-21.21, -15.56) # moveTo adds an implicit closeSubpath in QPainterPath path.moveTo(-38.18, 32.53) path.lineTo(-32.53, 38.18) path.lineTo(-15.56, 21.21) path.lineTo(-21.21, 15.56) # moveTo adds an implicit closeSubpath in QPainterPath path.moveTo( 38.18, -32.53) path.lineTo( 32.53, -38.18) path.lineTo( 15.56, -21.21) path.lineTo( 21.21, -15.56) # moveTo adds an implicit closeSubpath in QPainterPath path.moveTo( 38.18, 32.53) path.lineTo( 32.53, 38.18) path.lineTo( 15.56, 21.21) path.lineTo( 21.21, 15.56) # Qt closes the subpath automatically sympath = SymbolPath(path, True) elif symbol == 'circle': path = QPainterPath() path.addEllipse(-35.0, -35.0, 70.0, 70.0) sympath = SymbolPath(path, False) elif symbol == 'circfill': path = QPainterPath() path.addEllipse(-39.0, -39.0, 78.0, 78.0) sympath = SymbolPath(path, True) elif symbol == 'circplus': path = QPainterPath() path.addEllipse(-20.0, -20.0, 40.0, 40.0) # not a filled path, so just draw the lines path.moveTo( 0.0, -50.0) path.lineTo( 0.0, -20.0) path.moveTo( 0.0, 50.0) path.lineTo( 0.0, 20.0) path.moveTo(-50.0, 0.0) path.lineTo(-20.0, 0.0) path.moveTo( 50.0, 0.0) path.lineTo( 20.0, 0.0) sympath = SymbolPath(path, False) elif symbol == 'circex': path = QPainterPath() path.addEllipse(-20.0, -20.0, 40.0, 40.0) # not a filled path, so just draw the lines path.moveTo(-35.35, -35.35) path.lineTo(-14.15, -14.15) path.moveTo(-35.35, 35.35) path.lineTo(-14.15, 14.15) path.moveTo( 35.35, -35.35) path.lineTo( 14.15, -14.15) path.moveTo( 35.35, 35.35) path.lineTo( 14.15, 14.15) sympath = SymbolPath(path, False) else: raise ValueError("Unknown symbol '%s'" % str(symbol)) else: # define (or redefine) a symbol from the given path try: coords = [ [ float(val) for val in coord ] for coord in pts ] if not coords: raise ValueError for crd in coords: if len(crd) != 2: raise ValueError except Exception: raise ValueError('pts, if given, must be a sequence of pairs of numbers') path = QPainterPath() somethingdrawn = False newstart = True for (xval, yval) in coords: # flip so positive y is up yval *= -1.0 if (xval < -100.0) or (xval > 100.0) or (yval < -100.0) or (yval > 100.0): # end the current subpath newstart = True elif newstart: # start a new subpath; moveTo adds an implicit closeSubpath in QPainterPath path.moveTo(xval, yval) newstart = False else: # continue the current subpath path.lineTo(xval, yval) somethingdrawn = True if not somethingdrawn: del path raise ValueError('symbol definition does not contain any drawn lines') # Qt closes the (sub)path automatically sympath = SymbolPath(path, fill) # save and return the SymbolPath self.__symbolpaths[symbol] = sympath return sympath