From 94bdf6b9c6412bee9fc8188fc42cb5c77496ec63 Mon Sep 17 00:00:00 2001 From: Kamil Jarosz Date: Wed, 11 Sep 2024 20:05:21 +0200 Subject: [PATCH] desktop: Use FilePicker for picking files in ActionScript This improves the experience of picking files from AS, as the pickers will now be properly integrated with Ruffle. --- desktop/src/app.rs | 1 + desktop/src/backends/ui.rs | 78 ++++++++++++++++---------------------- desktop/src/player.rs | 8 +++- 3 files changed, 40 insertions(+), 47 deletions(-) diff --git a/desktop/src/app.rs b/desktop/src/app.rs index deec54821..634def4a5 100644 --- a/desktop/src/app.rs +++ b/desktop/src/app.rs @@ -84,6 +84,7 @@ impl App { gui.descriptors().clone(), font_database, preferences.clone(), + gui.file_picker(), ); if let Some(movie_url) = &movie_url { diff --git a/desktop/src/backends/ui.rs b/desktop/src/backends/ui.rs index 430ea7a4a..3d6e288d7 100644 --- a/desktop/src/backends/ui.rs +++ b/desktop/src/backends/ui.rs @@ -1,6 +1,6 @@ use crate::custom_event::RuffleEvent; use crate::gui::dialogs::message_dialog::MessageDialogConfiguration; -use crate::gui::{DialogDescriptor, LocalizableText}; +use crate::gui::{DialogDescriptor, FilePicker, LocalizableText}; use crate::preferences::GlobalPreferences; use anyhow::Error; use chrono::{DateTime, Utc}; @@ -125,8 +125,7 @@ pub struct DesktopUiBackend { preferred_cursor: MouseCursor, open_url_mode: OpenURLMode, font_database: Rc, - /// Is a dialog currently open - dialog_open: bool, + file_picker: FilePicker, } impl DesktopUiBackend { @@ -136,6 +135,7 @@ impl DesktopUiBackend { open_url_mode: OpenURLMode, font_database: Rc, preferences: GlobalPreferences, + file_picker: FilePicker, ) -> Result { // The window handle is only relevant to linux/wayland // If it fails it'll fallback to x11 or wlr-data-control @@ -154,8 +154,8 @@ impl DesktopUiBackend { preferences, preferred_cursor: MouseCursor::Arrow, open_url_mode, - dialog_open: false, font_database, + file_picker, }) } @@ -329,34 +329,28 @@ impl UiBackend for DesktopUiBackend { } fn display_file_open_dialog(&mut self, filters: Vec) -> Option { - // Prevent opening multiple dialogs at the same time - if self.dialog_open { - return None; - } - self.dialog_open = true; + let mut dialog = AsyncFileDialog::new(); - // Create the dialog future - Some(Box::pin(async move { - let mut dialog = AsyncFileDialog::new(); - - for filter in filters { - if cfg!(target_os = "macos") && filter.mac_type.is_some() { - let mac_type = filter.mac_type.expect("Checked above"); - let extensions: Vec<&str> = mac_type.split(';').collect(); - dialog = dialog.add_filter(&filter.description, &extensions); - } else { - let extensions: Vec<&str> = filter - .extensions - .split(';') - .map(|x| x.trim_start_matches("*.")) - .collect(); - dialog = dialog.add_filter(&filter.description, &extensions); - } + for filter in filters { + if cfg!(target_os = "macos") && filter.mac_type.is_some() { + let mac_type = filter.mac_type.expect("Checked above"); + let extensions: Vec<&str> = mac_type.split(';').collect(); + dialog = dialog.add_filter(&filter.description, &extensions); + } else { + let extensions: Vec<&str> = filter + .extensions + .split(';') + .map(|x| x.trim_start_matches("*.")) + .collect(); + dialog = dialog.add_filter(&filter.description, &extensions); } + } - let result: Result, DialogLoaderError> = Ok(Box::new( - DesktopFileDialogResult::new(dialog.pick_file().await), - )); + let result = self.file_picker.show_dialog(dialog, |d| d.pick_file())?; + + Some(Box::pin(async move { + let result: Result, DialogLoaderError> = + Ok(Box::new(DesktopFileDialogResult::new(result.await))); result })) } @@ -366,27 +360,19 @@ impl UiBackend for DesktopUiBackend { file_name: String, title: String, ) -> Option { - // Prevent opening multiple dialogs at the same time - if self.dialog_open { - return None; - } - self.dialog_open = true; + // Select the location to save the file to + let dialog = AsyncFileDialog::new() + .set_title(&title) + .set_file_name(&file_name); + + let result = self.file_picker.show_dialog(dialog, |d| d.save_file())?; - // Create the dialog future Some(Box::pin(async move { - // Select the location to save the file to - let dialog = AsyncFileDialog::new() - .set_title(&title) - .set_file_name(&file_name); - - let result: Result, DialogLoaderError> = Ok(Box::new( - DesktopFileDialogResult::new(dialog.save_file().await), - )); + let result: Result, DialogLoaderError> = + Ok(Box::new(DesktopFileDialogResult::new(result.await))); result })) } - fn close_file_dialog(&mut self) { - self.dialog_open = false; - } + fn close_file_dialog(&mut self) {} } diff --git a/desktop/src/player.rs b/desktop/src/player.rs index 0e5d9ae8d..7d1e02b8b 100644 --- a/desktop/src/player.rs +++ b/desktop/src/player.rs @@ -3,7 +3,7 @@ use crate::backends::{ DesktopNavigatorInterface, DesktopUiBackend, }; use crate::custom_event::RuffleEvent; -use crate::gui::MovieView; +use crate::gui::{FilePicker, MovieView}; use crate::preferences::GlobalPreferences; use crate::{CALLSTACK, RENDER_INFO, SWF_INFO}; use anyhow::anyhow; @@ -130,6 +130,7 @@ impl ActivePlayer { movie_view: MovieView, font_database: Rc, preferences: GlobalPreferences, + file_picker: FilePicker, ) -> Self { let mut builder = PlayerBuilder::new(); @@ -277,6 +278,7 @@ impl ActivePlayer { opt.open_url_mode, font_database, preferences, + file_picker, ) .expect("Couldn't create ui backend"), ) @@ -390,6 +392,7 @@ pub struct PlayerController { descriptors: Arc, font_database: Rc, preferences: GlobalPreferences, + file_picker: FilePicker, } impl PlayerController { @@ -399,6 +402,7 @@ impl PlayerController { descriptors: Arc, font_database: fontdb::Database, preferences: GlobalPreferences, + file_picker: FilePicker, ) -> Self { Self { player: None, @@ -407,6 +411,7 @@ impl PlayerController { descriptors, font_database: Rc::new(font_database), preferences, + file_picker, } } @@ -420,6 +425,7 @@ impl PlayerController { movie_view, self.font_database.clone(), self.preferences.clone(), + self.file_picker.clone(), )); }