use crate::consts::{UI_SCALE_DEFAULT, VIEWPORT_ZOOM_WHEEL_RATE}; use crate::messages::input_mapper::key_mapping::MappingVariant; use crate::messages::portfolio::document::utility_types::wires::GraphWireStyle; use crate::messages::preferences::SelectionMode; use crate::messages::prelude::*; use crate::messages::tool::utility_types::ToolType; use graph_craft::application_io::EditorPreferences; #[derive(ExtractField)] pub struct PreferencesMessageContext<'a> { pub tool_message_handler: &'a ToolMessageHandler, } #[cfg_attr(feature = "wasm", derive(tsify::Tsify))] #[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, ExtractField)] #[serde(default)] pub struct PreferencesMessageHandler { pub selection_mode: SelectionMode, pub zoom_with_scroll: bool, pub brush_tool: bool, pub graph_wire_style: GraphWireStyle, pub viewport_zoom_wheel_rate: f64, pub ui_scale: f64, pub max_render_region_size: u32, pub disable_ui_acceleration: bool, pub validate_storage_round_trip: bool, pub save_as_gdd: bool, pub show_storage_preferences: bool, #[cfg(target_os = "macos")] pub vsync: bool, } impl PreferencesMessageHandler { pub fn preferences_requiring_restart(&self, other: &Self) -> Vec { let mut requiring_restart = Vec::new(); if self.disable_ui_acceleration != other.disable_ui_acceleration { requiring_restart.push("Disable UI Acceleration"); } #[cfg(target_os = "macos")] if self.vsync != other.vsync { requiring_restart.push("Enable V-Sync"); } requiring_restart.into_iter().map(String::from).collect() } pub fn get_selection_mode(&self) -> SelectionMode { self.selection_mode } pub fn editor_preferences(&self) -> EditorPreferences { EditorPreferences { max_render_region_size: self.max_render_region_size, } } pub fn supports_wgpu(&self) -> bool { graph_craft::application_io::wgpu_available().unwrap_or_default() } } impl Default for PreferencesMessageHandler { fn default() -> Self { Self { selection_mode: SelectionMode::Touched, zoom_with_scroll: matches!(MappingVariant::default(), MappingVariant::ZoomWithScroll), brush_tool: false, graph_wire_style: GraphWireStyle::default(), viewport_zoom_wheel_rate: VIEWPORT_ZOOM_WHEEL_RATE, ui_scale: UI_SCALE_DEFAULT, max_render_region_size: EditorPreferences::default().max_render_region_size, disable_ui_acceleration: cfg!(target_os = "linux"), // TODO: Set this back to false once we have ui acceleration working more reliably on linux validate_storage_round_trip: false, save_as_gdd: false, show_storage_preferences: false, #[cfg(target_os = "macos")] vsync: false, } } } #[message_handler_data] impl MessageHandler> for PreferencesMessageHandler { fn process_message(&mut self, message: PreferencesMessage, responses: &mut VecDeque, context: PreferencesMessageContext) { let PreferencesMessageContext { tool_message_handler } = context; match message { // Management messages PreferencesMessage::Load { preferences } => { *self = preferences; responses.add(PortfolioMessage::EditorPreferences); responses.add(PreferencesMessage::ModifyLayout { zoom_with_scroll: self.zoom_with_scroll, }); responses.add(FrontendMessage::UpdateUIScale { scale: self.ui_scale }); responses.add(ToolMessage::RefreshToolShelf); } PreferencesMessage::ResetToDefaults => { responses.add(PreferencesMessage::Load { preferences: Self::default() }); responses.add(DialogMessage::RequestPreferencesDialog); } // Per-preference messages PreferencesMessage::BrushTool { enabled } => { self.brush_tool = enabled; if !enabled && tool_message_handler.tool_state.tool_data.active_tool_type == ToolType::Brush { responses.add(ToolMessage::ActivateToolSelect); } responses.add(ToolMessage::RefreshToolShelf); } PreferencesMessage::ModifyLayout { zoom_with_scroll } => { self.zoom_with_scroll = zoom_with_scroll; let variant = if zoom_with_scroll { MappingVariant::ZoomWithScroll } else { MappingVariant::Default }; responses.add(KeyMappingMessage::ModifyMapping { mapping: variant }); } PreferencesMessage::SelectionMode { selection_mode } => { self.selection_mode = selection_mode; } PreferencesMessage::GraphWireStyle { style } => { self.graph_wire_style = style; responses.add(NodeGraphMessage::UnloadWires); responses.add(NodeGraphMessage::SendWires); } PreferencesMessage::ViewportZoomWheelRate { rate } => { self.viewport_zoom_wheel_rate = rate; } PreferencesMessage::UIScale { scale } => { self.ui_scale = scale; responses.add(FrontendMessage::UpdateUIScale { scale: self.ui_scale }); } PreferencesMessage::MaxRenderRegionSize { size } => { self.max_render_region_size = size; responses.add(PortfolioMessage::EditorPreferences); responses.add(NodeGraphMessage::RunDocumentGraph); } PreferencesMessage::DisableUIAcceleration { disable_ui_acceleration } => { self.disable_ui_acceleration = disable_ui_acceleration; } PreferencesMessage::ValidateStorageRoundTrip { enabled } => { self.validate_storage_round_trip = enabled; } PreferencesMessage::SaveAsGdd { enabled } => { self.save_as_gdd = enabled; } PreferencesMessage::ToggleShowStoragePreferences => { self.show_storage_preferences = !self.show_storage_preferences; responses.add(MenuBarMessage::SendLayout); } #[cfg(target_os = "macos")] PreferencesMessage::VSync { vsync } => { self.vsync = vsync; } } responses.add(FrontendMessage::TriggerSavePreferences { preferences: self.clone() }); } advertise_actions!(PreferencesMessageDiscriminant; ); }