def updatePath(self): self.endPoints = [] controlPoints = [] endPt = self.endItem.getLinkPointForParameter(self.endIndex) if isinstance(self.startItem.element, QgsProcessingModelAlgorithm.ModelParameter): startPt = self.startItem.getLinkPointForParameter(self.startIndex) else: startPt = self.startItem.getLinkPointForOutput(self.startIndex) if isinstance(self.endItem.element, QgsProcessingModelAlgorithm.ModelParameter): endPt = self.endItem.getLinkPointForParameter(self.startIndex) if isinstance(self.startItem.element, QgsProcessingModelAlgorithm.ChildAlgorithm): if self.startIndex != -1: controlPoints.append(self.startItem.pos() + startPt) controlPoints.append(self.startItem.pos() + startPt + QPointF(ModelerGraphicItem.BOX_WIDTH / 3, 0)) controlPoints.append(self.endItem.pos() + endPt - QPointF(ModelerGraphicItem.BOX_WIDTH / 3, 0)) controlPoints.append(self.endItem.pos() + endPt) pt = QPointF(self.startItem.pos() + startPt + QPointF(-3, -3)) self.endPoints.append(pt) pt = QPointF(self.endItem.pos() + endPt + QPointF(-3, -3)) self.endPoints.append(pt) else: # Case where there is a dependency on an algorithm not # on an output controlPoints.append(self.startItem.pos() + startPt) controlPoints.append(self.startItem.pos() + startPt + QPointF(ModelerGraphicItem.BOX_WIDTH / 3, 0)) controlPoints.append(self.endItem.pos() + endPt - QPointF(ModelerGraphicItem.BOX_WIDTH / 3, 0)) controlPoints.append(self.endItem.pos() + endPt) else: controlPoints.append(self.startItem.pos()) controlPoints.append(self.startItem.pos() + QPointF(ModelerGraphicItem.BOX_WIDTH / 3, 0)) controlPoints.append(self.endItem.pos() + endPt - QPointF(ModelerGraphicItem.BOX_WIDTH / 3, 0)) controlPoints.append(self.endItem.pos() + endPt) pt = QPointF(self.endItem.pos() + endPt + QPointF(-3, -3)) self.endPoints.append(pt) path = QPainterPath() path.moveTo(controlPoints[0]) path.cubicTo(*controlPoints[1:]) self.setPath(path)
def updatePath(self): self.endPoints = [] controlPoints = [] endPt = self.endItem.getLinkPointForParameter(self.endIndex) if isinstance(self.startItem.element, QgsProcessingModelParameter): startPt = self.startItem.getLinkPointForParameter(self.startIndex) else: startPt = self.startItem.getLinkPointForOutput(self.startIndex) if isinstance(self.endItem.element, QgsProcessingModelParameter): endPt = self.endItem.getLinkPointForParameter(self.startIndex) if isinstance(self.startItem.element, QgsProcessingModelChildAlgorithm): if self.startIndex != -1: controlPoints.append(self.startItem.pos() + startPt) controlPoints.append(self.startItem.pos() + startPt + QPointF(ModelerGraphicItem.BOX_WIDTH / 3, 0)) controlPoints.append(self.endItem.pos() + endPt - QPointF(ModelerGraphicItem.BOX_WIDTH / 3, 0)) controlPoints.append(self.endItem.pos() + endPt) pt = QPointF(self.startItem.pos() + startPt + QPointF(-3, -3)) self.endPoints.append(pt) pt = QPointF(self.endItem.pos() + endPt + QPointF(-3, -3)) self.endPoints.append(pt) else: # Case where there is a dependency on an algorithm not # on an output controlPoints.append(self.startItem.pos() + startPt) controlPoints.append(self.startItem.pos() + startPt + QPointF(ModelerGraphicItem.BOX_WIDTH / 3, 0)) controlPoints.append(self.endItem.pos() + endPt - QPointF(ModelerGraphicItem.BOX_WIDTH / 3, 0)) controlPoints.append(self.endItem.pos() + endPt) else: controlPoints.append(self.startItem.pos()) controlPoints.append(self.startItem.pos() + QPointF(ModelerGraphicItem.BOX_WIDTH / 3, 0)) controlPoints.append(self.endItem.pos() + endPt - QPointF(ModelerGraphicItem.BOX_WIDTH / 3, 0)) controlPoints.append(self.endItem.pos() + endPt) pt = QPointF(self.endItem.pos() + endPt + QPointF(-3, -3)) self.endPoints.append(pt) path = QPainterPath() path.moveTo(controlPoints[0]) path.cubicTo(*controlPoints[1:]) self.setPath(path)
class PointRotationItem(QgsMapCanvasItem): """ A map canvas item which shows an angle display and preview of marker rotation """ def __init__(self, canvas): super().__init__(canvas) self.rotation = 0 self.pixmap = QPixmap() self.item_size = QSizeF() self.marker_font = QFont() self.marker_font.setPointSize(12) self.marker_font.setBold(True) self.arrow_path = QPainterPath() im = QImage(24, 24, QImage.Format_ARGB32) im.fill(Qt.transparent) self.set_symbol(im) def paint(self, painter, option, widget): if not painter: return painter.save() painter.setRenderHint(QPainter.Antialiasing, True) # do a bit of trigonometry to find out how to transform a rotated item such # that the center point is at the point feature x = 0.0 y = 0.0 if self.pixmap.width() > 0 and self.pixmap.height() > 0: half_item_diagonal = math.sqrt( self.pixmap.width() * self.pixmap.width() + self.pixmap.height() * self.pixmap.height()) / 2 diagonal_angle = math.acos( self.pixmap.width() / (half_item_diagonal * 2)) * 180 / math.pi x = half_item_diagonal * math.cos( (self.rotation - diagonal_angle) * math.pi / 180) y = half_item_diagonal * math.sin( (self.rotation - diagonal_angle) * math.pi / 180) painter.rotate(self.rotation) painter.translate(x - self.pixmap.width() / 2.0, -y - self.pixmap.height() / 2.0) painter.drawPixmap(0, 0, self.pixmap) # draw arrow, using a red line over a thicker white line so that the arrow is visible # against a range of backgrounds pen = QPen() pen.setWidth(GuiUtils.scale_icon_size(4)) pen.setColor(QColor(Qt.white)) painter.setPen(pen) painter.drawPath(self.arrow_path) pen.setWidth(GuiUtils.scale_icon_size(1)) pen.setColor(QColor(Qt.red)) painter.setPen(pen) painter.drawPath(self.arrow_path) painter.restore() # draw numeric value beside the symbol painter.save() painter.setRenderHint(QPainter.Antialiasing, True) buffer_pen = QPen() buffer_pen.setColor(Qt.white) buffer_pen.setWidthF(GuiUtils.scale_icon_size(4)) fm = QFontMetricsF(self.marker_font) label = QPainterPath() label.addText(self.pixmap.width(), self.pixmap.height() / 2.0 + fm.height() / 2.0, self.marker_font, str(round(self.rotation, 1))) painter.setPen(buffer_pen) painter.setBrush(Qt.NoBrush) painter.drawPath(label) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(Qt.black)) painter.drawPath(label) painter.restore() def set_point_location(self, p): transformed_point = self.toCanvasCoordinates(p) self.setPos(transformed_point.x() - self.pixmap.width() / 2.0, transformed_point.y() - self.pixmap.height() / 2.0) def set_symbol_rotation(self, rotation: float): self.rotation = rotation def set_symbol(self, symbol_image: QImage): self.pixmap = QPixmap.fromImage(symbol_image) fm = QFontMetricsF(self.marker_font) # set item size self.item_size.setWidth(self.pixmap.width() + fm.width("360")) pixmap_height = self.pixmap.height() font_height = fm.height() if pixmap_height >= font_height: self.item_size.setHeight(self.pixmap.height()) else: self.item_size.setHeight(fm.height()) half_item_width = self.pixmap.width() / 2.0 self.arrow_path = QPainterPath() self.arrow_path.moveTo(half_item_width, pixmap_height) self.arrow_path.lineTo(half_item_width, 0) self.arrow_path.moveTo(self.pixmap.width() * 0.25, pixmap_height * 0.25) self.arrow_path.lineTo(half_item_width, 0) self.arrow_path.lineTo(self.pixmap.width() * 0.75, pixmap_height * 0.25)
def drawLine(self, painter, commit, parent): commitRow = self.graph.commitRows[commit.commitid] commitCol = self.graph.commitColumns[commit.commitid] parentRow = self.graph.commitRows[parent.commitid] parentCol = self.graph.commitColumns[parent.commitid] commitX = self.RADIUS * 3 + commitCol * self.COLUMN_SEPARATION parentX = self.RADIUS * 3 + parentCol * self.COLUMN_SEPARATION commitY = commitRow * self.COMMIT_GRAPH_HEIGHT parentY = parentRow * self.COMMIT_GRAPH_HEIGHT color = self._columnColor(parentCol) if parent is not None and self.graph.isFauxLink(parent.commitid, commit.commitid)\ and len(parent.childrenIds)>1: # draw a faux line path = QPainterPath() path.moveTo(parentX, parentY) path.lineTo(commitX , commitY) color = QColor(255,160,255) pen = QPen() pen.setWidth(2) pen.setBrush(color) pen.setStyle(Qt.DashLine) painter.setPen(pen) painter.drawPath(path) # draw arrow # draw arrow ARROW_POINT_SIZE = 9 painter.setPen(color) painter.setBrush(color) line = QLineF(commitX , commitY, parentX, parentY) angle = math.acos(line.dx() / line.length()) if line.dy() >= 0: angle = 2.0 * math.pi - angle sourcePoint = QPointF(commitX,commitY) sourceArrowP1 = sourcePoint + QPointF(math.sin(angle + math.pi / 3) * ARROW_POINT_SIZE, math.cos(angle + math.pi / 3) * ARROW_POINT_SIZE) sourceArrowP2 = sourcePoint + QPointF(math.sin(angle + math.pi - math.pi / 3) * ARROW_POINT_SIZE, math.cos(angle + math.pi - math.pi / 3) * ARROW_POINT_SIZE) arrow = QPolygonF([line.p1(), sourceArrowP1, sourceArrowP2]) painter.drawPolygon(arrow) return path = QPainterPath() painter.setBrush(color) painter.setPen(color) if parentCol != commitCol: if parent.isFork() and commit.getParents()[0].commitid == parent.commitid: path.moveTo(commitX, commitY) path.lineTo(commitX, parentY) if parentX<commitX: path.lineTo(parentX + self.RADIUS + 1, parentY) else: path.lineTo(parentX - self.RADIUS, parentY) color = self._columnColor(commitCol) else: path2 = QPainterPath() path2.moveTo(commitX + self.RADIUS + 1, commitY) path2.lineTo(commitX + self.RADIUS + self.COLUMN_SEPARATION / 2, commitY + self.COLUMN_SEPARATION / 3) path2.lineTo(commitX + self.RADIUS + self.COLUMN_SEPARATION / 2, commitY - self.COLUMN_SEPARATION / 3) path2.lineTo(commitX + + self.RADIUS + 1, commitY) painter.setBrush(color) painter.setPen(color) painter.drawPath(path2) path.moveTo(commitX + self.RADIUS + self.COLUMN_SEPARATION / 2, commitY) path.lineTo(parentX, commitY) path.lineTo(parentX, parentY) if parent.isFork(): if commitCol in self.columnColor.keys(): del self.columnColor[commitCol] else: path.moveTo(commitX, commitY) path.lineTo(parentX, parentY) pen = QPen(color, self.PEN_WIDTH, Qt.SolidLine, Qt.FlatCap, Qt.RoundJoin) painter.strokePath(path, pen) if not commit.commitid in self.linked: y = commitRow * self.COLUMN_SEPARATION x = self.RADIUS * 3 + commitCol * self.COLUMN_SEPARATION painter.setPen(color) painter.setBrush(color) painter.drawEllipse(QPoint(x, y), self.RADIUS, self.RADIUS) self.linked.append(commit.commitid)