Files
sphere-grid/grid/ui/items.py

172 lines
4.9 KiB
Python

import logging
import random
from PySide6.QtCore import QRectF, Qt
from PySide6.QtGui import QBrush, QPainter, QPen
from PySide6.QtWidgets import (
QGraphicsEllipseItem,
QGraphicsItem,
QStyleOptionGraphicsItem,
QWidget,
)
class SphereGraphicsItem(QGraphicsEllipseItem):
"""Single sphere of a static size."""
SPHERE_WIDTH = 30
def __init__(
self, x_pos: int, y_pos: int, color: Qt.GlobalColor = Qt.GlobalColor.darkBlue
) -> None:
"""Create a sphere
Args:
x_pos (int): x coordinate of the center
y_pos (int): y coordinate of the center
"""
super().__init__(
x_pos - self.SPHERE_WIDTH / 2,
y_pos - self.SPHERE_WIDTH / 2,
self.SPHERE_WIDTH,
self.SPHERE_WIDTH,
)
self.x_pos = x_pos - self.SPHERE_WIDTH / 2
self.y_pos = y_pos - self.SPHERE_WIDTH / 2
logging.debug(f"sphere at {self.x_pos}:{self.y_pos}")
brush = QBrush(color)
self.setBrush(brush)
pen = QPen(Qt.GlobalColor.darkBlue)
pen.setWidth(2)
self.setPen(pen)
self.show()
def boundingRect(self) -> QRectF:
return QRectF(self.x_pos, self.y_pos, self.SPHERE_WIDTH, self.SPHERE_WIDTH)
class HPSphereGraphicsItem(SphereGraphicsItem):
def __init__(self, x_pos: int, y_pos: int) -> None:
super().__init__(x_pos, y_pos, Qt.GlobalColor.darkGreen)
class StrenghSphereGraphicsItem(SphereGraphicsItem):
def __init__(self, x_pos: int, y_pos: int) -> None:
super().__init__(x_pos, y_pos, Qt.GlobalColor.darkRed)
class AgilitySphereGraphicsItem(SphereGraphicsItem):
def __init__(self, x_pos: int, y_pos: int) -> None:
super().__init__(x_pos, y_pos, Qt.GlobalColor.darkYellow)
class EmptySphereGraphicsItem(SphereGraphicsItem):
def __init__(self, x_pos: int, y_pos: int) -> None:
self.SPHERE_WIDTH = 20
super().__init__(x_pos, y_pos, Qt.GlobalColor.black)
@staticmethod
def random_sphere_factory(x_pos: int, y_pos: int) -> SphereGraphicsItem:
rand = random.random()
if rand > 3 / 4:
obj = SphereGraphicsItem(x_pos, y_pos)
elif rand > 2 / 4:
obj = AgilitySphereGraphicsItem(x_pos, y_pos)
elif rand > 1 / 4:
obj = StrenghSphereGraphicsItem(x_pos, y_pos)
else:
obj = EmptySphereGraphicsItem(x_pos, y_pos)
return obj
class ArcGraphicsItem(QGraphicsItem):
"""Circle arc."""
def __init__(
self,
x_pos: int,
y_pos: int,
width: int,
angle_start: int,
angle_end: int,
parent: QGraphicsItem | None = ...,
):
"""Construct a circle arc.
Args:
x_pos (int): x center of the circle
y_pos (int): y center of the circle
width (int): width of the circle
angle_start (int): Angle start in human degree
angle_end (int): Angle end in human degree
parent (QGraphicsItem | None, optional): _description_. Defaults to ....
"""
super().__init__(parent)
shift = int(width / 2)
self.x_pos = x_pos - shift
self.y_pos = y_pos - shift
self.width = width
self.angle_start = angle_start
self.angle_end = angle_end
self.draw_angle_start = int(angle_start * 16)
# must a more elegant way but it works
if angle_end == 0:
angle_end = 360
self.draw_angle_end = int(abs(angle_end - angle_start) * 16)
logging.debug(
"arc from %s:%s of %s from %s° to %s°",
self.x_pos,
self.y_pos,
self.width,
self.angle_start,
self.angle_end,
)
def paint(
self,
painter: QPainter,
option: QStyleOptionGraphicsItem,
widget: QWidget | None = ...,
) -> None:
painter.drawArc(
self.x_pos,
self.y_pos,
self.width,
self.width,
self.draw_angle_start,
self.draw_angle_end,
)
def boundingRect(self) -> QRectF:
return QRectF(self.x_pos, self.y_pos, self.width, self.width)
class LineGraphicsItem(QGraphicsItem):
def __init__(
self,
begin_x: int,
begin_y: int,
end_x: int,
end_y: int,
parent: QGraphicsItem | None = ...,
) -> None:
super().__init__(parent)
logging.debug(f"line from {begin_x}:{begin_y} to {end_x}:{end_y}")
self.begin_x = begin_x
self.begin_y = begin_y
self.end_x = end_x
self.end_y = end_y
def paint(
self,
painter: QPainter,
option: QStyleOptionGraphicsItem,
widget: QWidget | None = ...,
) -> None:
painter.drawLine(self.begin_x, self.begin_y, self.end_x, self.end_y)
def boundingRect(self) -> QRectF:
return QRectF(self.begin_x, self.begin_y, self.end_x, self.end_y)