diff options
Diffstat (limited to 'winit/src')
| -rw-r--r-- | winit/src/application.rs | 185 | ||||
| -rw-r--r-- | winit/src/conversion.rs | 199 | ||||
| -rw-r--r-- | winit/src/lib.rs | 8 | 
3 files changed, 392 insertions, 0 deletions
| diff --git a/winit/src/application.rs b/winit/src/application.rs new file mode 100644 index 00000000..418ee3c4 --- /dev/null +++ b/winit/src/application.rs @@ -0,0 +1,185 @@ +use crate::{ +    column, conversion, input::mouse, renderer::Windowed, Cache, Column, +    Element, Event, Length, MouseCursor, UserInterface, +}; + +pub trait Application { +    type Renderer: Windowed + column::Renderer; + +    type Message; + +    fn update(&mut self, message: Self::Message); + +    fn view(&mut self) -> Element<Self::Message, Self::Renderer>; + +    fn run(mut self) +    where +        Self: 'static + Sized, +    { +        use winit::{ +            event::{self, WindowEvent}, +            event_loop::{ControlFlow, EventLoop}, +            window::WindowBuilder, +        }; + +        let event_loop = EventLoop::new(); + +        // TODO: Ask for window settings and configure this properly +        let window = WindowBuilder::new() +            .with_inner_size(winit::dpi::LogicalSize { +                width: 1280.0, +                height: 1024.0, +            }) +            .build(&event_loop) +            .expect("Open window"); + +        let mut size: Size = window +            .inner_size() +            .to_physical(window.hidpi_factor()) +            .into(); +        let mut new_size: Option<Size> = None; + +        let mut renderer = Self::Renderer::new(&window); +        let mut target = renderer.target(size.width, size.height); + +        let user_interface = UserInterface::build( +            document(&mut self, size), +            Cache::default(), +            &renderer, +        ); + +        let mut primitive = user_interface.draw(&mut renderer); +        let mut cache = Some(user_interface.into_cache()); +        let mut events = Vec::new(); +        let mut mouse_cursor = MouseCursor::OutOfBounds; + +        window.request_redraw(); + +        event_loop.run(move |event, _, control_flow| match event { +            event::Event::MainEventsCleared => { +                // TODO: We should be able to keep a user interface alive +                // between events once we remove state references. +                // +                // This will allow us to rebuild it only when a message is +                // handled. +                let mut user_interface = UserInterface::build( +                    document(&mut self, size), +                    cache.take().unwrap(), +                    &renderer, +                ); + +                let messages = user_interface.update(events.drain(..)); + +                if messages.is_empty() { +                    primitive = user_interface.draw(&mut renderer); + +                    cache = Some(user_interface.into_cache()); +                } else { +                    // When there are messages, we are forced to rebuild twice +                    // for now :^) +                    let temp_cache = user_interface.into_cache(); + +                    for message in messages { +                        log::debug!("Updating"); + +                        self.update(message); +                    } + +                    let user_interface = UserInterface::build( +                        document(&mut self, size), +                        temp_cache, +                        &renderer, +                    ); + +                    primitive = user_interface.draw(&mut renderer); + +                    cache = Some(user_interface.into_cache()); +                } + +                window.request_redraw(); +            } +            event::Event::RedrawRequested(_) => { +                if let Some(new_size) = new_size.take() { +                    target = renderer.target(new_size.width, new_size.height); +                    size = new_size; +                } + +                let new_mouse_cursor = renderer.draw(&primitive, &mut target); + +                if new_mouse_cursor != mouse_cursor { +                    window.set_cursor_icon(conversion::mouse_cursor( +                        new_mouse_cursor, +                    )); + +                    mouse_cursor = new_mouse_cursor; +                } + +                // TODO: Handle animations! +                // Maybe we can use `ControlFlow::WaitUntil` for this. +            } +            event::Event::WindowEvent { +                event: window_event, +                .. +            } => match window_event { +                WindowEvent::CursorMoved { position, .. } => { +                    let physical_position = +                        position.to_physical(window.hidpi_factor()); + +                    events.push(Event::Mouse(mouse::Event::CursorMoved { +                        x: physical_position.x as f32, +                        y: physical_position.y as f32, +                    })); +                } +                WindowEvent::MouseInput { button, state, .. } => { +                    events.push(Event::Mouse(mouse::Event::Input { +                        button: conversion::mouse_button(button), +                        state: conversion::button_state(state), +                    })); +                } +                WindowEvent::CloseRequested => { +                    *control_flow = ControlFlow::Exit; +                } +                WindowEvent::Resized(size) => { +                    new_size = +                        Some(size.to_physical(window.hidpi_factor()).into()); + +                    log::debug!("Resized: {:?}", new_size); +                } +                _ => {} +            }, +            _ => { +                *control_flow = ControlFlow::Wait; +            } +        }) +    } +} + +#[derive(Debug, Clone, Copy, Eq, PartialEq)] +struct Size { +    width: u16, +    height: u16, +} + +impl From<winit::dpi::PhysicalSize> for Size { +    fn from(physical_size: winit::dpi::PhysicalSize) -> Self { +        Self { +            width: physical_size.width.round() as u16, +            height: physical_size.height.round() as u16, +        } +    } +} + +fn document<Application>( +    application: &mut Application, +    size: Size, +) -> Element<Application::Message, Application::Renderer> +where +    Application: self::Application, +    Application::Message: 'static, +{ +    Column::new() +        .width(Length::Units(size.width)) +        .height(Length::Units(size.height)) +        .push(application.view()) +        .into() +} diff --git a/winit/src/conversion.rs b/winit/src/conversion.rs new file mode 100644 index 00000000..bb0d252e --- /dev/null +++ b/winit/src/conversion.rs @@ -0,0 +1,199 @@ +use crate::input::{keyboard::KeyCode, mouse, ButtonState}; +use crate::MouseCursor; + +pub fn mouse_cursor(mouse_cursor: MouseCursor) -> winit::window::CursorIcon { +    match mouse_cursor { +        MouseCursor::OutOfBounds => winit::window::CursorIcon::Default, +        MouseCursor::Idle => winit::window::CursorIcon::Default, +        MouseCursor::Pointer => winit::window::CursorIcon::Hand, +        MouseCursor::Working => winit::window::CursorIcon::Progress, +        MouseCursor::Grab => winit::window::CursorIcon::Grab, +        MouseCursor::Grabbing => winit::window::CursorIcon::Grabbing, +    } +} + +pub fn mouse_button(mouse_button: winit::event::MouseButton) -> mouse::Button { +    match mouse_button { +        winit::event::MouseButton::Left => mouse::Button::Left, +        winit::event::MouseButton::Right => mouse::Button::Right, +        winit::event::MouseButton::Middle => mouse::Button::Middle, +        winit::event::MouseButton::Other(other) => mouse::Button::Other(other), +    } +} + +pub fn button_state(element_state: winit::event::ElementState) -> ButtonState { +    match element_state { +        winit::event::ElementState::Pressed => ButtonState::Pressed, +        winit::event::ElementState::Released => ButtonState::Released, +    } +} + +pub fn key_code(virtual_keycode: winit::event::VirtualKeyCode) -> KeyCode { +    match virtual_keycode { +        winit::event::VirtualKeyCode::Key1 => KeyCode::Key1, +        winit::event::VirtualKeyCode::Key2 => KeyCode::Key2, +        winit::event::VirtualKeyCode::Key3 => KeyCode::Key3, +        winit::event::VirtualKeyCode::Key4 => KeyCode::Key4, +        winit::event::VirtualKeyCode::Key5 => KeyCode::Key5, +        winit::event::VirtualKeyCode::Key6 => KeyCode::Key6, +        winit::event::VirtualKeyCode::Key7 => KeyCode::Key7, +        winit::event::VirtualKeyCode::Key8 => KeyCode::Key8, +        winit::event::VirtualKeyCode::Key9 => KeyCode::Key9, +        winit::event::VirtualKeyCode::Key0 => KeyCode::Key0, +        winit::event::VirtualKeyCode::A => KeyCode::A, +        winit::event::VirtualKeyCode::B => KeyCode::B, +        winit::event::VirtualKeyCode::C => KeyCode::C, +        winit::event::VirtualKeyCode::D => KeyCode::D, +        winit::event::VirtualKeyCode::E => KeyCode::E, +        winit::event::VirtualKeyCode::F => KeyCode::F, +        winit::event::VirtualKeyCode::G => KeyCode::G, +        winit::event::VirtualKeyCode::H => KeyCode::H, +        winit::event::VirtualKeyCode::I => KeyCode::I, +        winit::event::VirtualKeyCode::J => KeyCode::J, +        winit::event::VirtualKeyCode::K => KeyCode::K, +        winit::event::VirtualKeyCode::L => KeyCode::L, +        winit::event::VirtualKeyCode::M => KeyCode::M, +        winit::event::VirtualKeyCode::N => KeyCode::N, +        winit::event::VirtualKeyCode::O => KeyCode::O, +        winit::event::VirtualKeyCode::P => KeyCode::P, +        winit::event::VirtualKeyCode::Q => KeyCode::Q, +        winit::event::VirtualKeyCode::R => KeyCode::R, +        winit::event::VirtualKeyCode::S => KeyCode::S, +        winit::event::VirtualKeyCode::T => KeyCode::T, +        winit::event::VirtualKeyCode::U => KeyCode::U, +        winit::event::VirtualKeyCode::V => KeyCode::V, +        winit::event::VirtualKeyCode::W => KeyCode::W, +        winit::event::VirtualKeyCode::X => KeyCode::X, +        winit::event::VirtualKeyCode::Y => KeyCode::Y, +        winit::event::VirtualKeyCode::Z => KeyCode::Z, +        winit::event::VirtualKeyCode::Escape => KeyCode::Escape, +        winit::event::VirtualKeyCode::F1 => KeyCode::F1, +        winit::event::VirtualKeyCode::F2 => KeyCode::F2, +        winit::event::VirtualKeyCode::F3 => KeyCode::F3, +        winit::event::VirtualKeyCode::F4 => KeyCode::F4, +        winit::event::VirtualKeyCode::F5 => KeyCode::F5, +        winit::event::VirtualKeyCode::F6 => KeyCode::F6, +        winit::event::VirtualKeyCode::F7 => KeyCode::F7, +        winit::event::VirtualKeyCode::F8 => KeyCode::F8, +        winit::event::VirtualKeyCode::F9 => KeyCode::F9, +        winit::event::VirtualKeyCode::F10 => KeyCode::F10, +        winit::event::VirtualKeyCode::F11 => KeyCode::F11, +        winit::event::VirtualKeyCode::F12 => KeyCode::F12, +        winit::event::VirtualKeyCode::F13 => KeyCode::F13, +        winit::event::VirtualKeyCode::F14 => KeyCode::F14, +        winit::event::VirtualKeyCode::F15 => KeyCode::F15, +        winit::event::VirtualKeyCode::F16 => KeyCode::F16, +        winit::event::VirtualKeyCode::F17 => KeyCode::F17, +        winit::event::VirtualKeyCode::F18 => KeyCode::F18, +        winit::event::VirtualKeyCode::F19 => KeyCode::F19, +        winit::event::VirtualKeyCode::F20 => KeyCode::F20, +        winit::event::VirtualKeyCode::F21 => KeyCode::F21, +        winit::event::VirtualKeyCode::F22 => KeyCode::F22, +        winit::event::VirtualKeyCode::F23 => KeyCode::F23, +        winit::event::VirtualKeyCode::F24 => KeyCode::F24, +        winit::event::VirtualKeyCode::Snapshot => KeyCode::Snapshot, +        winit::event::VirtualKeyCode::Scroll => KeyCode::Scroll, +        winit::event::VirtualKeyCode::Pause => KeyCode::Pause, +        winit::event::VirtualKeyCode::Insert => KeyCode::Insert, +        winit::event::VirtualKeyCode::Home => KeyCode::Home, +        winit::event::VirtualKeyCode::Delete => KeyCode::Delete, +        winit::event::VirtualKeyCode::End => KeyCode::End, +        winit::event::VirtualKeyCode::PageDown => KeyCode::PageDown, +        winit::event::VirtualKeyCode::PageUp => KeyCode::PageUp, +        winit::event::VirtualKeyCode::Left => KeyCode::Left, +        winit::event::VirtualKeyCode::Up => KeyCode::Up, +        winit::event::VirtualKeyCode::Right => KeyCode::Right, +        winit::event::VirtualKeyCode::Down => KeyCode::Down, +        winit::event::VirtualKeyCode::Back => KeyCode::Backspace, +        winit::event::VirtualKeyCode::Return => KeyCode::Enter, +        winit::event::VirtualKeyCode::Space => KeyCode::Space, +        winit::event::VirtualKeyCode::Compose => KeyCode::Compose, +        winit::event::VirtualKeyCode::Caret => KeyCode::Caret, +        winit::event::VirtualKeyCode::Numlock => KeyCode::Numlock, +        winit::event::VirtualKeyCode::Numpad0 => KeyCode::Numpad0, +        winit::event::VirtualKeyCode::Numpad1 => KeyCode::Numpad1, +        winit::event::VirtualKeyCode::Numpad2 => KeyCode::Numpad2, +        winit::event::VirtualKeyCode::Numpad3 => KeyCode::Numpad3, +        winit::event::VirtualKeyCode::Numpad4 => KeyCode::Numpad4, +        winit::event::VirtualKeyCode::Numpad5 => KeyCode::Numpad5, +        winit::event::VirtualKeyCode::Numpad6 => KeyCode::Numpad6, +        winit::event::VirtualKeyCode::Numpad7 => KeyCode::Numpad7, +        winit::event::VirtualKeyCode::Numpad8 => KeyCode::Numpad8, +        winit::event::VirtualKeyCode::Numpad9 => KeyCode::Numpad9, +        winit::event::VirtualKeyCode::AbntC1 => KeyCode::AbntC1, +        winit::event::VirtualKeyCode::AbntC2 => KeyCode::AbntC2, +        winit::event::VirtualKeyCode::Add => KeyCode::Add, +        winit::event::VirtualKeyCode::Apostrophe => KeyCode::Apostrophe, +        winit::event::VirtualKeyCode::Apps => KeyCode::Apps, +        winit::event::VirtualKeyCode::At => KeyCode::At, +        winit::event::VirtualKeyCode::Ax => KeyCode::Ax, +        winit::event::VirtualKeyCode::Backslash => KeyCode::Backslash, +        winit::event::VirtualKeyCode::Calculator => KeyCode::Calculator, +        winit::event::VirtualKeyCode::Capital => KeyCode::Capital, +        winit::event::VirtualKeyCode::Colon => KeyCode::Colon, +        winit::event::VirtualKeyCode::Comma => KeyCode::Comma, +        winit::event::VirtualKeyCode::Convert => KeyCode::Convert, +        winit::event::VirtualKeyCode::Decimal => KeyCode::Decimal, +        winit::event::VirtualKeyCode::Divide => KeyCode::Divide, +        winit::event::VirtualKeyCode::Equals => KeyCode::Equals, +        winit::event::VirtualKeyCode::Grave => KeyCode::Grave, +        winit::event::VirtualKeyCode::Kana => KeyCode::Kana, +        winit::event::VirtualKeyCode::Kanji => KeyCode::Kanji, +        winit::event::VirtualKeyCode::LAlt => KeyCode::LAlt, +        winit::event::VirtualKeyCode::LBracket => KeyCode::LBracket, +        winit::event::VirtualKeyCode::LControl => KeyCode::LControl, +        winit::event::VirtualKeyCode::LShift => KeyCode::LShift, +        winit::event::VirtualKeyCode::LWin => KeyCode::LWin, +        winit::event::VirtualKeyCode::Mail => KeyCode::Mail, +        winit::event::VirtualKeyCode::MediaSelect => KeyCode::MediaSelect, +        winit::event::VirtualKeyCode::MediaStop => KeyCode::MediaStop, +        winit::event::VirtualKeyCode::Minus => KeyCode::Minus, +        winit::event::VirtualKeyCode::Multiply => KeyCode::Multiply, +        winit::event::VirtualKeyCode::Mute => KeyCode::Mute, +        winit::event::VirtualKeyCode::MyComputer => KeyCode::MyComputer, +        winit::event::VirtualKeyCode::NavigateForward => { +            KeyCode::NavigateForward +        } +        winit::event::VirtualKeyCode::NavigateBackward => { +            KeyCode::NavigateBackward +        } +        winit::event::VirtualKeyCode::NextTrack => KeyCode::NextTrack, +        winit::event::VirtualKeyCode::NoConvert => KeyCode::NoConvert, +        winit::event::VirtualKeyCode::NumpadComma => KeyCode::NumpadComma, +        winit::event::VirtualKeyCode::NumpadEnter => KeyCode::NumpadEnter, +        winit::event::VirtualKeyCode::NumpadEquals => KeyCode::NumpadEquals, +        winit::event::VirtualKeyCode::OEM102 => KeyCode::OEM102, +        winit::event::VirtualKeyCode::Period => KeyCode::Period, +        winit::event::VirtualKeyCode::PlayPause => KeyCode::PlayPause, +        winit::event::VirtualKeyCode::Power => KeyCode::Power, +        winit::event::VirtualKeyCode::PrevTrack => KeyCode::PrevTrack, +        winit::event::VirtualKeyCode::RAlt => KeyCode::RAlt, +        winit::event::VirtualKeyCode::RBracket => KeyCode::RBracket, +        winit::event::VirtualKeyCode::RControl => KeyCode::RControl, +        winit::event::VirtualKeyCode::RShift => KeyCode::RShift, +        winit::event::VirtualKeyCode::RWin => KeyCode::RWin, +        winit::event::VirtualKeyCode::Semicolon => KeyCode::Semicolon, +        winit::event::VirtualKeyCode::Slash => KeyCode::Slash, +        winit::event::VirtualKeyCode::Sleep => KeyCode::Sleep, +        winit::event::VirtualKeyCode::Stop => KeyCode::Stop, +        winit::event::VirtualKeyCode::Subtract => KeyCode::Subtract, +        winit::event::VirtualKeyCode::Sysrq => KeyCode::Sysrq, +        winit::event::VirtualKeyCode::Tab => KeyCode::Tab, +        winit::event::VirtualKeyCode::Underline => KeyCode::Underline, +        winit::event::VirtualKeyCode::Unlabeled => KeyCode::Unlabeled, +        winit::event::VirtualKeyCode::VolumeDown => KeyCode::VolumeDown, +        winit::event::VirtualKeyCode::VolumeUp => KeyCode::VolumeUp, +        winit::event::VirtualKeyCode::Wake => KeyCode::Wake, +        winit::event::VirtualKeyCode::WebBack => KeyCode::WebBack, +        winit::event::VirtualKeyCode::WebFavorites => KeyCode::WebFavorites, +        winit::event::VirtualKeyCode::WebForward => KeyCode::WebForward, +        winit::event::VirtualKeyCode::WebHome => KeyCode::WebHome, +        winit::event::VirtualKeyCode::WebRefresh => KeyCode::WebRefresh, +        winit::event::VirtualKeyCode::WebSearch => KeyCode::WebSearch, +        winit::event::VirtualKeyCode::WebStop => KeyCode::WebStop, +        winit::event::VirtualKeyCode::Yen => KeyCode::Yen, +        winit::event::VirtualKeyCode::Copy => KeyCode::Copy, +        winit::event::VirtualKeyCode::Paste => KeyCode::Paste, +        winit::event::VirtualKeyCode::Cut => KeyCode::Cut, +    } +} diff --git a/winit/src/lib.rs b/winit/src/lib.rs new file mode 100644 index 00000000..b08fcb6c --- /dev/null +++ b/winit/src/lib.rs @@ -0,0 +1,8 @@ +pub use iced_native::*; +pub use winit; + +pub mod conversion; + +mod application; + +pub use application::Application; | 
