wfview/include/collapsiblesection.h
Elliott Liggett 6e78cb8830 Make TX/RX audio processing dialogs screen-reader accessible
Both audio processing dialogs were navigable by keyboard but exposed
unlabeled sliders/dials and an unreachable section toggle to VoiceOver
and other screen readers. No visual-layout changes.

- CollapsibleSection: give the disclosure toggle an accessible name
  (section title + expanded/collapsed state, re-announced on toggle)
  and make it StrongFocus, since QToolButton defaults to NoFocus and was
  the only way to reveal a collapsed section's controls.
- TX widget: accessible names on all gate, gain, compressor, EQ band,
  and self-monitor sliders, plus the spectrum display.
- RX widget: accessible names on all Speex/ANR sliders, output gain,
  EQ gain sliders and frequency dials, and the spectrum/noise-profile
  displays.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 11:06:38 -07:00

67 lines
2.1 KiB
C++

#ifndef COLLAPSIBLESECTION_H
#define COLLAPSIBLESECTION_H
// CollapsibleSection — a QGroupBox-like container with a disclosure-triangle toggle.
//
// Header row (always visible):
// [▶/▼ arrow button] [bold title label] [stretch] [optional pinned widget]
//
// Body widget is shown/hidden when the header is clicked.
// The pinned widget (typically an "Enable" checkbox) remains visible in the header
// regardless of the collapsed/expanded state.
//
// Usage:
// auto* sec = new CollapsibleSection("My Section", enableCheckbox);
// auto* body = new QWidget;
// auto* form = new QFormLayout(body);
// form->addRow(...);
// sec->setBodyWidget(body);
// layout->addWidget(sec);
#include <QFrame>
#include <QLabel>
#include <QToolButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
class CollapsibleSection : public QFrame
{
Q_OBJECT
public:
// pinnedWidget (optional) is placed in the header and is always visible.
// Typically this is the "Enable" checkbox for the section.
explicit CollapsibleSection(const QString& title,
QWidget* pinnedWidget = nullptr,
QWidget* parent = nullptr);
// Set the body widget (must be called once, before showing).
// The widget will be shown/hidden on toggle.
void setBodyWidget(QWidget* body);
bool isExpanded() const { return m_expanded; }
void setExpanded(bool expanded);
// Disable/enable the body content while keeping the collapse toggle functional.
void setContentEnabled(bool enabled);
signals:
void expandedChanged(bool expanded);
private slots:
void onHeaderClicked();
private:
void applyState();
// Keep the toggle's accessible name in sync with the title and the
// expanded/collapsed state so screen readers announce both.
void updateToggleAccessibility();
QString m_title;
QToolButton* m_toggle {nullptr};
QWidget* m_pinnedWidget {nullptr};
QWidget* m_body {nullptr};
bool m_expanded {true};
};
#endif // COLLAPSIBLESECTION_H