Source code for zooui.windows.dialogwindows.zoomsettingsdialog

## ZooUI - Zooming User Interface
## Copyright (C) 2009 David Roberts <d@vidr.cc>
##
## This program is free software; you can redistribute it and/or
## modify it under the terms of the GNU General Public License
## as published by the Free Software Foundation; either version 3
## of the License, or (at your option) any later version.
##
## This program is distributed in the hope that it will be useful,
## but WITHOUT ANY WARRANTY; without even the implied warranty of
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
## GNU General Public License for more details.
##
## You should have received a copy of the GNU General Public License
## along with this program; if not, see <https://www.gnu.org/licenses/>.

"""
Zoom Settings Dialog

Provides a dialog for configuring zoom limits including minimum and maximum
zoom levels with clamping to prevent crashes at extreme zoom values.
"""

from typing import Any

from PySide6 import QtWidgets


[docs] class ZoomSettingsDialog(QtWidgets.QDialog): """ Constructor : ZoomSettingsDialog(parent=None, initial_config=None) Parameters : parent : Optional[QtWidgets.QWidget] Parent widget initial_config : Optional[Dict[str, Any]] Initial zoom configuration ZoomSettingsDialog(parent=None, initial_config=None) --> None """ def __init__(self, parent: QtWidgets.QWidget | None = None, initial_config: dict[str, Any] | None = None) -> None: super().__init__(parent) self.setWindowTitle("Zoom Settings") self.setModal(True) self.resize(600, 500) self._config = initial_config or {} self._setup_ui() self._load_initial_config()
[docs] def _setup_ui(self) -> None: """Setup the dialog UI components.""" layout = QtWidgets.QVBoxLayout(self) # Zoom limits group limits_group = QtWidgets.QGroupBox("Zoom Limits") limits_layout = QtWidgets.QVBoxLayout() # Minimum zoom level min_hbox = QtWidgets.QHBoxLayout() min_hbox.addWidget(QtWidgets.QLabel("Minimum zoom level:")) self.min_spinbox = QtWidgets.QDoubleSpinBox() self.min_spinbox.setRange(-50.0, 0.0) self.min_spinbox.setDecimals(1) self.min_spinbox.setSingleStep(1.0) self.min_spinbox.setValue(-12.0) min_hbox.addWidget(self.min_spinbox) min_hbox.addStretch() limits_layout.addLayout(min_hbox) # Maximum zoom level max_hbox = QtWidgets.QHBoxLayout() max_hbox.addWidget(QtWidgets.QLabel("Maximum zoom level:")) self.max_spinbox = QtWidgets.QDoubleSpinBox() self.max_spinbox.setRange(0.0, 50.0) self.max_spinbox.setDecimals(1) self.max_spinbox.setSingleStep(1.0) self.max_spinbox.setValue(10.0) max_hbox.addWidget(self.max_spinbox) max_hbox.addStretch() limits_layout.addLayout(max_hbox) # Clamp enabled checkbox self.clamp_checkbox = QtWidgets.QCheckBox("Clamp zoom to limits (recommended)") self.clamp_checkbox.setChecked(True) limits_layout.addWidget(self.clamp_checkbox) limits_group.setLayout(limits_layout) layout.addWidget(limits_group) # Default zoom level section default_group = QtWidgets.QGroupBox("Default Zoom for New Scenes") default_layout = QtWidgets.QVBoxLayout() default_hbox = QtWidgets.QHBoxLayout() default_hbox.addWidget(QtWidgets.QLabel("Default zoom level:")) self.default_spinbox = QtWidgets.QDoubleSpinBox() self.default_spinbox.setRange(-50.0, 50.0) self.default_spinbox.setDecimals(1) self.default_spinbox.setSingleStep(1.0) self.default_spinbox.setValue(-4.0) default_hbox.addWidget(self.default_spinbox) # Performance note label note_label = QtWidgets.QLabel("(Negative values improve performance)") note_label.setStyleSheet("color: #666666; font-style: italic;") default_hbox.addWidget(note_label) default_hbox.addStretch() default_layout.addLayout(default_hbox) default_group.setLayout(default_layout) layout.addWidget(default_group) # Info/explanation text in read-only QTextEdit (theme-consistent) info_text = ( "Zoom Limits: Prevent crashes when zoomed too far out or too far in\n\n" "Default range: -12 to +10 (safe for StringMediaObjects)\n" " • -12: 0.00024x scale (0.024%)\n" " • -4: 0.0625x scale (6.25%) - Default for new scenes\n" " • +10: 1024x scale\n\n" "Default Zoom: Sets initial zoom level for new scenes\n" " • Negative values improve performance (less computation)\n" " • Applies only to new scenes, not loaded ones\n\n" "Why these limits?\n" "• Below -12: StringMediaObject fonts become too small (<0.5 point)\n" "• Below -20: Fonts become invisible (<0.1 point)\n" "• Below -30: Position calculations overflow\n" "• Above +10: UI elements become unusably large\n\n" "Values are clamped automatically when limits are reached.\n" "If min > max, they will be automatically swapped." ) # Create QTextEdit widget for theme-consistent info display info_edit = QtWidgets.QTextEdit() info_edit.setReadOnly(True) # Make it non-editable info_edit.setPlainText(info_text) info_edit.setFrameShape(QtWidgets.QFrame.Shape.NoFrame) # Remove border info_edit.setMinimumHeight(150) # Minimum height for readability info_edit.setMaximumHeight(250) # Maximum height to prevent taking too much space layout.addWidget(info_edit) # Button box button_box = QtWidgets.QDialogButtonBox( QtWidgets.QDialogButtonBox.StandardButton.Ok | QtWidgets.QDialogButtonBox.StandardButton.Cancel ) button_box.accepted.connect(self.accept) button_box.rejected.connect(self.reject) layout.addWidget(button_box)
[docs] def _load_initial_config(self) -> None: """Load initial configuration into UI.""" min_zoom = self._config.get("min_zoomlevel", -12.0) max_zoom = self._config.get("max_zoomlevel", 10.0) default_zoom = self._config.get("default_zoomlevel", -4.0) clamp_enabled = self._config.get("clamp_enabled", True) self.min_spinbox.setValue(min_zoom) self.max_spinbox.setValue(max_zoom) self.default_spinbox.setValue(default_zoom) self.clamp_checkbox.setChecked(clamp_enabled)
[docs] def get_config(self) -> dict[str, Any]: """ Method : get_config() Get the current configuration from the dialog. Returns : Dict[str, Any] Zoom configuration dictionary get_config() --> Dict[str, Any] """ min_zoom = self.min_spinbox.value() max_zoom = self.max_spinbox.value() default_zoom = self.default_spinbox.value() clamp_enabled = self.clamp_checkbox.isChecked() # Ensure min <= max (auto-swap if needed) if min_zoom > max_zoom: min_zoom, max_zoom = max_zoom, min_zoom # Ensure default stays within bounds if default_zoom < min_zoom: default_zoom = min_zoom elif default_zoom > max_zoom: default_zoom = max_zoom return { "min_zoomlevel": min_zoom, "max_zoomlevel": max_zoom, "default_zoomlevel": default_zoom, "clamp_enabled": clamp_enabled, }
[docs] @staticmethod def get_zoom_settings( parent: QtWidgets.QWidget | None = None, initial_config: dict[str, Any] | None = None ) -> dict[str, Any] | None: """ Method : get_zoom_settings(parent=None, initial_config=None) Static method to show dialog and get zoom settings. Parameters : parent : Optional[QtWidgets.QWidget] Parent widget initial_config : Optional[Dict[str, Any]] Initial zoom configuration Returns : Optional[Dict[str, Any]] Zoom configuration if accepted, None if cancelled get_zoom_settings(parent=None, initial_config=None) --> Optional[Dict[str, Any]] """ dialog = ZoomSettingsDialog(parent, initial_config) if dialog.exec() == QtWidgets.QDialog.DialogCode.Accepted: return dialog.get_config() return None