desktop: Move pick_file to picker.rs
This commit is contained in:
parent
7931b8f051
commit
be8be123ba
|
@ -3,7 +3,7 @@ use crate::gui::{GuiController, MENU_HEIGHT};
|
||||||
use crate::player::{LaunchOptions, PlayerController};
|
use crate::player::{LaunchOptions, PlayerController};
|
||||||
use crate::preferences::GlobalPreferences;
|
use crate::preferences::GlobalPreferences;
|
||||||
use crate::util::{
|
use crate::util::{
|
||||||
get_screen_size, gilrs_button_to_gamepad_button, parse_url, pick_file, plot_stats_in_tracy,
|
get_screen_size, gilrs_button_to_gamepad_button, parse_url, plot_stats_in_tracy,
|
||||||
winit_to_ruffle_key_code, winit_to_ruffle_text_control,
|
winit_to_ruffle_key_code, winit_to_ruffle_text_control,
|
||||||
};
|
};
|
||||||
use anyhow::{Context, Error};
|
use anyhow::{Context, Error};
|
||||||
|
@ -482,9 +482,10 @@ impl App {
|
||||||
|
|
||||||
winit::event::Event::UserEvent(RuffleEvent::BrowseAndOpen(options)) => {
|
winit::event::Event::UserEvent(RuffleEvent::BrowseAndOpen(options)) => {
|
||||||
let event_loop = event_loop_proxy.clone();
|
let event_loop = event_loop_proxy.clone();
|
||||||
let window = self.window.clone();
|
let picker = self.gui.borrow().file_picker();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
if let Some(url) = pick_file(None, Some(&window))
|
if let Some(url) = picker
|
||||||
|
.pick_file(None)
|
||||||
.await
|
.await
|
||||||
.and_then(|p| Url::from_file_path(p).ok())
|
.and_then(|p| Url::from_file_path(p).ok())
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,11 +3,13 @@ mod controller;
|
||||||
mod dialogs;
|
mod dialogs;
|
||||||
mod menu_bar;
|
mod menu_bar;
|
||||||
mod movie;
|
mod movie;
|
||||||
|
mod picker;
|
||||||
mod theme;
|
mod theme;
|
||||||
mod widgets;
|
mod widgets;
|
||||||
|
|
||||||
pub use controller::GuiController;
|
pub use controller::GuiController;
|
||||||
pub use movie::MovieView;
|
pub use movie::MovieView;
|
||||||
|
pub use picker::FilePicker;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
pub use theme::ThemePreference;
|
pub use theme::ThemePreference;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
|
@ -23,6 +23,8 @@ use winit::event_loop::EventLoop;
|
||||||
use winit::keyboard::{Key, NamedKey};
|
use winit::keyboard::{Key, NamedKey};
|
||||||
use winit::window::{Theme, Window};
|
use winit::window::{Theme, Window};
|
||||||
|
|
||||||
|
use super::FilePicker;
|
||||||
|
|
||||||
/// Integration layer connecting wgpu+winit to egui.
|
/// Integration layer connecting wgpu+winit to egui.
|
||||||
pub struct GuiController {
|
pub struct GuiController {
|
||||||
descriptors: Arc<Descriptors>,
|
descriptors: Arc<Descriptors>,
|
||||||
|
@ -149,6 +151,10 @@ impl GuiController {
|
||||||
&self.descriptors
|
&self.descriptors
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn file_picker(&self) -> FilePicker {
|
||||||
|
self.gui.dialogs.file_picker()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn resize(&mut self, size: PhysicalSize<u32>) {
|
pub fn resize(&mut self, size: PhysicalSize<u32>) {
|
||||||
if size.width > 0 && size.height > 0 {
|
if size.width > 0 && size.height > 0 {
|
||||||
self.size = size;
|
self.size = size;
|
||||||
|
|
|
@ -17,10 +17,12 @@ use url::Url;
|
||||||
use volume_controls::VolumeControls;
|
use volume_controls::VolumeControls;
|
||||||
use winit::event_loop::EventLoopProxy;
|
use winit::event_loop::EventLoopProxy;
|
||||||
|
|
||||||
|
use super::FilePicker;
|
||||||
|
|
||||||
pub struct Dialogs {
|
pub struct Dialogs {
|
||||||
window: Weak<winit::window::Window>,
|
|
||||||
event_loop: EventLoopProxy<RuffleEvent>,
|
event_loop: EventLoopProxy<RuffleEvent>,
|
||||||
|
|
||||||
|
picker: FilePicker,
|
||||||
preferences_dialog: Option<PreferencesDialog>,
|
preferences_dialog: Option<PreferencesDialog>,
|
||||||
bookmarks_dialog: Option<BookmarksDialog>,
|
bookmarks_dialog: Option<BookmarksDialog>,
|
||||||
bookmark_add_dialog: Option<BookmarkAddDialog>,
|
bookmark_add_dialog: Option<BookmarkAddDialog>,
|
||||||
|
@ -44,6 +46,7 @@ impl Dialogs {
|
||||||
window: Weak<winit::window::Window>,
|
window: Weak<winit::window::Window>,
|
||||||
event_loop: EventLoopProxy<RuffleEvent>,
|
event_loop: EventLoopProxy<RuffleEvent>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
let picker = FilePicker::new(window);
|
||||||
Self {
|
Self {
|
||||||
preferences_dialog: None,
|
preferences_dialog: None,
|
||||||
bookmarks_dialog: None,
|
bookmarks_dialog: None,
|
||||||
|
@ -52,7 +55,7 @@ impl Dialogs {
|
||||||
open_dialog: OpenDialog::new(
|
open_dialog: OpenDialog::new(
|
||||||
player_options,
|
player_options,
|
||||||
default_path,
|
default_path,
|
||||||
window.clone(),
|
picker.clone(),
|
||||||
event_loop.clone(),
|
event_loop.clone(),
|
||||||
),
|
),
|
||||||
is_open_dialog_visible: false,
|
is_open_dialog_visible: false,
|
||||||
|
@ -62,12 +65,16 @@ impl Dialogs {
|
||||||
|
|
||||||
is_about_visible: false,
|
is_about_visible: false,
|
||||||
|
|
||||||
window,
|
|
||||||
event_loop,
|
event_loop,
|
||||||
|
picker,
|
||||||
preferences,
|
preferences,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn file_picker(&self) -> FilePicker {
|
||||||
|
self.picker.clone()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn recreate_open_dialog(
|
pub fn recreate_open_dialog(
|
||||||
&mut self,
|
&mut self,
|
||||||
opt: LaunchOptions,
|
opt: LaunchOptions,
|
||||||
|
@ -75,7 +82,7 @@ impl Dialogs {
|
||||||
event_loop: EventLoopProxy<RuffleEvent>,
|
event_loop: EventLoopProxy<RuffleEvent>,
|
||||||
) {
|
) {
|
||||||
self.is_open_dialog_visible = false;
|
self.is_open_dialog_visible = false;
|
||||||
self.open_dialog = OpenDialog::new(opt, url, self.window.clone(), event_loop);
|
self.open_dialog = OpenDialog::new(opt, url, self.picker.clone(), event_loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn open_file_advanced(&mut self) {
|
pub fn open_file_advanced(&mut self) {
|
||||||
|
@ -89,7 +96,7 @@ impl Dialogs {
|
||||||
pub fn open_bookmarks(&mut self) {
|
pub fn open_bookmarks(&mut self) {
|
||||||
self.bookmarks_dialog = Some(BookmarksDialog::new(
|
self.bookmarks_dialog = Some(BookmarksDialog::new(
|
||||||
self.preferences.clone(),
|
self.preferences.clone(),
|
||||||
self.window.clone(),
|
self.picker.clone(),
|
||||||
self.event_loop.clone(),
|
self.event_loop.clone(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -98,7 +105,7 @@ impl Dialogs {
|
||||||
self.bookmark_add_dialog = Some(BookmarkAddDialog::new(
|
self.bookmark_add_dialog = Some(BookmarkAddDialog::new(
|
||||||
self.preferences.clone(),
|
self.preferences.clone(),
|
||||||
initial_url,
|
initial_url,
|
||||||
self.window.clone(),
|
self.picker.clone(),
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
use crate::gui::text;
|
|
||||||
use crate::gui::widgets::PathOrUrlField;
|
use crate::gui::widgets::PathOrUrlField;
|
||||||
|
use crate::gui::{text, FilePicker};
|
||||||
use crate::preferences::GlobalPreferences;
|
use crate::preferences::GlobalPreferences;
|
||||||
use crate::{custom_event::RuffleEvent, player::LaunchOptions};
|
use crate::{custom_event::RuffleEvent, player::LaunchOptions};
|
||||||
use egui::{Align2, Button, Grid, Label, Layout, Sense, Ui, Widget, Window};
|
use egui::{Align2, Button, Grid, Label, Layout, Sense, Ui, Widget, Window};
|
||||||
use egui_extras::{Column, TableBuilder};
|
use egui_extras::{Column, TableBuilder};
|
||||||
use ruffle_frontend_utils::bookmarks::Bookmark;
|
use ruffle_frontend_utils::bookmarks::Bookmark;
|
||||||
use std::sync::Weak;
|
|
||||||
use unic_langid::LanguageIdentifier;
|
use unic_langid::LanguageIdentifier;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use winit::event_loop::EventLoopProxy;
|
use winit::event_loop::EventLoopProxy;
|
||||||
|
@ -20,7 +19,7 @@ impl BookmarkAddDialog {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
preferences: GlobalPreferences,
|
preferences: GlobalPreferences,
|
||||||
initial_url: Option<Url>,
|
initial_url: Option<Url>,
|
||||||
window: Weak<winit::window::Window>,
|
picker: FilePicker,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
preferences,
|
preferences,
|
||||||
|
@ -29,7 +28,7 @@ impl BookmarkAddDialog {
|
||||||
.map(|x| ruffle_frontend_utils::url_to_readable_name(x).into_owned())
|
.map(|x| ruffle_frontend_utils::url_to_readable_name(x).into_owned())
|
||||||
.unwrap_or_default(),
|
.unwrap_or_default(),
|
||||||
// TODO: hint.
|
// TODO: hint.
|
||||||
url: PathOrUrlField::new(initial_url, "", window),
|
url: PathOrUrlField::new(initial_url, "", picker),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,8 +99,8 @@ struct SelectedBookmark {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct BookmarksDialog {
|
pub struct BookmarksDialog {
|
||||||
window: Weak<winit::window::Window>,
|
|
||||||
event_loop: EventLoopProxy<RuffleEvent>,
|
event_loop: EventLoopProxy<RuffleEvent>,
|
||||||
|
picker: FilePicker,
|
||||||
preferences: GlobalPreferences,
|
preferences: GlobalPreferences,
|
||||||
selected_bookmark: Option<SelectedBookmark>,
|
selected_bookmark: Option<SelectedBookmark>,
|
||||||
}
|
}
|
||||||
|
@ -109,11 +108,11 @@ pub struct BookmarksDialog {
|
||||||
impl BookmarksDialog {
|
impl BookmarksDialog {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
preferences: GlobalPreferences,
|
preferences: GlobalPreferences,
|
||||||
window: Weak<winit::window::Window>,
|
picker: FilePicker,
|
||||||
event_loop: EventLoopProxy<RuffleEvent>,
|
event_loop: EventLoopProxy<RuffleEvent>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
window,
|
picker,
|
||||||
event_loop,
|
event_loop,
|
||||||
preferences,
|
preferences,
|
||||||
selected_bookmark: None,
|
selected_bookmark: None,
|
||||||
|
@ -224,7 +223,7 @@ impl BookmarksDialog {
|
||||||
url: PathOrUrlField::new(
|
url: PathOrUrlField::new(
|
||||||
Some(bookmark.url.clone()),
|
Some(bookmark.url.clone()),
|
||||||
"",
|
"",
|
||||||
self.window.clone(),
|
self.picker.clone(),
|
||||||
),
|
),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use crate::custom_event::RuffleEvent;
|
use crate::custom_event::RuffleEvent;
|
||||||
use crate::gui::text;
|
|
||||||
use crate::gui::widgets::PathOrUrlField;
|
use crate::gui::widgets::PathOrUrlField;
|
||||||
|
use crate::gui::{text, FilePicker};
|
||||||
use crate::player::LaunchOptions;
|
use crate::player::LaunchOptions;
|
||||||
use egui::{
|
use egui::{
|
||||||
emath, Align2, Button, Checkbox, ComboBox, Grid, Layout, Slider, TextEdit, Ui, Widget, Window,
|
emath, Align2, Button, Checkbox, ComboBox, Grid, Layout, Slider, TextEdit, Ui, Widget, Window,
|
||||||
|
@ -11,7 +11,6 @@ use ruffle_core::{LoadBehavior, PlayerRuntime, StageAlign, StageScaleMode};
|
||||||
use ruffle_render::quality::StageQuality;
|
use ruffle_render::quality::StageQuality;
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::ops::RangeInclusive;
|
use std::ops::RangeInclusive;
|
||||||
use std::sync::Weak;
|
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use unic_langid::LanguageIdentifier;
|
use unic_langid::LanguageIdentifier;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
@ -50,7 +49,7 @@ impl OpenDialog {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
defaults: LaunchOptions,
|
defaults: LaunchOptions,
|
||||||
default_url: Option<Url>,
|
default_url: Option<Url>,
|
||||||
window: Weak<winit::window::Window>,
|
picker: FilePicker,
|
||||||
event_loop: EventLoopProxy<RuffleEvent>,
|
event_loop: EventLoopProxy<RuffleEvent>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
let spoof_url = OptionalField::new(
|
let spoof_url = OptionalField::new(
|
||||||
|
@ -73,7 +72,7 @@ impl OpenDialog {
|
||||||
defaults.proxy.as_ref().map(Url::to_string),
|
defaults.proxy.as_ref().map(Url::to_string),
|
||||||
UrlField::new("socks5://localhost:8080"),
|
UrlField::new("socks5://localhost:8080"),
|
||||||
);
|
);
|
||||||
let path = PathOrUrlField::new(default_url, "path/to/movie.swf", window);
|
let path = PathOrUrlField::new(default_url, "path/to/movie.swf", picker);
|
||||||
let script_timeout = OptionalField::new(
|
let script_timeout = OptionalField::new(
|
||||||
defaults
|
defaults
|
||||||
.player
|
.player
|
||||||
|
|
|
@ -0,0 +1,40 @@
|
||||||
|
use rfd::AsyncFileDialog;
|
||||||
|
use std::{
|
||||||
|
path::PathBuf,
|
||||||
|
sync::{Arc, Weak},
|
||||||
|
};
|
||||||
|
use winit::window::Window;
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
|
pub struct FilePicker {
|
||||||
|
data: Arc<FilePickerData>,
|
||||||
|
}
|
||||||
|
|
||||||
|
struct FilePickerData {
|
||||||
|
parent: Weak<Window>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FilePicker {
|
||||||
|
pub fn new(parent: Weak<Window>) -> Self {
|
||||||
|
Self {
|
||||||
|
data: Arc::new(FilePickerData { parent }),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn pick_file(&self, dir: Option<PathBuf>) -> Option<PathBuf> {
|
||||||
|
let mut dialog = AsyncFileDialog::new()
|
||||||
|
.add_filter("Flash Files", &["swf", "spl", "ruf"])
|
||||||
|
.add_filter("All Files", &["*"])
|
||||||
|
.set_title("Load a Flash File");
|
||||||
|
|
||||||
|
if let Some(dir) = dir {
|
||||||
|
dialog = dialog.set_directory(dir);
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(parent) = self.data.parent.upgrade() {
|
||||||
|
dialog = dialog.set_parent(&parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog.pick_file().await.map(|h| h.into())
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,29 +1,26 @@
|
||||||
use crate::gui::text;
|
use crate::gui::text;
|
||||||
use crate::util::pick_file;
|
|
||||||
use egui::{TextEdit, Ui};
|
use egui::{TextEdit, Ui};
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::sync::{Arc, Mutex, MutexGuard, Weak};
|
use std::sync::{Arc, Mutex, MutexGuard};
|
||||||
use unic_langid::LanguageIdentifier;
|
use unic_langid::LanguageIdentifier;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
|
use super::FilePicker;
|
||||||
|
|
||||||
pub struct PathOrUrlField {
|
pub struct PathOrUrlField {
|
||||||
window: Weak<winit::window::Window>,
|
picker: FilePicker,
|
||||||
value: Arc<Mutex<String>>,
|
value: Arc<Mutex<String>>,
|
||||||
result: Option<Url>,
|
result: Option<Url>,
|
||||||
hint: &'static str,
|
hint: &'static str,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PathOrUrlField {
|
impl PathOrUrlField {
|
||||||
pub fn new(
|
pub fn new(default: Option<Url>, hint: &'static str, picker: FilePicker) -> Self {
|
||||||
default: Option<Url>,
|
|
||||||
hint: &'static str,
|
|
||||||
window: Weak<winit::window::Window>,
|
|
||||||
) -> Self {
|
|
||||||
if let Some(default) = default {
|
if let Some(default) = default {
|
||||||
if default.scheme() == "file" {
|
if default.scheme() == "file" {
|
||||||
if let Ok(path) = default.to_file_path() {
|
if let Ok(path) = default.to_file_path() {
|
||||||
return Self {
|
return Self {
|
||||||
window,
|
picker,
|
||||||
value: Arc::new(Mutex::new(path.to_string_lossy().to_string())),
|
value: Arc::new(Mutex::new(path.to_string_lossy().to_string())),
|
||||||
result: Some(default),
|
result: Some(default),
|
||||||
hint,
|
hint,
|
||||||
|
@ -32,7 +29,7 @@ impl PathOrUrlField {
|
||||||
}
|
}
|
||||||
|
|
||||||
return Self {
|
return Self {
|
||||||
window,
|
picker,
|
||||||
value: Arc::new(Mutex::new(default.to_string())),
|
value: Arc::new(Mutex::new(default.to_string())),
|
||||||
result: Some(default),
|
result: Some(default),
|
||||||
hint,
|
hint,
|
||||||
|
@ -40,7 +37,7 @@ impl PathOrUrlField {
|
||||||
}
|
}
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
window,
|
picker,
|
||||||
value: Arc::new(Mutex::new("".to_string())),
|
value: Arc::new(Mutex::new("".to_string())),
|
||||||
result: None,
|
result: None,
|
||||||
hint,
|
hint,
|
||||||
|
@ -65,9 +62,9 @@ impl PathOrUrlField {
|
||||||
});
|
});
|
||||||
|
|
||||||
let value = self.value.clone();
|
let value = self.value.clone();
|
||||||
let window = self.window.upgrade();
|
let picker = self.picker.clone();
|
||||||
tokio::spawn(async move {
|
tokio::spawn(async move {
|
||||||
if let Some(path) = pick_file(dir, window.as_ref()).await {
|
if let Some(path) = picker.pick_file(dir).await {
|
||||||
let mut value_lock = Self::lock_value(&value);
|
let mut value_lock = Self::lock_value(&value);
|
||||||
*value_lock = path.to_string_lossy().to_string();
|
*value_lock = path.to_string_lossy().to_string();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
use crate::custom_event::RuffleEvent;
|
use crate::custom_event::RuffleEvent;
|
||||||
use anyhow::{anyhow, Error};
|
use anyhow::{anyhow, Error};
|
||||||
use gilrs::Button;
|
use gilrs::Button;
|
||||||
use rfd::AsyncFileDialog;
|
|
||||||
use ruffle_core::events::{GamepadButton, KeyCode, TextControlCode};
|
use ruffle_core::events::{GamepadButton, KeyCode, TextControlCode};
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::Path;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use wgpu::rwh::{HasDisplayHandle, HasWindowHandle};
|
|
||||||
use winit::dpi::PhysicalSize;
|
use winit::dpi::PhysicalSize;
|
||||||
use winit::event::{KeyEvent, Modifiers};
|
use winit::event::{KeyEvent, Modifiers};
|
||||||
use winit::event_loop::EventLoop;
|
use winit::event_loop::EventLoop;
|
||||||
|
@ -245,26 +243,6 @@ pub fn parse_url(path: &Path) -> Result<Url, Error> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn pick_file<W: HasWindowHandle + HasDisplayHandle>(
|
|
||||||
dir: Option<PathBuf>,
|
|
||||||
parent: Option<&W>,
|
|
||||||
) -> Option<PathBuf> {
|
|
||||||
let mut dialog = AsyncFileDialog::new()
|
|
||||||
.add_filter("Flash Files", &["swf", "spl", "ruf"])
|
|
||||||
.add_filter("All Files", &["*"])
|
|
||||||
.set_title("Load a Flash File");
|
|
||||||
|
|
||||||
if let Some(dir) = dir {
|
|
||||||
dialog = dialog.set_directory(dir);
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(parent) = parent {
|
|
||||||
dialog = dialog.set_parent(parent);
|
|
||||||
}
|
|
||||||
|
|
||||||
dialog.pick_file().await.map(|h| h.into())
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(feature = "tracy"))]
|
#[cfg(not(feature = "tracy"))]
|
||||||
pub fn plot_stats_in_tracy(_instance: &wgpu::Instance) {}
|
pub fn plot_stats_in_tracy(_instance: &wgpu::Instance) {}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue