172 lines
6.8 KiB
Markdown
172 lines
6.8 KiB
Markdown
# Sounds Tab Design
|
|
|
|
Date: 2026-04-05
|
|
|
|
## Context
|
|
|
|
Cthulhu currently stores several non-speech sound settings in the general settings file, but the preferences dialog does not present them coherently:
|
|
|
|
- The General tab contains an inline Sound section for backend, theme, and role-sound presentation.
|
|
- The progress-bar beep checkbox lives in the General tab's progress-bar section.
|
|
- `soundVolume` exists in settings and the user's active profile, but there is no UI control for it.
|
|
- `enableSound`, `playSoundForRole`, `playSoundForState`, `playSoundForPositionInSet`, and `playSoundForValue` exist as persisted settings but are not currently exposed in the dialog.
|
|
- `progressBarBeepInterval` exists in runtime defaults but is not part of the normal persisted general-settings key list.
|
|
|
|
The result is that sound-related behavior is split across the dialog and some active settings cannot be inspected or changed from the UI.
|
|
|
|
## Goals
|
|
|
|
- Add a dedicated `Sounds` preferences tab.
|
|
- Move currently exposed sound-related controls out of `General` and into `Sounds`.
|
|
- Move the progress-bar beep option into `Sounds` while leaving the rest of the progress-bar section in `General`.
|
|
- Expose currently hidden sound-related settings in the UI.
|
|
- Add a UI control for `soundVolume`.
|
|
- Expose and persist `progressBarBeepInterval`.
|
|
- Preserve the existing settings model and save format.
|
|
- Avoid clobbering unrelated settings when saving preferences.
|
|
|
|
## Non-Goals
|
|
|
|
- No refactor of the broader preferences architecture.
|
|
- No changes to sound playback implementation outside what is needed to load and save settings correctly.
|
|
- No new settings schema beyond persisting the existing hidden `progressBarBeepInterval`.
|
|
- No dynamic enable/disable logic for sound controls in this pass.
|
|
|
|
## Design Summary
|
|
|
|
Add a new notebook page labeled `Sounds` and make it the single home for non-speech sound configuration. Remove the inline Sound frame from `General`. Keep the existing progress-bar speech/braille controls and shared progress-bar behavior controls in `General`, but move beep-specific controls into `Sounds`.
|
|
|
|
The new tab will use existing settings keys wherever possible and will save through the existing `prefsDict` and settings-manager flow.
|
|
|
|
## Sounds Tab Layout
|
|
|
|
The `Sounds` tab will contain three sections.
|
|
|
|
### Output
|
|
|
|
- `enableSound` checkbox
|
|
- `soundVolume` slider
|
|
- `soundSink` combo box
|
|
|
|
`soundVolume` should be represented by a native `GtkScale` and persisted back to the existing floating-point `soundVolume` setting. The control should initialize from `prefsDict.get("soundVolume", settings.soundVolume)`.
|
|
|
|
For this implementation, the slider should match the stored setting directly rather than introducing a new percentage representation. That keeps the implementation small and avoids conversion-only complexity in a settings path that already exists.
|
|
|
|
### Presentation
|
|
|
|
- `soundTheme` combo box
|
|
- `roleSoundPresentation` combo box
|
|
- `playSoundForRole` checkbox
|
|
- `playSoundForState` checkbox
|
|
- `playSoundForPositionInSet` checkbox
|
|
- `playSoundForValue` checkbox
|
|
|
|
These controls will expose already-existing settings and use the same `prefsDict` update pattern already used by the current dialog.
|
|
|
|
### Alerts
|
|
|
|
- `beepProgressBarUpdates` checkbox
|
|
- `progressBarBeepInterval` spin button
|
|
|
|
This section controls only beep-based progress-bar alerts. The label should make it clear that the interval is beep-specific, not the general progress-bar announcement interval.
|
|
|
|
## General Tab Changes
|
|
|
|
Keep these controls in `General`:
|
|
|
|
- `speakProgressBarUpdates`
|
|
- `brailleProgressBarUpdates`
|
|
- `progressBarUpdateInterval`
|
|
- `progressBarVerbosity`
|
|
- `ignoreStatusBarProgressBars`
|
|
|
|
Remove these from `General`:
|
|
|
|
- the inline Sound frame
|
|
- `beepProgressBarUpdates`
|
|
|
|
This preserves the current organization for general progress-bar announcement behavior while moving sound-only concerns into the new tab.
|
|
|
|
## Settings and Persistence
|
|
|
|
### Existing Keys Reused
|
|
|
|
The new UI will continue to use the existing settings keys:
|
|
|
|
- `enableSound`
|
|
- `soundVolume`
|
|
- `soundSink`
|
|
- `soundTheme`
|
|
- `roleSoundPresentation`
|
|
- `playSoundForRole`
|
|
- `playSoundForState`
|
|
- `playSoundForPositionInSet`
|
|
- `playSoundForValue`
|
|
- `beepProgressBarUpdates`
|
|
|
|
### Persisted Hidden Key
|
|
|
|
Add `progressBarBeepInterval` to the persisted general-settings key list so it round-trips through:
|
|
|
|
- defaults in `settings.py`
|
|
- settings-manager general settings
|
|
- TOML backend save/load
|
|
- `prefsDict` in the preferences dialog
|
|
|
|
This avoids the current mismatch where beep interval exists as a runtime default but is not part of the normal persisted general-settings path.
|
|
|
|
### Save Behavior
|
|
|
|
The implementation should continue to update individual keys in `prefsDict` and then rely on the existing general-settings save flow. No bulk replacement of the whole settings structure should be introduced.
|
|
|
|
This is specifically intended to avoid accidental overwrites of unrelated settings already present in `user-settings.toml`.
|
|
|
|
## Default Values
|
|
|
|
- Keep `progressBarUpdateInterval = 10` as the default for speech and braille progress-bar updates.
|
|
- Keep `progressBarBeepInterval = 0` as the default for beep-based progress-bar updates.
|
|
- Keep `soundVolume = 0.5` as the existing default unless the user explicitly changes it.
|
|
|
|
The new UI should reflect these values accurately on load.
|
|
|
|
## Accessibility
|
|
|
|
Use native GTK controls and follow the existing preferences-dialog patterns:
|
|
|
|
- every label must be associated with its control via `mnemonic_widget`
|
|
- checkboxes should use the existing `checkButtonToggled` convention when possible
|
|
- combo boxes should keep proper `label-for` / `labelled-by` relationships
|
|
- no custom-drawn controls
|
|
- no keyboard traps
|
|
|
|
The new tab should be fully reachable with standard tab navigation.
|
|
|
|
## Implementation Notes
|
|
|
|
Expected files to change:
|
|
|
|
- `src/cthulhu/cthulhu-setup.ui`
|
|
- `src/cthulhu/cthulhu_gui_prefs.py`
|
|
- `src/cthulhu/settings.py`
|
|
|
|
Implementation should:
|
|
|
|
- add the new notebook page and move or recreate the relevant widgets there
|
|
- initialize and save the new sound controls using existing dialog patterns
|
|
- add explicit handling for `soundVolume`
|
|
- add explicit handling for `progressBarBeepInterval`
|
|
- keep all unrelated preference behavior unchanged
|
|
|
|
## Verification
|
|
|
|
The implementation should be considered complete only after all of the following are checked:
|
|
|
|
1. The preferences dialog opens and the new `Sounds` tab is present.
|
|
2. Existing sound settings load into the correct controls.
|
|
3. Changing sound settings updates `prefsDict` without breaking unrelated settings.
|
|
4. Saving preferences preserves unrelated keys in `user-settings.toml`.
|
|
5. `progressBarBeepInterval` is written and reloaded correctly.
|
|
6. The General tab still handles speech/braille progress-bar settings correctly.
|
|
7. Touched Python files pass compile checks.
|
|
8. Manual verification confirms keyboard navigation and label association remain intact.
|