Files
xml-editor/app/view/gallery_interface.py

217 lines
7.9 KiB
Python

# coding:utf-8
from PyQt6.QtCore import Qt, pyqtSignal, QUrl, QEvent
from PyQt6.QtGui import QDesktopServices, QPainter, QPen, QColor
from PyQt6.QtWidgets import QWidget, QLabel, QVBoxLayout, QHBoxLayout, QFrame
from qfluentwidgets import (ScrollArea, PushButton, ToolButton, FluentIcon,
isDarkTheme, IconWidget, Theme, ToolTipFilter, TitleLabel, CaptionLabel,
StrongBodyLabel, BodyLabel, toggleTheme)
from ..common.config import cfg, HELP_URL
from ..common.icon import Icon
from ..common.style_sheet import StyleSheet
from ..common.signal_bus import signalBus
class SeparatorWidget(QWidget):
""" Seperator widget """
def __init__(self, parent=None):
super().__init__(parent=parent)
self.setFixedSize(6, 16)
def paintEvent(self, e):
painter = QPainter(self)
pen = QPen(1)
pen.setCosmetic(True)
c = QColor(255, 255, 255, 21) if isDarkTheme() else QColor(0, 0, 0, 15)
pen.setColor(c)
painter.setPen(pen)
x = self.width() // 2
painter.drawLine(x, 0, x, self.height())
class ToolBar(QWidget):
""" Tool bar """
def __init__(self, title, subtitle, parent=None):
super().__init__(parent=parent)
self.titleLabel = TitleLabel(title, self)
self.subtitleLabel = CaptionLabel(subtitle, self)
self.documentButton = PushButton(
self.tr('Documentation'), self, FluentIcon.DOCUMENT)
self.sourceButton = PushButton(self.tr('Source'), self, FluentIcon.GITHUB)
self.themeButton = ToolButton(FluentIcon.CONSTRACT, self)
self.separator = SeparatorWidget(self)
self.supportButton = ToolButton(FluentIcon.HEART, self)
self.feedbackButton = ToolButton(FluentIcon.FEEDBACK, self)
self.vBoxLayout = QVBoxLayout(self)
self.buttonLayout = QHBoxLayout()
self.__initWidget()
def __initWidget(self):
self.setFixedHeight(138)
self.vBoxLayout.setSpacing(0)
self.vBoxLayout.setContentsMargins(36, 22, 36, 12)
self.vBoxLayout.addWidget(self.titleLabel)
self.vBoxLayout.addSpacing(4)
self.vBoxLayout.addWidget(self.subtitleLabel)
self.vBoxLayout.addSpacing(4)
self.vBoxLayout.addLayout(self.buttonLayout, 1)
self.vBoxLayout.setAlignment(Qt.AlignTop)
self.buttonLayout.setSpacing(4)
self.buttonLayout.setContentsMargins(0, 0, 0, 0)
self.buttonLayout.addWidget(self.documentButton, 0, Qt.AlignLeft)
self.buttonLayout.addWidget(self.sourceButton, 0, Qt.AlignLeft)
self.buttonLayout.addStretch(1)
self.buttonLayout.addWidget(self.themeButton, 0, Qt.AlignRight)
self.buttonLayout.addWidget(self.separator, 0, Qt.AlignRight)
self.buttonLayout.addWidget(self.supportButton, 0, Qt.AlignRight)
self.buttonLayout.addWidget(self.feedbackButton, 0, Qt.AlignRight)
self.buttonLayout.setAlignment(Qt.AlignVCenter | Qt.AlignLeft)
self.themeButton.installEventFilter(ToolTipFilter(self.themeButton))
self.supportButton.installEventFilter(ToolTipFilter(self.supportButton))
self.feedbackButton.installEventFilter(
ToolTipFilter(self.feedbackButton))
self.themeButton.setToolTip(self.tr('Toggle theme'))
self.supportButton.setToolTip(self.tr('Support me'))
self.feedbackButton.setToolTip(self.tr('Send feedback'))
self.themeButton.clicked.connect(lambda: toggleTheme(True))
self.supportButton.clicked.connect(signalBus.supportSignal)
self.documentButton.clicked.connect(
lambda: QDesktopServices.openUrl(QUrl(HELP_URL)))
self.sourceButton.clicked.connect(
lambda: QDesktopServices.openUrl(QUrl(EXAMPLE_URL)))
self.feedbackButton.clicked.connect(
lambda: QDesktopServices.openUrl(QUrl(FEEDBACK_URL)))
class ExampleCard(QWidget):
""" Example card """
def __init__(self, title, widget: QWidget, sourcePath, stretch=0, parent=None):
super().__init__(parent=parent)
self.widget = widget
self.stretch = stretch
self.titleLabel = StrongBodyLabel(title, self)
self.card = QFrame(self)
self.sourceWidget = QFrame(self.card)
self.sourcePath = sourcePath
self.sourcePathLabel = BodyLabel(
self.tr('Source code'), self.sourceWidget)
self.linkIcon = IconWidget(FluentIcon.LINK, self.sourceWidget)
self.vBoxLayout = QVBoxLayout(self)
self.cardLayout = QVBoxLayout(self.card)
self.topLayout = QHBoxLayout()
self.bottomLayout = QHBoxLayout(self.sourceWidget)
self.__initWidget()
def __initWidget(self):
self.linkIcon.setFixedSize(16, 16)
self.__initLayout()
self.sourceWidget.setCursor(Qt.PointingHandCursor)
self.sourceWidget.installEventFilter(self)
self.card.setObjectName('card')
self.sourceWidget.setObjectName('sourceWidget')
def __initLayout(self):
self.vBoxLayout.setSizeConstraint(QVBoxLayout.SetMinimumSize)
self.cardLayout.setSizeConstraint(QVBoxLayout.SetMinimumSize)
self.topLayout.setSizeConstraint(QHBoxLayout.SetMinimumSize)
self.vBoxLayout.setSpacing(12)
self.vBoxLayout.setContentsMargins(0, 0, 0, 0)
self.topLayout.setContentsMargins(12, 12, 12, 12)
self.bottomLayout.setContentsMargins(18, 18, 18, 18)
self.cardLayout.setContentsMargins(0, 0, 0, 0)
self.vBoxLayout.addWidget(self.titleLabel, 0, Qt.AlignTop)
self.vBoxLayout.addWidget(self.card, 0, Qt.AlignTop)
self.vBoxLayout.setAlignment(Qt.AlignTop)
self.cardLayout.setSpacing(0)
self.cardLayout.setAlignment(Qt.AlignTop)
self.cardLayout.addLayout(self.topLayout, 0)
self.cardLayout.addWidget(self.sourceWidget, 0, Qt.AlignBottom)
self.widget.setParent(self.card)
self.topLayout.addWidget(self.widget)
if self.stretch == 0:
self.topLayout.addStretch(1)
self.widget.show()
self.bottomLayout.addWidget(self.sourcePathLabel, 0, Qt.AlignLeft)
self.bottomLayout.addStretch(1)
self.bottomLayout.addWidget(self.linkIcon, 0, Qt.AlignRight)
self.bottomLayout.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
def eventFilter(self, obj, e):
if obj is self.sourceWidget:
if e.type() == QEvent.MouseButtonRelease:
QDesktopServices.openUrl(QUrl(self.sourcePath))
return super().eventFilter(obj, e)
class GalleryInterface(ScrollArea):
""" Gallery interface """
def __init__(self, title: str, subtitle: str, parent=None):
"""
Parameters
----------
title: str
The title of gallery
subtitle: str
The subtitle of gallery
parent: QWidget
parent widget
"""
super().__init__(parent=parent)
self.view = QWidget(self)
self.toolBar = ToolBar(title, subtitle, self)
self.vBoxLayout = QVBoxLayout(self.view)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.setViewportMargins(0, self.toolBar.height(), 0, 0)
self.setWidget(self.view)
self.setWidgetResizable(True)
self.vBoxLayout.setSpacing(30)
self.vBoxLayout.setAlignment(Qt.AlignTop)
self.vBoxLayout.setContentsMargins(36, 20, 36, 36)
self.view.setObjectName('view')
StyleSheet.GALLERY_INTERFACE.apply(self)
def addExampleCard(self, title, widget, sourcePath: str, stretch=0):
card = ExampleCard(title, widget, sourcePath, stretch, self.view)
self.vBoxLayout.addWidget(card, 0, Qt.AlignTop)
return card
def scrollToCard(self, index: int):
""" scroll to example card """
w = self.vBoxLayout.itemAt(index).widget()
self.verticalScrollBar().setValue(w.y())
def resizeEvent(self, e):
super().resizeEvent(e)
self.toolBar.resize(self.width(), self.toolBar.height())