def draw_text(self, style, painter, option, widget, index, item): tr = style.subElementRect(style.SE_ItemViewItemText, option, widget) text = index.data(Qt.DisplayRole) hover = option.state & style.State_MouseOver if hover or gprefs['tag_browser_show_counts']: count = unicode_type(index.data(COUNT_ROLE)) width = painter.fontMetrics().boundingRect(count).width() r = QRect(tr) r.setRight(r.right() - 1), r.setLeft(r.right() - width - 4) painter.drawText(r, Qt.AlignCenter | Qt.TextSingleLine, count) tr.setRight(r.left() - 1) else: tr.setRight(tr.right() - 1) is_rating = item.type == TagTreeItem.TAG and not self.rating_pat.sub('', text) if is_rating: painter.setFont(self.rating_font) flags = Qt.AlignVCenter | Qt.AlignLeft | Qt.TextSingleLine lr = QRect(tr) lr.setRight(lr.right() * 2) br = painter.boundingRect(lr, flags, text) if br.width() > tr.width(): g = QLinearGradient(tr.topLeft(), tr.topRight()) c = option.palette.color(QPalette.WindowText) g.setColorAt(0, c), g.setColorAt(0.8, c) c = QColor(c) c.setAlpha(0) g.setColorAt(1, c) pen = QPen() pen.setBrush(QBrush(g)) painter.setPen(pen) painter.drawText(tr, flags, text)
def draw_text(self, style, painter, option, widget, index, item): tr = style.subElementRect(style.SE_ItemViewItemText, option, widget) text = index.data(Qt.DisplayRole) hover = option.state & style.State_MouseOver if hover or gprefs['tag_browser_show_counts']: count = unicode_type(index.data(COUNT_ROLE)) width = painter.fontMetrics().boundingRect(count).width() r = QRect(tr) r.setRight(r.right() - 1), r.setLeft(r.right() - width - 4) self.paint_text(painter, r, Qt.AlignCenter | Qt.TextSingleLine, count, hover) tr.setRight(r.left() - 1) else: tr.setRight(tr.right() - 1) is_rating = item.type == TagTreeItem.TAG and not self.rating_pat.sub('', text) if is_rating: painter.setFont(self.rating_font) flags = Qt.AlignVCenter | Qt.AlignLeft | Qt.TextSingleLine lr = QRect(tr) lr.setRight(lr.right() * 2) br = painter.boundingRect(lr, flags, text) if br.width() > tr.width(): g = QLinearGradient(tr.topLeft(), tr.topRight()) c = option.palette.color(QPalette.WindowText) g.setColorAt(0, c), g.setColorAt(0.8, c) c = QColor(c) c.setAlpha(0) g.setColorAt(1, c) pen = QPen() pen.setBrush(QBrush(g)) painter.setPen(pen) self.paint_text(painter, tr, flags, text, hover)
def paint(self, painter, option, index): QStyledItemDelegate.paint(self, painter, option, index) hovering = index.data(HOVER_ROLE) is True painter.save() rect = option.rect is_current = index.data(Qt.FontRole) is not None if not hovering and is_current: qpp = QPainterPath() qpp.addRoundedRect(QRectF(rect), 6, 6) painter.fillPath(qpp, self.current_background) icon_rect = QRect(rect.left() + self.MARGIN, rect.top() + self.MARGIN, ICON_SIZE, ICON_SIZE) left = icon_rect.right() + 2 * self.MARGIN text_rect = QRect(left, icon_rect.top(), rect.width() - left + rect.left(), icon_rect.height()) mark = index.data(MARK_ROLE) if hovering or mark: text_rect.adjust(0, 0, -text_rect.height(), 0) text = index.data(DISPLAY_ROLE) or '' font = index.data(Qt.FontRole) if font: painter.setFont(font) text_flags = Qt.AlignVCenter | Qt.AlignLeft | Qt.TextSingleLine text = elided_text(text, font, text_rect.width(), 'right') if option.state & QStyle.State_Selected: painter.setPen(QPen(self.highlighted_text)) painter.drawText(text_rect, text_flags, text) if mark: hrect = QRect(text_rect.right(), text_rect.top(), text_rect.height(), text_rect.height()) painter.fillRect(hrect, QColor('#ffffaa')) painter.drawText(hrect, Qt.AlignCenter, mark) elif hovering: hrect = QRect(text_rect.right(), text_rect.top(), text_rect.height(), text_rect.height()) close_hover = index.data(CLOSE_HOVER_ROLE) is True if close_hover: pen = painter.pen() pen.setColor(QColor('red')) painter.setPen(pen) painter.drawText(hrect, Qt.AlignCenter, '✖ ') if index.data(LOADING_ROLE): if not self.errored_out: angle = index.data(ANGLE_ROLE) try: draw_snake_spinner(painter, icon_rect, angle, self.light, self.dark) except Exception: import traceback traceback.print_exc() self.errored_out = True else: icurl = index.data(URL_ROLE) if icurl == WELCOME_URL: icon = welcome_icon() elif icurl == DOWNLOADS_URL: icon = downloads_icon() else: icon = index.data(DECORATION_ROLE) icon.paint(painter, icon_rect) painter.restore()
def paint_embossed_emblem(self, pixmap, painter, orect, right_adjust, left=True): drect = QRect(orect) if left: drect.setLeft(drect.left() + right_adjust) drect.setRight(drect.left() + pixmap.width()) else: drect.setRight(drect.right() - right_adjust) drect.setLeft(drect.right() - pixmap.width() + 1) drect.setBottom(drect.bottom() - self.title_height) drect.setTop(drect.bottom() - pixmap.height()) painter.drawPixmap(drect, pixmap)
def paint_embossed_emblem(self, pixmap, painter, orect, right_adjust, left=True): drect = QRect(orect) pw = int(pixmap.width() / pixmap.devicePixelRatio()) ph = int(pixmap.height() / pixmap.devicePixelRatio()) if left: drect.setLeft(drect.left() + right_adjust) drect.setRight(drect.left() + pw) else: drect.setRight(drect.right() - right_adjust) drect.setLeft(drect.right() - pw + 1) drect.setBottom(drect.bottom() - self.title_height) drect.setTop(drect.bottom() - ph) painter.drawPixmap(drect, pixmap)
def createPixmapForSite(self, icon, title, url): ''' @param: icon QIcon @param: title QString @param: url QString @return: QPixmap ''' fontMetrics = QApplication.fontMetrics() padding = 4 text = len(title) > len(url) and title or url maxWidth = fontMetrics.width(text) + 3 * padding + 16 width = min(maxWidth, 150) height = fontMetrics.height() * 2 + fontMetrics.leading() + 2 * padding pixelRatio = gVar.app.devicePixelRatio() pixmap = QPixmap(width * pixelRatio, height * pixelRatio) pixmap.setDevicePixelRatio(pixelRatio) painter = QPainter(pixmap) painter.setRenderHint(QPainter.Antialiasing) # Draw background pen = QPen(Qt.black) pen.setWidth(1) painter.setPen(pen) path = QPainterPath() path.addRect(QRectF(0, 0, width, height)) painter.fillPath(path, Qt.white) painter.drawPath(path) # Draw icon iconRect = QRect(padding, 0, 16, height) icon.paint(painter, iconRect) # Draw title titleRect = QRectF(iconRect.right() + padding, padding, width - padding - iconRect.right(), fontMetrics.height()) painter.drawText(titleRect, fontMetrics.elidedText(title, Qt.ElideRight, titleRect.width())) # Draw url urlRect = QRectF(titleRect.x(), titleRect.bottom() + fontMetrics.leading(), titleRect.width(), titleRect.height()) painter.setPen(QApplication.palette().color(QPalette.Link)) painter.drawText(urlRect, fontMetrics.elidedText(url, Qt.ElideRight, urlRect.width())) return pixmap
def paint_emblems(self, painter, rect, emblems): gutter = self.emblem_size + self.MARGIN grect = QRect(rect) gpos = self.gutter_position if gpos is self.TOP: grect.setBottom(grect.top() + gutter) rect.setTop(rect.top() + gutter) elif gpos is self.BOTTOM: grect.setTop(grect.bottom() - gutter + self.MARGIN) rect.setBottom(rect.bottom() - gutter) elif gpos is self.LEFT: grect.setRight(grect.left() + gutter) rect.setLeft(rect.left() + gutter) else: grect.setLeft(grect.right() - gutter + self.MARGIN) rect.setRight(rect.right() - gutter) horizontal = gpos in (self.TOP, self.BOTTOM) painter.save() painter.setClipRect(grect) try: for i, emblem in enumerate(emblems): delta = 0 if i == 0 else self.emblem_size + self.MARGIN grect.moveLeft(grect.left() + delta) if horizontal else grect.moveTop(grect.top() + delta) rect = QRect(grect) rect.setWidth(int(emblem.width() / emblem.devicePixelRatio())), rect.setHeight(int(emblem.height() / emblem.devicePixelRatio())) painter.drawPixmap(rect, emblem) finally: painter.restore()
def paintEvent(self, event): ''' @param: event QPaintEvent ''' super().paintEvent(event) # Draw drop indicator if self._dropRow != -1: # BookmarksToolbarButton button = self._buttonAt(self._dropPos) if button: if button.bookmark().isFolder(): return tmpRect = QRect(button.x(), 0, button.width(), self.height()) rect = QRect() if self._dropRow == self._layout.indexOf(button): rect = QRect(max(0, tmpRect.left() - 2), tmpRect.top(), 3, tmpRect.height()) else: rect = QRect(tmpRect.right() + 0, tmpRect.top(), 3, tmpRect.height()) gVar.appTools.paintDropIndicator(self, rect)
def draw(self, painter, width, palette): flags = self.FLAGS | (Qt.AlignRight if self.right_align else Qt.AlignLeft) rect = QRect(self.rect) if self.right_align: rect.setRight(width - self.SIDE_MARGIN) painter.setPen(palette.color(self.color_role) if self.override_color is None else self.override_color) br = painter.drawText(rect, flags, self.text) if self.swatch is not None: r = QRect(br.right() + self.SIDE_MARGIN // 2, br.top() + 2, br.height() - 4, br.height() - 4) painter.fillRect(r, self.swatch) br.setRight(r.right()) if self.is_overriden: painter.setPen(palette.color(QPalette.WindowText)) painter.drawLine(br.left(), br.top() + br.height() // 2, br.right(), br.top() + br.height() // 2)
def decoration_for_style(palette, style, icon_size, device_pixel_ratio, is_dark): style_key = (is_dark, icon_size, device_pixel_ratio, tuple((k, style[k]) for k in sorted(style))) sentinel = object() ans = decoration_cache.get(style_key, sentinel) if ans is not sentinel: return ans ans = None kind = style.get('kind') if kind == 'color': key = 'dark' if is_dark else 'light' val = style.get(key) if val is None: which = style.get('which') val = (builtin_colors_dark if is_dark else builtin_colors_light).get(which) if val is None: val = style.get('background-color') if val is not None: ans = QColor(val) elif kind == 'decoration': which = style.get('which') if which is not None: q = builtin_decorations.get(which) if q is not None: style = q sz = int(math.ceil(icon_size * device_pixel_ratio)) canvas = QImage(sz, sz, QImage.Format.Format_ARGB32) canvas.fill(Qt.GlobalColor.transparent) canvas.setDevicePixelRatio(device_pixel_ratio) p = QPainter(canvas) p.setRenderHint(QPainter.RenderHint.Antialiasing, True) p.setPen(palette.color(QPalette.ColorRole.WindowText)) irect = QRect(0, 0, icon_size, icon_size) adjust = -2 text_rect = p.drawText( irect.adjusted(0, adjust, 0, adjust), Qt.AlignmentFlag.AlignHCenter | Qt.AlignmentFlag.AlignTop, 'a') p.drawRect(irect) fm = p.fontMetrics() pen = p.pen() if 'text-decoration-color' in style: pen.setColor(QColor(style['text-decoration-color'])) lstyle = style.get('text-decoration-style') or 'solid' q = { 'dotted': Qt.PenStyle.DotLine, 'dashed': Qt.PenStyle.DashLine, }.get(lstyle) if q is not None: pen.setStyle(q) lw = fm.lineWidth() if lstyle == 'double': lw * 2 pen.setWidth(fm.lineWidth()) q = style.get('text-decoration-line') or 'underline' pos = text_rect.bottom() height = irect.bottom() - pos if q == 'overline': pos = height elif q == 'line-through': pos = text_rect.center().y() - adjust - lw // 2 p.setPen(pen) if lstyle == 'wavy': p.drawPath(wavy_path(icon_size, height, pos)) else: p.drawLine(0, pos, irect.right(), pos) p.end() ans = QPixmap.fromImage(canvas) elif 'background-color' in style: ans = QColor(style['background-color']) decoration_cache[style_key] = ans return ans
def paintEvent(self, event): ''' @param: event QPaintEvent ''' p = QPainter(self) # Just draw separator if self._bookmark.isSeparator(): opt = QStyleOption() opt.initFrom(self) opt.state |= QStyle.State_Horizontal self.style().drawPrimitive(QStyle.PE_IndicatorToolBarSeparator, opt, p) return option = QStyleOptionButton() self.initStyleOption(option) # We are manually drawing the arrow option.features &= ~QStyleOptionButton.HasMenu # Draw button base (only under mouse, this is autoraise button) if self.isDown() or self.hitButton(self.mapFromGlobal(QCursor.pos())): option.state |= QStyle.State_AutoRaise | QStyle.State_Raised self.style().drawPrimitive(QStyle.PE_PanelButtonTool, option, p, self) if self.isDown(): shiftX = self.style().pixelMetric(QStyle.PM_ButtonShiftHorizontal, option, self) shiftY = self.style().pixelMetric(QStyle.PM_ButtonShiftVertical, option, self) else: shiftX = 0 shiftY = 0 height = option.rect.height() center = height / 2 + option.rect.top() + shiftY iconSize = 16 iconYPos = center - iconSize / 2 leftPosition = self.PADDING + shiftX rightPosition = option.rect.right() - self.PADDING # Draw icon if not self._showOnlyText: iconRect = QRect(leftPosition, iconYPos, iconSize, iconSize) p.drawPixmap( QStyle.visualRect(option.direction, option.rect, iconRect), self._bookmark.icon().pixmap(iconSize)) leftPosition = iconRect.right() + self.PADDING # Draw menu arrow if not self._showOnlyIcon and self.menu(): arrowSize = 8 opt = QStyleOption() opt.initFrom(self) rect = QRect(rightPosition - 8, center - arrowSize / 2, arrowSize, arrowSize) opt.rect = QStyle.visualRect(option.direction, option.rect, rect) opt.state &= ~QStyle.State_MouseOver self.style().drawPrimitive(QStyle.PE_IndicatorArrowDown, opt, p, self) rightPosition = rect.left() - self.PADDING # Draw text if not self._showOnlyIcon: textWidth = rightPosition - leftPosition textYPos = center - self.fontMetrics().height() / 2 txt = self.fontMetrics().elidedText(self._bookmark.title(), Qt.ElideRight, textWidth) textRect = QRect(leftPosition, textYPos, textWidth, self.fontMetrics().height()) self.style().drawItemText( p, QStyle.visualRect(option.direction, option.rect, textRect), Qt.TextSingleLine | Qt.AlignCenter, option.palette, True, txt)
def paint(self, painter, option, index): # noqa C901 ''' @param painter QPainter @param option index QStyleOptionViewItem @param option index QModelIndex ''' from ..LocationBar import LocationBar opt = QStyleOptionViewItem(option) self.initStyleOption(opt, index) w = opt.widget if w: style = w.style() else: style = QApplication.style() height = opt.rect.height() center = height / 2 + opt.rect.top() # Prepare link font # QFont linkFont = opt.font linkFont.setPointSize(linkFont.pointSize() - 1) linkMetrics = QFontMetrics(linkFont) leftPosition = self._padding * 2 rightPosition = opt.rect.right() - self._padding opt.state |= QStyle.State_Active if opt.state & QStyle.State_Selected: iconMode = QIcon.Selected colorRole = QPalette.HighlightedText colorLinkRole = QPalette.HighlightedText else: iconMode = QIcon.Normal colorRole = QPalette.Text colorLinkRole = QPalette.Link if const.OS_WIN: opt.palette.setColor(QPalette.All, QPalette.HighlightedText, opt.palette.color(QPalette.Active, QPalette.Text)) opt.palette.setColor(QPalette.All, QPalette.Highlight, opt.palette.base().color().darker(108)) textPalette = QPalette(opt.palette) if opt.state & QStyle.State_Enabled: textPalette.setCurrentColorGroup(QPalette.Normal) else: textPalette.setCurrentColorGroup(QPalette.Disabled) # Draw background style.drawPrimitive(QStyle.PE_PanelItemViewItem, opt, painter, w) isVisitSearchItem = index.data(LocationCompleterModel.VisitSearchItemRole) isSearchSuggestion = index.data(LocationCompleterModel.SearchSuggestionRole) loadAction = LocationBar.LoadAction() isWebSearch = isSearchSuggestion # BookmarkItem bookmark = index.data(LocationCompleterModel.BookmarkItemRole) if isVisitSearchItem: text = index.data(LocationCompleterModel.SearchStringRole) loadAction = LocationBar.loadAction(text) isWebSearch = loadAction.type == LocationBar.LoadAction.Search if not self._forceVisitItem: bookmark = loadAction.bookmark # Draw icon iconSize = 16 iconYPos = center - iconSize / 2 iconRect = QRect(leftPosition, iconYPos, iconSize, iconSize) icon = index.data(Qt.DecorationRole) if not icon: icon = QIcon() pixmap = icon.pixmap(iconSize) if isSearchSuggestion or (isVisitSearchItem and isWebSearch): pixmap = QIcon.fromTheme('edit-find', QIcon(':/icons/menu/search-icon.svg')).pixmap(iconSize, iconMode) if isVisitSearchItem and bookmark: pixmap = bookmark.icon().pixmap(iconSize) elif loadAction.type == LocationBar.LoadAction.Search: if loadAction.searchEngine.name != LocationBar.searchEngine().name: pixmap = loadAction.searchEngine.icon.pixmap(iconSize) painter.drawPixmap(iconRect, pixmap) leftPosition = iconRect.right() + self._padding * 2 # Draw star to bookmark items starPixmapWidth = 0 if bookmark: icon = IconProvider.instance().bookmarkIcon starSize = QSize(16, 16) starPixmapWidth = starSize.width() pos = QPoint(rightPosition - starPixmapWidth, center - starSize.height() / 2) starRect = QRect(pos, starSize) painter.drawPixmap(starRect, icon.pixmap(starSize, iconMode)) searchText = index.data(LocationCompleterModel.SearchStringRole) # Draw title leftPosition += 2 titleRect = QRect(leftPosition, center - opt.fontMetrics.height() / 2, opt.rect.width() * 0.6, opt.fontMetrics.height()) title = index.data(LocationCompleterModel.TitleRole) painter.setFont(opt.font) if isVisitSearchItem: if bookmark: title = bookmark.title() else: title = index.data(LocationCompleterModel.SearchStringRole) searchText = '' leftPosition += self.viewItemDrawText(painter, opt, titleRect, title, textPalette.color(colorRole), searchText) leftPosition += self._padding * 2 # Trim link to maximum number characters that can be visible, # otherwise there may be perf issue with huge URLs maxChars = int((opt.rect.width() - leftPosition) / opt.fontMetrics.width('i')) link = index.data(Qt.DisplayRole) if not link.startswith('data') and not link.startswith('javascript'): link = unquote(link)[:maxChars] else: link = link[:maxChars] if isVisitSearchItem or isSearchSuggestion: if not (opt.state & QStyle.State_Selected) and not (opt.state & QStyle.State_MouseOver): link = '' elif isVisitSearchItem and (not isWebSearch or self._forceVisitItem): link = _('Visit') else: searchEngineName = loadAction.searchEngine.name if not searchEngineName: searchEngineName = LocationBar.searchEngine().name link = _('Search with %s') % searchEngineName if bookmark: link = bookmark.url().toString() # Draw separator if link: separator = '-' separatorRect = QRect(leftPosition, center - linkMetrics.height() / 2, linkMetrics.width(separator), linkMetrics.height()) style.drawItemText(painter, separatorRect, Qt.AlignCenter, textPalette, True, separator, colorRole) leftPosition += separatorRect.width() + self._padding * 2 # Draw link leftLinkEdge = leftPosition rightLinkEdge = rightPosition - self._padding - starPixmapWidth linkRect = QRect(leftLinkEdge, center - linkMetrics.height() / 2, rightLinkEdge - leftLinkEdge, linkMetrics.height()) painter.setFont(linkFont) # Darw url (or switch to tab) tabPos = index.data(LocationCompleterModel.TabPositionTabRole) if gVar.appSettings.showSwitchTab and not self._forceVisitItem and tabPos != -1: tabIcon = QIcon(':/icons/menu/tab.svg') iconRect = QRect(linkRect) iconRect.setX(iconRect.x()) iconRect.setWidth(16) painter.drawPixmap(iconRect, tabIcon.pixmap(iconRect.size(), iconMode)) textRect = QRect(linkRect) textRect.setX(textRect.x() + self._padding + 16 + self._padding) self.viewItemDrawText(painter, opt, textRect, _('Switch to tab'), textPalette.color(colorLinkRole)) elif isVisitSearchItem or isSearchSuggestion: self.viewItemDrawText(painter, opt, linkRect, link, textPalette.color(colorLinkRole)) else: self.viewItemDrawText(painter, opt, linkRect, link, textPalette.color(colorLinkRole), searchText)