Source code for simvx.editor.preferences
"""Editor preferences and theme system.
Persistent settings via the unified ``AppConfig`` system
(``~/.config/simvx/config.json``). ``EditorPreferences`` delegates to
``AppConfig.general`` and ``AppConfig.editor`` sections while keeping
full backward-compatible field access.
"""
from __future__ import annotations
from simvx.core.config import AppConfig
from simvx.core.ui.theme import AppTheme, set_theme
# Lookup for preset names -> factory class methods.
_THEME_PRESETS = {
"dark": AppTheme.dark,
"light": AppTheme.light,
"monokai": AppTheme.monokai,
}
# Backward-compat alias -- old code may import EditorTheme from here.
EditorTheme = AppTheme
# ---------------------------------------------------------------------------
# EditorPreferences -- thin wrapper around AppConfig
# ---------------------------------------------------------------------------
[docs]
class EditorPreferences:
"""Persistent editor settings delegating to the unified ``AppConfig``.
All field access (``prefs.font_size``, ``prefs.show_grid``, etc.) is
fully backward-compatible with the previous ``@dataclass`` version.
"""
def __init__(self) -> None:
self._config = AppConfig()
# -- General section properties ------------------------------------------
@property
def theme_name(self) -> str:
return self._config.general.theme_preset
@theme_name.setter
def theme_name(self, value: str) -> None:
self._config.general.theme_preset = value
@property
def font_size(self) -> float:
return self._config.general.font_size
@font_size.setter
def font_size(self, value: float) -> None:
self._config.general.font_size = value
@property
def window_width(self) -> int:
return self._config.general.window_width
@window_width.setter
def window_width(self, value: int) -> None:
self._config.general.window_width = value
@property
def window_height(self) -> int:
return self._config.general.window_height
@window_height.setter
def window_height(self, value: int) -> None:
self._config.general.window_height = value
@property
def recent_files(self) -> list[str]:
return self._config.general.recent_files
@recent_files.setter
def recent_files(self, value: list[str]) -> None:
self._config.general.recent_files = value
@property
def custom_shortcuts(self) -> dict[str, str]:
return self._config.general.custom_shortcuts
@custom_shortcuts.setter
def custom_shortcuts(self, value: dict[str, str]) -> None:
self._config.general.custom_shortcuts = value
# -- Editor section properties -------------------------------------------
@property
def dock_layout(self) -> dict:
return self._config.editor.dock_layout
@dock_layout.setter
def dock_layout(self, value: dict) -> None:
self._config.editor.dock_layout = value
@property
def show_grid(self) -> bool:
return self._config.editor.show_grid
@show_grid.setter
def show_grid(self, value: bool) -> None:
self._config.editor.show_grid = value
@property
def grid_size(self) -> float:
return self._config.editor.grid_size
@grid_size.setter
def grid_size(self, value: float) -> None:
self._config.editor.grid_size = value
@property
def grid_subdivisions(self) -> int:
return self._config.editor.grid_subdivisions
@grid_subdivisions.setter
def grid_subdivisions(self, value: int) -> None:
self._config.editor.grid_subdivisions = value
@property
def snap_enabled(self) -> bool:
return self._config.editor.snap_enabled
@snap_enabled.setter
def snap_enabled(self, value: bool) -> None:
self._config.editor.snap_enabled = value
@property
def snap_size(self) -> float:
return self._config.editor.snap_size
@snap_size.setter
def snap_size(self, value: float) -> None:
self._config.editor.snap_size = value
@property
def auto_save_interval(self) -> int:
return self._config.editor.auto_save_interval
@auto_save_interval.setter
def auto_save_interval(self, value: int) -> None:
self._config.editor.auto_save_interval = value
# -- Persistence ---------------------------------------------------------
[docs]
def load(self) -> None:
"""Load preferences from disk via the unified config."""
self._config.load()
[docs]
def save(self) -> None:
"""Write current preferences to disk via the unified config."""
self._config.save()
[docs]
def get_theme(self) -> AppTheme:
"""Return an AppTheme instance matching *theme_name* and update the singleton."""
factory = _THEME_PRESETS.get(self.theme_name, AppTheme.dark)
theme = factory()
theme.font_size = self.font_size
theme._sync_dicts()
set_theme(theme)
return theme
[docs]
def reset_to_defaults(self) -> None:
"""Reset every field to its default value."""
self._config = AppConfig()