class PreCrossoverHandle(QGraphicsItem): scafpen = QPen(styles.pch_scaf_stroke, styles.PATH_STRAND_STROKE_WIDTH) scafpen.setCapStyle(Qt.FlatCap) # or Qt.RoundCap scafpen.setJoinStyle(Qt.RoundJoin) stappen = QPen(styles.pch_stap_stroke, styles.PATH_STRAND_STROKE_WIDTH) stappen.setCapStyle(Qt.FlatCap) # or Qt.RoundCap stappen.setJoinStyle(Qt.RoundJoin) disabpen = QPen(styles.pch_disab_stroke, styles.PATH_STRAND_STROKE_WIDTH) disabpen.setCapStyle(Qt.FlatCap) disabpen.setJoinStyle(Qt.RoundJoin) disabbrush = QBrush(styles.pch_disab_stroke) # For the helix number label enabbrush = QBrush(Qt.SolidPattern) # Also for the helix number label baseWidth = styles.PATH_BASE_WIDTH rect = QRectF(0, 0, styles.PATH_BASE_WIDTH, styles.PATH_BASE_WIDTH) toHelixNumFont = QFont("Times", 10, QFont.Bold) def __init__(self, parentPH, fromStrand, fromIdx, toVH, toIdx, orientedLeft): super(PreCrossoverHandle, self).__init__(parentPH) self.fromVH = parentPH.vhelix() self.fromStrand = fromStrand self.fromIdx = fromIdx self.toVH = toVH self.toIdx = toIdx self.orientedLeft = orientedLeft self.fromVH.basesModified.connect(self.updateVisibilityAndEnabledness) self.toVH.basesModified.connect(self.updateVisibilityAndEnabledness) self.label = QGraphicsSimpleTextItem(str(toVH.number()), parent=self) self.label.setFont(self.toHelixNumFont) x = self.baseWidth * self.fromIdx y = (-1.25 if self.onTopStrand() else 2.25) * self.baseWidth self.setPos(x, y) halfLabelW = self.label.boundingRect().width() / 2 labelX = self.baseWidth/2 - halfLabelW labelY = (-.10 if self.onTopStrand() else .48) * self.baseWidth self.label.setPos(labelX, labelY) self.updateVisibilityAndEnabledness() def onTopStrand(self): return self.fromVH.evenParity() and self.fromStrand==StrandType.Scaffold or\ not self.fromVH.evenParity() and self.fromStrand==StrandType.Staple def couldFormNewCrossover(self): return self.fromVH.possibleNewCrossoverAt(self.fromStrand, self.fromIdx, self.toVH, self.toIdx) def crossoverExists(self): return self.fromVH.hasCrossoverAt(self.fromStrand, self.fromIdx) def is3pEndOfCrossover(self): return self.orientedLeft and self.onTopStrand() or\ not self.orientedLeft and not self.onTopStrand def updateVisibilityAndEnabledness(self): shouldBeVisible = not self.crossoverExists() self.setVisible(shouldBeVisible) self.label.setVisible(shouldBeVisible) if self.couldFormNewCrossover(): self.label.setBrush(self.enabbrush) else: self.label.setBrush(self.disabbrush) self.update() def paint(self, painter, option, widget=None): #Look Up Table pathLUT = (_ppathRD, _ppathRU, _ppathLD, _ppathLU) path = pathLUT[2*int(self.orientedLeft) + int(self.onTopStrand())] pen = self.disabpen if self.couldFormNewCrossover(): if self.fromStrand == StrandType.Scaffold: pen = self.scafpen else: pen = self.stappen painter.setPen(pen) painter.drawPath(path) def boundingRect(self): return self.rect def mousePressEvent(self, event): if event.button() != Qt.LeftButton: return QGraphicsItem.mousePressEvent(self, event) if not self.couldFormNewCrossover(): return # Determine upstream base fromHelix, toHelix = self.fromVH, self.toVH fromIdx, toIdx = self.fromIdx, self.toIdx if not self.is3pEndOfCrossover(): fromHelix, toHelix = toHelix, fromHelix fromIdx, toIdx = toIdx, fromIdx # Create XoverHandlePair and store references # fromHelix.installXoverFrom3To5(StrandType.Scaffold, \ # fromIndex, toHelix, toIndex) fromHelix.installXoverFrom3To5(self.fromStrand, \ fromIdx, toHelix, toIdx)