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.

181 lines
5.4 KiB

# coding: utf-8
from typing import Union
from PySide6.QtCore import QSize, Qt, QRectF, Signal
from PySide6.QtGui import QPainter, QPainterPath, QIcon
from PySide6.QtWidgets import QHBoxLayout, QLineEdit, QToolButton, QTextEdit, QPlainTextEdit
from ...common.style_sheet import FluentStyleSheet, themeColor
from ...common.icon import isDarkTheme, FluentIconBase, drawIcon
from ...common.icon import FluentIcon as FIF
from ...common.font import setFont
from .menu import LineEditMenu, TextEditMenu
from .scroll_bar import SmoothScrollDelegate
class LineEditButton(QToolButton):
""" Line edit button """
def __init__(self, icon: Union[str, QIcon, FluentIconBase], parent=None):
super().__init__(parent=parent)
self._icon = icon
self.isPressed = False
self.setFixedSize(31, 23)
self.setIconSize(QSize(10, 10))
self.setCursor(Qt.CursorShape.PointingHandCursor)
self.setObjectName('lineEditButton')
FluentStyleSheet.LINE_EDIT.apply(self)
def mousePressEvent(self, e):
self.isPressed = True
super().mousePressEvent(e)
def mouseReleaseEvent(self, e):
self.isPressed = False
super().mouseReleaseEvent(e)
def paintEvent(self, e):
super().paintEvent(e)
painter = QPainter(self)
painter.setRenderHints(QPainter.Antialiasing |
QPainter.SmoothPixmapTransform)
iw, ih = self.iconSize().width(), self.iconSize().height()
w, h = self.width(), self.height()
rect = QRectF((w - iw)/2, (h - ih)/2, iw, ih)
if self.isPressed:
painter.setOpacity(0.7)
if isDarkTheme():
drawIcon(self._icon, painter, rect)
else:
drawIcon(self._icon, painter, rect, fill='#656565')
class LineEdit(QLineEdit):
""" Line edit """
def __init__(self, parent=None):
super().__init__(parent=parent)
self._isClearButtonEnabled = False
self.setProperty("transparent", True)
FluentStyleSheet.LINE_EDIT.apply(self)
self.setFixedHeight(33)
self.setAttribute(Qt.WA_MacShowFocusRect, False)
setFont(self)
self.hBoxLayout = QHBoxLayout(self)
self.clearButton = LineEditButton(FIF.CLOSE, self)
self.clearButton.setFixedSize(29, 25)
self.clearButton.hide()
self.hBoxLayout.setSpacing(3)
self.hBoxLayout.setContentsMargins(4, 4, 4, 4)
self.hBoxLayout.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
self.hBoxLayout.addWidget(self.clearButton, 0, Qt.AlignRight)
self.clearButton.clicked.connect(self.clear)
self.textChanged.connect(self.__onTextChanged)
def setClearButtonEnabled(self, enable: bool):
self._isClearButtonEnabled = enable
self.setTextMargins(0, 0, 28*enable, 0)
def isClearButtonEnabled(self) -> bool:
return self._isClearButtonEnabled
def focusOutEvent(self, e):
super().focusOutEvent(e)
self.clearButton.hide()
def focusInEvent(self, e):
super().focusInEvent(e)
if self.isClearButtonEnabled():
self.clearButton.setVisible(bool(self.text()))
def __onTextChanged(self, text):
""" text changed slot """
if self.isClearButtonEnabled():
self.clearButton.setVisible(bool(text) and self.hasFocus())
def contextMenuEvent(self, e):
menu = LineEditMenu(self)
menu.exec_(e.globalPos())
def paintEvent(self, e):
super().paintEvent(e)
if not self.hasFocus():
return
painter = QPainter(self)
painter.setRenderHints(QPainter.Antialiasing)
painter.setPen(Qt.NoPen)
m = self.contentsMargins()
path = QPainterPath()
w, h = self.width()-m.left()-m.right(), self.height()
path.addRoundedRect(QRectF(m.left(), h-10, w, 10), 5, 5)
rectPath = QPainterPath()
rectPath.addRect(m.left(), h-10, w, 8)
path = path.subtracted(rectPath)
painter.fillPath(path, themeColor())
class SearchLineEdit(LineEdit):
""" Search line edit """
searchSignal = Signal(str)
clearSignal = Signal()
def __init__(self, parent=None):
super().__init__(parent)
self.searchButton = LineEditButton(FIF.SEARCH, self)
self.hBoxLayout.addWidget(self.searchButton, 0, Qt.AlignRight)
self.setClearButtonEnabled(True)
self.setTextMargins(0, 0, 59, 0)
self.searchButton.clicked.connect(self.search)
self.clearButton.clicked.connect(self.clearSignal)
def search(self):
""" emit search signal """
text = self.text().strip()
if text:
self.searchSignal.emit(text)
else:
self.clearSignal.emit()
class TextEdit(QTextEdit):
""" Text edit """
def __init__(self, parent=None):
super().__init__(parent=parent)
self.scrollDelegate = SmoothScrollDelegate(self)
FluentStyleSheet.LINE_EDIT.apply(self)
setFont(self)
def contextMenuEvent(self, e):
menu = TextEditMenu(self)
menu.exec_(e.globalPos())
class PlainTextEdit(QPlainTextEdit):
""" Plain text edit """
def __init__(self, parent=None):
super().__init__(parent=parent)
self.scrollDelegate = SmoothScrollDelegate(self)
FluentStyleSheet.LINE_EDIT.apply(self)
setFont(self)
def contextMenuEvent(self, e):
menu = TextEditMenu(self)
menu.exec_(e.globalPos())