def text_layout(self, text, width, font, font_metrics): "Lays out wrapped text" text_option = QTextOption(Qt.AlignCenter) text_option.setUseDesignMetrics(True) text_option.setWrapMode(QTextOption.WordWrap) layout = QTextLayout(text, font) layout.setTextOption(text_option) leading = font_metrics.leading() height = 0 layout.setCacheEnabled(True) layout.beginLayout() while True: line = layout.createLine() if not line.isValid(): break line.setLineWidth(width) height += leading line.setPosition(QPointF(0, height)) height += line.height() layout.endLayout() return layout
def paint(self, painter, option, index): assert isinstance(painter, QPainter) if index.data(Qt.UserRole+1): if app_constants.HIGH_QUALITY_THUMBS: painter.setRenderHint(QPainter.SmoothPixmapTransform) painter.setRenderHint(QPainter.Antialiasing) gallery = index.data(Qt.UserRole+1) title = gallery.title artist = gallery.artist title_color = app_constants.GRID_VIEW_TITLE_COLOR artist_color = app_constants.GRID_VIEW_ARTIST_COLOR label_color = app_constants.GRID_VIEW_LABEL_COLOR # Enable this to see the defining box #painter.drawRect(option.rect) # define font size if 20 > len(title) > 15: title_size = "font-size:{}px;".format(self.font_size) elif 30 > len(title) > 20: title_size = "font-size:{}px;".format(self.font_size-1) elif 40 > len(title) >= 30: title_size = "font-size:{}px;".format(self.font_size-2) elif 50 > len(title) >= 40: title_size = "font-size:{}px;".format(self.font_size-3) elif len(title) >= 50: title_size = "font-size:{}px;".format(self.font_size-4) else: title_size = "font-size:{}px;".format(self.font_size) if 30 > len(artist) > 20: artist_size = "font-size:{}px;".format(self.font_size) elif 40 > len(artist) >= 30: artist_size = "font-size:{}px;".format(self.font_size-1) elif len(artist) >= 40: artist_size = "font-size:{}px;".format(self.font_size-2) else: artist_size = "font-size:{}px;".format(self.font_size) #painter.setPen(QPen(Qt.NoPen)) #option.rect = option.rect.adjusted(11, 10, 0, 0) option.rect.setWidth(self.W) option.rect.setHeight(self.H) rec = option.rect.getRect() x = rec[0] y = rec[1] w = rec[2] h = rec[3] text_area = QTextDocument() text_area.setDefaultFont(option.font) text_area.setHtml(""" <head> <style> #area {{ display:flex; width:{6}px; height:{7}px }} #title {{ position:absolute; color: {4}; font-weight:bold; {0} }} #artist {{ position:absolute; color: {5}; top:20px; right:0; {1} }} </style> </head> <body> <div id="area"> <center> <div id="title">{2} </div> <div id="artist">{3} </div> </div> </center> </body> """.format(title_size, artist_size, title, artist, title_color, artist_color, 130+app_constants.SIZE_FACTOR, 1+app_constants.SIZE_FACTOR)) text_area.setTextWidth(w) #chapter_area = QTextDocument() #chapter_area.setDefaultFont(option.font) #chapter_area.setHtml(""" #<font color="black">{}</font> #""".format("chapter")) #chapter_area.setTextWidth(w) def center_img(width): new_x = x if width < w: diff = w - width offset = diff//2 new_x += offset return new_x def img_too_big(start_x): txt_layout = misc.text_layout("Image is too big!", w, self.title_font, self.title_font_m) clipping = QRectF(x, y+h//4, w, app_constants.GRIDBOX_LBL_H - 10) txt_layout.draw(painter, QPointF(x, y+h//4), clip=clipping) # if we can't find a cached image pix_cache = QPixmapCache.find(self.key(gallery.profile)) if isinstance(pix_cache, QPixmap): self.image = pix_cache img_x = center_img(self.image.width()) if self.image.width() > w or self.image.height() > h: img_too_big(img_x) else: if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) else: self.image = QPixmap(gallery.profile) img_x = center_img(self.image.width()) QPixmapCache.insert(self.key(gallery.profile), self.image) if self.image.width() > w or self.image.height() > h: img_too_big(img_x) else: if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) # draw ribbon type painter.save() painter.setPen(Qt.NoPen) if app_constants.DISPLAY_GALLERY_RIBBON: type_ribbon_w = type_ribbon_l = w*0.11 rib_top_1 = QPointF(x+w-type_ribbon_l-type_ribbon_w, y) rib_top_2 = QPointF(x+w-type_ribbon_l, y) rib_side_1 = QPointF(x+w, y+type_ribbon_l) rib_side_2 = QPointF(x+w, y+type_ribbon_l+type_ribbon_w) ribbon_polygon = QPolygonF([rib_top_1, rib_top_2, rib_side_1, rib_side_2]) ribbon_path = QPainterPath() ribbon_path.setFillRule(Qt.WindingFill) ribbon_path.addPolygon(ribbon_polygon) ribbon_path.closeSubpath() painter.setBrush(QBrush(QColor(self._ribbon_color(gallery.type)))) painter.drawPath(ribbon_path) # draw if favourited if gallery.fav == 1: star_ribbon_w = star_ribbon_l = w*0.08 rib_top_1 = QPointF(x+star_ribbon_l, y) rib_side_1 = QPointF(x, y+star_ribbon_l) rib_top_2 = QPointF(x+star_ribbon_l+star_ribbon_w, y) rib_side_2 = QPointF(x, y+star_ribbon_l+star_ribbon_w) rib_star_mid_1 = QPointF((rib_top_1.x()+rib_side_1.x())/2, (rib_top_1.y()+rib_side_1.y())/2) rib_star_factor = star_ribbon_l/4 rib_star_p1_1 = rib_star_mid_1 + QPointF(rib_star_factor, -rib_star_factor) rib_star_p1_2 = rib_star_p1_1 + QPointF(-rib_star_factor, -rib_star_factor) rib_star_p1_3 = rib_star_mid_1 + QPointF(-rib_star_factor, rib_star_factor) rib_star_p1_4 = rib_star_p1_3 + QPointF(-rib_star_factor, -rib_star_factor) crown_1 = QPolygonF([rib_star_p1_1, rib_star_p1_2, rib_star_mid_1, rib_star_p1_4, rib_star_p1_3]) painter.setBrush(QBrush(QColor("yellow"))) painter.drawPolygon(crown_1) ribbon_polygon = QPolygonF([rib_top_1, rib_side_1, rib_side_2, rib_top_2]) ribbon_path = QPainterPath() ribbon_path.setFillRule(Qt.WindingFill) ribbon_path.addPolygon(ribbon_polygon) ribbon_path.closeSubpath() painter.drawPath(ribbon_path) #painter.setPen(QColor("#d35400")) #painter.drawPolyline(rib_top_1, rib_star_p1_1, rib_star_p1_2, rib_star_mid_1, rib_star_p1_4, rib_star_p1_3, rib_side_1) #painter.drawLine(rib_top_1, rib_top_2) #painter.drawLine(rib_top_2, rib_side_2) #painter.drawLine(rib_side_1, rib_side_2) painter.restore() if app_constants._REFRESH_EXTERNAL_VIEWER: if app_constants.USE_EXTERNAL_VIEWER: self.external_icon = self.file_icons.get_external_file_icon() else: self.external_icon = self.file_icons.get_default_file_icon() if gallery.state == self.G_DOWNLOAD: painter.save() dl_box = QRect(x, y, w, 20) painter.setBrush(QBrush(QColor(0,0,0,123))) painter.setPen(QColor('white')) painter.drawRect(dl_box) painter.drawText(dl_box, Qt.AlignCenter, 'Downloading...') painter.restore() else: if app_constants.DISPLAY_GALLERY_TYPE: self.type_icon = self.file_icons.get_file_icon(gallery.path) if self.type_icon and not self.type_icon.isNull(): self.type_icon.paint(painter, QRect(x+2, y+app_constants.THUMB_H_SIZE-16, 16, 16)) if app_constants.USE_EXTERNAL_PROG_ICO: if self.external_icon and not self.external_icon.isNull(): self.external_icon.paint(painter, QRect(x+w-30, y+app_constants.THUMB_H_SIZE-28, 28, 28)) def draw_text_label(lbl_h): #draw the label for text painter.save() painter.translate(x, y+app_constants.THUMB_H_SIZE) box_color = QBrush(QColor(label_color))#QColor(0,0,0,123)) painter.setBrush(box_color) rect = QRect(0, 0, w, lbl_h) #x, y, width, height painter.fillRect(rect, box_color) painter.restore() return rect if option.state & QStyle.State_MouseOver or\ option.state & QStyle.State_Selected: title_layout = misc.text_layout(title, w, self.title_font, self.title_font_m) artist_layout = misc.text_layout(artist, w, self.artist_font, self.artist_font_m) t_h = title_layout.boundingRect().height() a_h = artist_layout.boundingRect().height() if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(min(t_h+a_h+3, app_constants.GRIDBOX_LBL_H)) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) clipping = QRectF(x, y+app_constants.THUMB_H_SIZE, w, app_constants.GRIDBOX_LBL_H - 10) painter.setPen(QColor(title_color)) title_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE), clip=clipping) painter.setPen(QColor(artist_color)) artist_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE+t_h), clip=clipping) #painter.fillRect(option.rect, QColor) else: if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(self.text_label_h) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) # draw text painter.save() alignment = QTextOption(Qt.AlignCenter) alignment.setUseDesignMetrics(True) title_rect = QRectF(0,0,w, self.title_font_m.height()) artist_rect = QRectF(0,self.artist_font_m.height(),w, self.artist_font_m.height()) painter.translate(x, y+app_constants.THUMB_H_SIZE) if app_constants.GALLERY_FONT_ELIDE: painter.setFont(self.title_font) painter.setPen(QColor(title_color)) painter.drawText(title_rect, self.title_font_m.elidedText(title, Qt.ElideRight, w-10), alignment) painter.setPen(QColor(artist_color)) painter.setFont(self.artist_font) alignment.setWrapMode(QTextOption.NoWrap) painter.drawText(artist_rect, self.title_font_m.elidedText(artist, Qt.ElideRight, w-10), alignment) else: text_area.setDefaultFont(QFont(self.font_name)) text_area.drawContents(painter) ##painter.resetTransform() painter.restore() if option.state & QStyle.State_Selected: painter.save() selected_rect = QRectF(x, y, w, lbl_rect.height()+app_constants.THUMB_H_SIZE) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(QColor(164,164,164,120))) painter.drawRoundedRect(selected_rect, 5, 5) #painter.fillRect(selected_rect, QColor(164,164,164,120)) painter.restore() if gallery.dead_link: painter.save() selected_rect = QRectF(x, y, w, lbl_rect.height()+app_constants.THUMB_H_SIZE) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(QColor(255,0,0,120))) p_path = QPainterPath() p_path.setFillRule(Qt.WindingFill) p_path.addRoundedRect(selected_rect, 5,5) p_path.addRect(x,y, 20, 20) p_path.addRect(x+w-20,y, 20, 20) painter.drawPath(p_path.simplified()) painter.setPen(QColor("white")) txt_layout = misc.text_layout("Cannot find gallery source!", w, self.title_font, self.title_font_m) txt_layout.draw(painter, QPointF(x, y+h*0.3)) painter.restore() if app_constants.DEBUG: painter.save() painter.setBrush(QBrush(QColor("red"))) painter.setPen(QColor("white")) txt_l = self.title_font_m.width(str(gallery.id)) painter.drawRect(x, y+40, txt_l*2, self.title_font_m.height()) painter.drawText(x+1, y+51, str(gallery.id)) painter.restore() if option.state & QStyle.State_Selected: painter.setPen(QPen(option.palette.highlightedText().color())) else: super().paint(painter, option, index)
def paint(self, painter, option, index): assert isinstance(painter, QPainter) if index.data(Qt.UserRole+1): if app_constants.HIGH_QUALITY_THUMBS: painter.setRenderHint(QPainter.SmoothPixmapTransform) painter.setRenderHint(QPainter.Antialiasing) gallery = index.data(Qt.UserRole+1) title = gallery.title artist = gallery.artist title_color = app_constants.GRID_VIEW_TITLE_COLOR artist_color = app_constants.GRID_VIEW_ARTIST_COLOR label_color = app_constants.GRID_VIEW_LABEL_COLOR # Enable this to see the defining box #painter.drawRect(option.rect) # define font size if 20 > len(title) > 15: title_size = "font-size:{}px;".format(self.font_size) elif 30 > len(title) > 20: title_size = "font-size:{}px;".format(self.font_size-1) elif 40 > len(title) >= 30: title_size = "font-size:{}px;".format(self.font_size-2) elif 50 > len(title) >= 40: title_size = "font-size:{}px;".format(self.font_size-3) elif len(title) >= 50: title_size = "font-size:{}px;".format(self.font_size-4) else: title_size = "font-size:{}px;".format(self.font_size) if 30 > len(artist) > 20: artist_size = "font-size:{}px;".format(self.font_size) elif 40 > len(artist) >= 30: artist_size = "font-size:{}px;".format(self.font_size-1) elif len(artist) >= 40: artist_size = "font-size:{}px;".format(self.font_size-2) else: artist_size = "font-size:{}px;".format(self.font_size) #painter.setPen(QPen(Qt.NoPen)) #option.rect = option.rect.adjusted(11, 10, 0, 0) option.rect.setWidth(self.W) option.rect.setHeight(self.H) rec = option.rect.getRect() x = rec[0] y = rec[1] w = rec[2] h = rec[3] text_area = QTextDocument() text_area.setDefaultFont(option.font) text_area.setHtml(""" <head> <style> #area {{ display:flex; width:140px; height:10px }} #title {{ position:absolute; color: {4}; font-weight:bold; {0} }} #artist {{ position:absolute; color: {5}; top:20px; right:0; {1} }} </style> </head> <body> <div id="area"> <center> <div id="title">{2} </div> <div id="artist">{3} </div> </div> </center> </body> """.format(title_size, artist_size, title, artist, title_color, artist_color)) text_area.setTextWidth(w) #chapter_area = QTextDocument() #chapter_area.setDefaultFont(option.font) #chapter_area.setHtml(""" #<font color="black">{}</font> #""".format("chapter")) #chapter_area.setTextWidth(w) def center_img(width): new_x = x if width < w: diff = w - width offset = diff//2 new_x += offset return new_x # if we can't find a cached image pix_cache = QPixmapCache.find(self.key(gallery.profile)) if isinstance(pix_cache, QPixmap): self.image = pix_cache img_x = center_img(self.image.width()) if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) else: self.image = QPixmap(gallery.profile) img_x = center_img(self.image.width()) QPixmapCache.insert(self.key(gallery.profile), self.image) if self.image.height() < self.image.width(): #to keep aspect ratio painter.drawPixmap(QPoint(img_x,y), self.image) else: painter.drawPixmap(QPoint(img_x,y), self.image) # draw star if it's favorited if gallery.fav == 1: painter.drawPixmap(QPointF(x,y), QPixmap(app_constants.STAR_PATH)) if app_constants._REFRESH_EXTERNAL_VIEWER: if app_constants.USE_EXTERNAL_VIEWER: self.external_icon = self.file_icons.get_external_file_icon() else: self.external_icon = self.file_icons.get_default_file_icon() if gallery.state == self.G_DOWNLOAD: painter.save() dl_box = QRect(x, y, w, 20) painter.setBrush(QBrush(QColor(0,0,0,123))) painter.setPen(QColor('white')) painter.drawRect(dl_box) painter.drawText(dl_box, Qt.AlignCenter, 'Downloading...') painter.restore() else: if app_constants.DISPLAY_GALLERY_TYPE: self.type_icon = self.file_icons.get_file_icon(gallery.path) if self.type_icon and not self.type_icon.isNull(): self.type_icon.paint(painter, QRect(x+2, y+app_constants.THUMB_H_SIZE-16, 16, 16)) if app_constants.USE_EXTERNAL_PROG_ICO: if self.external_icon and not self.external_icon.isNull(): self.external_icon.paint(painter, QRect(x+w-30, y+app_constants.THUMB_H_SIZE-28, 28, 28)) def draw_text_label(lbl_h): #draw the label for text painter.save() painter.translate(x, y+app_constants.THUMB_H_SIZE) box_color = QBrush(QColor(label_color))#QColor(0,0,0,123)) painter.setBrush(box_color) rect = QRect(0, 0, w, lbl_h) #x, y, width, height painter.fillRect(rect, box_color) painter.restore() return rect if option.state & QStyle.State_MouseOver or\ option.state & QStyle.State_Selected: title_layout = self.text_layout(title, w, self.title_font, self.title_font_m) artist_layout = self.text_layout(artist, w, self.artist_font, self.artist_font_m) t_h = title_layout.boundingRect().height() a_h = artist_layout.boundingRect().height() if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(min(t_h+a_h+3, app_constants.GRIDBOX_LBL_H)) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) clipping = QRectF(x, y+app_constants.THUMB_H_SIZE, w, app_constants.GRIDBOX_LBL_H - 10) title_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE), clip=clipping) artist_layout.draw(painter, QPointF(x, y+app_constants.THUMB_H_SIZE+t_h), clip=clipping) #painter.fillRect(option.rect, QColor) else: if app_constants.GALLERY_FONT_ELIDE: lbl_rect = draw_text_label(self.text_label_h) else: lbl_rect = draw_text_label(app_constants.GRIDBOX_LBL_H) # draw text painter.save() alignment = QTextOption(Qt.AlignCenter) alignment.setUseDesignMetrics(True) title_rect = QRectF(0,0,w, self.title_font_m.height()) artist_rect = QRectF(0,self.artist_font_m.height(),w, self.artist_font_m.height()) painter.translate(x, y+app_constants.THUMB_H_SIZE) if app_constants.GALLERY_FONT_ELIDE: painter.setFont(self.title_font) painter.setPen(QColor(title_color)) painter.drawText(title_rect, self.title_font_m.elidedText(title, Qt.ElideRight, w-10), alignment) painter.setPen(QColor(artist_color)) painter.setFont(self.artist_font) alignment.setWrapMode(QTextOption.NoWrap) painter.drawText(artist_rect, self.title_font_m.elidedText(artist, Qt.ElideRight, w-10), alignment) else: text_area.setDefaultFont(QFont(self.font_name)) text_area.drawContents(painter) ##painter.resetTransform() painter.restore() if option.state & QStyle.State_Selected: painter.save() selected_rect = QRectF(x, y, w, lbl_rect.height()+app_constants.THUMB_H_SIZE) painter.setPen(Qt.NoPen) painter.setBrush(QBrush(QColor(164,164,164,120))) p_path = QPainterPath() p_path.setFillRule(Qt.WindingFill) p_path.addRoundedRect(selected_rect, 5,5) p_path.addRect(x,y, 20, 20) p_path.addRect(x+w-20,y, 20, 20) painter.drawPath(p_path.simplified()) #painter.fillRect(selected_rect, QColor(164,164,164,120)) painter.restore() #if option.state & QStyle.State_Selected: # painter.setPen(QPen(option.palette.highlightedText().color())) else: super().paint(painter, option, index)