diff options
Diffstat (limited to '')
-rw-r--r-- | winit/Cargo.toml | 13 | ||||
-rw-r--r-- | winit/src/application.rs | 185 | ||||
-rw-r--r-- | winit/src/conversion.rs | 199 | ||||
-rw-r--r-- | winit/src/lib.rs | 8 |
4 files changed, 405 insertions, 0 deletions
diff --git a/winit/Cargo.toml b/winit/Cargo.toml new file mode 100644 index 00000000..fa5d6adf --- /dev/null +++ b/winit/Cargo.toml @@ -0,0 +1,13 @@ +[package] +name = "iced_winit" +version = "0.1.0-alpha" +authors = ["Héctor Ramón Jiménez <hector0193@gmail.com>"] +edition = "2018" +description = "A winit runtime for Iced" +license = "MIT" +repository = "https://github.com/hecrj/iced" + +[dependencies] +iced_native = { version = "0.1.0-alpha", path = "../native" } +winit = { version = "0.20.0-alpha3", git = "https://github.com/hecrj/winit", branch = "redraw-requested-2.0" } +log = "0.4" 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; |