def paintEvent(self, pe): if self._drop_zones_shown: painter = QPainter(self.viewport( )) # See documentation to know why I draw on the viewport painter.setFont(self._titles_font) vr = self.rect() nb_drop_zones = len(self._drop_zones_titles) subr = QRect(vr) subr.setHeight(vr.height() / nb_drop_zones) for i in range(nb_drop_zones): c = self._drop_zones_colors[i] text_pen = QPen() text_pen.setColor(inverse_colors(c)) painter.setPen(text_pen) if i == self._selected_drop_zone: # mainlog.debug("selected drop zone is {}".format(i)) c = c.lighter(200) painter.setBrush(c) subr.moveTop(int(i * vr.height() / nb_drop_zones)) painter.drawRect(subr) painter.drawText( QPoint(10, int((i + 0.5) * vr.height() / nb_drop_zones)), self._drop_zones_titles[i]) return None else: return super(AnimatedTableView, self).paintEvent(pe)
def paintEvent(self, event): """ Paints the widget """ if self.enabled is False: return Panel.paintEvent(self, event) painter = QPainter(self) painter.fillRect(event.rect(), self.back_brush) for vb in self.editor.codeEdit.visible_blocks: line = vb.row # paint marker for line marker = self.getIndicatorForLine(line) if marker is None: continue # use the normal pen to draw the fold indicator drawLines = False pen = self.normal_pen if marker.hover is True: pen = self.highlight_pen drawLines = True painter.setPen(pen) # get the text to draw txt = '-' if marker.folded is True: drawLines = False txt = '+' offset = 4 h = self.size_hint.height() fm = QFontMetricsF(self.editor.codeEdit.font()) hoffset = (fm.height() - h) / 2.0 r = QRect(vb.rect.x(), vb.rect.y() + hoffset, self.size_hint.width(), self.size_hint.height()) painter.setFont(self.font) painter.drawText(r, Qt.AlignVCenter | Qt.AlignHCenter, txt) w = self.size_hint.width() - 2 * offset h = self.size_hint.width() - 2 * offset hoffset = (fm.height() - h) / 2.0 r.setX(vb.rect.x() + offset) r.setY(vb.rect.y() + hoffset) r.setWidth(w) r.setHeight(h) painter.drawRect(r) if drawLines is True: top = (vb.rect.x() + self.size_hint.width() / 2.0, vb.rect.y() + hoffset + offset * 2) delta = ((marker.end - marker.start) * vb.height) # - (vb.rect.height() / 2.0) bottom = (top[0], top[1] + delta) painter.drawLine(top[0], top[1], bottom[0], bottom[1]) painter.drawLine(bottom[0], bottom[1], bottom[0] + self.size_hint.width() / 2.0, bottom[1]) return
def paintEvent(self, event): """ Paints the widget """ if self.enabled is False: return Panel.paintEvent(self, event) painter = QPainter(self) painter.fillRect(event.rect(), self.back_brush) for vb in self.editor.codeEdit.visible_blocks: l = vb.row marker = self.__getMarkerForLine(l) if marker: if marker.icon is not None: r = QRect() r.setX(vb.rect.x()) r.setY(vb.rect.y()) r.setWidth(self.size_hint.width()) r.setHeight(self.size_hint.height()) marker.icon.paint(painter, r) return
def __giveUpSomeLeftoverSpace(self, neededArea): """ Sacrifice some leftover space to represent the neededARea""" thisDir = self.__updateDirectionToPreferSquareness(neededArea) giveUpFns = [self.__giveUpLeftoverWidth, self.__giveUpLeftoverHeight] fn = giveUpFns[thisDir] newRect = QRect() newRect.setTopLeft(self.leftoverRect.topLeft()) (width, height) = (self.leftoverRect.width(), self.leftoverRect.height()) (width, height) = fn(neededArea, width, height) if not self.leftoverRect.isValid() and not self.leftoverRect.isEmpty(): print "Failure with the following input" print "W/H %i/%i" % (width, height) print "ParentRect %s" % repr(self.parentRect) print "Leftover %s" % repr(self.leftoverRect) print "Percentages %s" % repr(self.percs) assert False newRect.setHeight(height) newRect.setWidth(width) return newRect
def paintEvent(self, event): painter = QStylePainter(self) painter.setPen(self.palette().color(QPalette.Text)) # Draw the combobox frame, focus rect, selected etc. opt = QStyleOptionComboBox() self.initStyleOption(opt) opt.currentText = "" # Don't draw the raw HTML painter.drawComplexControl(QStyle.CC_ComboBox, opt) # Draw the icon and text painter.drawControl(QStyle.CE_ComboBoxLabel, opt) # Draw the HTML self.label.setText(self.currentText()) self.label.adjustSize() pixmap = QPixmap(self.label.width(), self.label.height()) pixmap.fill(Qt.transparent) self.label.render(pixmap, renderFlags=QWidget.RenderFlags(0)) rect = QRect(opt.rect) y = (rect.height() - self.label.height()) / 2 rect.setX(self.fontMetrics().width("n")) rect.setY(y) rect.setHeight(pixmap.height()) rect.setWidth(pixmap.width()) painter.drawPixmap(rect, pixmap, pixmap.rect())
class PackedRect: """ Given p and a starting rect, draw a subrectangle that takes <= p% of the area of the starting rect. Repeat for p1,p2... as long as there continues to be room in the parent rect""" def __init__(self, parentRect, percentageItems): self.parentRect = self.leftoverRect = QRect() self.percItems = sorted(percentageItems, key=lambda pItem: pItem.getLocalPercentage(), reverse = True) self.parentRect = QRect(parentRect) self.reset() self.percs = [] def __iter__(self): return self def next(self): perc = 0 if self.currPercItem < len(self.percItems) and not self.isEmpty(): while perc == 0: if self.currPercItem < len(self.percItems): percItem = self.percItems[self.currPercItem] perc = percItem.getLocalPercentage() else: raise StopIteration() self.currPercItem += 1 return (percItem, self.nextRect(perc)) else: raise StopIteration() def reset(self): import copy self.lastFlipPercentage = 100 self.currPercItem = 0 self.leftoverRect = QRect(self.parentRect) def __updateDirectionToPreferSquareness(self, neededArea): """ Pick a direction that will give a more square result for the next rectangle, but strongly bias toward horizontal. Its important for there to be consistency in this algorithm and not have it depend on any weird side effects """ biasTowardHoriz = 1.5 (width, height) = (self.leftoverRect.width(),self.leftoverRect.height()) (width, height) = self.__calculaceGivingUpWidth(neededArea, width, height) widthDiff = abs(width-height) (width, height) = (self.leftoverRect.width(),self.leftoverRect.height()) (width, height) = self.__calculateGivingUpHeight(neededArea, width, height) heightDiff = abs(width-height) if widthDiff < (heightDiff * biasTowardHoriz): return Direction.Horizontal else: return Direction.Vertical def isEmpty(self): return self.leftoverRect.isEmpty() def __isNeededAreaMoreThanLeftover(self, neededArea): leftoverArea = self.leftoverRect.width() * self.leftoverRect.height() return (neededArea + 0.01) > leftoverArea @validRectReturned def __giveUpAllRemainingArea(self): """ Return all remaining leftover space and empty the leftover rect""" assert not self.leftoverRect.isEmpty() remaining = QRect(self.leftoverRect) self.leftoverRect.setWidth(-1) self.leftoverRect.setHeight(-1) assert self.leftoverRect.isEmpty() return remaining def __calculateGivingUpHeight(self, neededArea, width, height): height = neededArea / width height = ceil(height) return (width, height) def __calculaceGivingUpWidth(self, neededArea, width, height): width = neededArea / height width = ceil(width) return (width, height) def __giveUpLeftoverHeight(self, neededArea, width, height): """ Sacrifice some height from the leftover rect for the needed area""" (width, height) = self.__calculateGivingUpHeight(neededArea, width, height) self.leftoverRect.setY(self.leftoverRect.y() + height) return (width, height) def __giveUpLeftoverWidth(self, neededArea, width, height): """ Sacrifice some width from the leftover rect for the needed area""" (width, height) = self.__calculaceGivingUpWidth(neededArea, width, height) self.leftoverRect.setX(self.leftoverRect.x() + width) return (width, height) @validRectReturned def __giveUpSomeLeftoverSpace(self, neededArea): """ Sacrifice some leftover space to represent the neededARea""" thisDir = self.__updateDirectionToPreferSquareness(neededArea) giveUpFns = [self.__giveUpLeftoverWidth, self.__giveUpLeftoverHeight] fn = giveUpFns[thisDir] newRect = QRect() newRect.setTopLeft(self.leftoverRect.topLeft()) (width, height) = (self.leftoverRect.width(), self.leftoverRect.height()) (width, height) = fn(neededArea, width, height) if not self.leftoverRect.isValid() and not self.leftoverRect.isEmpty(): print "Failure with the following input" print "W/H %i/%i" % (width, height) print "ParentRect %s" % repr(self.parentRect) print "Leftover %s" % repr(self.leftoverRect) print "Percentages %s" % repr(self.percs) assert False newRect.setHeight(height) newRect.setWidth(width) return newRect @validRectReturned def nextRect(self, percentage): """ Get the next rect from leftoverRect, update leftoverRect with whats leftover """ self.percs.append(percentage) if self.isEmpty(): raise ValueError("This guy is empty pR: %s perc: %s" % (self.parentRect, self.percs)) neededArea = (self.parentRect.width() * self.parentRect.height()) * (percentage/100.0) if self.__isNeededAreaMoreThanLeftover(neededArea): return self.__giveUpAllRemainingArea() return self.__giveUpSomeLeftoverSpace(neededArea) def __repr__(self): return "PackedRect(%s)" % repr(self.parentRect) def __str__(self): return self.__repr__() + " Leftover(%s)" % repr(self.leftoverRect)