summaryrefslogtreecommitdiffstats
path: root/winit
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--winit/Cargo.toml13
-rw-r--r--winit/src/application.rs185
-rw-r--r--winit/src/conversion.rs199
-rw-r--r--winit/src/lib.rs8
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;