Source code for wheel.wheel
"""
WheelWidget
(c) 2025 JDXI Editor
"""
from PySide6.QtCore import Property, QPropertyAnimation, QRectF, Signal
from PySide6.QtGui import QColor, QLinearGradient, QMouseEvent, QPainter, QPen
from PySide6.QtWidgets import QWidget
[docs]
class WheelWidget(QWidget):
"""
Wheel Widget for Pitch and Mod Wheels
"""
def __init__(
self,
parent: object | None = None,
bidirectional: bool = False,
label: str = "Wheel",
) -> None:
super().__init__(parent)
self.setMinimumSize(40, 100)
self.setMouseTracking(True)
# Smooth snap-back animation
self.snap_animation.setDuration(300)
# self.snap_animation.setEasingCurve(Qt.EaseOutCubic)
[docs]
def set_value(self, value: float) -> None:
"""
set_value
:param value: float
:return: None
"""
clamped = max(-1.0 if self.bidirectional else 0.0, min(1.0, value))
if clamped != self._value:
self._value = clamped
self.valueChanged.emit(self._value)
self.update()
[docs]
def paintEvent(self, event: QMouseEvent) -> None:
"""
paintEvent
:param event: QMouseEvent
:return: None
"""
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
# Background and border
# Set pen for the border
painter.setPen(QPen(QColor("#000000"), 2))
# Create a vertical gradient from top to bottom
gradient = QLinearGradient(self.rect().topLeft(), self.rect().bottomLeft())
gradient.setColorAt(0.0, QColor("#111111"))
gradient.setColorAt(0.5, QColor("#333333"))
gradient.setColorAt(1.0, QColor("#000000"))
# Set the gradient as the brush for filling
painter.setBrush(gradient)
# Draw the rectangle with the gradient fill and border
painter.drawRect(self.rect())
# Draw wheel position
notch_height = 25
usable_height = self.height() - 40
center_y = self.height() / 2
offset = -self._value * (
usable_height / 2 if self.bidirectional else usable_height
)
wheel_y = center_y + offset - notch_height / 2
wheel_rect = QRectF(0, wheel_y, self.width(), int(notch_height))
# Create a vertical gradient for the wheel
gradient = QLinearGradient(wheel_rect.topLeft(), wheel_rect.bottomLeft())
gradient.setColorAt(0.0, QColor("black"))
gradient.setColorAt(0.5, QColor("#222222"))
gradient.setColorAt(1.0, QColor("black"))
painter.setBrush(gradient)
painter.setPen(QPen(QColor("black"), 2))
painter.drawRect(wheel_rect)
# Draw label above the wheel
painter.save()
painter.restore()
[docs]
def mousePressEvent(self, event: QMouseEvent) -> None:
"""
mousePressEvent
:param event: QMouseEvent
:return: None
"""
self._drag_active = True
self.snap_animation.stop()
self._update_value_from_mouse(event.pos().y())
[docs]
def mouseMoveEvent(self, event: QMouseEvent) -> None:
"""
mouseMoveEvent
:param event: QMouseEvent
:return: None
"""
if self._drag_active:
self._update_value_from_mouse(event.pos().y())
[docs]
def mouseReleaseEvent(self, event: QMouseEvent) -> None:
"""
mouseReleaseEvent
:param event: QMouseEvent
:return: None
"""
self._drag_active = False
if self.bidirectional:
self.snap_animation.stop()
self.snap_animation.setStartValue(self._value)
self.snap_animation.setEndValue(0.0)
self.snap_animation.start()
[docs]
def _update_value_from_mouse(self, y: int) -> None:
"""
_update_value_from_mouse
:param y: int
:return: None
"""
h = self.height()
if self.bidirectional:
center = h / 2
new_val = max(-1.0, min(1.0, (center - y) / (h / 2)))
else:
new_val = max(0.0, min(1.0, 1.0 - y / h))
self.set_value(new_val)