rust_widgets 2.8.4

Pure Rust cross-platform native GUI library with hardware-adaptive rendering, 180 widgets, touch/gesture support, i18n, and SVG-pipeline-accurate output
// SPDX-FileCopyrightText: Copyright (c) 2026 Mike Li/Mikewolfli/Wei Li(mikewolfli@163.com)
// SPDX-License-Identifier: MIT

use super::{ConfigLoadError, ConfigPersistence, MenuConfig, PerformanceLevel};
use std::io;
/// Menu configuration dialog for user preferences.
pub struct MenuConfigDialog {
    config: MenuConfig,
    persistence: ConfigPersistence,
}
impl MenuConfigDialog {
    /// Creates a new configuration dialog.
    pub fn new(config: MenuConfig) -> Self {
        Self { config, persistence: ConfigPersistence::new() }
    }
    /// Creates a dialog with custom persistence.
    pub fn with_persistence(config: MenuConfig, persistence: ConfigPersistence) -> Self {
        Self { config, persistence }
    }
    /// Gets the current configuration.
    pub fn config(&self) -> &MenuConfig {
        &self.config
    }
    /// Gets mutable configuration.
    pub fn config_mut(&mut self) -> &mut MenuConfig {
        &mut self.config
    }
    /// Toggles animations on/off.
    pub fn toggle_animations(&mut self) {
        let new_value = !self.config.animations_enabled();
        self.config.set_animations_enabled(new_value);
    }
    /// Toggles transparency on/off.
    pub fn toggle_transparency(&mut self) {
        let new_value = !self.config.transparency_enabled();
        self.config.set_transparency_enabled(new_value);
    }
    /// Toggles shadows on/off.
    pub fn toggle_shadows(&mut self) {
        let new_value = !self.config.shadows_enabled();
        self.config.set_shadows_enabled(new_value);
    }
    /// Toggles blur on/off.
    pub fn toggle_blur(&mut self) {
        let new_value = !self.config.blur_enabled();
        self.config.set_blur_enabled(new_value);
    }
    /// Increases animation speed.
    pub fn increase_animation_speed(&mut self) {
        let current = self.config.animation_speed();
        let new_speed = (current + 0.1).min(3.0);
        self.config.set_animation_speed(new_speed);
    }
    /// Decreases animation speed.
    pub fn decrease_animation_speed(&mut self) {
        let current = self.config.animation_speed();
        let new_speed = (current - 0.1).max(0.1);
        self.config.set_animation_speed(new_speed);
    }
    /// Increases max visible items, saturating at the type's maximum rather than
    /// wrapping back to a small value.
    pub fn increase_max_items(&mut self) {
        let current = self.config.max_visible_items();
        self.config.set_max_visible_items(current.saturating_add(5));
    }
    /// Decreases max visible items.
    pub fn decrease_max_items(&mut self) {
        let current = self.config.max_visible_items();
        if current > 5 {
            self.config.set_max_visible_items(current - 5);
        }
    }
    /// Resets all settings to hardware defaults.
    pub fn reset_to_defaults(&mut self) {
        self.config.reset_to_defaults();
    }
    /// Saves the current configuration.
    pub fn save(&self) -> io::Result<()> {
        self.persistence.save(&self.config)
    }
    /// Loads configuration from disk, restoring the hardware baseline first so a
    /// field removed from the file falls back to its default rather than keeping a
    /// stale reversed preference.
    ///
    /// A rejected load leaves `self.config` untouched, so a parse failure cannot
    /// corrupt the previous configuration.
    pub fn load(&mut self) -> Result<(), ConfigLoadError> {
        let overrides = self.persistence.load()?;
        self.config.reload_overrides(overrides);
        Ok(())
    }
    /// Returns a summary of current settings for display.
    pub fn settings_summary(&self) -> String {
        self.config.settings_summary()
    }
    /// Returns true if any settings have been overridden.
    pub fn has_overrides(&self) -> bool {
        self.config.has_user_overrides()
    }
    /// Returns the hardware-detected performance level.
    pub fn hardware_performance_level(&self) -> PerformanceLevel {
        self.config.hardware_caps().performance_level
    }
    /// Returns a description of the detected GPU.
    ///
    /// The memory figure is only printed when it was actually measured. This crate
    /// cannot query VRAM portably (wgpu exposes no size, the platform backends report
    /// system RAM), so on most hosts the honest description is the GPU type alone —
    /// the previous wording printed a defaulted `512` MB as if it had been detected.
    pub fn gpu_description(&self) -> String {
        let caps = self.config.hardware_caps();
        match (caps.gpu_memory_mb, caps.gpu_memory_is_measured) {
            (Some(mb), true) => format!("{} ({mb} MB)", caps.gpu_type.description()),
            _ => format!("{} (memory not reportable)", caps.gpu_type.description()),
        }
    }

    /// Returns a description of the detected system memory.
    ///
    /// The same rule [`Self::gpu_description`] follows: a figure is printed only when a
    /// backend actually measured it. When nothing could report physical memory the
    /// description says so, and names the conservative assumption the *scoring* model
    /// uses instead — clearly labelled as an assumption, so it cannot be read as a probe
    /// result.
    pub fn system_memory_description(&self) -> String {
        match self.config.hardware_caps().system_ram_mb {
            Some(mb) => format!("{mb} MB"),
            None => format!(
                "not reportable on this backend (scoring assumes {} MB)",
                MenuConfig::assumed_system_memory()
            ),
        }
    }
}