Source code for view.rotation_widget
"""Custom Qt Widget for Rotation Control.
This module provides a custom Qt widget to display a pointer
being rotated on the circle. The widget allows users to rotate
a pointer on a circle boundary.
Example usage:
rotation_widget = RotationWidget()
layout.addWidget(rotation_widget)
"""
import math
from typing import Tuple, Optional
from PySide6.QtGui import QPainter
from PySide6.QtCore import QRectF, QPointF
from PySide6.QtWidgets import QWidget
from PySide6.QtGui import QColor
[docs]
def cartesian_to_polar(x: float, y: float) -> Tuple[float, float]:
"""Convert Cartesian coordinates to polar coordinates.
Args:
x (float): The x-coordinate.
y (float): The y-coordinate.
Returns:
Tuple[float, float]: The polar coordinates (r, theta).
"""
r = math.sqrt(x ** 2 + y ** 2)
theta = math.atan2(y, x)
return r, theta
[docs]
def polar_to_cartesian(r: float, theta: float) -> Tuple[float, float]:
"""Convert polar coordinates to Cartesian coordinates.
Args:
r (float): The radial distance.
theta (float): The angle in radians.
Returns:
Tuple[float, float]: The Cartesian coordinates (x, y).
"""
x = r * math.cos(theta)
y = r * math.sin(theta)
return x, y
[docs]
class RotationWidget(QWidget):
"""Custom Qt Widget for Rotation Control.
Represents a custom Qt widget for rotation control, showing where a pointer is on a circle.
Attributes:
joystick_x: An int representing the x-coordinate of the joystick.
joystick_y: An int representing the y-coordinate of the joystick.
radius: An int representing the radius of the rotation control area.
pointer_radius: An int representing the radius of the rotation control pointer.
"""
def __init__(self, parent: Optional[QWidget] = None) -> None:
"""Initializes the widget.
Args:
parent: A QWidget inside which the joystick is going to be.
"""
super().__init__(parent)
self.joystick_x = 0
self.joystick_y = 0
self.radius = 50
self.pointer_radius = 10
[docs]
def paintEvent(self, event) -> None: # pylint: disable=unused-argument
"""Paint event handler to draw the joystick widget."""
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing, True)
bounds = QRectF(-self.radius, -self.radius, self.radius * 2,
self.radius * 2).translated(self._center())
painter.drawEllipse(bounds)
painter.setBrush(QColor(255, 0, 0, 127))
painter.drawEllipse(self.pointer())
def _center(self) -> QPointF:
"""Calculate the center point of the widget.
Returns:
QPointF: The center point of the widget.
"""
return QPointF(self.width() / 2, self.height() / 2)
[docs]
def pointer(self) -> QRectF:
"""Define the area of the rotation control pointer.
Returns:
QRectF: The area of the rotation control pointer.
"""
# Calculate the angle from the joystick position
_, theta = cartesian_to_polar(self.joystick_x, self.joystick_y)
# Use the angle and y-coordinate to find the position on the circle's edge
x, y = polar_to_cartesian(self.radius, theta)
return QRectF(-self.pointer_radius / 2, -self.pointer_radius / 2,
self.pointer_radius, self.pointer_radius).translated(self._center() + QPointF(x, -y))
[docs]
def set_joystick_position(self, x: float, y: float) -> None:
"""Set the position of the joystick pointer.
Args:
x (float): The x-coordinate of the joystick.
y (float): The y-coordinate of the joystick.
"""
self.joystick_x = x
self.joystick_y = y
self.update()