From 50bdb6098ad8a736e9c1faf8fe089670238eb4c3 Mon Sep 17 00:00:00 2001 From: NiseVoid <nisevoid@gmail.com> Date: Thu, 9 Mar 2023 15:05:50 +0100 Subject: [PATCH] Update to bevy 0.10 --- Cargo.toml | 6 +- examples/bevy_scene.rs | 14 +-- examples/conditional_widget.rs | 4 +- examples/context.rs | 2 +- examples/main_menu.rs | 4 +- examples/quads.rs | 2 +- examples/render_target.rs | 3 +- examples/simple_state.rs | 2 +- examples/tabs/tab_button.rs | 4 +- examples/test_no_startup.rs | 14 +-- examples/todo/input.rs | 2 +- examples/todo/items.rs | 2 +- examples/todo/todo.rs | 6 +- kayak_font/Cargo.toml | 5 +- kayak_font/src/bevy/mod.rs | 8 +- .../src/bevy/renderer/font_texture_cache.rs | 4 + kayak_ui_macros/Cargo.toml | 1 - src/camera/camera.rs | 27 +---- src/camera/mod.rs | 8 +- src/camera/ortho.rs | 17 +-- src/context.rs | 22 ++-- src/event.rs | 8 +- src/event_dispatcher.rs | 53 +++++---- src/input.rs | 15 ++- src/layout_dispatcher.rs | 2 +- src/on_event.rs | 14 +-- src/render/extract.rs | 35 ++++-- src/render/mod.rs | 108 ++++++++---------- src/render/ui_pass.rs | 11 +- src/render/unified/mod.rs | 19 +-- src/render/unified/pipeline.rs | 9 +- src/render/unified/shader.wgsl | 2 +- src/render/unified/text.rs | 6 +- src/widgets/app.rs | 22 +--- src/widgets/button.rs | 4 +- src/widgets/scroll/scroll_bar.rs | 4 +- src/widgets/scroll/scroll_box.rs | 4 +- src/widgets/text_box.rs | 4 +- src/widgets/window.rs | 6 +- src/window_size.rs | 30 +++-- 40 files changed, 258 insertions(+), 255 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f39ff22..817f111 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,6 @@ resolver = "2" authors = ["John Mitchell"] homepage = "https://github.com/StarArawn/kayak_ui" repository = "https://github.com/StarArawn/kayak_ui" -license = "MIT OR Apache-2.0" license-file = "LICENSE" exclude = ["assets/*", "screenshots/*", "book"] @@ -17,7 +16,7 @@ members = ["kayak_ui_macros", "kayak_font"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bevy = { version = "0.9", default-features = false, features = ["bevy_ui"] } +bevy = { version = "0.10", default-features = false, features = ["bevy_render", "bevy_asset", "bevy_winit", "bevy_core_pipeline"] } bytemuck = "1.12" dashmap = "5.4" kayak_font = { path = "./kayak_font", version = "0.2" } @@ -32,7 +31,8 @@ instant = "0.1" [dev-dependencies] fastrand = "1.8" -bevy-inspector-egui = "0.14" +bevy-inspector-egui = "0.18" +bevy = { version = "0.10", default-features = true } [[example]] name = "tabs" diff --git a/examples/bevy_scene.rs b/examples/bevy_scene.rs index bf8439b..ce16c36 100644 --- a/examples/bevy_scene.rs +++ b/examples/bevy_scene.rs @@ -1,6 +1,7 @@ use bevy::{ math::{Vec3Swizzles, Vec4Swizzles}, prelude::*, + window::PrimaryWindow, }; use kayak_ui::prelude::{widgets::*, *}; @@ -40,7 +41,7 @@ fn set_active_tile_target( cursor: Res<Input<MouseButton>>, event_context: Query<&EventDispatcher, With<GameUI>>, camera_transform: Query<&GlobalTransform, With<WorldCamera>>, - windows: Res<Windows>, + window: Query<&Window, With<PrimaryWindow>>, ) { if !cursor.just_pressed(MouseButton::Left) { // Only run this system when the mouse button is clicked @@ -62,7 +63,7 @@ fn set_active_tile_target( // } // ``` - let world_pos = cursor_to_world(&windows, camera_transform.single()); + let world_pos = cursor_to_world(window.single(), camera_transform.single()); let tile_pos = world_to_tile(world_pos); let mut tile = tile.single_mut(); tile.target = tile_pos; @@ -83,11 +84,11 @@ fn move_ghost_tile( mut tile: Query<&mut Transform, With<GhostTile>>, mut cursor_moved: EventReader<CursorMoved>, camera_transform: Query<&GlobalTransform, With<WorldCamera>>, - windows: Res<Windows>, + window: Query<&Window, With<PrimaryWindow>>, ) { for _ in cursor_moved.iter() { if !event_context.single().contains_cursor() { - let world_pos = cursor_to_world(&windows, camera_transform.single()); + let world_pos = cursor_to_world(window.single(), camera_transform.single()); let tile_pos = world_to_tile(world_pos); let mut ghost = tile.single_mut(); ghost.translation.x = tile_pos.x; @@ -139,8 +140,7 @@ fn world_setup(mut commands: Commands, active_color: Res<ActiveColor>) { } /// Get the world position of the cursor in 2D space -fn cursor_to_world(windows: &Windows, camera_transform: &GlobalTransform) -> Vec2 { - let window = windows.get_primary().unwrap(); +fn cursor_to_world(window: &Window, camera_transform: &GlobalTransform) -> Vec2 { let size = Vec2::new(window.width(), window.height()); let mut pos = window.cursor_position().unwrap_or_default(); @@ -181,7 +181,7 @@ fn startup( move |In((event_dispatcher_context, _, event, _)): In<( EventDispatcherContext, WidgetState, - Event, + KEvent, Entity, )>, mut active_color: ResMut<ActiveColor>| { diff --git a/examples/conditional_widget.rs b/examples/conditional_widget.rs index 1791f08..a3dd07f 100644 --- a/examples/conditional_widget.rs +++ b/examples/conditional_widget.rs @@ -48,7 +48,7 @@ fn my_widget_render( text: "Show Window".into(), }} on_event={OnEvent::new( - move |In((event_dispatcher_context, _, mut event, _entity)): In<(EventDispatcherContext, WidgetState, Event, Entity)>, + move |In((event_dispatcher_context, _, mut event, _entity)): In<(EventDispatcherContext, WidgetState, KEvent, Entity)>, mut query: Query<&mut MyWidgetState>| { event.prevent_default(); event.stop_propagation(); @@ -78,7 +78,7 @@ fn my_widget_render( <KButtonBundle button={KButton { text: "Hide Window".into(), ..Default::default() }} on_event={OnEvent::new( - move |In((event_dispatcher_context, _, mut event, _entity)): In<(EventDispatcherContext, WidgetState, Event, Entity)>, + move |In((event_dispatcher_context, _, mut event, _entity)): In<(EventDispatcherContext, WidgetState, KEvent, Entity)>, mut query: Query<&mut MyWidgetState>| { match event.event_type { EventType::Click(..) => { diff --git a/examples/context.rs b/examples/context.rs index a712519..0b8cac2 100644 --- a/examples/context.rs +++ b/examples/context.rs @@ -104,7 +104,7 @@ fn update_theme_button( move |In((event_dispatcher_context, _, event, _entity)): In<( EventDispatcherContext, WidgetState, - Event, + KEvent, Entity, )>, query: Query<&ThemeButton>, diff --git a/examples/main_menu.rs b/examples/main_menu.rs index 40949d6..d4dcb75 100644 --- a/examples/main_menu.rs +++ b/examples/main_menu.rs @@ -49,7 +49,7 @@ fn menu_button_render( move |In((event_dispatcher_context, _, mut event, _entity)): In<( EventDispatcherContext, WidgetState, - Event, + KEvent, Entity, )>, mut query: Query<&mut ButtonState>| { @@ -151,7 +151,7 @@ fn startup( move |In((event_dispatcher_context, _, event, _entity)): In<( EventDispatcherContext, WidgetState, - Event, + KEvent, Entity, )>, mut exit: EventWriter<AppExit>| { diff --git a/examples/quads.rs b/examples/quads.rs index 33216d6..431876e 100644 --- a/examples/quads.rs +++ b/examples/quads.rs @@ -39,7 +39,7 @@ fn my_quad_update( move |In((event_dispatcher_context, _, mut event, entity)): In<( EventDispatcherContext, WidgetState, - Event, + KEvent, Entity, )>, mut query: Query<(&mut KStyle, &MyQuad)>| { diff --git a/examples/render_target.rs b/examples/render_target.rs index d17bb3b..284771a 100644 --- a/examples/render_target.rs +++ b/examples/render_target.rs @@ -41,6 +41,7 @@ fn startup( label: None, size, dimension: TextureDimension::D2, + view_formats: &[TextureFormat::Bgra8UnormSrgb], format: TextureFormat::Bgra8UnormSrgb, mip_level_count: 1, sample_count: 1, @@ -84,7 +85,7 @@ fn startup( commands.spawn(UICameraBundle { camera: Camera { - priority: -1, + order: -1, target: RenderTarget::Image(image_handle.clone()), ..Camera::default() }, diff --git a/examples/simple_state.rs b/examples/simple_state.rs index 2e27896..4b1b64c 100644 --- a/examples/simple_state.rs +++ b/examples/simple_state.rs @@ -57,7 +57,7 @@ fn current_count_render( ..Default::default() }} on_event={OnEvent::new( - move |In((event_dispatcher_context, _, mut event, _entity)): In<(EventDispatcherContext, WidgetState, Event, Entity)>, + move |In((event_dispatcher_context, _, mut event, _entity)): In<(EventDispatcherContext, WidgetState, KEvent, Entity)>, mut query: Query<&mut CurrentCountState>| { match event.event_type { EventType::Click(..) => { diff --git a/examples/tabs/tab_button.rs b/examples/tabs/tab_button.rs index 2741684..811a515 100644 --- a/examples/tabs/tab_button.rs +++ b/examples/tabs/tab_button.rs @@ -1,7 +1,7 @@ use bevy::prelude::{Bundle, Color, Commands, Component, Entity, In, Query}; use kayak_ui::{ prelude::{ - rsx, widgets::KButtonBundle, Corner, Event, EventDispatcherContext, EventType, KStyle, + rsx, widgets::KButtonBundle, Corner, EventDispatcherContext, EventType, KEvent, KStyle, KayakWidgetContext, OnEvent, StyleProp, Units, Widget, WidgetName, WidgetState, }, widgets::KButton, @@ -57,7 +57,7 @@ pub fn tab_button_render( move |In((event_dispatcher_context, _, event, _entity)): In<( EventDispatcherContext, WidgetState, - Event, + KEvent, Entity, )>, mut query: Query<&mut TabContext>| { diff --git a/examples/test_no_startup.rs b/examples/test_no_startup.rs index 060081e..4f59b26 100644 --- a/examples/test_no_startup.rs +++ b/examples/test_no_startup.rs @@ -1,15 +1,15 @@ use bevy::prelude::*; use kayak_ui::prelude::{widgets::*, *}; -#[derive(Default, Clone, Copy, PartialEq, Hash, Eq, Debug)] +#[derive(Default, Clone, Copy, PartialEq, Hash, Eq, Debug, States)] pub enum GameState { #[default] First, Second, } -fn first_sys(mut state: ResMut<State<GameState>>) { - state.overwrite_replace(GameState::Second).unwrap(); +fn first_sys(mut state: ResMut<NextState<GameState>>) { + state.set(GameState::Second); } fn second_sys( @@ -42,8 +42,8 @@ fn main() { .add_plugins(DefaultPlugins) .add_plugin(KayakContextPlugin) .add_plugin(KayakWidgets) - .add_state(GameState::First) - .add_system_set(SystemSet::on_enter(GameState::First).with_system(first_sys)) - .add_system_set(SystemSet::on_enter(GameState::Second).with_system(second_sys)) - .run() + .add_state::<GameState>() + .add_system(first_sys.in_schedule(OnEnter(GameState::First))) + .add_system(second_sys.in_schedule(OnEnter(GameState::Second))) + .run(); } diff --git a/examples/todo/input.rs b/examples/todo/input.rs index 38b2da7..37017d9 100644 --- a/examples/todo/input.rs +++ b/examples/todo/input.rs @@ -52,7 +52,7 @@ pub fn render_todo_input( move |In((event_dispatcher_context, _, event, _)): In<( EventDispatcherContext, WidgetState, - Event, + KEvent, Entity, )>, mut todo_list: ResMut<TodoList>| { diff --git a/examples/todo/items.rs b/examples/todo/items.rs index 8892ece..d7adac9 100644 --- a/examples/todo/items.rs +++ b/examples/todo/items.rs @@ -50,7 +50,7 @@ pub fn render_todo_items( move |In((event_dispatcher_context, _, event, _)): In<( EventDispatcherContext, WidgetState, - Event, + KEvent, Entity, )>, mut todo_list: ResMut<TodoList>,| { diff --git a/examples/todo/todo.rs b/examples/todo/todo.rs index 4f62b88..2dc0a11 100644 --- a/examples/todo/todo.rs +++ b/examples/todo/todo.rs @@ -1,5 +1,5 @@ use bevy::prelude::*; -use bevy_inspector_egui::WorldInspectorPlugin; +use bevy_inspector_egui::quick::WorldInspectorPlugin; use kayak_ui::prelude::{widgets::*, *}; mod input; @@ -106,10 +106,10 @@ fn main() { App::new() .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0))) .add_plugins(DefaultPlugins) - .add_plugin(WorldInspectorPlugin::new()) + .add_plugin(WorldInspectorPlugin::default()) .add_plugin(KayakContextPlugin) .add_plugin(KayakWidgets) - .insert_non_send_resource(TodoList::new()) + .insert_resource(TodoList::new()) .add_startup_system(startup) .run() } diff --git a/kayak_font/Cargo.toml b/kayak_font/Cargo.toml index f219c8f..0802617 100644 --- a/kayak_font/Cargo.toml +++ b/kayak_font/Cargo.toml @@ -7,7 +7,6 @@ resolver = "2" authors = ["John Mitchell"] homepage = "https://github.com/StarArawn/kayak_ui" repository = "https://github.com/StarArawn/kayak_ui" -license = "MIT OR Apache-2.0" license-file = "../LICENSE" exclude = ["assets/*"] @@ -28,8 +27,8 @@ image = "0.24" # Provides UAX #14 line break segmentation xi-unicode = "0.3" -bevy = { version = "0.9", optional = true, default-features = false, features = ["bevy_asset", "bevy_render", "bevy_core_pipeline"] } +bevy = { version = "0.10", optional = true, default-features = false, features = ["bevy_asset", "bevy_render", "bevy_core_pipeline"] } [dev-dependencies] -bevy = { version = "0.9" } +bevy = { version = "0.10" } bytemuck = "1.12.0" diff --git a/kayak_font/src/bevy/mod.rs b/kayak_font/src/bevy/mod.rs index d214010..97da832 100644 --- a/kayak_font/src/bevy/mod.rs +++ b/kayak_font/src/bevy/mod.rs @@ -11,8 +11,8 @@ mod loader; mod renderer; mod plugin { - use bevy::prelude::{AddAsset, Plugin}; - use bevy::render::{RenderApp, RenderStage}; + use bevy::prelude::{AddAsset, IntoSystemAppConfig, IntoSystemConfig, Plugin}; + use bevy::render::{ExtractSchedule, RenderApp, RenderSet}; use crate::bevy::font_texture::init_font_texture; use crate::KayakFont; @@ -32,8 +32,8 @@ mod plugin { render_app .init_resource::<FontTextureCache>() .init_resource::<ExtractedFonts>() - .add_system_to_stage(RenderStage::Extract, extract_fonts) - .add_system_to_stage(RenderStage::Prepare, prepare_fonts); + .add_system(extract_fonts.in_schedule(ExtractSchedule)) + .add_system(prepare_fonts.in_set(RenderSet::Prepare)); } } } diff --git a/kayak_font/src/bevy/renderer/font_texture_cache.rs b/kayak_font/src/bevy/renderer/font_texture_cache.rs index ec1baec..eb7e153 100644 --- a/kayak_font/src/bevy/renderer/font_texture_cache.rs +++ b/kayak_font/src/bevy/renderer/font_texture_cache.rs @@ -126,6 +126,7 @@ impl FontTextureCache { mip_level_count: 1, sample_count: 1, dimension: TextureDimension::D2, + view_formats: &[format], format, usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST, }; @@ -163,6 +164,7 @@ impl FontTextureCache { texture, sampler, texture_view, + mip_level_count: 1, size: Vec2 { x: size.0 as f32, y: size.1 as f32, @@ -184,6 +186,7 @@ impl FontTextureCache { mip_level_count: 1, sample_count: 1, dimension: TextureDimension::D2, + view_formats: &[TextureFormat::Rgba8Unorm], format: TextureFormat::Rgba8Unorm, usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST, }; @@ -208,6 +211,7 @@ impl FontTextureCache { texture, sampler, texture_view, + mip_level_count: 1, size: Vec2 { x: 1.0, y: 1.0 }, texture_format: TextureFormat::Rgba8Unorm, }; diff --git a/kayak_ui_macros/Cargo.toml b/kayak_ui_macros/Cargo.toml index 9be77cd..155a45f 100644 --- a/kayak_ui_macros/Cargo.toml +++ b/kayak_ui_macros/Cargo.toml @@ -7,7 +7,6 @@ resolver = "2" authors = ["John Mitchell"] homepage = "https://github.com/StarArawn/kayak_ui" repository = "https://github.com/StarArawn/kayak_ui" -license = "MIT OR Apache-2.0" license-file = "../LICENSE" [lib] diff --git a/src/camera/camera.rs b/src/camera/camera.rs index f432ace..c9ca4a8 100644 --- a/src/camera/camera.rs +++ b/src/camera/camera.rs @@ -1,9 +1,8 @@ use bevy::{ core_pipeline::clear_color::ClearColorConfig, - ecs::query::QueryItem, - prelude::{Bundle, Component, GlobalTransform, Transform, With}, + prelude::{Bundle, Component, GlobalTransform, Transform, Vec2}, render::{ - camera::{Camera, CameraProjection, CameraRenderGraph, WindowOrigin}, + camera::{Camera, CameraProjection, CameraRenderGraph}, extract_component::ExtractComponent, primitives::Frustum, view::VisibleEntities, @@ -15,20 +14,11 @@ use crate::{context::KayakRootContext, event_dispatcher::EventDispatcher}; use super::ortho::UIOrthographicProjection; /// Kayak UI's default UI camera. -#[derive(Component, Clone, Default)] +#[derive(Component, ExtractComponent, Clone, Default)] pub struct CameraUIKayak { pub clear_color: ClearColorConfig, } -impl ExtractComponent for CameraUIKayak { - type Query = &'static Self; - type Filter = With<Camera>; - - fn extract_component(item: QueryItem<Self::Query>) -> Self { - item.clone() - } -} - /// Kayak UI's default UI camera bundle. #[derive(Bundle)] pub struct UICameraBundle { @@ -60,7 +50,7 @@ impl UICameraBundle { let orthographic_projection = UIOrthographicProjection { far, - window_origin: WindowOrigin::BottomLeft, + window_origin: Vec2::new(0.0, 0.0), ..Default::default() }; @@ -68,15 +58,10 @@ impl UICameraBundle { let view_projection = orthographic_projection.get_projection_matrix() * transform.compute_matrix().inverse(); - let frustum = Frustum::from_view_projection( - &view_projection, - &transform.translation, - &transform.back(), - orthographic_projection.far(), - ); + let frustum = Frustum::from_view_projection(&view_projection); UICameraBundle { camera: Camera { - priority: isize::MAX - 1, + order: isize::MAX - 1, ..Default::default() }, camera_render_graph: CameraRenderGraph::new(bevy::core_pipeline::core_2d::graph::NAME), diff --git a/src/camera/mod.rs b/src/camera/mod.rs index 60e86c3..9751b18 100644 --- a/src/camera/mod.rs +++ b/src/camera/mod.rs @@ -1,5 +1,5 @@ use bevy::{ - prelude::{CoreStage, Plugin}, + prelude::{CoreSet, IntoSystemConfig, Plugin}, render::{camera::CameraProjectionPlugin, extract_component::ExtractComponentPlugin}, }; @@ -13,9 +13,9 @@ pub struct KayakUICameraPlugin; impl Plugin for KayakUICameraPlugin { fn build(&self, app: &mut bevy::prelude::App) { - app.add_system_to_stage( - CoreStage::PostUpdate, - bevy::render::camera::camera_system::<UIOrthographicProjection>, + app.add_system( + bevy::render::camera::camera_system::<UIOrthographicProjection> + .in_base_set(CoreSet::PostUpdate), ) .add_plugin(CameraProjectionPlugin::<UIOrthographicProjection>::default()) .add_plugin(ExtractComponentPlugin::<CameraUIKayak>::default()); diff --git a/src/camera/ortho.rs b/src/camera/ortho.rs index bb7a800..cd6d024 100644 --- a/src/camera/ortho.rs +++ b/src/camera/ortho.rs @@ -1,9 +1,9 @@ use bevy::ecs::reflect::ReflectComponent; -use bevy::prelude::Component; +use bevy::prelude::{Component, Vec2}; use bevy::{ math::Mat4, reflect::Reflect, - render::camera::{CameraProjection, ScalingMode, WindowOrigin}, + render::camera::{CameraProjection, ScalingMode}, }; /// Kayak UI's default orthographic projection matrix @@ -19,7 +19,7 @@ pub struct UIOrthographicProjection { pub top: f32, pub near: f32, pub far: f32, - pub window_origin: WindowOrigin, + pub window_origin: Vec2, pub scaling_mode: ScalingMode, pub scale: f32, } @@ -39,8 +39,11 @@ impl CameraProjection for UIOrthographicProjection { } fn update(&mut self, width: f32, height: f32) { - match (&self.scaling_mode, &self.window_origin) { - (ScalingMode::WindowSize, WindowOrigin::BottomLeft) => { + match &self.scaling_mode { + ScalingMode::WindowSize(scale) => { + if *scale != 1.0 || self.window_origin != Vec2::ZERO { + return; + } self.left = 0.0; self.right = width; self.top = 0.0; @@ -64,8 +67,8 @@ impl Default for UIOrthographicProjection { top: 1.0, near: 0.0, far: 1000.0, - window_origin: WindowOrigin::Center, - scaling_mode: ScalingMode::WindowSize, + window_origin: Vec2::new(0.5, 0.5), + scaling_mode: ScalingMode::WindowSize(1.0), scale: 1.0, } } diff --git a/src/context.rs b/src/context.rs index ac9b8b8..1622952 100644 --- a/src/context.rs +++ b/src/context.rs @@ -4,6 +4,7 @@ use bevy::{ ecs::{event::ManualEventReader, system::CommandQueue}, prelude::*, utils::{HashMap, HashSet}, + window::PrimaryWindow, }; use morphorm::Hierarchy; @@ -18,7 +19,7 @@ use crate::{ input::query_world, layout::{LayoutCache, Rect}, layout_dispatcher::LayoutEventDispatcher, - node::{DirtyNode, WrappedIndex}, + node::{DirtyNode, Node, WrappedIndex}, prelude::KayakWidgetContext, render_primitive::RenderPrimitive, styles::{ @@ -990,9 +991,13 @@ impl Plugin for KayakContextPlugin { .add_plugin(crate::camera::KayakUICameraPlugin) .add_plugin(crate::render::BevyKayakUIRenderPlugin) .register_type::<Node>() - .add_system_to_stage(CoreStage::Update, crate::input::process_events) - .add_system_to_stage(CoreStage::PostUpdate, update_widgets_sys.at_start()) - .add_system_to_stage(CoreStage::PostUpdate, calculate_ui.at_end()) + .add_system(crate::input::process_events.in_base_set(CoreSet::Update)) + .add_system(update_widgets_sys.in_base_set(CoreSet::PostUpdate)) + .add_system( + calculate_ui + .after(update_widgets_sys) + .in_base_set(CoreSet::PostUpdate), + ) .add_system(crate::window_size::update_window_size); // Register reflection types. @@ -1061,10 +1066,11 @@ fn calculate_ui(world: &mut World) { } } - if let Some(ref mut windows) = world.get_resource_mut::<Windows>() { - if let Some(window) = windows.get_primary_mut() { - window.set_cursor_icon(context.current_cursor); - } + if let Ok(mut window) = world + .query_filtered::<&mut Window, With<PrimaryWindow>>() + .get_single_mut(world) + { + window.cursor.icon = context.current_cursor; } } diff --git a/src/event.rs b/src/event.rs index 7d24367..f8bf74e 100644 --- a/src/event.rs +++ b/src/event.rs @@ -8,7 +8,7 @@ use crate::{ /// An event type sent to widgets #[derive(Clone)] -pub struct Event { +pub struct KEvent { /// The node targeted by this event pub target: Entity, /// The current target of this event @@ -23,7 +23,7 @@ pub struct Event { pub(crate) on_change_systems: Vec<OnChange>, } -impl PartialEq for Event { +impl PartialEq for KEvent { fn eq(&self, other: &Self) -> bool { self.target == other.target && self.current_target == other.current_target @@ -33,7 +33,7 @@ impl PartialEq for Event { } } -impl Default for Event { +impl Default for KEvent { fn default() -> Self { Self { target: Entity::from_raw(0), @@ -46,7 +46,7 @@ impl Default for Event { } } -impl Event { +impl KEvent { /// Create a new event /// /// This is the preferred method for creating an event as it automatically sets up diff --git a/src/event_dispatcher.rs b/src/event_dispatcher.rs index e0750a8..fe7dc52 100644 --- a/src/event_dispatcher.rs +++ b/src/event_dispatcher.rs @@ -6,7 +6,7 @@ use bevy::{ use crate::{ context::KayakRootContext, cursor::{CursorEvent, PointerEvents, ScrollEvent, ScrollUnit}, - event::{Event, EventType}, + event::{EventType, KEvent}, focus_tree::FocusTree, input_event::{InputEvent, InputEventCategory}, keyboard_event::{KeyboardEvent, KeyboardModifiers}, @@ -185,21 +185,21 @@ impl EventDispatcher { self.dispatch_events(events, context, world); } - /// Dispatch an [Event](crate::Event) + /// Dispatch an [KEvent](crate::KEvent) #[allow(dead_code)] pub fn dispatch_event( &mut self, - event: Event, + event: KEvent, context: &mut KayakRootContext, world: &mut World, ) { self.dispatch_events(vec![event], context, world); } - /// Dispatch a set of [Events](crate::Event) + /// Dispatch a set of [KEvents](crate::KEvent) pub fn dispatch_events( &mut self, - events: Vec<Event>, + events: Vec<KEvent>, context: &mut KayakRootContext, world: &mut World, ) { @@ -211,7 +211,7 @@ impl EventDispatcher { // Create a copy of the event, specific for this node // This is to make sure unauthorized changes to the event are not propagated // (e.g., changing the event type, removing the target, etc.) - let mut node_event = Event { + let mut node_event = KEvent { current_target: index.0, ..event.clone() }; @@ -221,7 +221,7 @@ impl EventDispatcher { // --- Call Event --- // if let Some(mut entity) = world.get_entity_mut(index.0) { - if let Some(mut on_event) = entity.remove::<OnEvent>() { + if let Some(mut on_event) = entity.take::<OnEvent>() { let mut event_dispatcher_context = EventDispatcherContext { cursor_capture: self.cursor_capture, }; @@ -304,14 +304,14 @@ impl EventDispatcher { self.previous_events = next_events; } - /// Generates a stream of [Events](crate::Event) from a set of [InputEvents](crate::InputEvent) + /// Generates a stream of [KEvents](crate::KEvent) from a set of [InputEvents](crate::InputEvent) fn build_event_stream( &mut self, input_events: &[InputEvent], context: &mut KayakRootContext, world: &mut World, - ) -> Vec<Event> { - let mut event_stream = Vec::<Event>::new(); + ) -> Vec<KEvent> { + let mut event_stream = Vec::<KEvent>::new(); let mut states: HashMap<EventType, EventState> = HashMap::new(); if let Ok(node_tree) = context.tree.try_read() { @@ -451,7 +451,7 @@ impl EventDispatcher { // These events are ones that require a specific target and need the tree to be evaluated before selecting the best match for (event_type, state) in states { if let Some(node) = state.best_match { - event_stream.push(Event::new(node.0, event_type)); + event_stream.push(KEvent::new(node.0, event_type)); match event_type { EventType::Focus => { @@ -459,7 +459,7 @@ impl EventDispatcher { if let Some(current_focus) = focus_tree.current() { if current_focus != node { event_stream - .push(Event::new(current_focus.0, EventType::Blur)); + .push(KEvent::new(current_focus.0, EventType::Blur)); } } focus_tree.focus(node); @@ -476,7 +476,7 @@ impl EventDispatcher { if !had_focus_event && input_events.contains(&InputEvent::MouseLeftPress) { // A mouse press didn't contain a focus event -> blur if let Some(current_focus) = focus_tree.current() { - event_stream.push(Event::new(current_focus.0, EventType::Blur)); + event_stream.push(KEvent::new(current_focus.0, EventType::Blur)); focus_tree.blur(); } } @@ -513,7 +513,7 @@ impl EventDispatcher { /// * `widget_manager`: The widget manager /// * `ignore_layout`: Whether to ignore layout (useful for handling captured events) /// - /// returns: Vec<Event> + /// returns: Vec<KEvent> fn process_pointer_events( &mut self, input_event: &InputEvent, @@ -522,8 +522,8 @@ impl EventDispatcher { world: &mut World, context: &KayakRootContext, ignore_layout: bool, - ) -> Vec<Event> { - let mut event_stream = Vec::<Event>::new(); + ) -> Vec<KEvent> { + let mut event_stream = Vec::<KEvent>::new(); let (node, depth) = tree_node; // let widget_name = world.entity(node.0).get::<WidgetName>(); @@ -539,7 +539,7 @@ impl EventDispatcher { if was_contained { // Mouse out should fire even when event_stream - .push(Event::new(node.0, EventType::MouseOut(cursor_event))); + .push(KEvent::new(node.0, EventType::MouseOut(cursor_event))); // Self::update_state( // states, // (node, depth), @@ -688,12 +688,12 @@ impl EventDispatcher { input_event: &InputEvent, _states: &mut HashMap<EventType, EventState>, focus_tree: &FocusTree, - ) -> Vec<Event> { + ) -> Vec<KEvent> { let mut event_stream = Vec::new(); if let Some(current_focus) = focus_tree.current() { match input_event { InputEvent::CharEvent { c } => { - event_stream.push(Event::new(current_focus.0, EventType::CharInput { c: *c })) + event_stream.push(KEvent::new(current_focus.0, EventType::CharInput { c: *c })) } InputEvent::Keyboard { key, is_pressed } => { // === Modifers === // @@ -715,12 +715,12 @@ impl EventDispatcher { // === Event === // if *is_pressed { - event_stream.push(Event::new( + event_stream.push(KEvent::new( current_focus.0, EventType::KeyDown(KeyboardEvent::new(*key, self.keyboard_modifiers)), )) } else { - event_stream.push(Event::new( + event_stream.push(KEvent::new( current_focus.0, EventType::KeyUp(KeyboardEvent::new(*key, self.keyboard_modifiers)), )) @@ -789,7 +789,12 @@ impl EventDispatcher { } /// Executes default actions for events - fn execute_default(&mut self, event: Event, context: &mut KayakRootContext, world: &mut World) { + fn execute_default( + &mut self, + event: KEvent, + context: &mut KayakRootContext, + world: &mut World, + ) { match event.event_type { EventType::KeyDown(evt) => match evt.key() { KeyCode::Tab => { @@ -808,10 +813,10 @@ impl EventDispatcher { }; if let Some(index) = index { - let mut events = vec![Event::new(index.0, EventType::Focus)]; + let mut events = vec![KEvent::new(index.0, EventType::Focus)]; if let Some(current_focus) = current_focus { if current_focus != index { - events.push(Event::new(current_focus.0, EventType::Blur)); + events.push(KEvent::new(current_focus.0, EventType::Blur)); } } if let Ok(mut focus_tree) = context.focus_tree.try_write() { diff --git a/src/input.rs b/src/input.rs index c798500..d7adc3e 100644 --- a/src/input.rs +++ b/src/input.rs @@ -5,6 +5,7 @@ use bevy::{ ButtonState, }, prelude::*, + window::PrimaryWindow, }; use crate::{ @@ -14,13 +15,11 @@ use crate::{ }; pub(crate) fn process_events(world: &mut World) { - let window_size = if let Some(windows) = world.get_resource::<Windows>() { - if let Some(window) = windows.get_primary() { - Vec2::new(window.width(), window.height()) - } else { - log::warn!("Couldn't find primiary window!"); - return; - } + let window_size = if let Ok(window) = world + .query_filtered::<&Window, With<PrimaryWindow>>() + .get_single(&world) + { + Vec2::new(window.width(), window.height()) } else { log::warn!("Couldn't find primiary window!"); return; @@ -133,7 +132,7 @@ pub(crate) fn query_world<T: bevy::ecs::system::SystemParam + 'static, F, R>( world: &mut World, ) -> R where - F: FnOnce(<T::Fetch as bevy::ecs::system::SystemParamFetch<'_, '_>>::Item) -> R, + F: FnOnce(<T as bevy::ecs::system::SystemParam>::Item<'_, '_>) -> R, { let mut system_state = bevy::ecs::system::SystemState::<T>::new(world); let r = { diff --git a/src/layout_dispatcher.rs b/src/layout_dispatcher.rs index 913c7ea..fc4571b 100644 --- a/src/layout_dispatcher.rs +++ b/src/layout_dispatcher.rs @@ -67,7 +67,7 @@ impl LayoutEventDispatcher { // We should be able to just get layout from WidgetManager here // since the layouts will be calculated by this point if let Some(mut entity) = world.get_entity_mut(index.0) { - if let Some(mut on_layout) = entity.remove::<OnLayout>() { + if let Some(mut on_layout) = entity.take::<OnLayout>() { if let Some(rect) = layout_cache.rect.get(&index) { // dbg!(format!("Processing event for: {:?}", entity.id())); let layout_event = LayoutEvent::new(*rect, flags, index.0); diff --git a/src/on_event.rs b/src/on_event.rs index efe92c5..0f6ca06 100644 --- a/src/on_event.rs +++ b/src/on_event.rs @@ -2,7 +2,7 @@ use bevy::prelude::{Component, Entity, In, IntoSystem, System, World}; use std::fmt::{Debug, Formatter}; use std::sync::{Arc, RwLock}; -use crate::event::Event; +use crate::event::KEvent; use crate::event_dispatcher::EventDispatcherContext; use crate::widget_state::WidgetState; @@ -17,8 +17,8 @@ pub struct OnEvent { system: Arc< RwLock< dyn System< - In = (EventDispatcherContext, WidgetState, Event, Entity), - Out = (EventDispatcherContext, Event), + In = (EventDispatcherContext, WidgetState, KEvent, Entity), + Out = (EventDispatcherContext, KEvent), >, >, >, @@ -42,8 +42,8 @@ impl OnEvent { /// 2. The event pub fn new<Params>( system: impl IntoSystem< - (EventDispatcherContext, WidgetState, Event, Entity), - (EventDispatcherContext, Event), + (EventDispatcherContext, WidgetState, KEvent, Entity), + (EventDispatcherContext, KEvent), Params, >, ) -> OnEvent { @@ -61,9 +61,9 @@ impl OnEvent { mut event_dispatcher_context: EventDispatcherContext, widget_state: WidgetState, entity: Entity, - mut event: Event, + mut event: KEvent, world: &mut World, - ) -> (EventDispatcherContext, Event) { + ) -> (EventDispatcherContext, KEvent) { if let Ok(mut system) = self.system.try_write() { if !self.has_initialized { system.initialize(world); diff --git a/src/render/extract.rs b/src/render/extract.rs index e0a4ded..0990189 100644 --- a/src/render/extract.rs +++ b/src/render/extract.rs @@ -5,9 +5,12 @@ use crate::{ styles::Corner, }; use bevy::{ - prelude::{Assets, Camera, Color, Commands, Entity, Image, Plugin, Query, Rect, Res, Vec2}, - render::{Extract, RenderApp, RenderStage}, - window::Windows, + prelude::{ + Assets, Camera, Color, Commands, Entity, Image, IntoSystemAppConfig, Plugin, Query, Rect, + Res, Vec2, With, + }, + render::{Extract, ExtractSchedule, RenderApp}, + window::{PrimaryWindow, Window, WindowRef}, }; use kayak_font::KayakFont; @@ -25,7 +28,7 @@ pub struct BevyKayakUIExtractPlugin; impl Plugin for BevyKayakUIExtractPlugin { fn build(&self, app: &mut bevy::prelude::App) { let render_app = app.sub_app_mut(RenderApp); - render_app.add_system_to_stage(RenderStage::Extract, extract); + render_app.add_system(extract.in_schedule(ExtractSchedule)); } } @@ -37,18 +40,28 @@ pub fn extract( node_query: Extract<Query<&Node>>, widget_names: Extract<Query<&WidgetName>>, images: Extract<Res<Assets<Image>>>, - windows: Extract<Res<Windows>>, + primary_window: Extract<Query<&Window, With<PrimaryWindow>>>, + windows: Extract<Query<&Window>>, ) { let mut render_primitives = Vec::new(); for (entity, context, camera) in context_query.iter() { let dpi = match &camera.target { - bevy::render::camera::RenderTarget::Window(window_id) => { - if let Some(window) = windows.get(*window_id) { - window.scale_factor() as f32 - } else { - 1.0 + bevy::render::camera::RenderTarget::Window(window_ref) => match window_ref { + WindowRef::Primary => { + if let Ok(window) = primary_window.get_single() { + window.scale_factor() as f32 + } else { + 1.0 + } } - } + WindowRef::Entity(window_entity) => { + if let Ok(window) = windows.get(*window_entity) { + window.scale_factor() as f32 + } else { + 1.0 + } + } + }, _ => 1.0, }; let mut new_render_primitives = context.build_render_primitives(&node_query, &widget_names); diff --git a/src/render/mod.rs b/src/render/mod.rs index 67dbf1c..c6b1e80 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -1,9 +1,9 @@ use bevy::{ - prelude::{App, Camera, Commands, Entity, Plugin, Query, With}, + prelude::{App, Camera, Commands, Entity, IntoSystemAppConfig, Plugin, Query, With}, render::{ render_graph::{RenderGraph, RunGraphOnViewNode, SlotInfo, SlotType}, render_phase::{DrawFunctions, RenderPhase}, - Extract, RenderApp, RenderStage, + Extract, ExtractSchedule, RenderApp, }, }; @@ -43,7 +43,7 @@ impl Plugin for BevyKayakUIRenderPlugin { let render_app = app.sub_app_mut(RenderApp); render_app .init_resource::<DrawFunctions<TransparentUI>>() - .add_system_to_stage(RenderStage::Extract, extract_core_pipeline_camera_phases); + .add_system(extract_core_pipeline_camera_phases.in_schedule(ExtractSchedule)); // .add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<TransparentUI>); // let pass_node_ui = MainPassUINode::new(&mut render_app.world); @@ -78,32 +78,24 @@ impl Plugin for BevyKayakUIRenderPlugin { draw_ui_graph::node::MAIN_PASS, RunGraphOnViewNode::new(draw_ui_graph::NAME), ); - graph_2d - .add_node_edge( - bevy::core_pipeline::core_2d::graph::node::MAIN_PASS, - draw_ui_graph::node::MAIN_PASS, - ) - .unwrap(); - graph_2d - .add_slot_edge( - graph_2d.input_node().unwrap().id, - bevy::core_pipeline::core_2d::graph::input::VIEW_ENTITY, - draw_ui_graph::node::MAIN_PASS, - RunGraphOnViewNode::IN_VIEW, - ) - .unwrap(); - graph_2d - .add_node_edge( - bevy::core_pipeline::core_2d::graph::node::TONEMAPPING, - draw_ui_graph::node::MAIN_PASS, - ) - .unwrap(); - graph_2d - .add_node_edge( - draw_ui_graph::node::MAIN_PASS, - bevy::core_pipeline::core_2d::graph::node::UPSCALING, - ) - .unwrap(); + graph_2d.add_node_edge( + bevy::core_pipeline::core_2d::graph::node::MAIN_PASS, + draw_ui_graph::node::MAIN_PASS, + ); + graph_2d.add_slot_edge( + graph_2d.input_node().id, + bevy::core_pipeline::core_2d::graph::input::VIEW_ENTITY, + draw_ui_graph::node::MAIN_PASS, + RunGraphOnViewNode::IN_VIEW, + ); + graph_2d.add_node_edge( + bevy::core_pipeline::core_2d::graph::node::TONEMAPPING, + draw_ui_graph::node::MAIN_PASS, + ); + graph_2d.add_node_edge( + draw_ui_graph::node::MAIN_PASS, + bevy::core_pipeline::core_2d::graph::node::UPSCALING, + ); } if let Some(graph_3d) = graph.get_sub_graph_mut(bevy::core_pipeline::core_3d::graph::NAME) { @@ -112,32 +104,24 @@ impl Plugin for BevyKayakUIRenderPlugin { draw_ui_graph::node::MAIN_PASS, RunGraphOnViewNode::new(draw_ui_graph::NAME), ); - graph_3d - .add_node_edge( - bevy::core_pipeline::core_3d::graph::node::MAIN_PASS, - draw_ui_graph::node::MAIN_PASS, - ) - .unwrap(); - graph_3d - .add_node_edge( - bevy::core_pipeline::core_3d::graph::node::TONEMAPPING, - draw_ui_graph::node::MAIN_PASS, - ) - .unwrap(); - graph_3d - .add_node_edge( - draw_ui_graph::node::MAIN_PASS, - bevy::core_pipeline::core_3d::graph::node::UPSCALING, - ) - .unwrap(); - graph_3d - .add_slot_edge( - graph_3d.input_node().unwrap().id, - bevy::core_pipeline::core_3d::graph::input::VIEW_ENTITY, - draw_ui_graph::node::MAIN_PASS, - RunGraphOnViewNode::IN_VIEW, - ) - .unwrap(); + graph_3d.add_node_edge( + bevy::core_pipeline::core_3d::graph::node::MAIN_PASS, + draw_ui_graph::node::MAIN_PASS, + ); + graph_3d.add_node_edge( + bevy::core_pipeline::core_3d::graph::node::TONEMAPPING, + draw_ui_graph::node::MAIN_PASS, + ); + graph_3d.add_node_edge( + draw_ui_graph::node::MAIN_PASS, + bevy::core_pipeline::core_3d::graph::node::UPSCALING, + ); + graph_3d.add_slot_edge( + graph_3d.input_node().id, + bevy::core_pipeline::core_3d::graph::input::VIEW_ENTITY, + draw_ui_graph::node::MAIN_PASS, + RunGraphOnViewNode::IN_VIEW, + ); } app.add_plugin(font::TextRendererPlugin) @@ -154,14 +138,12 @@ fn get_ui_graph(render_app: &mut App) -> RenderGraph { draw_ui_graph::input::VIEW_ENTITY, SlotType::Entity, )]); - ui_graph - .add_slot_edge( - input_node_id, - draw_ui_graph::input::VIEW_ENTITY, - draw_ui_graph::node::MAIN_PASS, - MainPassUINode::IN_VIEW, - ) - .unwrap(); + ui_graph.add_slot_edge( + input_node_id, + draw_ui_graph::input::VIEW_ENTITY, + draw_ui_graph::node::MAIN_PASS, + MainPassUINode::IN_VIEW, + ); ui_graph } diff --git a/src/render/ui_pass.rs b/src/render/ui_pass.rs index 70ed333..89c510f 100644 --- a/src/render/ui_pass.rs +++ b/src/render/ui_pass.rs @@ -5,7 +5,7 @@ use bevy::render::render_phase::{DrawFunctionId, PhaseItem}; use bevy::render::render_resource::CachedRenderPipelineId; use bevy::render::{ render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType}, - render_phase::{DrawFunctions, RenderPhase, TrackedRenderPass}, + render_phase::{DrawFunctions, RenderPhase}, render_resource::{LoadOp, Operations, RenderPassDescriptor}, renderer::RenderContext, view::{ExtractedView, ViewTarget}, @@ -33,6 +33,10 @@ impl PhaseItem for TransparentUI { fn draw_function(&self) -> DrawFunctionId { self.draw_function } + + fn entity(&self) -> Entity { + self.entity + } } pub struct MainPassUINode { @@ -100,11 +104,8 @@ impl Node for MainPassUINode { .get_resource::<DrawFunctions<TransparentUI>>() .unwrap(); - let render_pass = render_context - .command_encoder - .begin_render_pass(&pass_descriptor); + let mut tracked_pass = render_context.begin_tracked_render_pass(pass_descriptor); let mut draw_functions = draw_functions.write(); - let mut tracked_pass = TrackedRenderPass::new(render_pass); for item in transparent_phase.items.iter() { let draw_function = draw_functions.get_mut(item.draw_function).unwrap(); draw_function.draw(world, &mut tracked_pass, view_entity, item); diff --git a/src/render/unified/mod.rs b/src/render/unified/mod.rs index 7efdec3..53a801a 100644 --- a/src/render/unified/mod.rs +++ b/src/render/unified/mod.rs @@ -1,12 +1,15 @@ use bevy::{ - prelude::{Assets, Commands, HandleUntyped, Plugin, Res, Resource}, + prelude::{ + Assets, Commands, HandleUntyped, IntoSystemAppConfig, IntoSystemConfig, Plugin, Query, Res, + Resource, With, + }, reflect::TypeUuid, render::{ render_phase::DrawFunctions, render_resource::{Shader, SpecializedRenderPipelines}, - Extract, RenderApp, RenderStage, + Extract, ExtractSchedule, RenderApp, RenderSet, }, - window::Windows, + window::{PrimaryWindow, Window}, }; use crate::{ @@ -41,9 +44,9 @@ impl Plugin for UnifiedRenderPlugin { .init_resource::<UnifiedPipeline>() .init_resource::<SpecializedRenderPipelines<UnifiedPipeline>>() .init_resource::<QuadMeta>() - .add_system_to_stage(RenderStage::Extract, extract_baseline) - .add_system_to_stage(RenderStage::Prepare, pipeline::prepare_quads) - .add_system_to_stage(RenderStage::Queue, pipeline::queue_quads); + .add_system(extract_baseline.in_schedule(ExtractSchedule)) + .add_system(pipeline::prepare_quads.in_set(RenderSet::Prepare)) + .add_system(pipeline::queue_quads.in_set(RenderSet::Queue)); let draw_quad = DrawUI::new(&mut render_app.world); @@ -61,10 +64,10 @@ pub struct Dpi(f32); pub fn extract_baseline( mut commands: Commands, - windows: Extract<Res<Windows>>, + windows: Extract<Query<&Window, With<PrimaryWindow>>>, window_size: Extract<Res<WindowSize>>, ) { - let dpi = if let Some(window) = windows.get_primary() { + let dpi = if let Ok(window) = windows.get_single() { window.scale_factor() as f32 } else { 1.0 diff --git a/src/render/unified/pipeline.rs b/src/render/unified/pipeline.rs index 4d5aa33..adc75a1 100644 --- a/src/render/unified/pipeline.rs +++ b/src/render/unified/pipeline.rs @@ -185,6 +185,7 @@ impl FromWorld for UnifiedPipeline { mip_level_count: 1, sample_count: 1, dimension: TextureDimension::D2, + view_formats: &[TextureFormat::Rgba8UnormSrgb], format: TextureFormat::Rgba8UnormSrgb, usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST, }; @@ -209,6 +210,7 @@ impl FromWorld for UnifiedPipeline { texture, sampler, texture_view, + mip_level_count: 1, size: Vec2::new(1.0, 1.0), texture_format: TextureFormat::Rgba8UnormSrgb, }; @@ -298,12 +300,12 @@ impl SpecializedRenderPipeline for UnifiedPipeline { write_mask: ColorWrites::ALL, })], }), - layout: Some(vec![ + layout: vec![ self.view_layout.clone(), self.font_image_layout.clone(), self.types_layout.clone(), self.image_layout.clone(), - ]), + ], primitive: PrimitiveState { front_face: FrontFace::Ccw, cull_mode: None, @@ -320,6 +322,7 @@ impl SpecializedRenderPipeline for UnifiedPipeline { alpha_to_coverage_enabled: false, }, label: Some("unified_pipeline".into()), + push_constant_ranges: vec![], } } } @@ -562,7 +565,7 @@ pub fn queue_quads( layout: &quad_pipeline.view_layout, })); - let key = UnifiedPipelineKey::from_msaa_samples(msaa.samples); + let key = UnifiedPipelineKey::from_msaa_samples(msaa.samples()); let spec_pipeline = pipelines.specialize(&mut pipeline_cache, &quad_pipeline, key); let draw_quad = draw_functions.read().get_id::<DrawUI>().unwrap(); diff --git a/src/render/unified/shader.wgsl b/src/render/unified/shader.wgsl index cc6061d..4341b7e 100644 --- a/src/render/unified/shader.wgsl +++ b/src/render/unified/shader.wgsl @@ -53,7 +53,7 @@ var image_texture: texture_2d<f32>; @group(3) @binding(1) var image_sampler: sampler; -let RADIUS: f32 = 0.1; +const RADIUS: f32 = 0.1; // Where P is the position in pixel space, B is the size of the box adn R is the radius of the current corner. fn sdRoundBox(p: vec2<f32>, b: vec2<f32>, r: f32) -> f32 { diff --git a/src/render/unified/text.rs b/src/render/unified/text.rs index 400917b..c9fdb93 100644 --- a/src/render/unified/text.rs +++ b/src/render/unified/text.rs @@ -1,10 +1,10 @@ use bevy::{ - prelude::{Plugin, Res, ResMut}, + prelude::{IntoSystemConfig, Plugin, Res, ResMut}, render::{ render_asset::RenderAssets, renderer::{RenderDevice, RenderQueue}, texture::Image, - RenderApp, RenderStage, + RenderApp, RenderSet, }, }; use kayak_font::bevy::{FontTextureCache, KayakFontPlugin}; @@ -19,7 +19,7 @@ impl Plugin for TextRendererPlugin { app.add_plugin(KayakFontPlugin); let render_app = app.sub_app_mut(RenderApp); - render_app.add_system_to_stage(RenderStage::Queue, create_and_update_font_cache_texture); + render_app.add_system(create_and_update_font_cache_texture.in_set(RenderSet::Queue)); } } fn create_and_update_font_cache_texture( diff --git a/src/widgets/app.rs b/src/widgets/app.rs index 6a0ba11..4b4aa96 100644 --- a/src/widgets/app.rs +++ b/src/widgets/app.rs @@ -1,4 +1,4 @@ -use bevy::prelude::*; +use bevy::{prelude::*, window::PrimaryWindow}; use kayak_ui_macros::rsx; use crate::{ @@ -45,7 +45,7 @@ pub fn app_update( In((widget_context, entity, previous_props_entity)): In<(KayakWidgetContext, Entity, Entity)>, widget_param: WidgetParam<KayakApp, EmptyState>, camera: Query<&Camera, With<CameraUIKayak>>, - windows: Res<Windows>, + windows: Query<&Window, With<PrimaryWindow>>, ) -> bool { let mut window_change = false; @@ -60,7 +60,7 @@ pub fn app_update( window_change = true; } } else { - let primary_window = windows.get_primary().unwrap(); + let primary_window = windows.single(); if app_style.0.width != StyleProp::Value(Units::Pixels(primary_window.width())) { window_change = true; @@ -84,8 +84,6 @@ pub fn app_render( mut commands: Commands, mut query: Query<(&KStyle, &mut ComputedStyles, &KChildren)>, camera: Query<&Camera, With<CameraUIKayak>>, - windows: Res<Windows>, - images: Res<Assets<Image>>, ) -> bool { let (mut width, mut height) = (0.0, 0.0); @@ -94,17 +92,9 @@ pub fn app_render( if let Some(size) = camera.logical_viewport_size() { width = size.x; height = size.y; - } else if let Some(viewport) = camera - .target - .get_render_target_info(&windows, &images) - .as_ref() - .map(|target_info| { - let scale = target_info.scale_factor; - (target_info.physical_size.as_dvec2() / scale).as_vec2() - }) - { - width = viewport.x; - height = viewport.y; + } else if let Some(viewport) = &camera.viewport { + width = viewport.physical_size.x as f32; + height = viewport.physical_size.y as f32; } } } diff --git a/src/widgets/button.rs b/src/widgets/button.rs index 96dee97..571e74d 100644 --- a/src/widgets/button.rs +++ b/src/widgets/button.rs @@ -7,7 +7,7 @@ use kayak_ui_macros::rsx; use crate::{ context::WidgetName, - event::{Event, EventType}, + event::{EventType, KEvent}, event_dispatcher::EventDispatcherContext, on_event::OnEvent, prelude::{KChildren, KayakWidgetContext, Units}, @@ -92,7 +92,7 @@ pub fn button_render( move |In((event_dispatcher_context, _, mut event, _entity)): In<( EventDispatcherContext, WidgetState, - Event, + KEvent, Entity, )>, mut query: Query<&mut ButtonState>| { diff --git a/src/widgets/scroll/scroll_bar.rs b/src/widgets/scroll/scroll_bar.rs index e45f3a1..f554548 100644 --- a/src/widgets/scroll/scroll_bar.rs +++ b/src/widgets/scroll/scroll_bar.rs @@ -3,7 +3,7 @@ use kayak_ui_macros::rsx; use crate::{ context::WidgetName, - event::{Event, EventType}, + event::{EventType, KEvent}, event_dispatcher::EventDispatcherContext, on_event::OnEvent, prelude::{KChildren, KayakWidgetContext}, @@ -206,7 +206,7 @@ pub fn scroll_bar_render( move |In((mut event_dispatcher_context, _, mut event, _entity)): In<( EventDispatcherContext, WidgetState, - Event, + KEvent, Entity, )>, mut query: Query<&mut ScrollContext>| { diff --git a/src/widgets/scroll/scroll_box.rs b/src/widgets/scroll/scroll_box.rs index 5d4643c..c59d7c2 100644 --- a/src/widgets/scroll/scroll_box.rs +++ b/src/widgets/scroll/scroll_box.rs @@ -4,7 +4,7 @@ use crate::{ children::KChildren, context::WidgetName, cursor::ScrollUnit, - event::{Event, EventType}, + event::{EventType, KEvent}, event_dispatcher::EventDispatcherContext, layout::{GeometryChanged, LayoutEvent}, on_event::OnEvent, @@ -185,7 +185,7 @@ pub fn scroll_box_render( move |In((event_dispatcher_context, _, mut event, _entity)): In<( EventDispatcherContext, WidgetState, - Event, + KEvent, Entity, )>, mut query: Query<&mut ScrollContext>| { diff --git a/src/widgets/text_box.rs b/src/widgets/text_box.rs index c0426e4..67cf244 100644 --- a/src/widgets/text_box.rs +++ b/src/widgets/text_box.rs @@ -6,7 +6,7 @@ use kayak_ui_macros::{constructor, rsx}; use crate::{ context::WidgetName, - event::{Event, EventType}, + event::{EventType, KEvent}, event_dispatcher::EventDispatcherContext, on_event::OnEvent, on_layout::OnLayout, @@ -185,7 +185,7 @@ pub fn text_box_render( move |In((event_dispatcher_context, _, mut event, _entity)): In<( EventDispatcherContext, WidgetState, - Event, + KEvent, Entity, )>, font_assets: Res<Assets<KayakFont>>, diff --git a/src/widgets/window.rs b/src/widgets/window.rs index dd00fd4..b362deb 100644 --- a/src/widgets/window.rs +++ b/src/widgets/window.rs @@ -7,7 +7,7 @@ use kayak_ui_macros::rsx; use crate::{ children::KChildren, context::WidgetName, - event::{Event, EventType}, + event::{EventType, KEvent}, event_dispatcher::EventDispatcherContext, on_event::OnEvent, prelude::KayakWidgetContext, @@ -132,7 +132,7 @@ pub fn window_render( move |In((event_dispatcher_context, _, mut event, _entity)): In<( EventDispatcherContext, WidgetState, - Event, + KEvent, Entity, )>, mut query: Query<&mut KWindowState>, @@ -226,7 +226,7 @@ pub fn window_render( move |In((mut event_dispatcher_context, _, mut event, entity)): In<( EventDispatcherContext, WidgetState, - Event, + KEvent, Entity, )>, mut query: Query<&mut KWindowState>| { diff --git a/src/window_size.rs b/src/window_size.rs index 4b17d24..dd274d5 100644 --- a/src/window_size.rs +++ b/src/window_size.rs @@ -10,32 +10,42 @@ pub struct WindowSize(pub f32, pub f32); pub fn update_window_size( mut window_resized_events: EventReader<WindowResized>, mut window_created_events: EventReader<WindowCreated>, - windows: Res<Windows>, + windows: Query<&Window>, mut window_size: ResMut<WindowSize>, ) { - let mut changed_window_ids = Vec::new(); + let mut changed_windows = Vec::new(); // handle resize events. latest events are handled first because we only want to resize each // window once - for event in window_resized_events.iter().rev() { - if changed_window_ids.contains(&event.id) { + for event in window_resized_events + .iter() + .collect::<Vec<_>>() + .iter() + .rev() + { + if changed_windows.contains(&event.window) { continue; } - changed_window_ids.push(event.id); + changed_windows.push(event.window); } // handle resize events. latest events are handled first because we only want to resize each // window once - for event in window_created_events.iter().rev() { - if changed_window_ids.contains(&event.id) { + for event in window_created_events + .iter() + .collect::<Vec<_>>() + .iter() + .rev() + { + if changed_windows.contains(&event.window) { continue; } - changed_window_ids.push(event.id); + changed_windows.push(event.window); } - for window_id in changed_window_ids { - if let Some(window) = windows.get(window_id) { + for window_entity in changed_windows { + if let Ok(window) = windows.get(window_entity) { let width = window.width(); let height = window.height(); *window_size = WindowSize(width, height); -- GitLab