84 lines
2.5 KiB
Python
84 lines
2.5 KiB
Python
import logging
|
|
|
|
from PySide6.QtWidgets import (
|
|
QGraphicsRectItem, QGraphicsSimpleTextItem, QGraphicsItem
|
|
)
|
|
from PySide6.QtGui import QBrush, QColor, QFont, QFontMetricsF, QPen, Qt
|
|
from PySide6.QtCore import Signal, QObject, QTimer
|
|
|
|
|
|
NORMAL_COLOR = QColor("lightgray")
|
|
CLICKED_COLOR = QColor("darkgray")
|
|
TEXT_SCALE_FACTOR = 0.4
|
|
CLICK_HIGHLIGHT_DURATION_MS = 100
|
|
Z_INDEX_MULTIPLIER = 2.0
|
|
|
|
class KeyItem(QGraphicsRectItem, QObject):
|
|
clicked = Signal(str)
|
|
|
|
def __init__(self, label: str):
|
|
QObject.__init__(self)
|
|
QGraphicsRectItem.__init__(self)
|
|
|
|
self.logger = logging.getLogger(__name__)
|
|
|
|
|
|
self.label = label
|
|
self.width = 0.0
|
|
self.height = 0.0
|
|
self.scale_factor = 1.0
|
|
|
|
self._reset_timer = QTimer()
|
|
self._reset_timer.setSingleShot(True)
|
|
self._reset_timer.timeout.connect(self.__reset_color)
|
|
|
|
self.text = QGraphicsSimpleTextItem(label, self)
|
|
self.text.setFlag(QGraphicsItem.ItemIgnoresTransformations, True)
|
|
|
|
self.__normal_brush = QBrush(NORMAL_COLOR)
|
|
self.__click_brush = QBrush(CLICKED_COLOR)
|
|
self.setBrush(self.__normal_brush)
|
|
|
|
def set_geometry(self, x: float, y: float, width: float, height: float):
|
|
self.width = width
|
|
self.height = height
|
|
|
|
self.setRect(0, 0, width, height)
|
|
self.setPos(x, y)
|
|
self.setTransformOriginPoint(width / 2, height / 2)
|
|
|
|
self.update_label_font()
|
|
|
|
def update_label_font(self):
|
|
min_dimension = min(self.width, self.height)
|
|
font_size = min_dimension * TEXT_SCALE_FACTOR
|
|
|
|
font = QFont()
|
|
font.setPointSizeF(font_size)
|
|
self.text.setFont(font)
|
|
|
|
metrics = QFontMetricsF(font)
|
|
text_rect = metrics.boundingRect(self.label)
|
|
|
|
text_x = (self.width - text_rect.width()) / 2
|
|
text_y = (self.height - text_rect.height()) / 2
|
|
self.text.setPos(text_x, text_y)
|
|
|
|
def set_scale_factor(self, scale: float):
|
|
scaled_z = scale * Z_INDEX_MULTIPLIER
|
|
self.scale_factor = scaled_z
|
|
self.setZValue(scaled_z)
|
|
self.setScale(scale)
|
|
|
|
def mousePressEvent(self, q_mouse_event):
|
|
self.logger.info("%s was clicked", self.label)
|
|
self.clicked.emit(self.label)
|
|
self.__onclick_color()
|
|
|
|
def __onclick_color(self):
|
|
self.setBrush(self.__click_brush)
|
|
self._reset_timer.start(CLICK_HIGHLIGHT_DURATION_MS)
|
|
|
|
def __reset_color(self):
|
|
self.setBrush(self.__normal_brush)
|