Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

desktop: Add "Advanced Open..." dialog #11240

Merged
merged 5 commits into from
May 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion core/src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ pub type Handle = Index;

/// How Ruffle should load movies.
#[cfg_attr(feature = "clap", derive(clap::ValueEnum))]
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum LoadBehavior {
/// Allow movies to execute before they have finished loading.
///
Expand Down
2 changes: 2 additions & 0 deletions desktop/assets/texts/en-US/common.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
start = Start
browse = Browse
4 changes: 2 additions & 2 deletions desktop/assets/texts/en-US/main_menu.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
# This is because some languages may use different wording for one or the other, especially with things like capitalisation.

file-menu = File
file-menu-open-file = Open File...
file-menu-open-url = Open URL...
file-menu-open-quick = Open...
file-menu-open-advanced = Open Advanced...
file-menu-close = Close
file-menu-exit = Exit

Expand Down
7 changes: 6 additions & 1 deletion desktop/assets/texts/en-US/open_dialog.ftl
Original file line number Diff line number Diff line change
@@ -1 +1,6 @@
open-url = Open URL
open-dialog = Open File or URL

open-dialog-path = File or URL

open-dialog-add-parameter = Add
open-dialog-delete-parameter = Delete
52 changes: 52 additions & 0 deletions desktop/assets/texts/en-US/settings.ftl
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
network-settings = Network Settings
player-settings = Player Settings
movie-parameters = Movie Parameters

custom-base-url = Custom Base URL

spoof-swf-url = Spoof SWF URL

proxy = Proxy

upgrade-http = Upgrade HTTP to HTTPS
upgrade-http-check = Upgrade

open-url-mode = Open URL Mode
open-url-mode-allow = Allow
open-url-mode-confirm = Confirm
open-url-mode-deny = Deny

load-behavior = Load Behavior
load-behavior-streaming = Streaming
load-behavior-delayed = Delayed
load-behavior-blocking = Blocking

max-execution-duration = Max Execution Duration
max-execution-duration-suffix = {" "} secs

quality = Quality
quality-low = Low
quality-medium = Medium
quality-high = High
quality-best = Best
quality-high8x8 = High (8x8)
quality-high8x8linear = High (8x8) Linear
quality-high16x16 = High (16x16)
quality-high16x16linear = High (16x16) Linear

scale-mode = Scale Mode
scale-mode-exactfit = Exact Fit
scale-mode-noborder = No Border
scale-mode-noscale = No Scale
scale-mode-showall = Show All

force-scale-mode = Force Scale Mode
force-scale-mode-check = Force

warn-if-unsupported = Warn if Unsupported
warn-if-unsupported-check = Warn

player-version = Player Version

custom-framerate = Custom Framerate
custom-framerate-suffix = {" "} fps
37 changes: 20 additions & 17 deletions desktop/src/app.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::cli::Opt;
use crate::custom_event::RuffleEvent;
use crate::gui::{GuiController, MENU_HEIGHT};
use crate::player::PlayerController;
use crate::player::{PlayerController, PlayerOptions};
use crate::util::{
get_screen_size, parse_url, pick_file, winit_key_to_char, winit_to_ruffle_key_code,
winit_to_ruffle_text_control,
Expand All @@ -12,6 +12,7 @@ use ruffle_render::backend::ViewportDimensions;
use std::rc::Rc;
use std::sync::{Arc, Mutex};
use std::time::Instant;
use url::Url;
use winit::dpi::{LogicalSize, PhysicalPosition, PhysicalSize, Size};
use winit::event::{ElementState, KeyboardInput, ModifiersState, VirtualKeyCode, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop, EventLoopBuilder};
Expand Down Expand Up @@ -53,13 +54,7 @@ impl App {
.build(&event_loop)?;
let window = Rc::new(window);

let gui = GuiController::new(
window.clone(),
&event_loop,
opt.trace_path(),
opt.graphics.into(),
opt.power.into(),
)?;
let mut gui = GuiController::new(window.clone(), &event_loop, &opt)?;

let mut player = PlayerController::new(
event_loop.create_proxy(),
Expand All @@ -68,7 +63,13 @@ impl App {
);

if let Some(movie_url) = movie_url {
player.create(&opt, movie_url, gui.create_movie_view());
player.create(
&PlayerOptions::from(&opt),
movie_url,
gui.create_movie_view(),
);
} else {
gui.show_open_dialog();
}

Ok(Self {
Expand Down Expand Up @@ -199,7 +200,11 @@ impl App {
if let Ok(url) = parse_url(&file) {
let movie_view =
self.gui.lock().expect("Gui lock").create_movie_view();
self.player.create(&self.opt, url, movie_view);
self.player.create(
&PlayerOptions::from(&self.opt),
url,
movie_view,
);
}
}
WindowEvent::MouseInput { button, state, .. } => {
Expand Down Expand Up @@ -427,21 +432,19 @@ impl App {
}
}

winit::event::Event::UserEvent(RuffleEvent::OpenFile) => {
if let Some(path) = pick_file() {
// TODO: Show dialog on error.
let url = parse_url(&path).expect("Couldn't load specified path");
winit::event::Event::UserEvent(RuffleEvent::BrowseAndOpen(options)) => {
if let Some(url) = pick_file(false).and_then(|p| Url::from_file_path(p).ok()) {
self.player.create(
&self.opt,
&options,
url,
self.gui.lock().expect("Gui lock").create_movie_view(),
);
}
}

winit::event::Event::UserEvent(RuffleEvent::OpenURL(url)) => {
winit::event::Event::UserEvent(RuffleEvent::OpenURL(url, options)) => {
self.player.create(
&self.opt,
&options,
url,
self.gui.lock().expect("Gui lock").create_movie_view(),
);
Expand Down
8 changes: 5 additions & 3 deletions desktop/src/custom_event.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
//! Custom event type for desktop ruffle

use crate::player::PlayerOptions;

/// User-defined events.
pub enum RuffleEvent {
/// Indicates that one or more tasks are ready to poll on our executor.
Expand All @@ -8,11 +10,11 @@ pub enum RuffleEvent {
/// Indicates that an asynchronous SWF metadata load has been completed.
OnMetadata(ruffle_core::swf::HeaderExt),

/// The user requested to open a new local SWF.
OpenFile,
/// The user requested to pick and then open a file.
BrowseAndOpen(Box<PlayerOptions>),

/// The user requested to open a URL.
OpenURL(url::Url),
OpenURL(url::Url, Box<PlayerOptions>),

/// The user requested to close the current SWF.
CloseFile,
Expand Down
84 changes: 35 additions & 49 deletions desktop/src/gui.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
mod controller;
mod movie;
mod open_dialog;

pub use controller::GuiController;
pub use movie::MovieView;
use std::borrow::Cow;

use crate::custom_event::RuffleEvent;
use crate::gui::open_dialog::OpenDialog;
use crate::player::PlayerOptions;
use chrono::DateTime;
use egui::*;
use fluent_templates::fluent_bundle::FluentValue;
Expand Down Expand Up @@ -56,15 +59,15 @@ pub const MENU_HEIGHT: u32 = 24;
/// The main controller for the Ruffle GUI.
pub struct RuffleGui {
event_loop: EventLoopProxy<RuffleEvent>,
open_url_text: String,
is_about_visible: bool,
is_open_url_prompt_visible: bool,
context_menu: Vec<ruffle_core::ContextMenuItem>,
locale: LanguageIdentifier,
default_player_options: PlayerOptions,
open_dialog: Option<OpenDialog>,
}

impl RuffleGui {
fn new(event_loop: EventLoopProxy<RuffleEvent>) -> Self {
fn new(event_loop: EventLoopProxy<RuffleEvent>, default_player_options: PlayerOptions) -> Self {
// TODO: language negotiation + https://github.com/1Password/sys-locale/issues/14
// This should also be somewhere else so it can be supplied through UiBackend too

Expand All @@ -75,11 +78,11 @@ impl RuffleGui {

Self {
event_loop,
open_url_text: String::new(),
is_about_visible: false,
is_open_url_prompt_visible: false,
context_menu: vec![],
locale,
default_player_options,
open_dialog: None,
}
}

Expand All @@ -96,7 +99,7 @@ impl RuffleGui {
}

self.about_window(egui_ctx);
self.open_url_prompt(egui_ctx);
self.open_dialog(egui_ctx);

if !self.context_menu.is_empty() {
self.context_menu(egui_ctx);
Expand Down Expand Up @@ -143,16 +146,17 @@ impl RuffleGui {
let mut shortcut;
shortcut = KeyboardShortcut::new(Modifiers::COMMAND, Key::O);

if Button::new(text(&self.locale, "file-menu-open-file"))
if Button::new(text(&self.locale, "file-menu-open-quick"))
.shortcut_text(ui.ctx().format_shortcut(&shortcut))
.ui(ui)
.clicked()
{
self.open_file(ui);
}

if Button::new(text(&self.locale, "file-menu-open-url")).ui(ui).clicked() {
self.show_open_url_prompt(ui);
if Button::new(text(&self.locale, "file-menu-open-advanced")).ui(ui).clicked() {
ui.close_menu();
self.open_file_advanced();
}

if ui.add_enabled(has_movie, Button::new(text(&self.locale, "file-menu-close"))).clicked() {
Expand Down Expand Up @@ -329,49 +333,36 @@ impl RuffleGui {
}

fn open_file(&mut self, ui: &mut egui::Ui) {
let _ = self.event_loop.send_event(RuffleEvent::OpenFile);
ui.close_menu();

let _ = self
.event_loop
.send_event(RuffleEvent::BrowseAndOpen(Box::new(
self.default_player_options.clone(),
)));
}

fn open_file_advanced(&mut self) {
self.open_dialog = Some(OpenDialog::new(
self.default_player_options.clone(),
self.event_loop.clone(),
self.locale.clone(),
));
}

fn close_movie(&mut self, ui: &mut egui::Ui) {
let _ = self.event_loop.send_event(RuffleEvent::CloseFile);
ui.close_menu();
}

fn open_url_prompt(&mut self, egui_ctx: &egui::Context) {
let mut close_prompt = false;
egui::Window::new(text(&self.locale, "open-url"))
.anchor(Align2::CENTER_CENTER, egui::Vec2::ZERO)
.collapsible(false)
.resizable(false)
.open(&mut self.is_open_url_prompt_visible)
.show(egui_ctx, |ui| {
ui.vertical_centered(|ui| {
let (enter_pressed, esc_pressed) = ui.ctx().input_mut(|input| {
(
input.consume_key(Modifiers::NONE, Key::Enter),
input.consume_key(Modifiers::NONE, Key::Escape),
)
});
ui.text_edit_singleline(&mut self.open_url_text);
ui.horizontal(|ui| {
if ui.button(text(&self.locale, "dialog-ok")).clicked() || enter_pressed {
if let Ok(url) = url::Url::parse(&self.open_url_text) {
let _ = self.event_loop.send_event(RuffleEvent::OpenURL(url));
} else {
// TODO: Show error prompt.
tracing::error!("Invalid URL: {}", self.open_url_text);
}
close_prompt = true;
}
if ui.button(text(&self.locale, "dialog-cancel")).clicked() || esc_pressed {
close_prompt = true;
}
});
});
});
if close_prompt {
self.is_open_url_prompt_visible = false;
fn open_dialog(&mut self, egui_ctx: &egui::Context) {
let keep_open = self
.open_dialog
.as_mut()
.map(|d| d.show(egui_ctx))
.unwrap_or_default();
if !keep_open {
self.open_dialog = None;
}
}

Expand All @@ -389,9 +380,4 @@ impl RuffleGui {
self.is_about_visible = true;
ui.close_menu();
}

fn show_open_url_prompt(&mut self, ui: &mut egui::Ui) {
self.is_open_url_prompt_visible = true;
ui.close_menu();
}
}
Loading