def paintEvent(self, event): painter = QPainter(self) painter.fillRect(self.rect(), QColor('#101010')) image = self._image if image is not None: if self.height() < 240: fast_scaler = QTransform() scale = 297 / image.height() if self.mirror: fast_scaler.scale(-scale, scale) else: fast_scaler.scale(scale, scale) rect = event.rect() painter.drawPixmap( rect, QPixmap.fromImage( image.transformed(fast_scaler)).scaledToHeight( self.height(), Qt.SmoothTransformation), rect) else: transform = QTransform() scale = min(self.width() / image.width(), self.height() / image.height()) if self.mirror: transform.translate( (self.width() + image.width() * scale) / 2, (self.height() - image.height() * scale) / 2) transform.scale(-scale, scale) else: transform.translate( (self.width() - image.width() * scale) / 2, (self.height() - image.height() * scale) / 2) transform.scale(scale, scale) inverse_transform, invertible = transform.inverted() rect = inverse_transform.mapRect(event.rect()).adjusted( -1, -1, 1, 1).intersected(image.rect()) painter.setTransform(transform) if self.height() > 400: painter.drawPixmap(rect, QPixmap.fromImage(image), rect) else: painter.drawImage(rect, image, rect) painter.end()
def paintEvent(self, ev): """Called when paint is needed, finds out which page to magnify.""" view = self.parent().parent() layout = view.pageLayout() scale = max( min(self._scale, view.MAX_ZOOM * self.MAX_EXTRA_ZOOM / layout.zoomFactor), view.MIN_ZOOM / layout.zoomFactor) matrix = QTransform().scale(scale, scale) # the position of our center on the layout c = self.geometry().center() - view.layoutPosition() # make a region scaling back to the view scale rect = matrix.inverted()[0].mapRect(self.rect()) rect.moveCenter(c) region = QRegion(rect, QRegion.Ellipse) # touches the Pages we need to draw # our rect on the enlarged pages our_rect = self.rect() our_rect.moveCenter(matrix.map(c)) # the virtual position of the whole scaled-up layout ev_rect = ev.rect().translated(our_rect.topLeft()) # draw shadow border? shadow = False if hasattr(view, "drawDropShadow") and view.dropShadowEnabled: shadow = True shadow_width = layout.spacing * scale // 2 painter = QPainter(self) for p in layout.pagesAt(region.boundingRect()): # get a (reused) the copy of the page page = p.copy(self, matrix) # now paint it rect = (page.geometry() & ev_rect).translated(-page.pos()) painter.save() painter.translate(page.pos() - our_rect.topLeft()) if shadow: view.drawDropShadow(page, painter, shadow_width) page.paint(painter, rect, self.repaintPage) painter.restore() self.drawBorder(painter)
def updateTransform(self): # update transform such that this item has the correct orientation # and scaling relative to the scene, but inherits its position from its # parent. # This is similar to setting ItemIgnoresTransformations = True, but # does not break mouse interaction and collision detection. p = self.parentItem() if p is None: pt = QTransform() else: pt = p.sceneTransform() if pt == self._lastTransform: return t = pt.inverted()[0] # reset translation t.setMatrix(t.m11(), t.m12(), t.m13(), t.m21(), t.m22(), t.m23(), 0, 0, t.m33()) self.setTransform(t) self._lastTransform = pt
def get_tile_ranges(self, imw, imh, w, h, tr: QTransform): """Calculates the number of tiles depending on the transform. Parameters ---------- imw imh w h tr Returns ------- """ # we find where the display surface is in the coordinate system of a single tile corner_points = [ np.array([0.0, 0.0]), np.array([w, 0.0]), np.array([w, h]), np.array([0.0, h]), ] points_transformed = np.array( [tr.inverted()[0].map(*cp) for cp in corner_points]) # calculate the rectangle covering the transformed display surface min_x, min_y = np.min(points_transformed, 0) max_x, max_y = np.max(points_transformed, 0) # count which tiles need to be drawn x_start, x_end = (int(np.floor(min_x / imw)), int(np.ceil(max_x / imw))) y_start, y_end = (int(np.floor(min_y / imh)), int(np.ceil(max_y / imh))) return range(x_start, x_end + 1), range(y_start, y_end + 1)
def paintEvent(self, event): painter = QPainter(self) painter.fillRect(self.rect(), QColor('#101010')) image = self._image if image is not None: if self.height() < 240: fast_scaler = QTransform() scale = 297/image.height() if self.mirror: fast_scaler.scale(-scale, scale) else: fast_scaler.scale(scale, scale) rect = event.rect() painter.drawPixmap(rect, QPixmap.fromImage(image.transformed(fast_scaler)).scaledToHeight(self.height(), Qt.SmoothTransformation), rect) else: transform = QTransform() scale = min(self.width()/image.width(), self.height()/image.height()) if self.mirror: transform.translate((self.width() + image.width()*scale)/2, (self.height() - image.height()*scale)/2) transform.scale(-scale, scale) else: transform.translate((self.width() - image.width()*scale)/2, (self.height() - image.height()*scale)/2) transform.scale(scale, scale) inverse_transform, invertible = transform.inverted() rect = inverse_transform.mapRect(event.rect()).adjusted(-1, -1, 1, 1).intersected(image.rect()) painter.setTransform(transform) if self.height() > 400: painter.drawPixmap(rect, QPixmap.fromImage(image), rect) else: painter.drawImage(rect, image, rect) painter.end()
def drawWidget(self, qp): # Clear qp.setPen(self._backgroundColor) qp.setBrush(self._backgroundColor) qp.drawRect(self.rect()) # Get the widget dimensions (needed for the matrix calculations) w = self.rect().width() h = self.rect().height() # function space => widget space # [l; r] => [0; w] # [t; b] => [0; h] # (x - l) * w / (r - l) # (y - t) * h / (b - t) l = self._viewRect.left() r = self._viewRect.right() t = self._viewRect.top() b = self._viewRect.bottom() # Compute the transformation matrix # Note: we invert the y axis in order to go upwards cameraMatrix = QTransform().scale(1, -1) * QTransform().translate( -l, -t) * QTransform().scale(w / (r - l), h / (b - t)) # Also compute the inverse camera matrix (it can be useful to draw overlays with zoom-independent size) inverseCameraMatrix = cameraMatrix.inverted() # Setup qp.setTransform(cameraMatrix) # Draw the objects for plot in self._plots: qp.save() plot.draw(qp, cameraMatrix, inverseCameraMatrix) qp.restore()
class SchView(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self._transform = QTransform() # set up transform self._transform.translate(0, 0) # set to 100 px = 1 inch self._transform.scale(100.0 / Coord.inchToSch(1), -100.0 / Coord.inchToSch(1)) self._mousePos = QPoint() self._wheelAngle = 0 self._ctrl = None self.setMouseTracking(True) self.setFocusPolicy(Qt.StrongFocus) def setCtrl(self, ctrl): self._ctrl = ctrl def paintEvent(self, event): painter = QPainter(self) # erase background painter.setBackground(QBrush(Layer.color(LayerType.background))) painter.setClipping(True) painter.eraseRect(self.rect()) # draw document if self._ctrl is not None: # draw grid painter.setRenderHint(QPainter.Antialiasing, False) pen = QPen(Layer.color(LayerType.grid)) pen.setCapStyle(Qt.RoundCap) pen.setJoinStyle(Qt.RoundJoin) pen.setWidth(0) painter.setTransform(self._transform) painter.setPen(pen) self._drawGrid(painter) # draw drawables # painter.setRenderHint(QPainter.Antialiasing) for d in self._ctrl.getDrawables(): d.draw(painter) painter.end() def _drawGrid(self, painter): g = self._ctrl.grid if self._transform.map(QLine(QPoint(0, 0), QPoint(g, 0))).dx() <= 5: return # grid points too close, don't draw grid viewport = self._transform.inverted()[0].mapRect(self.rect()) startX = int(viewport.x() / g) * g startY = int(viewport.y() / g) * g endX = viewport.x() + viewport.width() endY = viewport.y() + viewport.height() pts = QPolygon( (QPoint(i[0], i[1]) for i in product(range(startX, endX, g), range(startY, endY, g)))) painter.drawPoints(pts) def _handleEvent(self, event: Event): if self._ctrl is not None: self._ctrl.handleEvent(event) def zoom(self, factor, pos): self.recenter(pos) p = self._transform.inverted()[0].map(self.rect().center()) test = QTransform(self._transform) test.scale(factor, factor) # check if the bounding rectangle does not enclose the view # refuse to zoom out (factor < 1) if this is the case # XXX TODO self._transform.scale(factor, factor) self.recenter(p, True) def recenter(self, pt=None, world=False): if pt is None: pt = self._mousePos ctr = self._transform.inverted()[0].map(self.rect().center()) if not world: pt = self._transform.inverted()[0].map(pt) ctr -= pt self._transform.translate(ctr.x(), ctr.y()) # move cursor to center of window QCursor.setPos(self.mapToGlobal(self.rect().center())) self.update() def mouseMoveEvent(self, e): if e.buttons() & Qt.MidButton: dl = QLine(QPoint(0, 0), e.pos() - self._mousePos) dl = self._transform.inverted()[0].map(dl) self._transform.translate(dl.dx(), dl.dy()) self.update() self._handleEvent( Event(evType=Event.Type.MouseMoved, pos=self._transform.inverted()[0].map(e.pos()))) self._mousePos = e.pos() def mousePressEvent(self, e): if e.button() == Qt.LeftButton: self._handleEvent( Event(evType=Event.Type.MousePressed, pos=self._transform.inverted()[0].map(e.pos()))) def mouseReleaseEvent(self, e): if e.button() == Qt.LeftButton: self._handleEvent( Event(evType=Event.Type.MouseReleased, pos=self._transform.inverted()[0].map(e.pos()))) def mouseDoubleClickEvent(self, e): if e.button() == Qt.LeftButton: self._handleEvent( Event(evType=Event.Type.MouseDblClicked, pos=self._transform.inverted()[0].map(e.pos()))) def hitRadius(self): return self._transform.inverted()[0].m11() * 6 # 6 pixels def keyPressEvent(self, e): self._handleEvent(Event(evType=Event.Type.KeyPressed, key=e.key())) def keyReleaseEvent(self, e: QKeyEvent): self._handleEvent(Event(evType=Event.Type.KeyReleased, key=e.key())) def wheelEvent(self, e): self._wheelAngle += e.angleDelta().y() if self._wheelAngle >= 120: self._wheelAngle -= 120 self.zoom(1.25, e.pos()) elif self._wheelAngle <= -120: self._wheelAngle += 120 self.zoom(0.8, e.pos()) def enterEvent(self, e): self.setFocus(Qt.MouseFocusReason) def leaveEvent(self, e): self.clearFocus() @pyqtSlot() def slotUpdate(self): self.update()
def zoom_out(self): scale_tr = QTransform() scale_tr.scale(1.2, 1.2) scale_inverted = scale_tr.inverted()[0] transformacion = self.programa.vista.transform() * scale_inverted self.programa.vista.setTransform(transformacion)
class World2D(QWidget): """A Widget which has it's own 2D world space, onto which shapes can be drawn. """ def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.world_transform = QTransform() self.zoom_base = 1.001 self._is_mouse_down = False self._last_mouse_pos = QPoint() def inverse_world_transform(self): """Returns the inverted world_transform. """ inverted, _ = self.world_transform.inverted() return inverted def world_painter(self, painter_class=QPainter): """Create a painter with the world transformation. Args: painter_class: You may specify a different class for the painter to be created. This should be a subclass of QPainter. Default is QPainter. """ painter = painter_class() painter.begin(self) painter.setWorldMatrixEnabled(True) painter.setWorldTransform(self.world_transform) return painter def translate(self, dx, dy): """Translate the viewport. """ self.world_transform.translate(dx, dy) self.update() def zoom(self, amount, center): """Scale the viewport around a center point. """ self.world_transform.translate(center.x(), center.y()) self.world_transform.scale(amount, amount) self.world_transform.translate(-center.x(), -center.y()) self.update() def zoom_to_fit(self, bounding_box): """Set the scale to fit the bounding_box and center on it. """ scale_x = self.width() / bounding_box.width() scale_y = self.height() / bounding_box.height() scale = min(scale_x, scale_y) dx = bounding_box.center().x() dy = bounding_box.center().y() self.world_transform = QTransform() self.world_transform.translate(self.width() / 2, self.height() / 2) self.world_transform.scale(scale, scale) self.world_transform.translate(-dx, -dy) self.update() def wheelEvent(self, wheel_event): super().wheelEvent(wheel_event) zoom_amount = self.zoom_base**wheel_event.angleDelta().y() center = QPointF(wheel_event.pos()) * self.inverse_world_transform() self.zoom(zoom_amount, center) def mousePressEvent(self, mouse_event): super().mousePressEvent(mouse_event) self._last_mouse_pos = mouse_event.pos() def mouseMoveEvent(self, mouse_event): super().mouseMoveEvent(mouse_event) new_mouse_pos = mouse_event.pos() new_mouse_in_world = QPointF( new_mouse_pos) * self.inverse_world_transform() last_mouse_in_world = QPointF( self._last_mouse_pos) * self.inverse_world_transform() dx = new_mouse_in_world.x() - last_mouse_in_world.x() dy = new_mouse_in_world.y() - last_mouse_in_world.y() self.translate(dx, dy) self._last_mouse_pos = new_mouse_pos
class SchView(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self._transform = QTransform() # set up transform self._transform.translate(0, 0) # set to 100 px = 1 inch self._transform.scale(100.0/Coord.inchToSch(1), -100.0/Coord.inchToSch(1)) self._mousePos = QPoint() self._wheelAngle = 0 self._ctrl = None self.setMouseTracking(True) self.setFocusPolicy(Qt.StrongFocus) def setCtrl(self, ctrl): self._ctrl = ctrl def paintEvent(self, event): painter = QPainter(self) # erase background painter.setBackground(QBrush(Layer.color(LayerType.background))) painter.setClipping(True) painter.eraseRect(self.rect()) # draw document if self._ctrl is not None: # draw grid painter.setRenderHint(QPainter.Antialiasing, False) pen = QPen(Layer.color(LayerType.grid)) pen.setCapStyle(Qt.RoundCap) pen.setJoinStyle(Qt.RoundJoin) pen.setWidth(0) painter.setTransform(self._transform) painter.setPen(pen) self._drawGrid(painter) # draw drawables # painter.setRenderHint(QPainter.Antialiasing) for d in self._ctrl.getDrawables(): d.draw(painter) painter.end() def _drawGrid(self, painter): g = self._ctrl.grid if self._transform.map(QLine(QPoint(0, 0), QPoint(g, 0))).dx() <= 5: return # grid points too close, don't draw grid viewport = self._transform.inverted()[0].mapRect(self.rect()) startX = int(viewport.x() / g) * g startY = int(viewport.y() / g) * g endX = viewport.x() + viewport.width() endY = viewport.y() + viewport.height() pts = QPolygon((QPoint(i[0], i[1]) for i in product(range(startX, endX, g), range(startY, endY, g)))) painter.drawPoints(pts) def _handleEvent(self, event: Event): if self._ctrl is not None: self._ctrl.handleEvent(event) def zoom(self, factor, pos): self.recenter(pos) p = self._transform.inverted()[0].map(self.rect().center()) test = QTransform(self._transform) test.scale(factor, factor) # check if the bounding rectangle does not enclose the view # refuse to zoom out (factor < 1) if this is the case # XXX TODO self._transform.scale(factor, factor) self.recenter(p, True) def recenter(self, pt=None, world=False): if pt is None: pt = self._mousePos ctr = self._transform.inverted()[0].map(self.rect().center()) if not world: pt = self._transform.inverted()[0].map(pt) ctr -= pt self._transform.translate(ctr.x(), ctr.y()) # move cursor to center of window QCursor.setPos(self.mapToGlobal(self.rect().center())) self.update() def mouseMoveEvent(self, e): if e.buttons() & Qt.MidButton: dl = QLine(QPoint(0, 0), e.pos() - self._mousePos) dl = self._transform.inverted()[0].map(dl) self._transform.translate(dl.dx(), dl.dy()) self.update() self._handleEvent(Event(evType=Event.Type.MouseMoved, pos=self._transform.inverted()[0].map(e.pos()))) self._mousePos = e.pos() def mousePressEvent(self, e): if e.button() == Qt.LeftButton: self._handleEvent(Event(evType=Event.Type.MousePressed, pos=self._transform.inverted()[0].map(e.pos()))) def mouseReleaseEvent(self, e): if e.button() == Qt.LeftButton: self._handleEvent(Event(evType=Event.Type.MouseReleased, pos=self._transform.inverted()[0].map(e.pos()))) def mouseDoubleClickEvent(self, e): if e.button() == Qt.LeftButton: self._handleEvent(Event(evType=Event.Type.MouseDblClicked, pos=self._transform.inverted()[0].map(e.pos()))) def hitRadius(self): return self._transform.inverted()[0].m11()*6 # 6 pixels def keyPressEvent(self, e): self._handleEvent(Event(evType=Event.Type.KeyPressed, key=e.key())) def keyReleaseEvent(self, e: QKeyEvent): self._handleEvent(Event(evType=Event.Type.KeyReleased, key=e.key())) def wheelEvent(self, e): self._wheelAngle += e.angleDelta().y() if self._wheelAngle >= 120: self._wheelAngle -= 120 self.zoom(1.25, e.pos()) elif self._wheelAngle <= -120: self._wheelAngle += 120 self.zoom(0.8, e.pos()) def enterEvent(self, e): self.setFocus(Qt.MouseFocusReason) def leaveEvent(self, e): self.clearFocus() @pyqtSlot() def slotUpdate(self): self.update()
def paintEvent(self, event): painter = QPainter(self) width = self.width() height = self.height() if DEBUG: painter.fillRect(0, 0, width, height, Qt.blue) else: painter.fillRect(event.rect(), self.plot.canvas_color) y_min_scale = self.plot.y_scale.value_min y_max_scale = self.plot.y_scale.value_max factor_x = width / self.plot.x_diff factor_y = (height - CURVE_HEIGHT_COMPENSATION) / max(y_max_scale - y_min_scale, EPSILON) if self.plot.x_min != None and self.plot.x_max != None: x_min = self.plot.x_min x_max = self.plot.x_max if self.plot.curve_start == 'left': curve_x_offset = 0 else: curve_x_offset = round((self.plot.x_diff - (x_max - x_min)) * factor_x) transform = QTransform() transform.translate(curve_x_offset, height - CURVE_Y_OFFSET_COMPENSATION) transform.scale(factor_x, -factor_y) transform.translate(-x_min, -y_min_scale) self.plot.partial_update_width = math.ceil(transform.map(QLineF(0, 0, 1.5, 0)).length()) inverted_event_rect = transform.inverted()[0].mapRect(QRectF(event.rect())) painter.save() painter.setTransform(transform) pen = QPen() pen.setCosmetic(True) pen.setWidth(0) painter.setPen(pen) if False and self.plot.curves_visible[0]: # Currently unused support for bar graphs. # If we need this later on we should add an option to the # PlotWidget for it. # I tested this for the Sound Pressure Level Bricklet and it works, # but it didnt't look good. curve_x = self.plot.curves_x[0] curve_y = self.plot.curves_y[0] t = time.time() if self.max_points == None: self.max_points = [] for y in curve_y: self.max_points.append((t, y)) else: for i in range(len(curve_y)): if (curve_y[i] > self.max_points[i][1]) or ((t - self.max_points[i][0]) > 5): self.max_points[i] = (t, curve_y[i]) for i in range(len(self.plot.curves_x[0])): pen.setColor(self.plot.curve_configs[0].color) painter.setPen(pen) painter.drawLine(QPoint(curve_x[i], 0), QPoint(curve_x[i], curve_y[i])) pen.setColor(Qt.white) painter.setPen(pen) painter.drawLine(QPoint(curve_x[i], curve_y[i]), QPoint(curve_x[i], y_max_scale)) pen.setColor(Qt.darkGreen) painter.setPen(pen) painter.drawPoint(QPoint(curve_x[i], self.max_points[i][1])) else: for c in range(len(self.plot.curves_x)): if not self.plot.curves_visible[c]: continue curve_x = self.plot.curves_x[c] curve_y = self.plot.curves_y[c] curve_jump = self.plot.curves_jump[c] path = QPainterPath() lineTo = path.lineTo moveTo = path.moveTo start = max(min(bisect.bisect_left(curve_x, inverted_event_rect.left()), len(curve_x) - 1) - 1, 0) if start >= len(curve_x): continue moveTo(curve_x[start], curve_y[start]) for i in range(start + 1, len(curve_x)): if curve_jump[i]: curve_x_diff_half = (curve_x[i] - curve_x[i - 1]) / 2 lineTo(curve_x[i - 1] + curve_x_diff_half, curve_y[i - 1]) moveTo(curve_x[i] - curve_x_diff_half, curve_y[i]) lineTo(curve_x[i], curve_y[i]) pen.setColor(self.plot.curve_configs[c].color) painter.setPen(pen) painter.drawPath(path) painter.restore()
def drawMapObject(self, painter, object, color): painter.save() pen = QPen(Qt.black) pen.setCosmetic(True) cell = object.cell() if (not cell.isEmpty()): tile = cell.tile imgSize = tile.size() pos = self.pixelToScreenCoords_(object.position()) tileOffset = tile.offset() CellRenderer(painter).render(cell, pos, object.size(), CellRenderer.BottomCenter) if (self.testFlag(RenderFlag.ShowTileObjectOutlines)): rect = QRectF(QPointF(pos.x() - imgSize.width() / 2 + tileOffset.x(), pos.y() - imgSize.height() + tileOffset.y()), QSizeF(imgSize)) pen.setStyle(Qt.SolidLine) painter.setPen(pen) painter.drawRect(rect) pen.setStyle(Qt.DotLine) pen.setColor(color) painter.setPen(pen) painter.drawRect(rect) else: lineWidth = self.objectLineWidth() scale = self.painterScale() x = 1 if lineWidth != 0: x = lineWidth shadowOffset = x / scale brushColor = QColor(color) brushColor.setAlpha(50) brush = QBrush(brushColor) pen.setJoinStyle(Qt.RoundJoin) pen.setCapStyle(Qt.RoundCap) pen.setWidth(lineWidth) colorPen = QPen(pen) colorPen.setColor(color) painter.setPen(pen) painter.setRenderHint(QPainter.Antialiasing) # TODO: Do something sensible to make null-sized objects usable x = object.shape() if x==MapObject.Ellipse: polygon = self.pixelRectToScreenPolygon(object.bounds()) tw = self.map().tileWidth() th = self.map().tileHeight() transformScale = QPointF(1, 1) if (tw > th): transformScale = QPointF(1, th/tw) else: transformScale = QPointF(tw/th, 1) l1 = polygon.at(1) - polygon.at(0) l2 = polygon.at(3) - polygon.at(0) trans = QTransform() trans.scale(transformScale.x(), transformScale.y()) trans.rotate(45) iTrans, ok = trans.inverted() l1x = iTrans.map(l1) l2x = iTrans.map(l2) ellipseSize = QSizeF(l1x.manhattanLength(), l2x.manhattanLength()) if (ellipseSize.width() > 0 and ellipseSize.height() > 0): painter.save() painter.setPen(pen) painter.translate(polygon.at(0)) painter.scale(transformScale.x(), transformScale.y()) painter.rotate(45) painter.drawEllipse(QRectF(QPointF(0, 0), ellipseSize)) painter.restore() painter.setBrush(Qt.NoBrush) painter.drawPolygon(polygon) painter.setPen(colorPen) painter.setBrush(Qt.NoBrush) painter.translate(QPointF(0, -shadowOffset)) painter.drawPolygon(polygon) painter.setBrush(brush) if (ellipseSize.width() > 0 and ellipseSize.height() > 0): painter.save() painter.translate(polygon.at(0)) painter.scale(transformScale.x(), transformScale.y()) painter.rotate(45) painter.drawEllipse(QRectF(QPointF(0, 0), ellipseSize)) painter.restore() elif x==MapObject.Rectangle: polygon = self.pixelRectToScreenPolygon(object.bounds()) painter.drawPolygon(polygon) painter.setPen(colorPen) painter.setBrush(brush) polygon.translate(0, -shadowOffset) painter.drawPolygon(polygon) elif x==MapObject.Polygon: pos = object.position() polygon = object.polygon().translated(pos) screenPolygon = self.pixelToScreenCoords_(polygon) thickPen = QPen(pen) thickColorPen = QPen(colorPen) thickPen.setWidthF(thickPen.widthF() * 4) thickColorPen.setWidthF(thickColorPen.widthF() * 4) painter.drawPolygon(screenPolygon) painter.setPen(thickPen) painter.drawPoint(screenPolygon.first()) painter.setPen(colorPen) painter.setBrush(brush) screenPolygon.translate(0, -shadowOffset) painter.drawPolygon(screenPolygon) painter.setPen(thickColorPen) painter.drawPoint(screenPolygon.first()) elif x==MapObject.Polyline: pos = object.position() polygon = object.polygon().translated(pos) screenPolygon = self.pixelToScreenCoords_(polygon) thickPen = QPen(pen) thickColorPen = QPen(colorPen) thickPen.setWidthF(thickPen.widthF() * 4) thickColorPen.setWidthF(thickColorPen.widthF() * 4) painter.drawPolyline(screenPolygon) painter.setPen(thickPen) painter.drawPoint(screenPolygon.first()) painter.setPen(colorPen) screenPolygon.translate(0, -shadowOffset) painter.drawPolyline(screenPolygon) painter.setPen(thickColorPen) painter.drawPoint(screenPolygon.first()) painter.restore()
def drawMapObject(self, painter, object, color): painter.save() pen = QPen(Qt.black) pen.setCosmetic(True) cell = object.cell() if (not cell.isEmpty()): tile = cell.tile imgSize = tile.size() pos = self.pixelToScreenCoords_(object.position()) tileOffset = tile.offset() CellRenderer(painter).render(cell, pos, object.size(), CellRenderer.BottomCenter) if (self.testFlag(RenderFlag.ShowTileObjectOutlines)): rect = QRectF( QPointF(pos.x() - imgSize.width() / 2 + tileOffset.x(), pos.y() - imgSize.height() + tileOffset.y()), QSizeF(imgSize)) pen.setStyle(Qt.SolidLine) painter.setPen(pen) painter.drawRect(rect) pen.setStyle(Qt.DotLine) pen.setColor(color) painter.setPen(pen) painter.drawRect(rect) else: lineWidth = self.objectLineWidth() scale = self.painterScale() x = 1 if lineWidth != 0: x = lineWidth shadowOffset = x / scale brushColor = QColor(color) brushColor.setAlpha(50) brush = QBrush(brushColor) pen.setJoinStyle(Qt.RoundJoin) pen.setCapStyle(Qt.RoundCap) pen.setWidth(lineWidth) colorPen = QPen(pen) colorPen.setColor(color) painter.setPen(pen) painter.setRenderHint(QPainter.Antialiasing) # TODO: Do something sensible to make null-sized objects usable x = object.shape() if x == MapObject.Ellipse: polygon = self.pixelRectToScreenPolygon(object.bounds()) tw = self.map().tileWidth() th = self.map().tileHeight() transformScale = QPointF(1, 1) if (tw > th): transformScale = QPointF(1, th / tw) else: transformScale = QPointF(tw / th, 1) l1 = polygon.at(1) - polygon.at(0) l2 = polygon.at(3) - polygon.at(0) trans = QTransform() trans.scale(transformScale.x(), transformScale.y()) trans.rotate(45) iTrans, ok = trans.inverted() l1x = iTrans.map(l1) l2x = iTrans.map(l2) ellipseSize = QSizeF(l1x.manhattanLength(), l2x.manhattanLength()) if (ellipseSize.width() > 0 and ellipseSize.height() > 0): painter.save() painter.setPen(pen) painter.translate(polygon.at(0)) painter.scale(transformScale.x(), transformScale.y()) painter.rotate(45) painter.drawEllipse(QRectF(QPointF(0, 0), ellipseSize)) painter.restore() painter.setBrush(Qt.NoBrush) painter.drawPolygon(polygon) painter.setPen(colorPen) painter.setBrush(Qt.NoBrush) painter.translate(QPointF(0, -shadowOffset)) painter.drawPolygon(polygon) painter.setBrush(brush) if (ellipseSize.width() > 0 and ellipseSize.height() > 0): painter.save() painter.translate(polygon.at(0)) painter.scale(transformScale.x(), transformScale.y()) painter.rotate(45) painter.drawEllipse(QRectF(QPointF(0, 0), ellipseSize)) painter.restore() elif x == MapObject.Rectangle: polygon = self.pixelRectToScreenPolygon(object.bounds()) painter.drawPolygon(polygon) painter.setPen(colorPen) painter.setBrush(brush) polygon.translate(0, -shadowOffset) painter.drawPolygon(polygon) elif x == MapObject.Polygon: pos = object.position() polygon = object.polygon().translated(pos) screenPolygon = self.pixelToScreenCoords_(polygon) thickPen = QPen(pen) thickColorPen = QPen(colorPen) thickPen.setWidthF(thickPen.widthF() * 4) thickColorPen.setWidthF(thickColorPen.widthF() * 4) painter.drawPolygon(screenPolygon) painter.setPen(thickPen) painter.drawPoint(screenPolygon.first()) painter.setPen(colorPen) painter.setBrush(brush) screenPolygon.translate(0, -shadowOffset) painter.drawPolygon(screenPolygon) painter.setPen(thickColorPen) painter.drawPoint(screenPolygon.first()) elif x == MapObject.Polyline: pos = object.position() polygon = object.polygon().translated(pos) screenPolygon = self.pixelToScreenCoords_(polygon) thickPen = QPen(pen) thickColorPen = QPen(colorPen) thickPen.setWidthF(thickPen.widthF() * 4) thickColorPen.setWidthF(thickColorPen.widthF() * 4) painter.drawPolyline(screenPolygon) painter.setPen(thickPen) painter.drawPoint(screenPolygon.first()) painter.setPen(colorPen) screenPolygon.translate(0, -shadowOffset) painter.drawPolyline(screenPolygon) painter.setPen(thickColorPen) painter.drawPoint(screenPolygon.first()) painter.restore()