diff --git a/lib/definition.py b/lib/definition.py index bd0a73b..5817d7d 100644 --- a/lib/definition.py +++ b/lib/definition.py @@ -1,6 +1,5 @@ import re -import copy -from typing import Any, Optional, cast +from typing import Any, Optional, cast, overload import re from PyQt6.QtCore import QMargins, QPoint, QRect, QSize, QUrl, Qt, pyqtSignal from PyQt6.QtGui import QColor, QFont, QFontMetrics, QMouseEvent, QPaintEvent, QPainter, QResizeEvent, QTextOption, QTransform, QBrush @@ -45,21 +44,7 @@ class Fragment: return self.__repr__() def size(self, width: int) -> QSize: - pos = self._position - pos.setX(self._indent * 30) - rect = QRect(pos, QSize(width - self._position.x(), 2000)) - flags = ( - Qt.AlignmentFlag.AlignLeft - | Qt.AlignmentFlag.AlignBaseline - | Qt.TextFlag.TextWordWrap - ) - fm = QFontMetrics(self._font) - bounding = fm.boundingRect(rect, flags, self._text) - size = bounding.size() - size = size.grownBy(self._padding) - size = size.grownBy(self._border) - size = size.grownBy(self._margin) - return size + return self.repaintEvent(width) def height(self, width: int) -> int: return self.size(width).height() @@ -70,16 +55,28 @@ class Fragment: def __repr__(self) -> str: return f"({self._position.x()}, {self._position.y()}): {self._text}" - def repaintEvent(self, painter: QPainter) -> int: - painter.save() - painter.setFont(self._font) + @overload + def repaintEvent(self, widthSrc:int) -> QSize: + ... + @overload + def repaintEvent(self, widthSrc: QPainter) -> int: + ... + + def repaintEvent(self, widthSrc) -> int|QSize: + if isinstance(widthSrc, QPainter): + viewportWidth = widthSrc.viewport().width() + painter = widthSrc + else: + viewportWidth = widthSrc + painter = None + fm = QFontMetrics(self._font) top = ( self._position.y() - + painter.fontMetrics().descent() - - painter.fontMetrics().height() + + fm.descent() + - fm.height() ) left = self._position.x() - width = painter.viewport().width() - left + width = viewportWidth - left height = 2000 rect = QRect(left, top, width, height) indent = self._indent * 30 @@ -87,7 +84,7 @@ class Fragment: Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignBaseline ) - boundingNoWrap = painter.fontMetrics().boundingRect( + boundingNoWrap = fm.boundingRect( rect, flags|Qt.TextFlag.TextSingleLine, self._text ) flags = ( @@ -95,7 +92,7 @@ class Fragment: | Qt.AlignmentFlag.AlignBaseline | Qt.TextFlag.TextWordWrap ) - bounding = painter.fontMetrics().boundingRect( + bounding = fm.boundingRect( rect, flags|Qt.TextFlag.TextWordWrap, self._text ) text = self._text @@ -110,7 +107,7 @@ class Fragment: while pos < rect.right(): if text[char] == ' ': lastSpace = char - pos += painter.fontMetrics().horizontalAdvance( + pos += fm.horizontalAdvance( text[char] ) char += 1 @@ -119,6 +116,27 @@ class Fragment: size = boundingNoWrap.size() + if remainingText != '': + top += size.height() + remainingRect = QRect( + indent, top, + viewportWidth - indent, height + ) + size = size.grownBy( + QMargins( + 0,0,0, + fm.boundingRect( + remainingRect, flags | Qt.TextFlag.TextWordWrap, remainingText + ).height() + ) + ) + size = size.grownBy(self._margin) + size = size.grownBy(self._border) + size = size.grownBy(self._padding) + if painter is None: + return size + painter.save() + painter.setFont(self._font) painter.setPen(QColor("#f00")) if self._audio.isValid(): radius = self._borderRect.height() / 2 @@ -129,25 +147,9 @@ class Fragment: painter.drawLine(start, end) painter.setPen(self._color) painter.drawText(rect, flags, text) - if remainingText != '': - top += size.height() - rect = QRect( - indent, top, - painter.viewport().width() - indent, height - ) - painter.drawText(rect, flags|Qt.TextFlag.TextWordWrap, remainingText) - size = size.grownBy( - QMargins( - 0,0,0, - painter.fontMetrics().boundingRect( - rect, flags | Qt.TextFlag.TextWordWrap, remainingText - ).height() - ) - ) + if remainingText: + painter.drawText(remainingRect, flags|Qt.TextFlag.TextWordWrap, remainingText) painter.restore() - size = size.grownBy(self._margin) - size = size.grownBy(self._border) - size = size.grownBy(self._padding) return size.height() #