Le test exerce enfin l'annulation de la garde, dans les deux interfaces
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+52
-51
@@ -23,8 +23,8 @@ repère basculé, pour ne pas sortir à l'envers.
|
||||
import threading
|
||||
|
||||
from PySide6.QtCore import QPointF, QRectF, Qt, QTimer
|
||||
from PySide6.QtGui import QColor, QFontMetrics, QPainter, QPainterPath, QPen
|
||||
from PySide6.QtWidgets import QWidget
|
||||
from PySide6.QtGui import QColor, QFontMetrics, QGuiApplication, QPainter, QPainterPath, QPen
|
||||
from PySide6.QtWidgets import QApplication, QWidget
|
||||
|
||||
from audio_level import bar_heights, push_level
|
||||
from core import CONFIG, bar_metrics
|
||||
@@ -184,51 +184,54 @@ class VueOverlay(QWidget):
|
||||
painter.drawPath(tail)
|
||||
|
||||
def paintEvent(self, event):
|
||||
painter = QPainter(self)
|
||||
painter.setRenderHint(QPainter.RenderHint.Antialiasing, True)
|
||||
# `with` ferme le QPainter (.end()) meme si une exception surgit en
|
||||
# cours de dessin : sans ca, la fermeture ne tenait qu'au comptage de
|
||||
# references de PySide6 — suffisant aujourd'hui, fragile demain.
|
||||
with QPainter(self) as painter:
|
||||
painter.setRenderHint(QPainter.RenderHint.Antialiasing, True)
|
||||
|
||||
w = CONFIG["bar_width"]
|
||||
h = CONFIG["bar_height"]
|
||||
x = (self.width() - w) / 2.0
|
||||
y = _BOTTOM_INSET
|
||||
cy = y + h / 2.0
|
||||
w = CONFIG["bar_width"]
|
||||
h = CONFIG["bar_height"]
|
||||
x = (self.width() - w) / 2.0
|
||||
y = _BOTTOM_INSET
|
||||
cy = y + h / 2.0
|
||||
|
||||
m = bar_metrics(h)
|
||||
pad, stop_d, mic_w, ecart = (
|
||||
m["marge_laterale"], m["stop_diametre"], m["mic_largeur"], m["ecart_interne"]
|
||||
)
|
||||
bubble = self._bubble_box(x, y + h, w)
|
||||
|
||||
# Bascule de repère : à partir d'ici, y croît vers le HAUT comme dans
|
||||
# Cocoa (voir docstring du module). On la retire (`restore`) avant de
|
||||
# dessiner le texte de la bulle plus bas, pour qu'il ne sorte pas à
|
||||
# l'envers.
|
||||
painter.save()
|
||||
painter.translate(0, self.height())
|
||||
painter.scale(1, -1)
|
||||
|
||||
self._draw_bar_background(painter, x, y, w, h)
|
||||
self._draw_stop_button(painter, x + pad + stop_d / 2, cy, stop_d)
|
||||
self._draw_mic(painter, x + w - pad - mic_w / 2, cy, m)
|
||||
wave_x = x + pad + stop_d + ecart
|
||||
wave_w = (x + w - pad - mic_w - ecart) - wave_x
|
||||
self._draw_waveform(painter, wave_x, cy, wave_w)
|
||||
if bubble is not None:
|
||||
self._draw_bubble_shape(painter, bubble)
|
||||
|
||||
painter.restore()
|
||||
|
||||
if bubble is not None:
|
||||
# Repère Qt normal (y vers le bas) : on convertit le coin bas-gauche
|
||||
# « repère Cocoa » de la bulle en un rectangle Qt haut-gauche.
|
||||
text_top_qt = self.height() - (bubble["y"] + _BUBBLE_PAD + bubble["th"])
|
||||
painter.setFont(bubble["font"])
|
||||
painter.setPen(_qcolor(CONFIG["bubble_text_rgb"]))
|
||||
painter.drawText(
|
||||
QRectF(bubble["x"] + _BUBBLE_PAD, text_top_qt, bubble["tw"], bubble["th"]),
|
||||
int(Qt.TextFlag.TextWordWrap),
|
||||
self._status,
|
||||
m = bar_metrics(h)
|
||||
pad, stop_d, mic_w, ecart = (
|
||||
m["marge_laterale"], m["stop_diametre"], m["mic_largeur"], m["ecart_interne"]
|
||||
)
|
||||
bubble = self._bubble_box(x, y + h, w)
|
||||
|
||||
# Bascule de repère : à partir d'ici, y croît vers le HAUT comme dans
|
||||
# Cocoa (voir docstring du module). On la retire (`restore`) avant de
|
||||
# dessiner le texte de la bulle plus bas, pour qu'il ne sorte pas à
|
||||
# l'envers.
|
||||
painter.save()
|
||||
painter.translate(0, self.height())
|
||||
painter.scale(1, -1)
|
||||
|
||||
self._draw_bar_background(painter, x, y, w, h)
|
||||
self._draw_stop_button(painter, x + pad + stop_d / 2, cy, stop_d)
|
||||
self._draw_mic(painter, x + w - pad - mic_w / 2, cy, m)
|
||||
wave_x = x + pad + stop_d + ecart
|
||||
wave_w = (x + w - pad - mic_w - ecart) - wave_x
|
||||
self._draw_waveform(painter, wave_x, cy, wave_w)
|
||||
if bubble is not None:
|
||||
self._draw_bubble_shape(painter, bubble)
|
||||
|
||||
painter.restore()
|
||||
|
||||
if bubble is not None:
|
||||
# Repère Qt normal (y vers le bas) : on convertit le coin bas-gauche
|
||||
# « repère Cocoa » de la bulle en un rectangle Qt haut-gauche.
|
||||
text_top_qt = self.height() - (bubble["y"] + _BUBBLE_PAD + bubble["th"])
|
||||
painter.setFont(bubble["font"])
|
||||
painter.setPen(_qcolor(CONFIG["bubble_text_rgb"]))
|
||||
painter.drawText(
|
||||
QRectF(bubble["x"] + _BUBBLE_PAD, text_top_qt, bubble["tw"], bubble["th"]),
|
||||
int(Qt.TextFlag.TextWordWrap),
|
||||
self._status,
|
||||
)
|
||||
|
||||
|
||||
class OverlayQt:
|
||||
@@ -253,13 +256,11 @@ class OverlayQt:
|
||||
def _ensure_view(self):
|
||||
if self._view is not None:
|
||||
return
|
||||
# Import local : PySide6 ne doit être exigé QUE quand cette classe est
|
||||
# réellement instanciée (cf interface/__init__.py::classe_overlay_pour),
|
||||
# jamais au chargement du module — sinon les tests réclameraient Qt sur
|
||||
# toute machine, y compris ce Mac où Cocoa suffit.
|
||||
from PySide6.QtGui import QGuiApplication
|
||||
from PySide6.QtWidgets import QApplication
|
||||
|
||||
# PySide6 est déjà exigé dès l'IMPORT de ce module (QWidget, QTimer...
|
||||
# ci-dessus) : le report réel n'est pas ici, mais dans la fabrique
|
||||
# (interface/__init__.py::classe_overlay_pour), qui n'importe
|
||||
# `interface.qt` que pour la branche win32 — jamais sur ce Mac, où
|
||||
# Cocoa suffit.
|
||||
if QApplication.instance() is None:
|
||||
QApplication([])
|
||||
|
||||
|
||||
Reference in New Issue
Block a user