You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: app.rs
    path of file: ./repos/ruffle/desktop/src
    
    the code of the file until where you have to start completion: use crate::custom_event::RuffleEvent;
use crate::gui::{GuiController, MENU_HEIGHT};
use crate::player::{PlayerController, PlayerOptions};
use crate::preferences::GlobalPreferences;
use crate::util::{
    get_screen_size, gilrs_button_to_gamepad_button, parse_url, pick_file, plot_stats_in_tracy,
    winit_to_ruffle_key_code, winit_to_ruffle_text_control,
};
use anyhow::{Context, Error};
use gilrs::{Event, EventType, Gilrs};
use ruffle_core::{PlayerEvent, StageDisplayState};
use ruffle_render::backend::ViewportDimensions;
use std::cell::RefCell;
use std::rc::Rc;
use std::time::{Duration, Instant};
use url::Url;
use winit::dpi::{LogicalSize, PhysicalPosition, PhysicalSize, Size};
use winit::event::{ElementState, KeyEvent, Modifiers, WindowEvent};
use winit::event_loop::{ControlFlow, EventLoop, EventLoopBuilder};
use winit::keyboard::{Key, NamedKey};
use winit::window::{Fullscreen, Icon, Window, WindowBuilder};

pub struct App {
    preferences: GlobalPreferences,
    window: Rc<Window>,
    event_loop: Option<EventLoop<RuffleEvent>>,
    gui: Rc<RefCell<GuiController>>,
    player: PlayerController,
    min_window_size: LogicalSize<u32>,
    max_window_size: PhysicalSize<u32>,
    initial_movie_url: Option<Url>,
    no_gui: bool,
    preferred_width: Option<f64>,
    preferred_height: Option<f64>,
    start_fullscreen: bool,
}

impl App {
    pub fn new(preferences: GlobalPreferences) -> Result<Self, Error> {
        let movie_url = preferences.cli.movie_url.clone();
        let icon_bytes = include_bytes!("../assets/favicon-32.rgba");
        let icon =
            Icon::from_rgba(icon_bytes.to_vec(), 32, 32).context("Couldn't load app icon")?;

        let event_loop = EventLoopBuilder::with_user_event().build()?;

        let no_gui = preferences.cli.no_gui;
        let min_window_size = (16, if no_gui { 16 } else { MENU_HEIGHT + 16 }).into();
        let max_window_size = get_screen_size(&event_loop);
        let preferred_width = preferences.cli.width;
        let preferred_height = preferences.cli.height;
        let start
    
    pub fn new(preferences: GlobalPreferences) -> Result<Self, Error> {
        let movie_url = preferences.cli.movie_url.clone();
        let icon_bytes = include_bytes!("../assets/favicon-32.rgba");
        let icon =
            Icon::from_rgba(icon_bytes.to_vec(), 32, 32).context("Couldn't load app icon")?;

        let event_loop = EventLoopBuilder::with_user_event().build()?;

        let no_gui = preferences.cli.no_gui;
        let min_window_size = (16, if no_gui { 16 } else { MENU_HEIGHT + 16 }).into();
        let max_window_size = get_screen_size(&event_loop);
        let preferred_width = preferences.cli.width;
        let preferred_height = preferences.cli.height;
        let start_fullscreen = preferences.cli.fullscreen;

        let window = WindowBuilder::new()
            .with_visible(false)
            .with_title("Ruffle")
            .with_window_icon(Some(icon))
            .with_min_inner_size(min_window_size)
            .with_max_inner_size(max_window_size)
            .build(&event_loop)?;
        let window = Rc::new(window);

        let mut font_database = fontdb::Database::default();
        font_database.load_system_fonts();

        let mut gui = GuiController::new(
            window.clone(),
            &event_loop,
            preferences.clone(),
            &font_database,
            movie_url.clone(),
            no_gui,
        )?;

        let mut player = PlayerController::new(
            event_loop.create_proxy(),
            window.clone(),
            gui.descriptors().clone(),
            font_database,
            preferences.clone(),
        );

        if let Some(movie_url) = &movie_url {
            gui.create_movie(
                &mut player,
                PlayerOptions::from(&preferences),
                movie_url.clone(),
            );
        } else {
            gui.show_open_dialog();
        }

        Ok(Self {
            preferences,
            window,
            event_loop: Some(event_loop),
            gui: Rc::new(RefCell::new(gui)),
            player,
            min_window_size,
            max_window_size,
            initial_movie_url: movie_url,
            no_gui,
            preferred_width,
            preferred_height,
            start_fullscreen,
        })
    }