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
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())
|
|
|