WCAG: Overlay - border, keyboard, accessibility, reduced motion

This commit is contained in:
Your Name
2026-02-18 21:06:43 +02:00
parent 07ad3b220d
commit d8707b5ade

View File

@@ -13,6 +13,8 @@ ApplicationWindow {
visible: true visible: true
flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool flags: Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool
color: "transparent" color: "transparent"
title: "WhisperVoice"
Accessible.name: "WhisperVoice Overlay"
FontLoader { FontLoader {
id: jetBrainsMono id: jetBrainsMono
@@ -35,7 +37,7 @@ ApplicationWindow {
property bool isActive: ui.isRecording || ui.isProcessing property bool isActive: ui.isRecording || ui.isProcessing
SequentialAnimation { SequentialAnimation {
running: true running: !ui.reduceMotion
loops: Animation.Infinite loops: Animation.Infinite
PauseAnimation { duration: 3000 } PauseAnimation { duration: 3000 }
NumberAnimation { NumberAnimation {
@@ -96,6 +98,7 @@ ApplicationWindow {
ShaderEffect { ShaderEffect {
anchors.fill: parent anchors.fill: parent
opacity: 0.4 opacity: 0.4
visible: !ui.reduceMotion
property real time: 0 property real time: 0
fragmentShader: "gradient_blobs.qsb" fragmentShader: "gradient_blobs.qsb"
NumberAnimation on time { from: 0; to: 1000; duration: 100000; loops: Animation.Infinite } NumberAnimation on time { from: 0; to: 1000; duration: 100000; loops: Animation.Infinite }
@@ -105,6 +108,7 @@ ApplicationWindow {
ShaderEffect { ShaderEffect {
anchors.fill: parent anchors.fill: parent
opacity: 0.04 opacity: 0.04
visible: !ui.reduceMotion
property real time: 0 property real time: 0
property real intensity: ui.amplitude property real intensity: ui.amplitude
fragmentShader: "glow.qsb" fragmentShader: "glow.qsb"
@@ -115,6 +119,7 @@ ApplicationWindow {
ParticleSystem { ParticleSystem {
id: particles id: particles
anchors.fill: parent anchors.fill: parent
running: !ui.reduceMotion
ItemParticle { ItemParticle {
system: particles system: particles
delegate: Rectangle { width: 2; height: 2; radius: 1; color: "#10ffffff" } delegate: Rectangle { width: 2; height: 2; radius: 1; color: "#10ffffff" }
@@ -143,6 +148,7 @@ ApplicationWindow {
// F. CRT Shader Effect (Overlay on chassis ONLY) // F. CRT Shader Effect (Overlay on chassis ONLY)
ShaderEffect { ShaderEffect {
anchors.fill: parent anchors.fill: parent
visible: !ui.reduceMotion
property real time: 0 property real time: 0
fragmentShader: "crt.qsb" fragmentShader: "crt.qsb"
NumberAnimation on time { from: 0; to: 100; duration: 5000; loops: Animation.Infinite } NumberAnimation on time { from: 0; to: 100; duration: 5000; loops: Animation.Infinite }
@@ -172,7 +178,7 @@ ApplicationWindow {
radius: height / 2 radius: height / 2
color: "transparent" color: "transparent"
border.width: 1 border.width: 1
border.color: "#40ffffff" border.color: Qt.rgba(1, 1, 1, 0.22)
MouseArea { MouseArea {
anchors.fill: parent; hoverEnabled: true anchors.fill: parent; hoverEnabled: true
@@ -194,7 +200,7 @@ ApplicationWindow {
NumberAnimation { duration: 150; easing.type: Easing.OutCubic } NumberAnimation { duration: 150; easing.type: Easing.OutCubic }
} }
SequentialAnimation on border.color { SequentialAnimation on border.color {
running: ui.isRecording running: ui.isRecording && !ui.reduceMotion
loops: Animation.Infinite loops: Animation.Infinite
ColorAnimation { from: "#A0ff4b4b"; to: "#C0ff6b6b"; duration: 800 } ColorAnimation { from: "#A0ff4b4b"; to: "#C0ff6b6b"; duration: 800 }
ColorAnimation { from: "#C0ff6b6b"; to: "#A0ff4b4b"; duration: 800 } ColorAnimation { from: "#C0ff6b6b"; to: "#A0ff4b4b"; duration: 800 }
@@ -209,7 +215,12 @@ ApplicationWindow {
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: 10 anchors.leftMargin: 10
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
activeFocusOnTab: true
Accessible.name: ui.isRecording ? "Stop recording" : "Start recording"
Accessible.role: Accessible.Button
Keys.onReturnPressed: ui.toggleRecordingRequested()
Keys.onSpacePressed: ui.toggleRecordingRequested()
// Make entire button scale with amplitude // Make entire button scale with amplitude
scale: ui.isRecording ? (1.0 + ui.amplitude * 0.12) : 1.0 scale: ui.isRecording ? (1.0 + ui.amplitude * 0.12) : 1.0
Behavior on scale { Behavior on scale {
@@ -245,7 +256,7 @@ ApplicationWindow {
border.width: 2; border.color: "#60ffffff" border.width: 2; border.color: "#60ffffff"
SequentialAnimation on scale { SequentialAnimation on scale {
running: ui.isRecording running: ui.isRecording && !ui.reduceMotion
loops: Animation.Infinite loops: Animation.Infinite
NumberAnimation { from: 1.0; to: 1.08; duration: 600; easing.type: Easing.InOutQuad } NumberAnimation { from: 1.0; to: 1.08; duration: 600; easing.type: Easing.InOutQuad }
NumberAnimation { from: 1.08; to: 1.0; duration: 600; easing.type: Easing.InOutQuad } NumberAnimation { from: 1.08; to: 1.0; duration: 600; easing.type: Easing.InOutQuad }
@@ -263,6 +274,17 @@ ApplicationWindow {
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
} }
} }
// Focus ring
Rectangle {
anchors.fill: micCircle
anchors.margins: -4
radius: width / 2
color: "transparent"
border.width: 2
border.color: "#B794F6"
visible: micContainer.activeFocus
}
} }
// --- RAINBOW WAVEFORM (Shader) --- // --- RAINBOW WAVEFORM (Shader) ---
@@ -277,6 +299,7 @@ ApplicationWindow {
ShaderEffect { ShaderEffect {
anchors.fill: parent anchors.fill: parent
visible: !ui.reduceMotion
property real time: 0 property real time: 0
property real amplitude: ui.amplitude property real amplitude: ui.amplitude
fragmentShader: "rainbow_wave.qsb" fragmentShader: "rainbow_wave.qsb"
@@ -341,8 +364,10 @@ ApplicationWindow {
font.family: jetBrainsMono.name; font.pixelSize: 16; font.bold: true; font.letterSpacing: 2 font.family: jetBrainsMono.name; font.pixelSize: 16; font.bold: true; font.letterSpacing: 2
style: Text.Outline style: Text.Outline
styleColor: ui.isRecording ? "#ff0000" : "#808085" styleColor: ui.isRecording ? "#ff0000" : "#808085"
Accessible.role: Accessible.StaticText
Accessible.name: "Recording time: " + text
SequentialAnimation on opacity { SequentialAnimation on opacity {
running: ui.isRecording; loops: Animation.Infinite running: ui.isRecording && !ui.reduceMotion; loops: Animation.Infinite
NumberAnimation { from: 1.0; to: 0.7; duration: 800 } NumberAnimation { from: 1.0; to: 0.7; duration: 800 }
NumberAnimation { from: 0.7; to: 1.0; duration: 800 } NumberAnimation { from: 0.7; to: 1.0; duration: 800 }
} }