Overload Fragment.repaintEvent to just calculate size

This commit is contained in:
Christopher T. Johnson
2024-04-14 17:26:22 -04:00
parent eda370ecb4
commit b82f775621

View File

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