You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

222 lines
8.1 KiB

# coding:utf-8
from PySide6.QtCore import Qt, QUrl, QEvent
from PySide6.QtGui import QDesktopServices, QPainter, QPen, QColor
from PySide6.QtWidgets import QWidget, QLabel, QVBoxLayout, QHBoxLayout, QFrame
from qfluentwidgets import (ScrollArea, PushButton, ToolButton, FluentIcon,
isDarkTheme, IconWidget, Theme, ToolTipFilter)
from ..common.config import cfg, FEEDBACK_URL, HELP_URL, EXAMPLE_URL
from ..common.signal_bus import signalBus
from ..common.style_sheet import StyleSheet
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 = QLabel(title, self)
self.subtitleLabel = QLabel(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.titleLabel.setObjectName('titleLabel')
self.subtitleLabel.setObjectName('subtitleLabel')
self.themeButton.clicked.connect(self.toggleTheme)
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)))
def toggleTheme(self):
theme = Theme.LIGHT if isDarkTheme() else Theme.DARK
cfg.set(cfg.themeMode, theme)
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 = QLabel(title, self)
self.card = QFrame(self)
self.sourceWidget = QFrame(self.card)
self.sourcePath = sourcePath
self.sourcePathLabel = QLabel(
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.titleLabel.setObjectName('titleLabel')
self.card.setObjectName('card')
self.sourcePathLabel.setObjectName('sourcePathLabel')
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())