From cb0dd4b80682069837ae8e2ce3717f8daa9e8411 Mon Sep 17 00:00:00 2001 From: Madeline Sparkles Date: Sun, 28 Apr 2024 10:27:28 +0800 Subject: [PATCH 1/7] update winit to 0.30 --- crates/bootstrap/Cargo.toml | 2 +- crates/bootstrap/src/lib.rs | 323 +++++++++++++++------------ crates/demo/Cargo.toml | 2 +- crates/demo/src/main.rs | 38 ++-- crates/yakui-app/Cargo.toml | 2 +- crates/yakui-app/src/lib.rs | 33 +-- crates/yakui-vulkan/Cargo.toml | 2 +- crates/yakui-vulkan/examples/demo.rs | 28 +-- crates/yakui-winit/Cargo.toml | 2 +- crates/yakui-winit/src/lib.rs | 64 ++---- 10 files changed, 246 insertions(+), 250 deletions(-) diff --git a/crates/bootstrap/Cargo.toml b/crates/bootstrap/Cargo.toml index 3745b5cd..f9311194 100644 --- a/crates/bootstrap/Cargo.toml +++ b/crates/bootstrap/Cargo.toml @@ -21,4 +21,4 @@ pollster = "0.3.0" profiling = "1.0.6" tracy-client = { version = "0.15.1", optional = true } wgpu = "0.19.0" -winit = "0.29.2" +winit = "0.30.0" diff --git a/crates/bootstrap/src/lib.rs b/crates/bootstrap/src/lib.rs index 0b188c84..467db1b7 100644 --- a/crates/bootstrap/src/lib.rs +++ b/crates/bootstrap/src/lib.rs @@ -3,14 +3,15 @@ mod custom_texture; use std::fmt::Write; use std::time::Instant; -use winit::dpi::LogicalSize; -use winit::event::{Event, WindowEvent}; -use winit::event_loop::{ControlFlow, EventLoop}; -use winit::window::WindowBuilder; +use winit::application::ApplicationHandler; +use winit::event::WindowEvent; +use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop}; +use winit::window::{Window, WindowAttributes, WindowId}; use yakui::font::{Font, FontSettings, Fonts}; use yakui::paint::{Texture, TextureFilter, TextureFormat}; -use yakui::{ManagedTextureId, Rect, TextureId, UVec2, Vec2}; +use yakui::{ManagedTextureId, Rect, TextureId, UVec2, Vec2, Yakui}; +use yakui_app::Graphics; const MONKEY_PNG: &[u8] = include_bytes!("../assets/monkey.png"); const MONKEY_BLURRED_PNG: &[u8] = include_bytes!("../assets/monkey-blurred.png"); @@ -37,6 +38,169 @@ pub struct ExampleState { pub custom: TextureId, } +struct App { + yak: Yakui, + + attributes: WindowAttributes, + start: Instant, + + state: Option, + window: Option, + app: Option, + + body: T, +} + +impl ApplicationHandler for App { + // This is a common indicator that you can create a window. + fn resumed(&mut self, event_loop: &ActiveEventLoop) { + let window = event_loop.create_window(self.attributes.clone()).unwrap(); + window.set_ime_allowed(true); + + let sample_count = get_sample_count(); + + let mut app = pollster::block_on(yakui_app::Graphics::new(&window, sample_count)); + + // By default, yakui_winit will measure the system's scale factor and pass + // it to yakui. + // + // Sometimes, it might be desirable to scale the UI by a different factor, + // like if your game has a "UI scale" option, if you're writing tests, or + // you want to ensure your widgets work at a different scale. + // + // In these examples, setting the YAKUI_FORCE_SCALE environment variable to + // a number will override the automatic scaling. + if let Some(scale) = get_scale_override() { + app.window_mut().set_automatic_scale_factor(false); + self.yak.set_scale_factor(scale); + } + + // In these examples, set YAKUI_INSET to force the UI to be contained within + // a sub-viewport with the given edge inset on all sides. + let inset = get_inset_override(); + if inset.is_some() { + app.window_mut().set_automatic_viewport(false); + } + + // Preload some textures for the examples to use. + let monkey = self + .yak + .add_texture(load_texture(MONKEY_PNG, TextureFilter::Linear)); + let monkey_blurred = self + .yak + .add_texture(load_texture(MONKEY_BLURRED_PNG, TextureFilter::Linear)); + let brown_inlay = self + .yak + .add_texture(load_texture(BROWN_INLAY_PNG, TextureFilter::Nearest)); + let custom = app.renderer.add_texture( + custom_texture::generate(&app.device, &app.queue), + wgpu::FilterMode::Nearest, + wgpu::FilterMode::Nearest, + wgpu::FilterMode::Nearest, + ); + + // Add a custom font for some of the examples. + let fonts = self.yak.dom().get_global_or_init(Fonts::default); + let font = Font::from_bytes( + include_bytes!("../assets/Hack-Regular.ttf").as_slice(), + FontSettings::default(), + ) + .unwrap(); + + fonts.add(font, Some("monospace")); + + self.state = Some(ExampleState { + time: 0.0, + monkey, + monkey_blurred, + brown_inlay, + custom, + }); + + self.app = Some(app); + self.window = Some(window); + } + + fn window_event( + &mut self, + event_loop: &ActiveEventLoop, + _window_id: WindowId, + event: WindowEvent, + ) { + if self + .app + .as_mut() + .unwrap() + .handle_event(&mut self.yak, &event, event_loop) + { + return; + } + + // Handle window event. + match event { + WindowEvent::RedrawRequested => { + self.state.as_mut().unwrap().time = (Instant::now() - self.start).as_secs_f32(); + + { + profiling::scope!("Build UI"); + + // Every frame, call yak.start() to begin building the UI for + // this frame. Any yakui widget calls that happen on this thread + // between start() and finish() will be applied to this yakui + // State. + self.yak.start(); + + // Call out to the body of the program, passing in a bit of + // shared state that all the examples can use. + self.body.run(self.state.as_mut().unwrap()); + + // Finish building the UI and compute this frame's layout. + self.yak.finish(); + } + + // The example graphics abstraction calls yak.paint() to get + // access to the underlying PaintDom, which holds all the state + // about how to paint widgets. + self.app.as_mut().unwrap().paint(&mut self.yak, { + let bg = yakui::colors::BACKGROUND_1.to_linear(); + wgpu::Color { + r: bg.x.into(), + g: bg.y.into(), + b: bg.z.into(), + a: 1.0, + } + }); + + profiling::finish_frame!(); + + self.window.as_ref().unwrap().request_redraw(); + } + + WindowEvent::MouseInput { state, button, .. } => { + // This print is a handy way to show which mouse events are + // handled by yakui, and which ones will make it to the + // underlying application. + if button == winit::event::MouseButton::Left { + println!("Left mouse button {state:?}"); + } + } + + WindowEvent::Resized(size) => { + let inset = get_inset_override(); + if let Some(inset) = inset { + let size = Vec2::new(size.width as f32, size.height as f32); + self.yak.set_unscaled_viewport(Rect::from_pos_size( + Vec2::splat(inset), + size - Vec2::splat(inset * 2.0), + )); + } + } + + _ => (), + } + } +} + pub trait ExampleBody: 'static { fn run(&self, state: &mut ExampleState); } @@ -61,10 +225,10 @@ pub fn start(body: impl ExampleBody) { init_logging(); - pollster::block_on(run(body)); + run(body); } -async fn run(body: impl ExampleBody) { +fn run(body: impl ExampleBody) { let mut title = "yakui demo".to_owned(); if let Some(scale) = get_scale_override() { @@ -73,149 +237,26 @@ async fn run(body: impl ExampleBody) { // Normal winit setup for an EventLoop and Window. let event_loop = EventLoop::new().unwrap(); - let window = WindowBuilder::new() - .with_title(title) - .with_inner_size(LogicalSize::new(800.0, 600.0)) - .build(&event_loop) - .unwrap(); - - window.set_ime_allowed(true); - - let sample_count = get_sample_count(); - - // yakui_app has a helper for setting up winit and wgpu. - let mut app = yakui_app::Graphics::new(&window, sample_count).await; + let window_attribute = Window::default_attributes().with_title(title); // Create our yakui state. This is where our UI will be built, laid out, and // calculations for painting will happen. - let mut yak = yakui::Yakui::new(); - - // By default, yakui_winit will measure the system's scale factor and pass - // it to yakui. - // - // Sometimes, it might be desirable to scale the UI by a different factor, - // like if your game has a "UI scale" option, if you're writing tests, or - // you want to ensure your widgets work at a different scale. - // - // In these examples, setting the YAKUI_FORCE_SCALE environment variable to - // a number will override the automatic scaling. - if let Some(scale) = get_scale_override() { - app.window_mut().set_automatic_scale_factor(false); - yak.set_scale_factor(scale); - } - - // In these examples, set YAKUI_INSET to force the UI to be contained within - // a sub-viewport with the given edge inset on all sides. - let inset = get_inset_override(); - if inset.is_some() { - app.window_mut().set_automatic_viewport(false); - } - - // Preload some textures for the examples to use. - let monkey = yak.add_texture(load_texture(MONKEY_PNG, TextureFilter::Linear)); - let monkey_blurred = yak.add_texture(load_texture(MONKEY_BLURRED_PNG, TextureFilter::Linear)); - let brown_inlay = yak.add_texture(load_texture(BROWN_INLAY_PNG, TextureFilter::Nearest)); - let custom = app.renderer.add_texture( - custom_texture::generate(&app.device, &app.queue), - wgpu::FilterMode::Nearest, - wgpu::FilterMode::Nearest, - wgpu::FilterMode::Nearest, - ); - - // Add a custom font for some of the examples. - let fonts = yak.dom().get_global_or_init(Fonts::default); - let font = Font::from_bytes( - include_bytes!("../assets/Hack-Regular.ttf").as_slice(), - FontSettings::default(), - ) - .unwrap(); - - fonts.add(font, Some("monospace")); + let yak = yakui::Yakui::new(); // Set up some default state that we'll modify later. - let mut state = ExampleState { - time: 0.0, - monkey, - monkey_blurred, - brown_inlay, - custom, + let mut app = App { + yak, + attributes: window_attribute, + start: Instant::now(), + state: None, + window: None, + app: None, + body, }; - let start = Instant::now(); - event_loop.set_control_flow(ControlFlow::Poll); - event_loop - .run(move |event, elwt| { - if app.handle_event(&mut yak, &event, elwt) { - return; - } - - match event { - Event::AboutToWait => { - state.time = (Instant::now() - start).as_secs_f32(); - - { - profiling::scope!("Build UI"); - - // Every frame, call yak.start() to begin building the UI for - // this frame. Any yakui widget calls that happen on this thread - // between start() and finish() will be applied to this yakui - // State. - yak.start(); - // Call out to the body of the program, passing in a bit of - // shared state that all the examples can use. - body.run(&mut state); - - // Finish building the UI and compute this frame's layout. - yak.finish(); - } - - // The example graphics abstraction calls yak.paint() to get - // access to the underlying PaintDom, which holds all the state - // about how to paint widgets. - app.paint(&mut yak, { - let bg = yakui::colors::BACKGROUND_1.to_linear(); - wgpu::Color { - r: bg.x.into(), - g: bg.y.into(), - b: bg.z.into(), - a: 1.0, - } - }); - - profiling::finish_frame!(); - } - - Event::WindowEvent { - event: WindowEvent::MouseInput { state, button, .. }, - .. - } => { - // This print is a handy way to show which mouse events are - // handled by yakui, and which ones will make it to the - // underlying application. - if button == winit::event::MouseButton::Left { - println!("Left mouse button {state:?}"); - } - } - - Event::WindowEvent { - event: WindowEvent::Resized(size), - .. - } => { - if let Some(inset) = inset { - let size = Vec2::new(size.width as f32, size.height as f32); - yak.set_unscaled_viewport(Rect::from_pos_size( - Vec2::splat(inset), - size - Vec2::splat(inset * 2.0), - )); - } - } - - _ => (), - } - }) - .unwrap(); + event_loop.run_app(&mut app).unwrap(); } /// This function takes some bytes and turns it into a yakui `Texture` object so diff --git a/crates/demo/Cargo.toml b/crates/demo/Cargo.toml index eb819e60..4e5ad11c 100644 --- a/crates/demo/Cargo.toml +++ b/crates/demo/Cargo.toml @@ -15,7 +15,7 @@ env_logger = "0.10.0" log = "0.4.17" pollster = "0.3.0" wgpu = { version = "0.19.0", features = ["webgl"] } -winit = "0.29.2" +winit = "0.30.0" [target.'cfg(target_arch = "wasm32")'.dependencies] console_log = "0.2.1" diff --git a/crates/demo/src/main.rs b/crates/demo/src/main.rs index 0ec73c0c..77507e3a 100644 --- a/crates/demo/src/main.rs +++ b/crates/demo/src/main.rs @@ -24,36 +24,40 @@ async fn run(event_loop: EventLoop<()>, window: Window) { let mut graphics = Graphics::new(&window, 4).await; event_loop.set_control_flow(ControlFlow::Poll); + // FIXME update this as well event_loop - .run(move |event, elwt| { - if graphics.handle_event(&mut yak, &event, elwt) { - return; + .run(move |event, event_loop| match event { + Event::AboutToWait => { + window.request_redraw(); } - match event { - Event::AboutToWait => { - window.request_redraw(); - } + Event::WindowEvent { + event: WindowEvent::RedrawRequested { .. }, + .. + } => { + yak.start(); + app(); + yak.finish(); - Event::WindowEvent { - event: WindowEvent::RedrawRequested { .. }, - .. - } => { - yak.start(); - app(); - yak.finish(); + graphics.paint(&mut yak, wgpu::Color::BLACK); + } - graphics.paint(&mut yak, wgpu::Color::BLACK); + Event::WindowEvent { event, .. } => { + if graphics.handle_event(&mut yak, &event, event_loop) { + return; } - _ => (), } + _ => (), }) .unwrap(); } fn main() { let event_loop = EventLoop::new().unwrap(); - let window = winit::window::Window::new(&event_loop).unwrap(); + // FIXME update this as well + let window = event_loop + .create_window(winit::window::Window::default_attributes()) + .unwrap(); #[cfg(not(target_arch = "wasm32"))] { diff --git a/crates/yakui-app/Cargo.toml b/crates/yakui-app/Cargo.toml index 9ff1696d..80200ce3 100644 --- a/crates/yakui-app/Cargo.toml +++ b/crates/yakui-app/Cargo.toml @@ -18,4 +18,4 @@ yakui-wgpu = { path = "../yakui-wgpu" } profiling = { version = "1.0.6", optional = true } wgpu = "0.19.0" -winit = { version = "0.29.2", features = ["rwh_05"] } +winit = { version = "0.30.0" } diff --git a/crates/yakui-app/src/lib.rs b/crates/yakui-app/src/lib.rs index 24a68664..af6421a8 100644 --- a/crates/yakui-app/src/lib.rs +++ b/crates/yakui-app/src/lib.rs @@ -1,11 +1,6 @@ mod multisampling; -use winit::{ - dpi::PhysicalSize, - event::{Event, StartCause, WindowEvent}, - event_loop::EventLoopWindowTarget, - window::Window, -}; +use winit::{dpi::PhysicalSize, event::WindowEvent, event_loop::ActiveEventLoop, window::Window}; use multisampling::Multisampling; @@ -184,11 +179,11 @@ impl Graphics { output.present(); } - pub fn handle_event( + pub fn handle_event( &mut self, yak: &mut yakui::Yakui, - event: &Event, - elwt: &EventLoopWindowTarget, + event: &WindowEvent, + event_loop: &ActiveEventLoop, ) -> bool { // yakui_winit will return whether it handled an event. This means that // yakui believes it should handle that event exclusively, like if a @@ -198,25 +193,11 @@ impl Graphics { } match event { - Event::WindowEvent { - event: WindowEvent::CloseRequested, - .. - } => { - elwt.exit(); + WindowEvent::CloseRequested => { + event_loop.exit(); } - Event::NewEvents(cause) => { - if *cause == StartCause::Init { - self.is_init = true; - } else { - self.is_init = false; - } - } - - Event::WindowEvent { - event: WindowEvent::Resized(size), - .. - } => { + WindowEvent::Resized(size) => { // Ignore any resize events that happen during Winit's // initialization in order to avoid racing the wgpu swapchain // and causing issues. diff --git a/crates/yakui-vulkan/Cargo.toml b/crates/yakui-vulkan/Cargo.toml index 88182ebb..cec67cf5 100644 --- a/crates/yakui-vulkan/Cargo.toml +++ b/crates/yakui-vulkan/Cargo.toml @@ -19,4 +19,4 @@ ash = { version = "0.38", default-features = false, features = ["loaded"] } ash-window = "0.13" image = "0.24.5" raw-window-handle = "0.6.0" -winit = "0.29.2" +winit = "0.30.0" diff --git a/crates/yakui-vulkan/examples/demo.rs b/crates/yakui-vulkan/examples/demo.rs index b17cc7b5..518a9a82 100644 --- a/crates/yakui-vulkan/examples/demo.rs +++ b/crates/yakui-vulkan/examples/demo.rs @@ -68,7 +68,7 @@ fn main() { let mut winit_initializing = true; event_loop.set_control_flow(ControlFlow::Poll); - _ = event_loop.run(|event, elwt| match event { + _ = event_loop.run(|event, event_loop| match event { Event::WindowEvent { event: WindowEvent::CloseRequested @@ -82,7 +82,7 @@ fn main() { .. }, .. - } => elwt.exit(), + } => event_loop.exit(), Event::NewEvents(cause) => { if cause == winit::event::StartCause::Init { @@ -696,17 +696,19 @@ fn init_winit( window_width: u32, window_height: u32, ) -> (winit::event_loop::EventLoop<()>, winit::window::Window) { - use winit::{event_loop::EventLoopBuilder, window::WindowBuilder}; - - let event_loop = EventLoopBuilder::new().build().unwrap(); - - let window = WindowBuilder::new() - .with_title("Yakui Vulkan - Test") - .with_inner_size(winit::dpi::LogicalSize::new( - f64::from(window_width), - f64::from(window_height), - )) - .build(&event_loop) + use winit::{event_loop::EventLoop, window::Window}; + + let event_loop = EventLoop::new().unwrap(); + + let window = event_loop + .create_window( + Window::default_attributes() + .with_title("Yakui Vulkan - Test") + .with_inner_size(winit::dpi::LogicalSize::new( + f64::from(window_width), + f64::from(window_height), + )), + ) .unwrap(); (event_loop, window) } diff --git a/crates/yakui-winit/Cargo.toml b/crates/yakui-winit/Cargo.toml index 3103cc08..fc707131 100644 --- a/crates/yakui-winit/Cargo.toml +++ b/crates/yakui-winit/Cargo.toml @@ -12,4 +12,4 @@ edition = "2021" yakui-core = { path = "../yakui-core", version = "0.2.0" } # TODO: Disable all default features once supported (https://github.com/rust-windowing/winit/issues/3174) -winit = { version = "0.29.2", default-features = false, features = ["x11"] } +winit = { version = "0.30.0", default-features = false, features = ["x11"] } diff --git a/crates/yakui-winit/src/lib.rs b/crates/yakui-winit/src/lib.rs index 533be1c2..f68c7044 100644 --- a/crates/yakui-winit/src/lib.rs +++ b/crates/yakui-winit/src/lib.rs @@ -1,10 +1,7 @@ mod keys; use winit::dpi::PhysicalSize; -use winit::event::{ - ElementState, Event as WinitEvent, MouseButton as WinitMouseButton, MouseScrollDelta, - WindowEvent, -}; +use winit::event::{ElementState, MouseButton as WinitMouseButton, MouseScrollDelta, WindowEvent}; use winit::window::Window; use yakui_core::event::Event; use yakui_core::geometry::{Rect, Vec2}; @@ -53,11 +50,7 @@ impl YakuiWinit { self.auto_viewport = enabled; } - pub fn handle_event( - &mut self, - state: &mut yakui_core::Yakui, - event: &WinitEvent, - ) -> bool { + pub fn handle_event(&mut self, state: &mut yakui_core::Yakui, event: &WindowEvent) -> bool { if let Some(init) = self.init.take() { let size = Vec2::new(init.size.width as f32, init.size.height as f32); state.set_surface_size(size); @@ -72,10 +65,7 @@ impl YakuiWinit { } match event { - WinitEvent::WindowEvent { - event: WindowEvent::Resized(size), - .. - } => { + WindowEvent::Resized(size) => { let size = Vec2::new(size.width as f32, size.height as f32); state.set_surface_size(size); @@ -85,34 +75,22 @@ impl YakuiWinit { false } - WinitEvent::WindowEvent { - event: WindowEvent::ScaleFactorChanged { scale_factor, .. }, - .. - } => { + WindowEvent::ScaleFactorChanged { scale_factor, .. } => { if self.auto_scale { state.set_scale_factor(*scale_factor as f32) } false } - WinitEvent::WindowEvent { - event: WindowEvent::CursorMoved { position, .. }, - .. - } => { + WindowEvent::CursorMoved { position, .. } => { let pos = Vec2::new(position.x as f32, position.y as f32); state.handle_event(Event::CursorMoved(Some(pos))) } - WinitEvent::WindowEvent { - event: WindowEvent::CursorLeft { .. }, - .. - } => state.handle_event(Event::CursorMoved(None)), - WinitEvent::WindowEvent { - event: - WindowEvent::MouseInput { - button, - state: button_state, - .. - }, + WindowEvent::CursorLeft { .. } => state.handle_event(Event::CursorMoved(None)), + + WindowEvent::MouseInput { + button, + state: button_state, .. } => { let button = match button { @@ -129,10 +107,7 @@ impl YakuiWinit { state.handle_event(Event::MouseButtonChanged { button, down }) } - WinitEvent::WindowEvent { - event: WindowEvent::MouseWheel { delta, .. }, - .. - } => { + WindowEvent::MouseWheel { delta, .. } => { // Observed logical pixels per scroll wheel increment in Windows on Chrome const LINE_HEIGHT: f32 = 100.0 / 3.0; @@ -149,14 +124,10 @@ impl YakuiWinit { state.handle_event(Event::MouseScroll { delta }) } - WinitEvent::WindowEvent { - event: WindowEvent::ModifiersChanged(mods), - .. - } => state.handle_event(Event::ModifiersChanged(from_winit_modifiers(mods.state()))), - WinitEvent::WindowEvent { - event: WindowEvent::KeyboardInput { event, .. }, - .. - } => { + WindowEvent::ModifiersChanged(mods) => { + state.handle_event(Event::ModifiersChanged(from_winit_modifiers(mods.state()))) + } + WindowEvent::KeyboardInput { event, .. } => { if event.state == ElementState::Pressed { if let Some(text) = event.text.as_ref() { for c in text.chars() { @@ -180,10 +151,7 @@ impl YakuiWinit { } } - WinitEvent::WindowEvent { - event: WindowEvent::Ime(winit::event::Ime::Commit(text)), - .. - } => { + WindowEvent::Ime(winit::event::Ime::Commit(text)) => { for c in text.chars() { state.handle_event(Event::TextInput(c)); } From e99d43274bfc13689fba87576c682c710836a72f Mon Sep 17 00:00:00 2001 From: Madeline Sparkles Date: Mon, 6 May 2024 08:05:30 +0800 Subject: [PATCH 2/7] fully commenting out the is_init stuff until further notice --- crates/yakui-app/src/lib.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/crates/yakui-app/src/lib.rs b/crates/yakui-app/src/lib.rs index af6421a8..fdf93137 100644 --- a/crates/yakui-app/src/lib.rs +++ b/crates/yakui-app/src/lib.rs @@ -18,9 +18,10 @@ pub struct Graphics { window: yakui_winit::YakuiWinit, pub renderer: yakui_wgpu::YakuiWgpu, - + /* /// Tracks whether winit is still initializing is_init: bool, + */ } impl Graphics { @@ -105,8 +106,7 @@ impl Graphics { renderer, window, - - is_init: true, + /*is_init: true,*/ } } @@ -203,9 +203,9 @@ impl Graphics { // and causing issues. // // https://github.com/rust-windowing/winit/issues/2094 - if self.is_init { + /*if self.is_init { return false; - } + }*/ self.resize(*size); } From 1235a73d74c16bbf4f0ed7d7f363b02585a2b50f Mon Sep 17 00:00:00 2001 From: Madeline Sparkles Date: Mon, 6 May 2024 08:06:04 +0800 Subject: [PATCH 3/7] remove fixmes --- crates/demo/src/main.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/crates/demo/src/main.rs b/crates/demo/src/main.rs index 77507e3a..03a7c32a 100644 --- a/crates/demo/src/main.rs +++ b/crates/demo/src/main.rs @@ -24,7 +24,6 @@ async fn run(event_loop: EventLoop<()>, window: Window) { let mut graphics = Graphics::new(&window, 4).await; event_loop.set_control_flow(ControlFlow::Poll); - // FIXME update this as well event_loop .run(move |event, event_loop| match event { Event::AboutToWait => { @@ -54,7 +53,6 @@ async fn run(event_loop: EventLoop<()>, window: Window) { fn main() { let event_loop = EventLoop::new().unwrap(); - // FIXME update this as well let window = event_loop .create_window(winit::window::Window::default_attributes()) .unwrap(); From b33a92dee21bc5597391accd390825226bcb009a Mon Sep 17 00:00:00 2001 From: Madeline Sparkles Date: Mon, 6 May 2024 08:07:15 +0800 Subject: [PATCH 4/7] regroup winit imports --- crates/bootstrap/src/lib.rs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/crates/bootstrap/src/lib.rs b/crates/bootstrap/src/lib.rs index 467db1b7..65a45b2e 100644 --- a/crates/bootstrap/src/lib.rs +++ b/crates/bootstrap/src/lib.rs @@ -3,9 +3,11 @@ mod custom_texture; use std::fmt::Write; use std::time::Instant; -use winit::application::ApplicationHandler; -use winit::event::WindowEvent; -use winit::event_loop::{ActiveEventLoop, ControlFlow, EventLoop}; +use winit::{ + application::ApplicationHandler, + event::WindowEvent, + event_loop::{ActiveEventLoop, ControlFlow, EventLoop}, +}; use winit::window::{Window, WindowAttributes, WindowId}; use yakui::font::{Font, FontSettings, Fonts}; From 11f957bc404e9547e3c1846c3c11050df6a130ed Mon Sep 17 00:00:00 2001 From: Madeline Sparkles Date: Mon, 6 May 2024 08:12:11 +0800 Subject: [PATCH 5/7] cleanup some --- crates/bootstrap/src/lib.rs | 62 ++++++++++++--------------- crates/yakui/examples/custom_image.rs | 2 +- 2 files changed, 29 insertions(+), 35 deletions(-) diff --git a/crates/bootstrap/src/lib.rs b/crates/bootstrap/src/lib.rs index 65a45b2e..be722cd6 100644 --- a/crates/bootstrap/src/lib.rs +++ b/crates/bootstrap/src/lib.rs @@ -37,16 +37,16 @@ pub struct ExampleState { /// `TextureId` represents either a managed texture or a texture owned by /// the renderer. This image is generated in `custom_texture.rs` and /// uploaded with wgpu directly. - pub custom: TextureId, + pub custom: Option, } struct App { + state: ExampleState, yak: Yakui, attributes: WindowAttributes, start: Instant, - state: Option, window: Option, app: Option, @@ -84,40 +84,13 @@ impl ApplicationHandler for App { app.window_mut().set_automatic_viewport(false); } - // Preload some textures for the examples to use. - let monkey = self - .yak - .add_texture(load_texture(MONKEY_PNG, TextureFilter::Linear)); - let monkey_blurred = self - .yak - .add_texture(load_texture(MONKEY_BLURRED_PNG, TextureFilter::Linear)); - let brown_inlay = self - .yak - .add_texture(load_texture(BROWN_INLAY_PNG, TextureFilter::Nearest)); let custom = app.renderer.add_texture( custom_texture::generate(&app.device, &app.queue), wgpu::FilterMode::Nearest, wgpu::FilterMode::Nearest, wgpu::FilterMode::Nearest, ); - - // Add a custom font for some of the examples. - let fonts = self.yak.dom().get_global_or_init(Fonts::default); - let font = Font::from_bytes( - include_bytes!("../assets/Hack-Regular.ttf").as_slice(), - FontSettings::default(), - ) - .unwrap(); - - fonts.add(font, Some("monospace")); - - self.state = Some(ExampleState { - time: 0.0, - monkey, - monkey_blurred, - brown_inlay, - custom, - }); + self.state.custom = Some(custom); self.app = Some(app); self.window = Some(window); @@ -141,7 +114,7 @@ impl ApplicationHandler for App { // Handle window event. match event { WindowEvent::RedrawRequested => { - self.state.as_mut().unwrap().time = (Instant::now() - self.start).as_secs_f32(); + self.state.time = (Instant::now() - self.start).as_secs_f32(); { profiling::scope!("Build UI"); @@ -154,7 +127,7 @@ impl ApplicationHandler for App { // Call out to the body of the program, passing in a bit of // shared state that all the examples can use. - self.body.run(self.state.as_mut().unwrap()); + self.body.run(&mut self.state); // Finish building the UI and compute this frame's layout. self.yak.finish(); @@ -243,14 +216,35 @@ fn run(body: impl ExampleBody) { // Create our yakui state. This is where our UI will be built, laid out, and // calculations for painting will happen. - let yak = yakui::Yakui::new(); + let mut yak = yakui::Yakui::new(); + + // Preload some textures for the examples to use. + let monkey = yak.add_texture(load_texture(MONKEY_PNG, TextureFilter::Linear)); + let monkey_blurred = yak.add_texture(load_texture(MONKEY_BLURRED_PNG, TextureFilter::Linear)); + let brown_inlay = yak.add_texture(load_texture(BROWN_INLAY_PNG, TextureFilter::Nearest)); + + // Add a custom font for some of the examples. + let fonts = yak.dom().get_global_or_init(Fonts::default); + let font = Font::from_bytes( + include_bytes!("../assets/Hack-Regular.ttf").as_slice(), + FontSettings::default(), + ) + .unwrap(); + + fonts.add(font, Some("monospace")); // Set up some default state that we'll modify later. let mut app = App { yak, attributes: window_attribute, start: Instant::now(), - state: None, + state: ExampleState { + time: 0.0, + monkey, + monkey_blurred, + brown_inlay, + custom: None, + }, window: None, app: None, body, diff --git a/crates/yakui/examples/custom_image.rs b/crates/yakui/examples/custom_image.rs index 0c65861b..7009e8ad 100644 --- a/crates/yakui/examples/custom_image.rs +++ b/crates/yakui/examples/custom_image.rs @@ -3,7 +3,7 @@ use yakui::image; use bootstrap::ExampleState; pub fn run(state: &mut ExampleState) { - image(state.custom, [512.0, 512.0]); + image(state.custom.unwrap(), [512.0, 512.0]); } fn main() { From 02bf8cb3409f0abce7359c2cee367f49a2d01a50 Mon Sep 17 00:00:00 2001 From: Madeline Sparkles Date: Sat, 29 Jun 2024 12:12:00 +0800 Subject: [PATCH 6/7] fix build --- crates/bootstrap/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/crates/bootstrap/src/lib.rs b/crates/bootstrap/src/lib.rs index be722cd6..b4178243 100644 --- a/crates/bootstrap/src/lib.rs +++ b/crates/bootstrap/src/lib.rs @@ -89,6 +89,7 @@ impl ApplicationHandler for App { wgpu::FilterMode::Nearest, wgpu::FilterMode::Nearest, wgpu::FilterMode::Nearest, + wgpu::AddressMode::ClampToEdge, ); self.state.custom = Some(custom); From 939f78c9007286c048a6a40aa9c11624a7834133 Mon Sep 17 00:00:00 2001 From: Madeline Sparkles Date: Sat, 29 Jun 2024 12:19:22 +0800 Subject: [PATCH 7/7] revert removal of is_init bugfix and rename handle_event to handle_window_event --- crates/bootstrap/src/lib.rs | 14 ++++++++++++-- crates/demo/src/main.rs | 12 ++++++++++-- crates/yakui-app/src/lib.rs | 14 ++++++-------- crates/yakui-winit/src/lib.rs | 6 +++++- 4 files changed, 33 insertions(+), 13 deletions(-) diff --git a/crates/bootstrap/src/lib.rs b/crates/bootstrap/src/lib.rs index b4178243..3e2fc618 100644 --- a/crates/bootstrap/src/lib.rs +++ b/crates/bootstrap/src/lib.rs @@ -5,7 +5,7 @@ use std::time::Instant; use winit::{ application::ApplicationHandler, - event::WindowEvent, + event::{StartCause, WindowEvent}, event_loop::{ActiveEventLoop, ControlFlow, EventLoop}, }; @@ -97,6 +97,16 @@ impl ApplicationHandler for App { self.window = Some(window); } + fn new_events(&mut self, _event_loop: &ActiveEventLoop, cause: winit::event::StartCause) { + if let Some(app) = self.app.as_mut() { + if cause == StartCause::Init { + app.is_init = true; + } else { + app.is_init = false; + } + } + } + fn window_event( &mut self, event_loop: &ActiveEventLoop, @@ -107,7 +117,7 @@ impl ApplicationHandler for App { .app .as_mut() .unwrap() - .handle_event(&mut self.yak, &event, event_loop) + .handle_window_event(&mut self.yak, &event, event_loop) { return; } diff --git a/crates/demo/src/main.rs b/crates/demo/src/main.rs index 03a7c32a..b1e3125c 100644 --- a/crates/demo/src/main.rs +++ b/crates/demo/src/main.rs @@ -1,5 +1,5 @@ use winit::{ - event::{Event, WindowEvent}, + event::{Event, StartCause, WindowEvent}, event_loop::{ControlFlow, EventLoop}, window::Window, }; @@ -30,6 +30,14 @@ async fn run(event_loop: EventLoop<()>, window: Window) { window.request_redraw(); } + Event::NewEvents(cause) => { + if cause == StartCause::Init { + graphics.is_init = true; + } else { + graphics.is_init = false; + } + } + Event::WindowEvent { event: WindowEvent::RedrawRequested { .. }, .. @@ -42,7 +50,7 @@ async fn run(event_loop: EventLoop<()>, window: Window) { } Event::WindowEvent { event, .. } => { - if graphics.handle_event(&mut yak, &event, event_loop) { + if graphics.handle_window_event(&mut yak, &event, event_loop) { return; } } diff --git a/crates/yakui-app/src/lib.rs b/crates/yakui-app/src/lib.rs index fdf93137..2ff7ee7e 100644 --- a/crates/yakui-app/src/lib.rs +++ b/crates/yakui-app/src/lib.rs @@ -18,10 +18,8 @@ pub struct Graphics { window: yakui_winit::YakuiWinit, pub renderer: yakui_wgpu::YakuiWgpu, - /* /// Tracks whether winit is still initializing - is_init: bool, - */ + pub is_init: bool, } impl Graphics { @@ -106,7 +104,7 @@ impl Graphics { renderer, window, - /*is_init: true,*/ + is_init: true, } } @@ -179,7 +177,7 @@ impl Graphics { output.present(); } - pub fn handle_event( + pub fn handle_window_event( &mut self, yak: &mut yakui::Yakui, event: &WindowEvent, @@ -188,7 +186,7 @@ impl Graphics { // yakui_winit will return whether it handled an event. This means that // yakui believes it should handle that event exclusively, like if a // button in the UI was clicked. - if self.window.handle_event(yak, event) { + if self.window.handle_window_event(yak, event) { return true; } @@ -203,9 +201,9 @@ impl Graphics { // and causing issues. // // https://github.com/rust-windowing/winit/issues/2094 - /*if self.is_init { + if self.is_init { return false; - }*/ + } self.resize(*size); } diff --git a/crates/yakui-winit/src/lib.rs b/crates/yakui-winit/src/lib.rs index f68c7044..2a201936 100644 --- a/crates/yakui-winit/src/lib.rs +++ b/crates/yakui-winit/src/lib.rs @@ -50,7 +50,11 @@ impl YakuiWinit { self.auto_viewport = enabled; } - pub fn handle_event(&mut self, state: &mut yakui_core::Yakui, event: &WindowEvent) -> bool { + pub fn handle_window_event( + &mut self, + state: &mut yakui_core::Yakui, + event: &WindowEvent, + ) -> bool { if let Some(init) = self.init.take() { let size = Vec2::new(init.size.width as f32, init.size.height as f32); state.set_surface_size(size);