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.
414 lines
12 KiB
414 lines
12 KiB
# coding:utf-8
|
|
from typing import Union
|
|
|
|
from PySide6.QtCore import Qt, Signal
|
|
from PySide6.QtGui import QColor, QIcon, QPainter
|
|
from PySide6.QtWidgets import QFrame, QHBoxLayout, QLabel, QToolButton, QVBoxLayout, QPushButton
|
|
from PySide6.QtSvgWidgets import QSvgWidget
|
|
|
|
from ..dialog_box.color_dialog import ColorDialog
|
|
from ..widgets.combo_box import ComboBox
|
|
from ..widgets.switch_button import SwitchButton, IndicatorPosition
|
|
from ..widgets.slider import Slider
|
|
from ..widgets.icon_widget import IconWidget
|
|
from ..widgets.button import HyperlinkButton
|
|
from ...common.style_sheet import FluentStyleSheet
|
|
from ...common.config import qconfig, isDarkTheme, ConfigItem, OptionsConfigItem
|
|
from ...common.icon import FluentIconBase
|
|
|
|
|
|
class SettingCard(QFrame):
|
|
""" Setting card """
|
|
|
|
def __init__(self, icon: Union[str, QIcon, FluentIconBase], title, content=None, parent=None):
|
|
"""
|
|
Parameters
|
|
----------
|
|
icon: str | QIcon | FluentIconBase
|
|
the icon to be drawn
|
|
|
|
title: str
|
|
the title of card
|
|
|
|
content: str
|
|
the content of card
|
|
|
|
parent: QWidget
|
|
parent widget
|
|
"""
|
|
super().__init__(parent=parent)
|
|
self.iconLabel = IconWidget(icon, self)
|
|
self.titleLabel = QLabel(title, self)
|
|
self.contentLabel = QLabel(content or '', self)
|
|
self.hBoxLayout = QHBoxLayout(self)
|
|
self.vBoxLayout = QVBoxLayout()
|
|
|
|
if not content:
|
|
self.contentLabel.hide()
|
|
|
|
self.setFixedHeight(70 if content else 50)
|
|
self.iconLabel.setFixedSize(16, 16)
|
|
|
|
# initialize layout
|
|
self.hBoxLayout.setSpacing(0)
|
|
self.hBoxLayout.setContentsMargins(16, 0, 0, 0)
|
|
self.hBoxLayout.setAlignment(Qt.AlignVCenter)
|
|
self.vBoxLayout.setSpacing(0)
|
|
self.vBoxLayout.setContentsMargins(0, 0, 0, 0)
|
|
self.vBoxLayout.setAlignment(Qt.AlignVCenter)
|
|
|
|
self.hBoxLayout.addWidget(self.iconLabel, 0, Qt.AlignLeft)
|
|
self.hBoxLayout.addSpacing(16)
|
|
|
|
self.hBoxLayout.addLayout(self.vBoxLayout)
|
|
self.vBoxLayout.addWidget(self.titleLabel, 0, Qt.AlignLeft)
|
|
self.vBoxLayout.addWidget(self.contentLabel, 0, Qt.AlignLeft)
|
|
|
|
self.hBoxLayout.addSpacing(16)
|
|
self.hBoxLayout.addStretch(1)
|
|
|
|
self.contentLabel.setObjectName('contentLabel')
|
|
FluentStyleSheet.SETTING_CARD.apply(self)
|
|
|
|
def setTitle(self, title: str):
|
|
""" set the title of card """
|
|
self.titleLabel.setText(title)
|
|
|
|
def setContent(self, content: str):
|
|
""" set the content of card """
|
|
self.contentLabel.setText(content)
|
|
self.contentLabel.setVisible(bool(content))
|
|
|
|
def setValue(self, value):
|
|
""" set the value of config item """
|
|
pass
|
|
|
|
|
|
class SwitchSettingCard(SettingCard):
|
|
""" Setting card with switch button """
|
|
|
|
checkedChanged = Signal(bool)
|
|
|
|
def __init__(self, icon: Union[str, QIcon, FluentIconBase], title, content=None,
|
|
configItem: ConfigItem = None, parent=None):
|
|
"""
|
|
Parameters
|
|
----------
|
|
icon: str | QIcon | FluentIconBase
|
|
the icon to be drawn
|
|
|
|
title: str
|
|
the title of card
|
|
|
|
content: str
|
|
the content of card
|
|
|
|
configItem: ConfigItem
|
|
configuration item operated by the card
|
|
|
|
parent: QWidget
|
|
parent widget
|
|
"""
|
|
super().__init__(icon, title, content, parent)
|
|
self.configItem = configItem
|
|
self.switchButton = SwitchButton(
|
|
self.tr('Off'), self, IndicatorPosition.RIGHT)
|
|
|
|
if configItem:
|
|
self.setValue(qconfig.get(configItem))
|
|
configItem.valueChanged.connect(self.setValue)
|
|
|
|
# add switch button to layout
|
|
self.hBoxLayout.addWidget(self.switchButton, 0, Qt.AlignRight)
|
|
self.hBoxLayout.addSpacing(16)
|
|
|
|
self.switchButton.checkedChanged.connect(self.__onCheckedChanged)
|
|
|
|
def __onCheckedChanged(self, isChecked: bool):
|
|
""" switch button checked state changed slot """
|
|
self.setValue(isChecked)
|
|
self.checkedChanged.emit(isChecked)
|
|
|
|
def setValue(self, isChecked: bool):
|
|
if self.configItem:
|
|
qconfig.set(self.configItem, isChecked)
|
|
|
|
self.switchButton.setChecked(isChecked)
|
|
self.switchButton.setText(
|
|
self.tr('On') if isChecked else self.tr('Off'))
|
|
|
|
def isChecked(self):
|
|
return self.switchButton.isChecked()
|
|
|
|
|
|
class RangeSettingCard(SettingCard):
|
|
""" Setting card with a slider """
|
|
|
|
valueChanged = Signal(int)
|
|
|
|
def __init__(self, configItem, icon: Union[str, QIcon, FluentIconBase], title, content=None, parent=None):
|
|
"""
|
|
Parameters
|
|
----------
|
|
configItem: RangeConfigItem
|
|
configuration item operated by the card
|
|
|
|
icon: str | QIcon | FluentIconBase
|
|
the icon to be drawn
|
|
|
|
title: str
|
|
the title of card
|
|
|
|
content: str
|
|
the content of card
|
|
|
|
parent: QWidget
|
|
parent widget
|
|
"""
|
|
super().__init__(icon, title, content, parent)
|
|
self.configItem = configItem
|
|
self.slider = Slider(Qt.Horizontal, self)
|
|
self.valueLabel = QLabel(self)
|
|
self.slider.setMinimumWidth(268)
|
|
|
|
self.slider.setSingleStep(1)
|
|
self.slider.setRange(*configItem.range)
|
|
self.slider.setValue(configItem.value)
|
|
self.valueLabel.setNum(configItem.value)
|
|
|
|
self.hBoxLayout.addStretch(1)
|
|
self.hBoxLayout.addWidget(self.valueLabel, 0, Qt.AlignRight)
|
|
self.hBoxLayout.addSpacing(6)
|
|
self.hBoxLayout.addWidget(self.slider, 0, Qt.AlignRight)
|
|
self.hBoxLayout.addSpacing(16)
|
|
|
|
self.valueLabel.setObjectName('valueLabel')
|
|
configItem.valueChanged.connect(self.setValue)
|
|
self.slider.valueChanged.connect(self.__onValueChanged)
|
|
|
|
def __onValueChanged(self, value: int):
|
|
""" slider value changed slot """
|
|
self.setValue(value)
|
|
self.valueChanged.emit(value)
|
|
|
|
def setValue(self, value):
|
|
qconfig.set(self.configItem, value)
|
|
self.valueLabel.setNum(value)
|
|
self.valueLabel.adjustSize()
|
|
|
|
|
|
class PushSettingCard(SettingCard):
|
|
""" Setting card with a push button """
|
|
|
|
clicked = Signal()
|
|
|
|
def __init__(self, text, icon: Union[str, QIcon, FluentIconBase], title, content=None, parent=None):
|
|
"""
|
|
Parameters
|
|
----------
|
|
text: str
|
|
the text of push button
|
|
|
|
icon: str | QIcon | FluentIconBase
|
|
the icon to be drawn
|
|
|
|
title: str
|
|
the title of card
|
|
|
|
content: str
|
|
the content of card
|
|
|
|
parent: QWidget
|
|
parent widget
|
|
"""
|
|
super().__init__(icon, title, content, parent)
|
|
self.button = QPushButton(text, self)
|
|
self.hBoxLayout.addWidget(self.button, 0, Qt.AlignRight)
|
|
self.hBoxLayout.addSpacing(16)
|
|
self.button.clicked.connect(self.clicked)
|
|
|
|
|
|
class PrimaryPushSettingCard(PushSettingCard):
|
|
""" Push setting card with primary color """
|
|
|
|
def __init__(self, text, icon, title, content=None, parent=None):
|
|
super().__init__(text, icon, title, content, parent)
|
|
self.button.setObjectName('primaryButton')
|
|
|
|
|
|
class HyperlinkCard(SettingCard):
|
|
""" Hyperlink card """
|
|
|
|
def __init__(self, url, text, icon: Union[str, QIcon, FluentIconBase], title, content=None, parent=None):
|
|
"""
|
|
Parameters
|
|
----------
|
|
url: str
|
|
the url to be opened
|
|
|
|
text: str
|
|
text of url
|
|
|
|
icon: str | QIcon | FluentIconBase
|
|
the icon to be drawn
|
|
|
|
title: str
|
|
the title of card
|
|
|
|
content: str
|
|
the content of card
|
|
|
|
text: str
|
|
the text of push button
|
|
|
|
parent: QWidget
|
|
parent widget
|
|
"""
|
|
super().__init__(icon, title, content, parent)
|
|
self.linkButton = HyperlinkButton(url, text, self)
|
|
self.hBoxLayout.addWidget(self.linkButton, 0, Qt.AlignRight)
|
|
self.hBoxLayout.addSpacing(16)
|
|
|
|
|
|
class ColorPickerButton(QToolButton):
|
|
""" Color picker button """
|
|
|
|
colorChanged = Signal(QColor)
|
|
|
|
def __init__(self, color: QColor, title: str, parent=None, enableAlpha=False):
|
|
super().__init__(parent=parent)
|
|
self.title = title
|
|
self.enableAlpha = enableAlpha
|
|
self.setFixedSize(96, 32)
|
|
self.setAttribute(Qt.WA_TranslucentBackground)
|
|
|
|
self.setColor(color)
|
|
self.setCursor(Qt.PointingHandCursor)
|
|
self.clicked.connect(self.__showColorDialog)
|
|
|
|
def __showColorDialog(self):
|
|
""" show color dialog """
|
|
w = ColorDialog(self.color, self.tr(
|
|
'Choose ')+self.title, self.window(), self.enableAlpha)
|
|
w.colorChanged.connect(self.__onColorChanged)
|
|
w.exec()
|
|
|
|
def __onColorChanged(self, color):
|
|
""" color changed slot """
|
|
self.setColor(color)
|
|
self.colorChanged.emit(color)
|
|
|
|
def setColor(self, color):
|
|
""" set color """
|
|
self.color = QColor(color)
|
|
self.update()
|
|
|
|
def paintEvent(self, e):
|
|
painter = QPainter(self)
|
|
painter.setRenderHints(QPainter.Antialiasing)
|
|
pc = QColor(255, 255, 255, 10) if isDarkTheme() else QColor(234, 234, 234)
|
|
painter.setPen(pc)
|
|
|
|
color = QColor(self.color)
|
|
if not self.enableAlpha:
|
|
color.setAlpha(255)
|
|
|
|
painter.setBrush(color)
|
|
painter.drawRoundedRect(self.rect().adjusted(1, 1, -1, -1), 5, 5)
|
|
|
|
|
|
class ColorSettingCard(SettingCard):
|
|
""" Setting card with color picker """
|
|
|
|
colorChanged = Signal(QColor)
|
|
|
|
def __init__(self, configItem, icon: Union[str, QIcon, FluentIconBase],
|
|
title: str, content: str = None, parent=None, enableAlpha=False):
|
|
"""
|
|
Parameters
|
|
----------
|
|
configItem: RangeConfigItem
|
|
configuration item operated by the card
|
|
|
|
icon: str | QIcon | FluentIconBase
|
|
the icon to be drawn
|
|
|
|
title: str
|
|
the title of card
|
|
|
|
content: str
|
|
the content of card
|
|
|
|
parent: QWidget
|
|
parent widget
|
|
|
|
enableAlpha: bool
|
|
whether to enable the alpha channel
|
|
"""
|
|
super().__init__(icon, title, content, parent)
|
|
self.configItem = configItem
|
|
self.colorPicker = ColorPickerButton(
|
|
qconfig.get(configItem), title, self, enableAlpha)
|
|
self.hBoxLayout.addWidget(self.colorPicker, 0, Qt.AlignRight)
|
|
self.hBoxLayout.addSpacing(16)
|
|
self.colorPicker.colorChanged.connect(self.__onColorChanged)
|
|
configItem.valueChanged.connect(self.setValue)
|
|
|
|
def __onColorChanged(self, color: QColor):
|
|
qconfig.set(self.configItem, color)
|
|
self.colorChanged.emit(color)
|
|
|
|
def setValue(self, color: QColor):
|
|
self.colorPicker.setColor(color)
|
|
qconfig.set(self.configItem, color)
|
|
|
|
|
|
class ComboBoxSettingCard(SettingCard):
|
|
""" Setting card with a combo box """
|
|
|
|
def __init__(self, configItem: OptionsConfigItem, icon: Union[str, QIcon, FluentIconBase], title, content=None, texts=None, parent=None):
|
|
"""
|
|
Parameters
|
|
----------
|
|
configItem: OptionsConfigItem
|
|
configuration item operated by the card
|
|
|
|
icon: str | QIcon | FluentIconBase
|
|
the icon to be drawn
|
|
|
|
title: str
|
|
the title of card
|
|
|
|
content: str
|
|
the content of card
|
|
|
|
texts: List[str]
|
|
the text of items
|
|
|
|
parent: QWidget
|
|
parent widget
|
|
"""
|
|
super().__init__(icon, title, content, parent)
|
|
self.configItem = configItem
|
|
self.comboBox = ComboBox(self)
|
|
self.hBoxLayout.addWidget(self.comboBox, 0, Qt.AlignRight)
|
|
self.hBoxLayout.addSpacing(16)
|
|
|
|
self.optionToText = {o: t for o, t in zip(configItem.options, texts)}
|
|
for text, option in zip(texts, configItem.options):
|
|
self.comboBox.addItem(text, userData=option)
|
|
|
|
self.comboBox.setCurrentText(self.optionToText[qconfig.get(configItem)])
|
|
self.comboBox.currentIndexChanged.connect(self._onCurrentIndexChanged)
|
|
configItem.valueChanged.connect(self.setValue)
|
|
|
|
def _onCurrentIndexChanged(self, index: int):
|
|
|
|
qconfig.set(self.configItem, self.comboBox.itemData(index))
|
|
|
|
def setValue(self, value):
|
|
if value not in self.optionToText:
|
|
return
|
|
|
|
self.comboBox.setCurrentText(self.optionToText[value])
|
|
qconfig.set(self.configItem, value) |