Add Dispatch_V0.1.1
This commit is contained in:
129
Dispatch_V0.1.1/ui/cards/task_card_pixmap_factory.py
Normal file
129
Dispatch_V0.1.1/ui/cards/task_card_pixmap_factory.py
Normal file
@@ -0,0 +1,129 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# hub/ticket/ui/cards/task_card_pixmap_factory.py
|
||||
|
||||
"""Pixmap-хелперы для карточки Ticket."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from PySide6.QtCore import Qt
|
||||
from PySide6.QtGui import QColor, QFont, QPainter, QPainterPath, QPixmap
|
||||
|
||||
|
||||
def compute_square_size(width: int, height: int, padding: int = 0) -> int:
|
||||
"""Вернуть квадратный размер по меньшей стороне с учётом внутреннего отступа."""
|
||||
available = min(width, height) - padding
|
||||
return max(0, available)
|
||||
|
||||
|
||||
def build_avatar_pixmap(source: QPixmap, size: int) -> QPixmap:
|
||||
"""Построить круглый avatar-pixmap из исходной фотографии."""
|
||||
avatar = QPixmap(size, size)
|
||||
avatar.fill(Qt.GlobalColor.transparent)
|
||||
|
||||
painter = QPainter(avatar)
|
||||
painter.setRenderHint(QPainter.RenderHint.Antialiasing, True)
|
||||
|
||||
outer_padding = 1
|
||||
outer_size = size - (outer_padding * 2)
|
||||
outer_path = QPainterPath()
|
||||
outer_path.addEllipse(outer_padding, outer_padding, outer_size, outer_size)
|
||||
painter.fillPath(outer_path, QColor("#A3A3A3"))
|
||||
|
||||
inner_padding = outer_padding + 2
|
||||
inner_size = size - (inner_padding * 2)
|
||||
inner_path = QPainterPath()
|
||||
inner_path.addEllipse(inner_padding, inner_padding, inner_size, inner_size)
|
||||
painter.setClipPath(inner_path)
|
||||
|
||||
scaled = source.scaled(
|
||||
inner_size,
|
||||
inner_size,
|
||||
Qt.AspectRatioMode.KeepAspectRatioByExpanding,
|
||||
Qt.TransformationMode.SmoothTransformation,
|
||||
)
|
||||
source_x = max(0, (scaled.width() - inner_size) // 2)
|
||||
source_y = max(0, (scaled.height() - inner_size) // 2)
|
||||
painter.drawPixmap(inner_padding, inner_padding, scaled, source_x, source_y, inner_size, inner_size)
|
||||
painter.end()
|
||||
|
||||
return avatar
|
||||
|
||||
|
||||
def build_placeholder_avatar_pixmap(size: int) -> QPixmap:
|
||||
"""Построить круглый placeholder-аватар с вопросительным знаком."""
|
||||
avatar = QPixmap(size, size)
|
||||
avatar.fill(Qt.GlobalColor.transparent)
|
||||
|
||||
painter = QPainter(avatar)
|
||||
painter.setRenderHint(QPainter.RenderHint.Antialiasing, True)
|
||||
|
||||
outer_padding = 1
|
||||
circle_size = size - (outer_padding * 2)
|
||||
circle_path = QPainterPath()
|
||||
circle_path.addEllipse(outer_padding, outer_padding, circle_size, circle_size)
|
||||
painter.fillPath(circle_path, QColor("#F6A493"))
|
||||
painter.setPen(QColor("#FFFFFF"))
|
||||
painter.drawPath(circle_path)
|
||||
|
||||
font = QFont()
|
||||
font.setPixelSize(18)
|
||||
font.setBold(True)
|
||||
painter.setFont(font)
|
||||
painter.setPen(QColor("#172B4D"))
|
||||
painter.drawText(outer_padding, outer_padding, circle_size, circle_size, Qt.AlignmentFlag.AlignCenter, "?")
|
||||
painter.end()
|
||||
|
||||
return avatar
|
||||
|
||||
|
||||
def load_scaled_icon_pixmap(image_path: str, width: int, height: int, padding: int = 0) -> QPixmap | None:
|
||||
"""Загрузить и отмасштабировать stage-icon по фактическому размеру ячейки."""
|
||||
if not image_path:
|
||||
return None
|
||||
pixmap = QPixmap(image_path)
|
||||
if pixmap.isNull():
|
||||
return None
|
||||
icon_size = compute_square_size(width, height, padding)
|
||||
if icon_size <= 0:
|
||||
return None
|
||||
return pixmap.scaled(
|
||||
icon_size,
|
||||
icon_size,
|
||||
Qt.AspectRatioMode.KeepAspectRatio,
|
||||
Qt.TransformationMode.SmoothTransformation,
|
||||
)
|
||||
|
||||
|
||||
def load_tinted_icon_pixmap(
|
||||
image_path: str,
|
||||
width: int,
|
||||
height: int,
|
||||
color_hex: str,
|
||||
padding: int = 0,
|
||||
) -> QPixmap | None:
|
||||
"""Загрузить stage-icon и перекрасить его в нужный цвет."""
|
||||
scaled = load_scaled_icon_pixmap(image_path, width, height, padding)
|
||||
if scaled is None:
|
||||
return None
|
||||
tinted = QPixmap(scaled.size())
|
||||
tinted.fill(Qt.GlobalColor.transparent)
|
||||
|
||||
painter = QPainter(tinted)
|
||||
painter.drawPixmap(0, 0, scaled)
|
||||
painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceIn)
|
||||
painter.fillRect(tinted.rect(), QColor(color_hex))
|
||||
painter.end()
|
||||
return tinted
|
||||
|
||||
|
||||
def load_avatar_pixmap(image_path: str, width: int, height: int, padding: int = 0) -> QPixmap | None:
|
||||
"""Загрузить фото специалиста и подготовить круглый avatar-pixmap."""
|
||||
if not image_path:
|
||||
return None
|
||||
pixmap = QPixmap(image_path)
|
||||
if pixmap.isNull():
|
||||
return None
|
||||
avatar_size = compute_square_size(width, height, padding)
|
||||
if avatar_size <= 0:
|
||||
return None
|
||||
return build_avatar_pixmap(pixmap, avatar_size)
|
||||
Reference in New Issue
Block a user