Add an editor preference for touched/enclosed/directional based selection (#2156)

* implemented left selection logic

* added logic for right ward selection

* removed the logs code

* corrected capitalization error

* corrected capitalization error

* added radio buttons for selection_mode

* fixed multiple selection of checkboxes

* adapted to the RadioEntryData

* State management bug

* integrated message system to selection_mode

* updated

* updated

* added selection mode to transition arms

* removed from portfolio message and added preference in ToolMessageData

* removed dead code of selection_mode from frontend logic

* removed dead code for zoomWithScroll

* Cleanup

* Rename, simplify, use dashed box, and highlight only outlines of layers that'll get selected

* More code review

---------

Co-authored-by: Pratik Agrawal <patrik@Pratiks-MacBook-Air.local>
Co-authored-by: Keavon Chambers <keavon@keavon.com>
This commit is contained in:
Pratik Agrawal
2025-01-26 06:34:37 +00:00
committed by GitHub
co-authored by Pratik Agrawal Keavon Chambers
parent 93880abc4c
commit 96c57605b7
17 changed files with 266 additions and 113 deletions
@@ -1,17 +1,24 @@
use crate::messages::input_mapper::key_mapping::MappingVariant;
use crate::messages::preferences::SelectionMode;
use crate::messages::prelude::*;
use graph_craft::wasm_application_io::EditorPreferences;
#[derive(Debug, PartialEq, Clone, serde::Serialize, serde::Deserialize, specta::Type)]
pub struct PreferencesMessageHandler {
pub imaginate_server_hostname: String,
pub imaginate_refresh_frequency: f64,
pub selection_mode: SelectionMode,
pub zoom_with_scroll: bool,
pub use_vello: bool,
pub vector_meshes: bool,
}
impl PreferencesMessageHandler {
pub fn get_selection_mode(&self) -> SelectionMode {
self.selection_mode
}
pub fn editor_preferences(&self) -> EditorPreferences {
EditorPreferences {
imaginate_hostname: self.imaginate_server_hostname.clone(),
@@ -33,6 +40,7 @@ impl Default for PreferencesMessageHandler {
Self {
imaginate_server_hostname: host_name,
imaginate_refresh_frequency: 1.,
selection_mode: SelectionMode::Touched,
zoom_with_scroll: matches!(MappingVariant::default(), MappingVariant::ZoomWithScroll),
use_vello,
vector_meshes: false,
@@ -43,6 +51,7 @@ impl Default for PreferencesMessageHandler {
impl MessageHandler<PreferencesMessage, ()> for PreferencesMessageHandler {
fn process_message(&mut self, message: PreferencesMessage, responses: &mut VecDeque<Message>, _data: ()) {
match message {
// Management messages
PreferencesMessage::Load { preferences } => {
if let Ok(deserialized_preferences) = serde_json::from_str::<PreferencesMessageHandler>(&preferences) {
*self = deserialized_preferences;
@@ -65,31 +74,12 @@ impl MessageHandler<PreferencesMessage, ()> for PreferencesMessageHandler {
*self = Self::default()
}
PreferencesMessage::ImaginateRefreshFrequency { seconds } => {
self.imaginate_refresh_frequency = seconds;
responses.add(PortfolioMessage::ImaginateCheckServerStatus);
responses.add(PortfolioMessage::EditorPreferences);
}
// Per-preference messages
PreferencesMessage::UseVello { use_vello } => {
self.use_vello = use_vello;
responses.add(PortfolioMessage::UpdateVelloPreference);
responses.add(PortfolioMessage::EditorPreferences);
}
PreferencesMessage::ImaginateServerHostname { hostname } => {
let initial = hostname.clone();
let has_protocol = hostname.starts_with("http://") || hostname.starts_with("https://");
let hostname = if has_protocol { hostname } else { "http://".to_string() + &hostname };
let hostname = if hostname.ends_with('/') { hostname } else { hostname + "/" };
if hostname != initial {
refresh_dialog(responses);
}
self.imaginate_server_hostname = hostname;
responses.add(PortfolioMessage::ImaginateServerHostname);
responses.add(PortfolioMessage::ImaginateCheckServerStatus);
responses.add(PortfolioMessage::EditorPreferences);
}
PreferencesMessage::VectorMeshes { enabled } => {
self.vector_meshes = enabled;
}
@@ -102,7 +92,31 @@ impl MessageHandler<PreferencesMessage, ()> for PreferencesMessageHandler {
};
responses.add(KeyMappingMessage::ModifyMapping(variant));
}
PreferencesMessage::SelectionMode { selection_mode } => {
self.selection_mode = selection_mode;
}
}
// TODO: Reenable when Imaginate is restored (and move back up one line since the auto-formatter doesn't like it in that block)
// PreferencesMessage::ImaginateRefreshFrequency { seconds } => {
// self.imaginate_refresh_frequency = seconds;
// responses.add(PortfolioMessage::ImaginateCheckServerStatus);
// responses.add(PortfolioMessage::EditorPreferences);
// }
// PreferencesMessage::ImaginateServerHostname { hostname } => {
// let initial = hostname.clone();
// let has_protocol = hostname.starts_with("http://") || hostname.starts_with("https://");
// let hostname = if has_protocol { hostname } else { "http://".to_string() + &hostname };
// let hostname = if hostname.ends_with('/') { hostname } else { hostname + "/" };
// if hostname != initial {
// refresh_dialog(responses);
// }
// self.imaginate_server_hostname = hostname;
// responses.add(PortfolioMessage::ImaginateServerHostname);
// responses.add(PortfolioMessage::ImaginateCheckServerStatus);
// responses.add(PortfolioMessage::EditorPreferences);
//}
responses.add(FrontendMessage::TriggerSavePreferences { preferences: self.clone() });
}