def _isChunkVisible(self, chunk: Chunk, size: QSize) -> bool: x = int(self.cam_x - (self.cam_z * size.width()) / 2) y = int(self.cam_y - (self.cam_z * size.height()) / 2) return (-16 * ISOMETRIC_WIDTH <= ((chunk.x - chunk.y) * ISOMETRIC_WIDTH - x) <= size.width() * self.cam_z + 16 * ISOMETRIC_WIDTH and -32 * ISOMETRIC_HEIGHT1 <= ((chunk.x + chunk.y) * ISOMETRIC_HEIGHT1 - y) <= size.height() * self.cam_z)
def drawDefault(self, size: QSize) -> QPixmap: blocks = self.blocks[self.default_variant] pix = QPixmap((4 + len(blocks) + len(blocks[0])) * ISOMETRIC_WIDTH, (len(blocks) + len(blocks[0]) + 3) * ISOMETRIC_HEIGHT1 + matrix3DHeight(blocks) * ISOMETRIC_HEIGHT2) pix.fill(Qt.transparent) painter = QPainter(pix) fx = pix.width() * (2 + len(blocks[0])) / (4 + len(blocks) + len(blocks[0])) fy = matrix3DHeight(blocks) * ISOMETRIC_HEIGHT2 + ISOMETRIC_HEIGHT1 for block_x in range(-1, len(blocks) + 1): for block_y in range(-1, len(blocks[0]) + 1): Grounds.grass.draw( (block_x - block_y) * ISOMETRIC_WIDTH + fx, (block_x + block_y) * ISOMETRIC_HEIGHT1 + fy, painter) if 0 <= block_x < len(blocks) and 0 <= block_y < len( blocks[0]): for z in range(len(blocks[block_x][block_y])): if blocks[block_x][block_y][z] is not None: blocks[block_x][block_y][z].draw( (block_x - block_y) * ISOMETRIC_WIDTH + fx, (block_x + block_y) * ISOMETRIC_HEIGHT1 - z * ISOMETRIC_HEIGHT2 + fy, 0, painter, self.default_blocks[block_x][block_y][z]) painter.end() some_size = size * max(.1 + pix.height() / size.height(), pix.width() / size.width()) pixmap = QPixmap(some_size) pixmap.fill(Qt.transparent) painter = QPainter(pixmap) painter.drawPixmap((some_size.width() - pix.width()) / 2, (some_size.height() - pix.height()) / 2, pix) painter.end() return pixmap
class CoverView(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.current_pixmap_size = QSize(0, 0) self.pixmap = QPixmap() self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) def set_pixmap(self, data): self.pixmap.loadFromData(data) self.current_pixmap_size = self.pixmap.size() self.update() def paintEvent(self, event): if self.pixmap.isNull(): return canvas_size = self.rect() width = self.current_pixmap_size.width() extrax = canvas_size.width() - width if extrax < 0: extrax = 0 x = int(extrax / 2.0) height = self.current_pixmap_size.height() extray = canvas_size.height() - height if extray < 0: extray = 0 y = int(extray / 2.0) target = QRect(x, y, min(canvas_size.width(), width), min(canvas_size.height(), height)) p = QPainter(self) p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform) p.drawPixmap(target, self.pixmap.scaled(target.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) p.end() def sizeHint(self): return QSize(300, 400)
def tabDropAction(cls, pos, tabRect, allowSelect): if not tabRect.contains(pos): return cls._NoAction # QPoint c = tabRect.center() # QSize csize = QSize(tabRect.width() * 0.7, tabRect.height() * 0.7) center = QRect(c.x() - csize.width() // 2, c.y() - csize.height() // 2, csize.width(), csize.height()) if allowSelect and center.contains(pos): return cls._SelectTab elif pos.x() < c.x(): return cls._PrependTab else: return cls._AppendTab
def update_tooltip(self, current_path): try: sz = self.pixmap.size() except: sz = QSize(0, 0) self.setToolTip('<p>' + _('Double-click to open Book Details window') + '<br><br>' + _('Path') + ': ' + current_path + '<br><br>' + _('Cover size: %(width)d x %(height)d') % dict(width=sz.width(), height=sz.height()))
def drawDefault(self, size: QSize) -> QPixmap: pix = QPixmap(size) pix.fill(Qt.transparent) painter = QPainter(pix) painter.drawImage(size.width() / 2 - ISOMETRIC_WIDTH / 2, size.height() / 2 - ISOMETRIC_HEIGHT1 / 2, self.textures['center']) painter.end() return pix
def update_tooltip(self, current_path): try: sz = self.pixmap.size() except: sz = QSize(0, 0) self.setToolTip( '<p>'+_('Double click to open the Book details window') + '<br><br>' + _('Path') + ': ' + current_path + '<br><br>' + _('Cover size: %(width)d x %(height)d pixels')%dict( width=sz.width(), height=sz.height()) )
def update_tooltip(self, current_path): try: sz = self.pixmap.size() except: sz = QSize(0, 0) self.setToolTip( "<p>" + _("Double-click to open Book Details window") + "<br><br>" + _("Path") + ": " + current_path + "<br><br>" + _("Cover size: %(width)d x %(height)d") % dict(width=sz.width(), height=sz.height()) )
class ThrobbingButton(QToolButton): def __init__(self, *args): QToolButton.__init__(self, *args) self.animation = QPropertyAnimation(self, 'iconSize', self) self.animation.setDuration(60/72.*1000) self.animation.setLoopCount(4) self.normal_icon_size = QSize(64, 64) self.animation.valueChanged.connect(self.value_changed) self.setCursor(Qt.PointingHandCursor) self.animation.finished.connect(self.animation_finished) def set_normal_icon_size(self, w, h): self.normal_icon_size = QSize(w, h) self.setIconSize(self.normal_icon_size) try: self.setMinimumSize(self.sizeHint()) except: self.setMinimumSize(QSize(w+5, h+5)) def animation_finished(self): self.setIconSize(self.normal_icon_size) def enterEvent(self, ev): self.start_animation() def leaveEvent(self, ev): self.stop_animation() def value_changed(self, val): self.update() def start_animation(self): if config['disable_animations']: return if self.animation.state() != self.animation.Stopped or not self.isVisible(): return size = self.normal_icon_size.width() smaller = int(0.7 * size) self.animation.setStartValue(QSize(smaller, smaller)) self.animation.setEndValue(self.normal_icon_size) QMetaObject.invokeMethod(self.animation, 'start', Qt.QueuedConnection) def stop_animation(self): self.animation.stop() self.animation_finished()
def draw(self, painter: QPainter, size: QSize, projecting_opacity: float, builded_opacity: float = 1) -> None: """Draw town on screen with changed size.""" if not (0 <= projecting_opacity <= 1): raise AttributeError(f"Opacity must be between 0 and 1, not {projecting_opacity}.") x = int(self.cam_x - (self.cam_z * size.width()) / 2) y = int(self.cam_y - (self.cam_z * size.height()) / 2) painter.save() painter.scale(self.scale, self.scale) for chunks in self.chunks: for chunk in chunks: if self._isChunkVisible(chunk, size): chunk.draw(painter, x, y, projecting_opacity, builded_opacity) painter.restore()
class ThrobbingButton(QToolButton): def __init__(self, *args): QToolButton.__init__(self, *args) self.animation = QPropertyAnimation(self, 'iconSize', self) self.animation.setDuration(60 / 72. * 1000) self.animation.setLoopCount(4) self.normal_icon_size = QSize(64, 64) self.animation.valueChanged.connect(self.value_changed) self.setCursor(Qt.PointingHandCursor) self.animation.finished.connect(self.animation_finished) def set_normal_icon_size(self, w, h): self.normal_icon_size = QSize(w, h) self.setIconSize(self.normal_icon_size) try: self.setMinimumSize(self.sizeHint()) except: self.setMinimumSize(QSize(w + 5, h + 5)) def animation_finished(self): self.setIconSize(self.normal_icon_size) def enterEvent(self, ev): self.start_animation() def leaveEvent(self, ev): self.stop_animation() def value_changed(self, val): self.update() def start_animation(self): if config['disable_animations']: return if self.animation.state( ) != self.animation.Stopped or not self.isVisible(): return size = self.normal_icon_size.width() smaller = int(0.7 * size) self.animation.setStartValue(QSize(smaller, smaller)) self.animation.setEndValue(self.normal_icon_size) QMetaObject.invokeMethod(self.animation, 'start', Qt.QueuedConnection) def stop_animation(self): self.animation.stop() self.animation_finished()
class CoverView(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.current_pixmap_size = QSize(0, 0) self.pixmap = QPixmap() self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding) def set_pixmap(self, data): self.pixmap.loadFromData(data) self.current_pixmap_size = self.pixmap.size() self.update() def paintEvent(self, event): if self.pixmap.isNull(): return canvas_size = self.rect() width = self.current_pixmap_size.width() extrax = canvas_size.width() - width if extrax < 0: extrax = 0 x = int(extrax / 2.) height = self.current_pixmap_size.height() extray = canvas_size.height() - height if extray < 0: extray = 0 y = int(extray / 2.) target = QRect(x, y, min(canvas_size.width(), width), min(canvas_size.height(), height)) p = QPainter(self) p.setRenderHints(QPainter.RenderHint.Antialiasing | QPainter.RenderHint.SmoothPixmapTransform) p.drawPixmap( target, self.pixmap.scaled(target.size(), Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation)) p.end() def sizeHint(self): return QSize(300, 400)
class CoverView(QWidget): # {{{ cover_changed = pyqtSignal(object, object) cover_removed = pyqtSignal(object) open_cover_with = pyqtSignal(object, object) search_internet = pyqtSignal(object) def __init__(self, vertical, parent=None): QWidget.__init__(self, parent) self._current_pixmap_size = QSize(120, 120) self.vertical = vertical self.animation = QPropertyAnimation(self, b'current_pixmap_size', self) self.animation.setEasingCurve(QEasingCurve(QEasingCurve.OutExpo)) self.animation.setDuration(1000) self.animation.setStartValue(QSize(0, 0)) self.animation.valueChanged.connect(self.value_changed) self.setSizePolicy( QSizePolicy.Expanding if vertical else QSizePolicy.Minimum, QSizePolicy.Expanding) self.default_pixmap = QPixmap(I('default_cover.png')) self.pixmap = self.default_pixmap self.pwidth = self.pheight = None self.data = {} self.do_layout() def value_changed(self, val): self.update() def setCurrentPixmapSize(self, val): self._current_pixmap_size = val def do_layout(self): if self.rect().width() == 0 or self.rect().height() == 0: return pixmap = self.pixmap pwidth, pheight = pixmap.width(), pixmap.height() try: self.pwidth, self.pheight = fit_image(pwidth, pheight, self.rect().width(), self.rect().height())[1:] except: self.pwidth, self.pheight = self.rect().width()-1, \ self.rect().height()-1 self.current_pixmap_size = QSize(self.pwidth, self.pheight) self.animation.setEndValue(self.current_pixmap_size) def show_data(self, data): self.animation.stop() same_item = getattr(data, 'id', True) == self.data.get('id', False) self.data = {'id':data.get('id', None)} if data.cover_data[1]: self.pixmap = QPixmap.fromImage(data.cover_data[1]) if self.pixmap.isNull() or self.pixmap.width() < 5 or \ self.pixmap.height() < 5: self.pixmap = self.default_pixmap else: self.pixmap = self.default_pixmap self.do_layout() self.update() if (not same_item and not config['disable_animations'] and self.isVisible()): self.animation.start() def paintEvent(self, event): canvas_size = self.rect() width = self.current_pixmap_size.width() extrax = canvas_size.width() - width if extrax < 0: extrax = 0 x = int(extrax/2.) height = self.current_pixmap_size.height() extray = canvas_size.height() - height if extray < 0: extray = 0 y = int(extray/2.) target = QRect(x, y, width, height) p = QPainter(self) p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform) try: dpr = self.devicePixelRatioF() except AttributeError: dpr = self.devicePixelRatio() spmap = self.pixmap.scaled(target.size() * dpr, Qt.KeepAspectRatio, Qt.SmoothTransformation) spmap.setDevicePixelRatio(dpr) p.drawPixmap(target, spmap) if gprefs['bd_overlay_cover_size']: sztgt = target.adjusted(0, 0, 0, -4) f = p.font() f.setBold(True) p.setFont(f) sz = u'\u00a0%d x %d\u00a0'%(self.pixmap.width(), self.pixmap.height()) flags = Qt.AlignBottom|Qt.AlignRight|Qt.TextSingleLine szrect = p.boundingRect(sztgt, flags, sz) p.fillRect(szrect.adjusted(0, 0, 0, 4), QColor(0, 0, 0, 200)) p.setPen(QPen(QColor(255,255,255))) p.drawText(sztgt, flags, sz) p.end() current_pixmap_size = pyqtProperty('QSize', fget=lambda self: self._current_pixmap_size, fset=setCurrentPixmapSize ) def contextMenuEvent(self, ev): from calibre.gui2.open_with import populate_menu, edit_programs cm = QMenu(self) paste = cm.addAction(_('Paste cover')) copy = cm.addAction(_('Copy cover')) remove = cm.addAction(_('Remove cover')) gc = cm.addAction(_('Generate cover from metadata')) cm.addSeparator() if not QApplication.instance().clipboard().mimeData().hasImage(): paste.setEnabled(False) copy.triggered.connect(self.copy_to_clipboard) paste.triggered.connect(self.paste_from_clipboard) remove.triggered.connect(self.remove_cover) gc.triggered.connect(self.generate_cover) m = QMenu(_('Open cover with...')) populate_menu(m, self.open_with, 'cover_image') if len(m.actions()) == 0: cm.addAction(_('Open cover with...'), self.choose_open_with) else: m.addSeparator() m.addAction(_('Add another application to open cover...'), self.choose_open_with) m.addAction(_('Edit Open with applications...'), partial(edit_programs, 'cover_image', self)) cm.ocw = m cm.addMenu(m) cm.si = m = create_search_internet_menu(self.search_internet.emit) cm.addMenu(m) cm.exec_(ev.globalPos()) def open_with(self, entry): id_ = self.data.get('id', None) if id_ is not None: self.open_cover_with.emit(id_, entry) def choose_open_with(self): from calibre.gui2.open_with import choose_program entry = choose_program('cover_image', self) if entry is not None: self.open_with(entry) def copy_to_clipboard(self): QApplication.instance().clipboard().setPixmap(self.pixmap) def paste_from_clipboard(self, pmap=None): if not isinstance(pmap, QPixmap): cb = QApplication.instance().clipboard() pmap = cb.pixmap() if pmap.isNull() and cb.supportsSelection(): pmap = cb.pixmap(cb.Selection) if not pmap.isNull(): self.update_cover(pmap) def update_cover(self, pmap=None, cdata=None): if pmap is None: pmap = QPixmap() pmap.loadFromData(cdata) if pmap.isNull(): return if pmap.hasAlphaChannel(): pmap = QPixmap.fromImage(blend_image(image_from_x(pmap))) self.pixmap = pmap self.do_layout() self.update() self.update_tooltip(getattr(self.parent(), 'current_path', '')) if not config['disable_animations']: self.animation.start() id_ = self.data.get('id', None) if id_ is not None: self.cover_changed.emit(id_, cdata or pixmap_to_data(pmap)) def generate_cover(self, *args): book_id = self.data.get('id') if book_id is not None: from calibre.ebooks.covers import generate_cover from calibre.gui2.ui import get_gui mi = get_gui().current_db.new_api.get_metadata(book_id) cdata = generate_cover(mi) self.update_cover(cdata=cdata) def remove_cover(self): id_ = self.data.get('id', None) self.pixmap = self.default_pixmap self.do_layout() self.update() if id_ is not None: self.cover_removed.emit(id_) def update_tooltip(self, current_path): try: sz = self.pixmap.size() except: sz = QSize(0, 0) self.setToolTip( '<p>'+_('Double click to open the Book details window') + '<br><br>' + _('Path') + ': ' + current_path + '<br><br>' + _('Cover size: %(width)d x %(height)d pixels')%dict( width=sz.width(), height=sz.height()) )
class ImageDelegate(QStyledItemDelegate): MARGIN = 4 def __init__(self, parent): super(ImageDelegate, self).__init__(parent) self.set_dimensions() self.cover_cache = {} def set_dimensions(self): width, height = 120, 160 self.cover_size = QSize(width, height) f = self.parent().font() sz = f.pixelSize() if sz < 5: sz = f.pointSize() * self.parent().logicalDpiY() / 72.0 self.title_height = max(25, sz + 10) self.item_size = self.cover_size + QSize(2 * self.MARGIN, (2 * self.MARGIN) + self.title_height) self.calculate_spacing() def calculate_spacing(self): self.spacing = max(10, min(50, int(0.1 * self.item_size.width()))) def sizeHint(self, option, index): return self.item_size def paint(self, painter, option, index): QStyledItemDelegate.paint(self, painter, option, QModelIndex()) # draw the hover and selection highlights name = unicode(index.data(Qt.DisplayRole) or '') cover = self.cover_cache.get(name, None) if cover is None: cover = self.cover_cache[name] = QPixmap() try: raw = current_container().raw_data(name, decode=False) except: pass else: cover.loadFromData(raw) if not cover.isNull(): scaled, width, height = fit_image(cover.width(), cover.height(), self.cover_size.width(), self.cover_size.height()) if scaled: cover = self.cover_cache[name] = cover.scaled(width, height, transformMode=Qt.SmoothTransformation) painter.save() try: rect = option.rect rect.adjust(self.MARGIN, self.MARGIN, -self.MARGIN, -self.MARGIN) trect = QRect(rect) rect.setBottom(rect.bottom() - self.title_height) if not cover.isNull(): dx = max(0, int((rect.width() - cover.width())/2.0)) dy = max(0, rect.height() - cover.height()) rect.adjust(dx, dy, -dx, 0) painter.drawPixmap(rect, cover) rect = trect rect.setTop(rect.bottom() - self.title_height + 5) painter.setRenderHint(QPainter.TextAntialiasing, True) metrics = painter.fontMetrics() painter.drawText(rect, Qt.AlignCenter|Qt.TextSingleLine, metrics.elidedText(name, Qt.ElideLeft, rect.width())) finally: painter.restore()
class PieChart (QGraphicsView): def __init__(self,parent,total_value): super(PieChart,self).__init__(parent) self.my_scene = QGraphicsScene() #self.my_scene.setSceneRect(self.sceneRect()) self.setScene(self.my_scene) #self.setBackgroundBrush(QBrush(QtCore.Qt.black, QtCore.Qt.SolidPattern)); self.total_value = total_value self.initialize = False self.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff) self.margin = {'top':10,'bottom':10,'left':10,'right':10} self.space = 30 self.pie_items = [] def setTotal (self, total): self.total_value = total # def setData (self,list_item): # # rect = QGraphicsRectItem(self.sceneRect()) # rect.setBrush(QColor("red")) # self.scene().addItem(rect) def setData (self,list_items): size = min(self.frameSize().width()/2.0,self.frameSize().height()) self.size_pie = QSize(size,size) #print ('size pie ',self.size_pie) if self.initialize == False: self.c_box = QComboBox() self.c_box.addItem("all") self.c_box.addItem("alive") self.c_box.addItem("dead") self.c_box.currentIndexChanged.connect(self.update) proxy = self.my_scene.addWidget(self.c_box) x = self.size_pie.width()+ self.space proxy.setPos(QPointF(x,self.margin['top'])) self.initialize = True self.data = list_items self.update() def update(self): restant = 360 i = 0 #self.my_scene.clear() for item in self.pie_items : self.my_scene.removeItem(item) self.pie_items = [] self.scene().setSceneRect(QRectF(0,0,self.frameSize().width(),self.frameSize().height())) #print ('size',self.scene().sceneRect()) #proxy = QGraphicsProxyWidget () for item in self.data : if (i==len(self.data)-1 ): angle = restant else: try : angle = int(360*item[self.c_box.currentText()]/self.total_value[self.c_box.currentText()]) except ZeroDivisionError: angle = 0 ellipse = Section(0,0,self.size_pie.width(),self.size_pie.height()) y = (self.parent().size().height()-self.size_pie.height())/2.0 x_pie = ((self.parent().size().width()/2.0)-self.size_pie.height())/2.0 ellipse.setPos(x_pie,y) ellipse.setStartAngle(16*(360-restant)) ellipse.setSpanAngle(angle*16) ellipse.setBrush(item['color']) self.my_scene.addItem(ellipse) self.pie_items.append(ellipse) # text pourcentage a afficher dans les portions de disque try : v = (item[self.c_box.currentText()]/self.total_value[self.c_box.currentText()])*100 except ZeroDivisionError : v = 0 text = QGraphicsSimpleTextItem("{0:5.2f}".format(v)+"%") trans = QTransform().translate(x_pie+self.size_pie.width()/2.0,y+self.size_pie.height()/2.0).rotate(((360-restant)+angle/2.0)*-1) pts = trans.map(QPointF(self.size_pie.width()/3.0,0)) text.setPos(pts.x(),pts.y()) self.my_scene.addItem(text) self.pie_items.append(text) #libelle rect = QGraphicsRectItem(0,0,10,10) x = x_pie + self.size_pie.width()+ self.space interval_height = (self.parent().size().height()-self.margin['top']-self.margin['bottom'])/(len(self.data)+1) rect.setPos(QPointF(x,self.margin['top']+((i+1)*interval_height))) rect.setBrush(item['color']) self.my_scene.addItem(rect) self.pie_items.append(rect) text = QGraphicsSimpleTextItem(item['label']+ " ("+str(int(item[self.c_box.currentText()]))+")") pts = rect.pos() transform = QTransform().translate(30, 0) pts = transform.map(pts) text.setPos(pts) self.my_scene.addItem(text) self.pie_items.append(text) restant = restant - angle i +=1 # self.fitInView(self.scene.sceneRect())
class CoverView(QWidget): # {{{ cover_changed = pyqtSignal(object, object) cover_removed = pyqtSignal(object) def __init__(self, vertical, parent=None): QWidget.__init__(self, parent) self._current_pixmap_size = QSize(120, 120) self.vertical = vertical self.animation = QPropertyAnimation(self, 'current_pixmap_size', self) self.animation.setEasingCurve(QEasingCurve(QEasingCurve.OutExpo)) self.animation.setDuration(1000) self.animation.setStartValue(QSize(0, 0)) self.animation.valueChanged.connect(self.value_changed) self.setSizePolicy( QSizePolicy.Expanding if vertical else QSizePolicy.Minimum, QSizePolicy.Expanding) self.default_pixmap = QPixmap(I('book.png')) self.pixmap = self.default_pixmap self.pwidth = self.pheight = None self.data = {} self.do_layout() def value_changed(self, val): self.update() def setCurrentPixmapSize(self, val): self._current_pixmap_size = val def do_layout(self): if self.rect().width() == 0 or self.rect().height() == 0: return pixmap = self.pixmap pwidth, pheight = pixmap.width(), pixmap.height() try: self.pwidth, self.pheight = fit_image(pwidth, pheight, self.rect().width(), self.rect().height())[1:] except: self.pwidth, self.pheight = self.rect().width()-1, \ self.rect().height()-1 self.current_pixmap_size = QSize(self.pwidth, self.pheight) self.animation.setEndValue(self.current_pixmap_size) def show_data(self, data): self.animation.stop() same_item = getattr(data, 'id', True) == self.data.get('id', False) self.data = {'id':data.get('id', None)} if data.cover_data[1]: self.pixmap = QPixmap.fromImage(data.cover_data[1]) if self.pixmap.isNull() or self.pixmap.width() < 5 or \ self.pixmap.height() < 5: self.pixmap = self.default_pixmap else: self.pixmap = self.default_pixmap self.do_layout() self.update() if (not same_item and not config['disable_animations'] and self.isVisible()): self.animation.start() def paintEvent(self, event): canvas_size = self.rect() width = self.current_pixmap_size.width() extrax = canvas_size.width() - width if extrax < 0: extrax = 0 x = int(extrax/2.) height = self.current_pixmap_size.height() extray = canvas_size.height() - height if extray < 0: extray = 0 y = int(extray/2.) target = QRect(x, y, width, height) p = QPainter(self) p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform) p.drawPixmap(target, self.pixmap.scaled(target.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) if gprefs['bd_overlay_cover_size']: sztgt = target.adjusted(0, 0, 0, -4) f = p.font() f.setBold(True) p.setFont(f) sz = u'\u00a0%d x %d\u00a0'%(self.pixmap.width(), self.pixmap.height()) flags = Qt.AlignBottom|Qt.AlignRight|Qt.TextSingleLine szrect = p.boundingRect(sztgt, flags, sz) p.fillRect(szrect.adjusted(0, 0, 0, 4), QColor(0, 0, 0, 200)) p.setPen(QPen(QColor(255,255,255))) p.drawText(sztgt, flags, sz) p.end() current_pixmap_size = pyqtProperty('QSize', fget=lambda self: self._current_pixmap_size, fset=setCurrentPixmapSize ) def contextMenuEvent(self, ev): cm = QMenu(self) paste = cm.addAction(_('Paste Cover')) copy = cm.addAction(_('Copy Cover')) remove = cm.addAction(_('Remove Cover')) if not QApplication.instance().clipboard().mimeData().hasImage(): paste.setEnabled(False) copy.triggered.connect(self.copy_to_clipboard) paste.triggered.connect(self.paste_from_clipboard) remove.triggered.connect(self.remove_cover) cm.exec_(ev.globalPos()) def copy_to_clipboard(self): QApplication.instance().clipboard().setPixmap(self.pixmap) def paste_from_clipboard(self, pmap=None): if not isinstance(pmap, QPixmap): cb = QApplication.instance().clipboard() pmap = cb.pixmap() if pmap.isNull() and cb.supportsSelection(): pmap = cb.pixmap(cb.Selection) if not pmap.isNull(): self.pixmap = pmap self.do_layout() self.update() self.update_tooltip(getattr(self.parent(), 'current_path', '')) if not config['disable_animations']: self.animation.start() id_ = self.data.get('id', None) if id_ is not None: self.cover_changed.emit(id_, pixmap_to_data(pmap)) def remove_cover(self): id_ = self.data.get('id', None) self.pixmap = self.default_pixmap self.do_layout() self.update() if id_ is not None: self.cover_removed.emit(id_) def update_tooltip(self, current_path): try: sz = self.pixmap.size() except: sz = QSize(0, 0) self.setToolTip( '<p>'+_('Double-click to open Book Details window') + '<br><br>' + _('Path') + ': ' + current_path + '<br><br>' + _('Cover size: %(width)d x %(height)d')%dict( width=sz.width(), height=sz.height()) )
class TempleItem (QtWidgets.QGraphicsItem): SIZE_MULTIPLICATOR = 2 def __init__(self,view, scene_coord,temple,size,parent=None): super (TempleItem,self).__init__(parent) #self.polygon = self.getTriangle (size) self.rotation = 0.0 self.color = QColor(0,0,125) self.name_visible = True self.name = temple.name self.model = temple self.view = view self.size = QSize(32,32) self.scene_coord = scene_coord #set flags self.setFlag(QGraphicsItem.ItemIgnoresTransformations) self.setFlag(QGraphicsItem.ItemSendsGeometryChanges) self.setFlag(QGraphicsItem.ItemIsSelectable) self.setFlag(QGraphicsItem.ItemIsMovable) # self.graphics_effect = QGraphicsColorizeEffect() # color = self.model.kingdom().color # self.graphics_effect.setColor(QColor(color.red(),color.green(),color.blue(),125)) # self.setGraphicsEffect(self.graphics_effect ) # self.graphics_effect.setEnabled(True) def boundingRect(self): return QtCore.QRectF(0,0,self.size.width(),self.size.height()) def itemChange(self, change, value): if change == QGraphicsItem.ItemPositionHasChanged : self.model.position = value #pos = self.view.mapToScene(value.x(),value.y()) lat,lon = self.scene_coord.SceneToLatLon(value.x(),value.y()) self.model.changePosition (lat,lon) print ('new position ',self.model.position) else: return QGraphicsItem.itemChange(self,change,value) def paint (self,painter,option, widget): painter.setRenderHints(QtGui.QPainter.Antialiasing) painter.rotate(self.rotation) painter.translate(-16,-16) # taille fixe correspondant a la pixmap utilisee pour generer la geometry painter.scale(1.5,1.5) if self.isSelected() == True : pen = QPen(QtCore.Qt.red) pen.setWidth(1) else: pen = QPen(QtCore.Qt.black) pen.setWidth(1) painter.setPen(pen) radialGradient = QRadialGradient(self.size.width()/2, self.size.height()/2,self.size.width()*0.8, self.size.width(), self.size.height()) radialGradient.setColorAt(0.0, QtCore.Qt.white) #radialGradient.setColorAt(0.2, self.heros.kingdom().color) if self.view.color_mode == ColorMode.Empire : color = self.model.empire().color else : color = self.model.kingdom().color radialGradient.setColorAt(0.2, color) radialGradient.setColorAt(1.0, QtCore.Qt.black) painter.setBrush(QBrush(radialGradient)) #brush = QBrush(self.color) #painter.setBrush(brush) geometry = self.model.empire().geometry #qDebug("info : map_item Temple : nombre de polygones %d"%len(geometry['polygon'])) for p in geometry['polygon']: painter.drawPolygon(QPolygon(p)) # # painter.drawPolygon(self.polygon) # path = os.path.join(Config().instance.path_to_icons(),'kingdom','32x32') # path+="/temple_artemis.png" # print ('path icon',path) # pix = QPixmap(path) # # painter.drawPixmap(-pix.width()/2.0,-pix.height()/2.0,pix) if self.name_visible == True : painter.setPen(QPen(QColor('black'))) painter.translate(0,10) painter.drawText (self.boundingRect(),QtCore.Qt.AlignHCenter|QtCore.Qt.AlignBottom, self.name) def contextMenuEvent(self, event): menu = QMenu() testAction = QAction('Go Inside', None) testAction.triggered.connect(self.showTempleView) menu.addAction(testAction) menu.exec_(event.screenPos()) event.accept() def showTempleView (self): self.frame = QFrame() self.frame.setWindowTitle(self.kingdom.name) self.frame.setObjectName("Frame") self.frame.resize(400, 300) self.frame.setFrameShape(QFrame.StyledPanel) self.frame.setFrameShadow(QFrame.Raised) self.verticalLayout = QVBoxLayout(self.frame) self.verticalLayout.setObjectName("verticalLayout") self.view = TempleView(self.frame) self.view.setTemple(self.kingdom) self.verticalLayout.addWidget(self.view) self.frame.show()
class ImageDelegate(QStyledItemDelegate): MARGIN = 4 def __init__(self, parent): super(ImageDelegate, self).__init__(parent) self.current_basic_size = tprefs.get('image-thumbnail-preview-size', [120, 160]) self.set_dimensions() def change_size(self, increase=True): percent = 10 if increase else -10 frac = (100 + percent) / 100. self.current_basic_size[0] = min(1200, max(40, int(frac * self.current_basic_size[0]))) self.current_basic_size[1] = min(1600, max(60, int(frac * self.current_basic_size[1]))) tprefs.set('image-thumbnail-preview-size', self.current_basic_size) self.set_dimensions() def set_dimensions(self): width, height = self.current_basic_size self.cover_size = QSize(width, height) f = self.parent().font() sz = f.pixelSize() if sz < 5: sz = f.pointSize() * self.parent().logicalDpiY() / 72.0 self.title_height = max(25, sz + 10) self.item_size = self.cover_size + QSize(2 * self.MARGIN, (2 * self.MARGIN) + self.title_height) self.calculate_spacing() self.cover_cache = {} def calculate_spacing(self): self.spacing = max(10, min(50, int(0.1 * self.item_size.width()))) def sizeHint(self, option, index): return self.item_size def paint(self, painter, option, index): QStyledItemDelegate.paint(self, painter, option, empty_index) # draw the hover and selection highlights name = unicode_type(index.data(Qt.DisplayRole) or '') cover = self.cover_cache.get(name, None) if cover is None: cover = self.cover_cache[name] = QPixmap() try: raw = current_container().raw_data(name, decode=False) except: pass else: try: dpr = painter.device().devicePixelRatioF() except AttributeError: dpr = painter.device().devicePixelRatio() cover.loadFromData(raw) cover.setDevicePixelRatio(dpr) if not cover.isNull(): scaled, width, height = fit_image(cover.width(), cover.height(), self.cover_size.width(), self.cover_size.height()) if scaled: cover = self.cover_cache[name] = cover.scaled(int(dpr*width), int(dpr*height), transformMode=Qt.SmoothTransformation) painter.save() try: rect = option.rect rect.adjust(self.MARGIN, self.MARGIN, -self.MARGIN, -self.MARGIN) trect = QRect(rect) rect.setBottom(rect.bottom() - self.title_height) if not cover.isNull(): dx = max(0, int((rect.width() - int(cover.width()/cover.devicePixelRatio()))/2.0)) dy = max(0, rect.height() - int(cover.height()/cover.devicePixelRatio())) rect.adjust(dx, dy, -dx, 0) painter.drawPixmap(rect, cover) rect = trect rect.setTop(rect.bottom() - self.title_height + 5) painter.setRenderHint(QPainter.TextAntialiasing, True) metrics = painter.fontMetrics() painter.drawText(rect, Qt.AlignCenter|Qt.TextSingleLine, metrics.elidedText(name, Qt.ElideLeft, rect.width())) finally: painter.restore()
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)
class CoverView(QWidget): # {{{ cover_changed = pyqtSignal(object, object) cover_removed = pyqtSignal(object) def __init__(self, vertical, parent=None): QWidget.__init__(self, parent) self._current_pixmap_size = QSize(120, 120) self.vertical = vertical self.animation = QPropertyAnimation(self, "current_pixmap_size", self) self.animation.setEasingCurve(QEasingCurve(QEasingCurve.OutExpo)) self.animation.setDuration(1000) self.animation.setStartValue(QSize(0, 0)) self.animation.valueChanged.connect(self.value_changed) self.setSizePolicy(QSizePolicy.Expanding if vertical else QSizePolicy.Minimum, QSizePolicy.Expanding) self.default_pixmap = QPixmap(I("book.png")) self.pixmap = self.default_pixmap self.pwidth = self.pheight = None self.data = {} self.do_layout() def value_changed(self, val): self.update() def setCurrentPixmapSize(self, val): self._current_pixmap_size = val def do_layout(self): if self.rect().width() == 0 or self.rect().height() == 0: return pixmap = self.pixmap pwidth, pheight = pixmap.width(), pixmap.height() try: self.pwidth, self.pheight = fit_image(pwidth, pheight, self.rect().width(), self.rect().height())[1:] except: self.pwidth, self.pheight = self.rect().width() - 1, self.rect().height() - 1 self.current_pixmap_size = QSize(self.pwidth, self.pheight) self.animation.setEndValue(self.current_pixmap_size) def show_data(self, data): self.animation.stop() same_item = getattr(data, "id", True) == self.data.get("id", False) self.data = {"id": data.get("id", None)} if data.cover_data[1]: self.pixmap = QPixmap.fromImage(data.cover_data[1]) if self.pixmap.isNull() or self.pixmap.width() < 5 or self.pixmap.height() < 5: self.pixmap = self.default_pixmap else: self.pixmap = self.default_pixmap self.do_layout() self.update() if not same_item and not config["disable_animations"] and self.isVisible(): self.animation.start() def paintEvent(self, event): canvas_size = self.rect() width = self.current_pixmap_size.width() extrax = canvas_size.width() - width if extrax < 0: extrax = 0 x = int(extrax / 2.0) height = self.current_pixmap_size.height() extray = canvas_size.height() - height if extray < 0: extray = 0 y = int(extray / 2.0) target = QRect(x, y, width, height) p = QPainter(self) p.setRenderHints(QPainter.Antialiasing | QPainter.SmoothPixmapTransform) p.drawPixmap(target, self.pixmap.scaled(target.size(), Qt.KeepAspectRatio, Qt.SmoothTransformation)) if gprefs["bd_overlay_cover_size"]: sztgt = target.adjusted(0, 0, 0, -4) f = p.font() f.setBold(True) p.setFont(f) sz = u"\u00a0%d x %d\u00a0" % (self.pixmap.width(), self.pixmap.height()) flags = Qt.AlignBottom | Qt.AlignRight | Qt.TextSingleLine szrect = p.boundingRect(sztgt, flags, sz) p.fillRect(szrect.adjusted(0, 0, 0, 4), QColor(0, 0, 0, 200)) p.setPen(QPen(QColor(255, 255, 255))) p.drawText(sztgt, flags, sz) p.end() current_pixmap_size = pyqtProperty("QSize", fget=lambda self: self._current_pixmap_size, fset=setCurrentPixmapSize) def contextMenuEvent(self, ev): cm = QMenu(self) paste = cm.addAction(_("Paste Cover")) copy = cm.addAction(_("Copy Cover")) remove = cm.addAction(_("Remove Cover")) if not QApplication.instance().clipboard().mimeData().hasImage(): paste.setEnabled(False) copy.triggered.connect(self.copy_to_clipboard) paste.triggered.connect(self.paste_from_clipboard) remove.triggered.connect(self.remove_cover) cm.exec_(ev.globalPos()) def copy_to_clipboard(self): QApplication.instance().clipboard().setPixmap(self.pixmap) def paste_from_clipboard(self, pmap=None): if not isinstance(pmap, QPixmap): cb = QApplication.instance().clipboard() pmap = cb.pixmap() if pmap.isNull() and cb.supportsSelection(): pmap = cb.pixmap(cb.Selection) if not pmap.isNull(): self.pixmap = pmap self.do_layout() self.update() self.update_tooltip(getattr(self.parent(), "current_path", "")) if not config["disable_animations"]: self.animation.start() id_ = self.data.get("id", None) if id_ is not None: self.cover_changed.emit(id_, pixmap_to_data(pmap)) def remove_cover(self): id_ = self.data.get("id", None) self.pixmap = self.default_pixmap self.do_layout() self.update() if id_ is not None: self.cover_removed.emit(id_) def update_tooltip(self, current_path): try: sz = self.pixmap.size() except: sz = QSize(0, 0) self.setToolTip( "<p>" + _("Double-click to open Book Details window") + "<br><br>" + _("Path") + ": " + current_path + "<br><br>" + _("Cover size: %(width)d x %(height)d") % dict(width=sz.width(), height=sz.height()) )