Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update winit to 0.30 #152

Closed
wants to merge 8 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion crates/bootstrap/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,6 @@ log = "0.4.17"
pollster = "0.3.0"
profiling = "1.0.6"
tracy-client = { version = "0.15.1", optional = true }

winit = "0.30.0"
wgpu = "0.20.1"
winit = "0.29.2"
301 changes: 174 additions & 127 deletions crates/bootstrap/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,17 @@ 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,
event::{StartCause, WindowEvent},
event_loop::{ActiveEventLoop, ControlFlow, EventLoop},
};

use winit::window::{Window, WindowAttributes, WindowId};
msparkles marked this conversation as resolved.
Show resolved Hide resolved
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");
Expand All @@ -34,7 +37,154 @@ 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<TextureId>,
}

struct App<T: ExampleBody> {
state: ExampleState,
yak: Yakui,

attributes: WindowAttributes,
start: Instant,

window: Option<Window>,
app: Option<Graphics>,

body: T,
}
msparkles marked this conversation as resolved.
Show resolved Hide resolved

impl<T: ExampleBody> ApplicationHandler for App<T> {
// 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);
}

let custom = app.renderer.add_texture(
custom_texture::generate(&app.device, &app.queue),
wgpu::FilterMode::Nearest,
wgpu::FilterMode::Nearest,
wgpu::FilterMode::Nearest,
wgpu::AddressMode::ClampToEdge,
);
self.state.custom = Some(custom);

self.app = Some(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,
_window_id: WindowId,
event: WindowEvent,
) {
if self
.app
.as_mut()
.unwrap()
.handle_window_event(&mut self.yak, &event, event_loop)
{
return;
}

// Handle window event.
match event {
WindowEvent::RedrawRequested => {
self.state.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(&mut self.state);

// 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 {
Expand All @@ -61,10 +211,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() {
Expand All @@ -73,55 +223,16 @@ 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,
wgpu::AddressMode::ClampToEdge,
);

// Add a custom font for some of the examples.
let fonts = yak.dom().get_global_or_init(Fonts::default);
Expand All @@ -134,89 +245,25 @@ async fn run(body: impl ExampleBody) {
fonts.add(font, Some("monospace"));

// 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: ExampleState {
time: 0.0,
monkey,
monkey_blurred,
brown_inlay,
custom: 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
Expand Down
2 changes: 1 addition & 1 deletion crates/demo/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ env_logger = "0.10.0"
log = "0.4.17"
pollster = "0.3.0"
wgpu = { version = "0.20.1", features = ["webgl"] }
winit = "0.29.2"
winit = "0.30.0"

[target.'cfg(target_arch = "wasm32")'.dependencies]
console_log = "0.2.1"
Expand Down
Loading
Loading