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.
This commit is contained in:
Kamil Jarosz 2024-09-11 20:05:21 +02:00 committed by Nathan Adams
parent 4e395b26ad
commit 94bdf6b9c6
3 changed files with 40 additions and 47 deletions

View File

@ -84,6 +84,7 @@ impl App {
gui.descriptors().clone(),
font_database,
preferences.clone(),
gui.file_picker(),
);
if let Some(movie_url) = &movie_url {

View File

@ -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<fontdb::Database>,
/// 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<fontdb::Database>,
preferences: GlobalPreferences,
file_picker: FilePicker,
) -> Result<Self, Error> {
// 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<FileFilter>) -> Option<DialogResultFuture> {
// 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<Box<dyn FileDialogResult>, 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<Box<dyn FileDialogResult>, DialogLoaderError> =
Ok(Box::new(DesktopFileDialogResult::new(result.await)));
result
}))
}
@ -366,27 +360,19 @@ impl UiBackend for DesktopUiBackend {
file_name: String,
title: String,
) -> Option<DialogResultFuture> {
// 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<Box<dyn FileDialogResult>, DialogLoaderError> = Ok(Box::new(
DesktopFileDialogResult::new(dialog.save_file().await),
));
let result: Result<Box<dyn FileDialogResult>, 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) {}
}

View File

@ -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<fontdb::Database>,
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<Descriptors>,
font_database: Rc<fontdb::Database>,
preferences: GlobalPreferences,
file_picker: FilePicker,
}
impl PlayerController {
@ -399,6 +402,7 @@ impl PlayerController {
descriptors: Arc<Descriptors>,
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(),
));
}