Update Screen: Cong cu, settings, them/Chinh sua task
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+94
-6
@@ -5,12 +5,14 @@ from __future__ import annotations
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from PySide6.QtCore import QEvent, QObject, QPointF, QRectF, Qt, Signal
|
||||
from PySide6.QtCore import (
|
||||
QEvent, QObject, QPoint, QPointF, QRect, QRectF, QSize, Qt, Signal,
|
||||
)
|
||||
from PySide6.QtGui import QColor, QPainter, QPen
|
||||
from PySide6.QtWidgets import (
|
||||
QAbstractSpinBox, QCheckBox, QComboBox, QDoubleSpinBox, QFrame,
|
||||
QHBoxLayout, QLabel, QListWidget, QListWidgetItem, QPushButton, QSizePolicy,
|
||||
QVBoxLayout, QWidget,
|
||||
QHBoxLayout, QLabel, QLayout, QListWidget, QListWidgetItem, QPushButton,
|
||||
QSizePolicy, QVBoxLayout, QWidget,
|
||||
)
|
||||
|
||||
from ..core.flows import STEP_DONE, STEP_ERROR, STEP_PENDING, STEP_RUNNING
|
||||
@@ -37,7 +39,93 @@ def badge_pill_widget(text: str, object_name: str) -> QWidget:
|
||||
return container
|
||||
|
||||
|
||||
def _style_card(frame: QFrame) -> None:
|
||||
def enable_height_for_width(widget: QWidget) -> None:
|
||||
"""Flag ``widget`` as height-for-width so a PARENT layout reserves the
|
||||
right amount of vertical space for it — needed at every widget boundary
|
||||
between a :class:`FlowLayout` and the outermost layout, since each
|
||||
``addWidget()`` hop asks the WIDGET's own sizePolicy, not its layout's
|
||||
(see FlowLayout's docstring)."""
|
||||
policy = widget.sizePolicy()
|
||||
policy.setHeightForWidth(True)
|
||||
widget.setSizePolicy(policy)
|
||||
|
||||
|
||||
class FlowLayout(QLayout):
|
||||
"""A left-aligned layout that wraps its children onto new lines as the
|
||||
container narrows, each item kept at its own natural size — the
|
||||
``.card`` grids in ui-audit_v2.html ("không kéo giãn lấp đầy hàng": cards
|
||||
stay sized to their own content, never stretched to fill a row). Qt has
|
||||
no built-in equivalent; this is the standard recipe (Qt's own C++
|
||||
FlowLayout example, ported)."""
|
||||
|
||||
def __init__(self, parent=None, margin: int = 0, h_spacing: int = 8, v_spacing: int = 8):
|
||||
super().__init__(parent)
|
||||
self._h_spacing = h_spacing
|
||||
self._v_spacing = v_spacing
|
||||
self._items: list = []
|
||||
self.setContentsMargins(margin, margin, margin, margin)
|
||||
if parent is not None:
|
||||
enable_height_for_width(parent)
|
||||
|
||||
def addItem(self, item) -> None: # noqa: N802 - Qt override
|
||||
self._items.append(item)
|
||||
|
||||
def count(self) -> int: # noqa: N802 - Qt override
|
||||
return len(self._items)
|
||||
|
||||
def itemAt(self, index: int): # noqa: N802 - Qt override
|
||||
return self._items[index] if 0 <= index < len(self._items) else None
|
||||
|
||||
def takeAt(self, index: int): # noqa: N802 - Qt override
|
||||
return self._items.pop(index) if 0 <= index < len(self._items) else None
|
||||
|
||||
def expandingDirections(self): # noqa: N802 - Qt override
|
||||
return Qt.Orientations(Qt.Orientation(0))
|
||||
|
||||
def hasHeightForWidth(self) -> bool: # noqa: N802 - Qt override
|
||||
return True
|
||||
|
||||
def heightForWidth(self, width: int) -> int: # noqa: N802 - Qt override
|
||||
return self._do_layout(QRect(0, 0, width, 0), test_only=True)
|
||||
|
||||
def setGeometry(self, rect) -> None: # noqa: N802 - Qt override
|
||||
super().setGeometry(rect)
|
||||
self._do_layout(rect, test_only=False)
|
||||
|
||||
def sizeHint(self): # noqa: N802 - Qt override
|
||||
return self.minimumSize()
|
||||
|
||||
def minimumSize(self): # noqa: N802 - Qt override
|
||||
size = QSize()
|
||||
for item in self._items:
|
||||
size = size.expandedTo(item.minimumSize())
|
||||
m = self.contentsMargins()
|
||||
size += QSize(m.left() + m.right(), m.top() + m.bottom())
|
||||
return size
|
||||
|
||||
def _do_layout(self, rect, test_only: bool) -> int:
|
||||
m = self.contentsMargins()
|
||||
effective = QRect(rect.x() + m.left(), rect.y() + m.top(),
|
||||
rect.width() - m.left() - m.right(),
|
||||
rect.height() - m.top() - m.bottom())
|
||||
x, y = effective.x(), effective.y()
|
||||
line_height = 0
|
||||
for item in self._items:
|
||||
hint = item.sizeHint()
|
||||
next_x = x + hint.width() + self._h_spacing
|
||||
if next_x - self._h_spacing > effective.right() and line_height > 0:
|
||||
x = effective.x()
|
||||
y = y + line_height + self._v_spacing
|
||||
next_x = x + hint.width() + self._h_spacing
|
||||
line_height = 0
|
||||
if not test_only:
|
||||
item.setGeometry(QRect(QPoint(x, y), hint))
|
||||
x = next_x
|
||||
line_height = max(line_height, hint.height())
|
||||
return y + line_height - rect.y() + m.bottom()
|
||||
|
||||
|
||||
def style_card(frame: QFrame) -> None:
|
||||
"""Give a stat/budget card its surface. Flat by design: the raised surface
|
||||
plus a hairline is what separates it from the page — the old drop shadow
|
||||
made a grid of these look like it was hovering off the screen."""
|
||||
@@ -54,7 +142,7 @@ class StatCard(QFrame):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setFrameShape(QFrame.NoFrame)
|
||||
_style_card(self)
|
||||
style_card(self)
|
||||
lay = QVBoxLayout(self)
|
||||
self.title_lbl = QLabel("")
|
||||
self.title_lbl.setObjectName("hint")
|
||||
@@ -105,7 +193,7 @@ class BudgetCard(QFrame):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setFrameShape(QFrame.NoFrame)
|
||||
_style_card(self)
|
||||
style_card(self)
|
||||
lay = QVBoxLayout(self)
|
||||
self.title_lbl = QLabel("")
|
||||
self.title_lbl.setObjectName("hint")
|
||||
|
||||
Reference in New Issue
Block a user