Fix settings dialog for smaller screens with scroll area

The settings dialog was using a fixed 1200px height which exceeded
the available space on 1920x1080 displays, causing settings to be
cut off. Added scroll area and dynamic sizing based on screen size.

Changes:
- Added QScrollArea to wrap all settings content
- Dialog height now calculated as 80% of screen height (max 900px)
- Minimum size reduced to 700x500 for smaller screens
- Save/Cancel buttons remain fixed at bottom (outside scroll area)
- Horizontal scrollbar disabled, vertical scrollbar shown when needed

Benefits:
- Works on any screen size (1080p, 1440p, 4K, etc.)
- All settings always accessible via scrolling
- Buttons always visible at bottom
- More professional UX

Resolves: Settings dialog running off screen on 1920x1080

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2025-12-28 19:19:20 -08:00
parent d34d272cf0
commit aad7ab0713

View File

@@ -3,9 +3,10 @@
from PySide6.QtWidgets import (
QDialog, QVBoxLayout, QHBoxLayout, QFormLayout,
QLabel, QLineEdit, QComboBox, QCheckBox, QSlider,
QPushButton, QMessageBox, QGroupBox
QPushButton, QMessageBox, QGroupBox, QScrollArea, QWidget
)
from PySide6.QtCore import Qt
from PySide6.QtGui import QScreen
from typing import Callable, List, Tuple
@@ -39,20 +40,42 @@ class SettingsDialog(QDialog):
# Window configuration
self.setWindowTitle("Settings")
self.setMinimumSize(700, 1200)
self.resize(700, 1200) # Set initial size
self.setModal(True)
# Calculate size based on screen size (80% of screen height, max 900px)
screen = QScreen.availableGeometry(parent.screen() if parent else None)
max_height = min(int(screen.height() * 0.8), 900)
self.setMinimumSize(700, 500)
self.resize(700, max_height)
self._create_widgets()
self._load_current_settings()
def _create_widgets(self):
"""Create all settings widgets."""
# Main layout for the dialog (contains scroll area + buttons)
main_layout = QVBoxLayout()
main_layout.setSpacing(15) # Add spacing between groups
main_layout.setContentsMargins(20, 20, 20, 20) # Add padding around dialog
main_layout.setContentsMargins(0, 0, 0, 0)
main_layout.setSpacing(0)
self.setLayout(main_layout)
# Create scroll area for settings content
scroll_area = QScrollArea()
scroll_area.setWidgetResizable(True)
scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
# Create content widget for scroll area
content_widget = QWidget()
content_layout = QVBoxLayout()
content_layout.setSpacing(15) # Add spacing between groups
content_layout.setContentsMargins(20, 20, 20, 20) # Add padding
content_widget.setLayout(content_layout)
scroll_area.setWidget(content_widget)
# Add scroll area to main layout
main_layout.addWidget(scroll_area)
# User Settings Group
user_group = QGroupBox("User Settings")
user_layout = QFormLayout()
@@ -63,7 +86,7 @@ class SettingsDialog(QDialog):
user_layout.addRow("Display Name:", self.name_input)
user_group.setLayout(user_layout)
main_layout.addWidget(user_group)
content_layout.addWidget(user_group)
# Audio Settings Group
audio_group = QGroupBox("Audio Settings")
@@ -77,7 +100,7 @@ class SettingsDialog(QDialog):
audio_layout.addRow("Input Device:", self.audio_device_combo)
audio_group.setLayout(audio_layout)
main_layout.addWidget(audio_group)
content_layout.addWidget(audio_group)
# Transcription Settings Group
transcription_group = QGroupBox("Transcription Settings")
@@ -137,7 +160,7 @@ class SettingsDialog(QDialog):
transcription_layout.addRow("Beam Size:", self.beam_size_combo)
transcription_group.setLayout(transcription_layout)
main_layout.addWidget(transcription_group)
content_layout.addWidget(transcription_group)
# Realtime Preview Group
realtime_group = QGroupBox("Realtime Preview (Optional)")
@@ -157,7 +180,7 @@ class SettingsDialog(QDialog):
realtime_layout.addRow("Preview Model:", self.realtime_model_combo)
realtime_group.setLayout(realtime_layout)
main_layout.addWidget(realtime_group)
content_layout.addWidget(realtime_group)
# VAD (Voice Activity Detection) Group
vad_group = QGroupBox("Voice Activity Detection")
@@ -205,7 +228,7 @@ class SettingsDialog(QDialog):
vad_layout.addRow("ONNX Acceleration:", self.silero_onnx_check)
vad_group.setLayout(vad_layout)
main_layout.addWidget(vad_group)
content_layout.addWidget(vad_group)
# Advanced Timing Group
timing_group = QGroupBox("Advanced Timing Settings")
@@ -239,7 +262,7 @@ class SettingsDialog(QDialog):
timing_layout.addRow("Pre-Recording Buffer (s):", self.pre_buffer_input)
timing_group.setLayout(timing_layout)
main_layout.addWidget(timing_group)
content_layout.addWidget(timing_group)
# Display Settings Group
display_group = QGroupBox("Display Settings")
@@ -276,7 +299,7 @@ class SettingsDialog(QDialog):
display_layout.addRow("Fade After (seconds):", self.fade_seconds_input)
display_group.setLayout(display_layout)
main_layout.addWidget(display_group)
content_layout.addWidget(display_group)
# Server Sync Group
server_group = QGroupBox("Multi-User Server Sync (Optional)")
@@ -317,10 +340,15 @@ class SettingsDialog(QDialog):
server_layout.addRow("Passphrase:", self.server_passphrase_input)
server_group.setLayout(server_layout)
main_layout.addWidget(server_group)
content_layout.addWidget(server_group)
# Buttons
# Add stretch to push everything to the top
content_layout.addStretch()
# Buttons (outside scroll area, always visible at bottom)
button_container = QWidget()
button_layout = QHBoxLayout()
button_layout.setContentsMargins(20, 10, 20, 10)
button_layout.addStretch()
self.cancel_button = QPushButton("Cancel")
@@ -332,7 +360,8 @@ class SettingsDialog(QDialog):
self.save_button.setDefault(True)
button_layout.addWidget(self.save_button)
main_layout.addLayout(button_layout)
button_container.setLayout(button_layout)
main_layout.addWidget(button_container)
def _update_silero_label(self, value):
"""Update the Silero sensitivity label."""