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

237 lines
7.9 KiB
Python

# coding:utf-8
from typing import List
from PyQt6.QtCore import Qt, pyqtSignal
from PyQt6.QtWidgets import QApplication, QFrame, QVBoxLayout, QLabel, QWidget, QHBoxLayout
from qfluentwidgets import (FluentIcon, IconWidget, FlowLayout, isDarkTheme,
Theme, applyThemeColor, SmoothScrollArea, SearchLineEdit, StrongBodyLabel,
BodyLabel)
from .gallery_interface import GalleryInterface
from ..common.translator import Translator
from ..common.config import cfg
from ..common.style_sheet import StyleSheet
from ..common.trie import Trie
class LineEdit(SearchLineEdit):
""" Search line edit """
def __init__(self, parent=None):
super().__init__(parent)
self.setPlaceholderText(self.tr('Search icons'))
self.setFixedWidth(304)
self.textChanged.connect(self.search)
class IconCard(QFrame):
""" Icon card """
clicked = pyqtSignal(FluentIcon)
def __init__(self, icon: FluentIcon, parent=None):
super().__init__(parent=parent)
self.icon = icon
self.isSelected = False
self.iconWidget = IconWidget(icon, self)
self.nameLabel = QLabel(self)
self.vBoxLayout = QVBoxLayout(self)
self.setFixedSize(96, 96)
self.vBoxLayout.setSpacing(0)
self.vBoxLayout.setContentsMargins(8, 28, 8, 0)
self.vBoxLayout.setAlignment(Qt.AlignTop)
self.iconWidget.setFixedSize(28, 28)
self.vBoxLayout.addWidget(self.iconWidget, 0, Qt.AlignHCenter)
self.vBoxLayout.addSpacing(14)
self.vBoxLayout.addWidget(self.nameLabel, 0, Qt.AlignHCenter)
text = self.nameLabel.fontMetrics().elidedText(icon.value, Qt.ElideRight, 90)
self.nameLabel.setText(text)
def mouseReleaseEvent(self, e):
if self.isSelected:
return
self.clicked.emit(self.icon)
def setSelected(self, isSelected: bool, force=False):
if isSelected == self.isSelected and not force:
return
self.isSelected = isSelected
if not isSelected:
self.iconWidget.setIcon(self.icon)
else:
icon = self.icon.icon(Theme.LIGHT if isDarkTheme() else Theme.DARK)
self.iconWidget.setIcon(icon)
self.setProperty('isSelected', isSelected)
self.setStyle(QApplication.style())
class IconInfoPanel(QFrame):
""" Icon info panel """
def __init__(self, icon: FluentIcon, parent=None):
super().__init__(parent=parent)
self.nameLabel = QLabel(icon.value, self)
self.iconWidget = IconWidget(icon, self)
self.iconNameTitleLabel = QLabel(self.tr('Icon name'), self)
self.iconNameLabel = QLabel(icon.value, self)
self.enumNameTitleLabel = QLabel(self.tr('Enum member'), self)
self.enumNameLabel = QLabel("FluentIcon." + icon.name, self)
self.vBoxLayout = QVBoxLayout(self)
self.vBoxLayout.setContentsMargins(16, 20, 16, 20)
self.vBoxLayout.setSpacing(0)
self.vBoxLayout.setAlignment(Qt.AlignTop)
self.vBoxLayout.addWidget(self.nameLabel)
self.vBoxLayout.addSpacing(16)
self.vBoxLayout.addWidget(self.iconWidget)
self.vBoxLayout.addSpacing(45)
self.vBoxLayout.addWidget(self.iconNameTitleLabel)
self.vBoxLayout.addSpacing(5)
self.vBoxLayout.addWidget(self.iconNameLabel)
self.vBoxLayout.addSpacing(34)
self.vBoxLayout.addWidget(self.enumNameTitleLabel)
self.vBoxLayout.addSpacing(5)
self.vBoxLayout.addWidget(self.enumNameLabel)
self.iconWidget.setFixedSize(48, 48)
self.setFixedWidth(216)
self.nameLabel.setObjectName('nameLabel')
self.iconNameTitleLabel.setObjectName('subTitleLabel')
self.enumNameTitleLabel.setObjectName('subTitleLabel')
def setIcon(self, icon: FluentIcon):
self.iconWidget.setIcon(icon)
self.nameLabel.setText(icon.value)
self.iconNameLabel.setText(icon.value)
self.enumNameLabel.setText("FluentIcon."+icon.name)
class IconCardView(QWidget):
""" Icon card view """
def __init__(self, parent=None):
super().__init__(parent=parent)
self.trie = Trie()
self.iconLibraryLabel = StrongBodyLabel(self.tr('Fluent Icons Library'), self)
self.searchLineEdit = LineEdit(self)
self.view = QFrame(self)
self.scrollArea = SmoothScrollArea(self.view)
self.scrollWidget = QWidget(self.scrollArea)
self.infoPanel = IconInfoPanel(FluentIcon.MENU, self)
self.vBoxLayout = QVBoxLayout(self)
self.hBoxLayout = QHBoxLayout(self.view)
self.flowLayout = FlowLayout(self.scrollWidget, isTight=True)
self.cards = [] # type:List[IconCard]
self.icons = []
self.currentIndex = -1
self.__initWidget()
def __initWidget(self):
self.scrollArea.setWidget(self.scrollWidget)
self.scrollArea.setViewportMargins(0, 5, 0, 5)
self.scrollArea.setWidgetResizable(True)
self.scrollArea.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.vBoxLayout.setContentsMargins(0, 0, 0, 0)
self.vBoxLayout.setSpacing(12)
self.vBoxLayout.addWidget(self.iconLibraryLabel)
self.vBoxLayout.addWidget(self.searchLineEdit)
self.vBoxLayout.addWidget(self.view)
self.hBoxLayout.setSpacing(0)
self.hBoxLayout.setContentsMargins(0, 0, 0, 0)
self.hBoxLayout.addWidget(self.scrollArea)
self.hBoxLayout.addWidget(self.infoPanel, 0, Qt.AlignRight)
self.flowLayout.setVerticalSpacing(8)
self.flowLayout.setHorizontalSpacing(8)
self.flowLayout.setContentsMargins(8, 3, 8, 8)
self.__setQss()
cfg.themeChanged.connect(self.__setQss)
self.searchLineEdit.clearSignal.connect(self.showAllIcons)
self.searchLineEdit.searchSignal.connect(self.search)
for icon in FluentIcon._member_map_.values():
self.addIcon(icon)
self.setSelectedIcon(self.icons[0])
def addIcon(self, icon: FluentIcon):
""" add icon to view """
card = IconCard(icon, self)
card.clicked.connect(self.setSelectedIcon)
self.trie.insert(icon.value, len(self.cards))
self.cards.append(card)
self.icons.append(icon)
self.flowLayout.addWidget(card)
def setSelectedIcon(self, icon: FluentIcon):
""" set selected icon """
index = self.icons.index(icon)
if self.currentIndex >= 0:
self.cards[self.currentIndex].setSelected(False)
self.currentIndex = index
self.cards[index].setSelected(True)
self.infoPanel.setIcon(icon)
def __setQss(self):
self.view.setObjectName('iconView')
self.scrollWidget.setObjectName('scrollWidget')
StyleSheet.ICON_INTERFACE.apply(self)
StyleSheet.ICON_INTERFACE.apply(self.scrollWidget)
if self.currentIndex >= 0:
self.cards[self.currentIndex].setSelected(True, True)
def search(self, keyWord: str):
""" search icons """
items = self.trie.items(keyWord.lower())
indexes = {i[1] for i in items}
self.flowLayout.removeAllWidgets()
for i, card in enumerate(self.cards):
isVisible = i in indexes
card.setVisible(isVisible)
if isVisible:
self.flowLayout.addWidget(card)
def showAllIcons(self):
self.flowLayout.removeAllWidgets()
for card in self.cards:
card.show()
self.flowLayout.addWidget(card)
class IconInterface(GalleryInterface):
""" Icon interface """
def __init__(self, parent=None):
t = Translator()
super().__init__(
title=t.icons,
subtitle="qfluentwidgets.common.icon",
parent=parent
)
self.setObjectName('iconInterface')
self.iconView = IconCardView(self)
self.vBoxLayout.addWidget(self.iconView)