diff --git a/Cargo.toml b/Cargo.toml index be47d22f62faef09491e5ca652496b853d46909c..10084b05c693a9bbfa63c51dc2e49fc7c72af6ed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,7 +10,7 @@ members = ["kayak_ui_macros"] # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -bevy = { git = "https://github.com/bevyengine/bevy", rev="9423cb6a8d0c140e11364eb23c8feb7e576baa8c" } +bevy = { git = "https://github.com/bevyengine/bevy", rev="4bcf49b2ea6fb5f42388b0e15d204020053ee5c7" } bytemuck = "1.12" dashmap = "5.4" kayak_font = { path = "./kayak_font" } @@ -18,6 +18,7 @@ morphorm = { git = "https://github.com/geom3trik/morphorm", rev = "1243152d4cebe kayak_ui_macros = { path = "./kayak_ui_macros" } indexmap = "1.9" log = "0.4" +bitflags = "1.3.2" [dev-dependencies] fastrand = "1.8" diff --git a/examples/clipping.rs b/examples/clipping.rs index 86d30277efa2d6ba06aa87a9cb8296ad942fb969..47ab6c1ae0bdf421e98c37492206c26f94aae75f 100644 --- a/examples/clipping.rs +++ b/examples/clipping.rs @@ -1,7 +1,4 @@ -use bevy::{ - prelude::{App, AssetServer, Commands, ImageSettings, Res, ResMut}, - DefaultPlugins, -}; +use bevy::prelude::*; use kayak_ui::prelude::{widgets::*, KStyle, *}; fn startup( @@ -64,8 +61,8 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sed tellus neque. fn main() { App::new() - .insert_resource(ImageSettings::default_nearest()) - .add_plugins(DefaultPlugins) + .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0))) + .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) .add_plugin(KayakContextPlugin) .add_plugin(KayakWidgets) .add_startup_system(startup) diff --git a/examples/context.rs b/examples/context.rs index 3e26f1f3ec43205006a8a67298a262a7a5bde980..3a2e6547dc94a6998085709256861a67205bcd87 100644 --- a/examples/context.rs +++ b/examples/context.rs @@ -7,13 +7,7 @@ //! for better specificity and makes local contexts much easier to manage. In the case of theming, //! this allows us to have multiple active themes, even if they are nested within each other! -use bevy::{ - prelude::{ - App as BevyApp, AssetServer, Bundle, Color, Commands, Component, Entity, ImageSettings, In, - Query, Res, ResMut, Vec2, - }, - DefaultPlugins, -}; +use bevy::prelude::*; use kayak_ui::prelude::{widgets::*, KStyle, *}; /// The color theme struct we will be using across our demo widgets @@ -395,8 +389,7 @@ fn startup( } fn main() { - BevyApp::new() - .insert_resource(ImageSettings::default_nearest()) + App::new() .add_plugins(DefaultPlugins) .add_plugin(KayakContextPlugin) .add_plugin(KayakWidgets) diff --git a/examples/hello_world.rs b/examples/hello_world.rs index b4269ab36499098921b1273eaafa695b5c92cf8e..759faea50664bc48945c5f566d60dceba749e24f 100644 --- a/examples/hello_world.rs +++ b/examples/hello_world.rs @@ -27,7 +27,6 @@ fn startup( fn main() { App::new() - .insert_resource(ImageSettings::default_nearest()) .add_plugins(DefaultPlugins) .add_plugin(KayakContextPlugin) .add_plugin(KayakWidgets) diff --git a/examples/hello_world_no_macro.rs b/examples/hello_world_no_macro.rs index 7f951a46e7ce7103893ccef06791c642f9206930..02192bd40bff8da9f1a3b7ec24ba02ac7080eb0f 100644 --- a/examples/hello_world_no_macro.rs +++ b/examples/hello_world_no_macro.rs @@ -53,7 +53,6 @@ fn startup( } fn main() { App::new() - .insert_resource(ImageSettings::default_nearest()) .add_plugins(DefaultPlugins) .add_plugin(KayakContextPlugin) .add_plugin(KayakWidgets) diff --git a/examples/image.rs b/examples/image.rs index 7b89333a1333e55a9c999dd50caa3d524499f32b..ec2cd59cae5215c3d26f11876671632457424482 100644 --- a/examples/image.rs +++ b/examples/image.rs @@ -1,7 +1,4 @@ -use bevy::{ - prelude::{App as BevyApp, AssetServer, Commands, ImageSettings, Res, ResMut}, - DefaultPlugins, -}; +use bevy::prelude::*; use kayak_ui::prelude::{widgets::*, KStyle, *}; fn startup( @@ -19,10 +16,10 @@ fn startup( let parent_id = None; rsx! { <KayakAppBundle> - <ImageBundle + <KImageBundle image={Image(image.clone())} style={KStyle { - position_type: StyleProp::Value(PositionType::SelfDirected), + position_type: StyleProp::Value(KPositionType::SelfDirected), left: StyleProp::Value(Units::Pixels(10.0)), top: StyleProp::Value(Units::Pixels(10.0)), border_radius: StyleProp::Value(Corner::all(500.0)), @@ -37,9 +34,8 @@ fn startup( } fn main() { - BevyApp::new() - .insert_resource(ImageSettings::default_nearest()) - .add_plugins(DefaultPlugins) + App::new() + .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) .add_plugin(KayakContextPlugin) .add_plugin(KayakWidgets) .add_startup_system(startup) diff --git a/examples/nine_patch.rs b/examples/nine_patch.rs index f2558ddb5469aa67aeb5046d28b099f864c1673c..5dd452dcb9a8215f4c5ab60d4924ba34098b688a 100644 --- a/examples/nine_patch.rs +++ b/examples/nine_patch.rs @@ -1,7 +1,4 @@ -use bevy::{ - prelude::{App as BevyApp, AssetServer, Commands, ImageSettings, Res, ResMut}, - DefaultPlugins, -}; +use bevy::prelude::*; use kayak_ui::prelude::{widgets::*, KStyle, *}; fn startup( @@ -59,9 +56,8 @@ fn startup( } fn main() { - BevyApp::new() - .insert_resource(ImageSettings::default_nearest()) - .add_plugins(DefaultPlugins) + App::new() + .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) .add_plugin(KayakContextPlugin) .add_plugin(KayakWidgets) .add_startup_system(startup) diff --git a/examples/quads.rs b/examples/quads.rs index 4bd8422b2735b5e91eff512f4b0fe0e21e4fc7e6..168141653585e02bad14362dfa8ab9f3cf529da5 100644 --- a/examples/quads.rs +++ b/examples/quads.rs @@ -1,10 +1,6 @@ use bevy::{ diagnostic::{FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin}, - prelude::{ - App as BevyApp, AssetServer, Bundle, Color, Commands, Component, Entity, In, Query, Res, - ResMut, Vec2, - }, - DefaultPlugins, + prelude::*, }; use kayak_ui::prelude::{widgets::*, KStyle, *}; @@ -22,7 +18,7 @@ fn my_quad_update( if let Ok((quad, mut style, mut on_event)) = query.get_mut(entity) { if style.render_command.resolve() != RenderCommand::Quad { style.render_command = StyleProp::Value(RenderCommand::Quad); - style.position_type = StyleProp::Value(PositionType::SelfDirected); + style.position_type = StyleProp::Value(KPositionType::SelfDirected); style.left = StyleProp::Value(Units::Pixels(quad.pos.x)); style.top = StyleProp::Value(Units::Pixels(quad.pos.y)); style.width = StyleProp::Value(Units::Pixels(quad.size.x)); @@ -126,7 +122,7 @@ fn startup( } fn main() { - BevyApp::new() + App::new() .add_plugins(DefaultPlugins) .add_plugin(LogDiagnosticsPlugin::default()) .add_plugin(FrameTimeDiagnosticsPlugin::default()) diff --git a/examples/scrolling.rs b/examples/scrolling.rs index 3c0498236bfb17dd0e04b65c063449981708c8ed..6c87b1b662266b4786278e69df4029146b7206ae 100644 --- a/examples/scrolling.rs +++ b/examples/scrolling.rs @@ -1,7 +1,4 @@ -use bevy::{ - prelude::{App, AssetServer, Commands, ImageSettings, Res, ResMut}, - DefaultPlugins, -}; +use bevy::prelude::*; use kayak_ui::prelude::{widgets::*, KStyle, *}; fn startup( @@ -66,8 +63,7 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras sed tellus neque. fn main() { App::new() - .insert_resource(ImageSettings::default_nearest()) - .add_plugins(DefaultPlugins) + .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) .add_plugin(KayakContextPlugin) .add_plugin(KayakWidgets) .add_startup_system(startup) diff --git a/examples/simple_state.rs b/examples/simple_state.rs index bbae0446c66a9b52c0c6fd078d462284536890fd..00fe63cfae480e374bc3d1b6824e8fc1aee52201 100644 --- a/examples/simple_state.rs +++ b/examples/simple_state.rs @@ -1,10 +1,4 @@ -use bevy::{ - prelude::{ - App as BevyApp, AssetServer, Bundle, Commands, Component, Entity, In, Query, Res, ResMut, - Vec2, - }, - DefaultPlugins, -}; +use bevy::prelude::*; use kayak_ui::prelude::{widgets::*, *}; #[derive(Component, Default, PartialEq, Clone)] @@ -125,7 +119,8 @@ fn startup( } fn main() { - BevyApp::new() + App::new() + .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0))) .add_plugins(DefaultPlugins) .add_plugin(KayakContextPlugin) .add_plugin(KayakWidgets) diff --git a/examples/tabs/tabs.rs b/examples/tabs/tabs.rs index d0827ced5c1130e6272a2081448cb6fd4ca9902f..416f0a98b7fe934b102cbe988c0ab04518657d30 100644 --- a/examples/tabs/tabs.rs +++ b/examples/tabs/tabs.rs @@ -89,7 +89,6 @@ fn startup( fn main() { App::new() - .insert_resource(ImageSettings::default_nearest()) .add_plugins(DefaultPlugins) .add_plugin(KayakContextPlugin) .add_plugin(KayakWidgets) diff --git a/examples/text.rs b/examples/text.rs index b7d90b3d3c91efea7f74fcf0fb40a0a9465d719c..b53322d9d60a81c68c802cc328ab5c385d75ab45 100644 --- a/examples/text.rs +++ b/examples/text.rs @@ -1,10 +1,4 @@ -use bevy::{ - prelude::{ - App as BevyApp, AssetServer, Bundle, Commands, Component, Entity, In, Input, KeyCode, - Query, Res, ResMut, Resource, - }, - DefaultPlugins, -}; +use bevy::prelude::*; use kayak_ui::prelude::{widgets::*, KStyle, *}; #[derive(Component, Default, Clone, PartialEq)] @@ -12,24 +6,35 @@ pub struct MyWidgetProps { pub foo: u32, } -fn my_widget_1_update( +fn my_widget_1_render( In((_widget_context, entity)): In<(KayakWidgetContext, Entity)>, my_resource: Res<MyResource>, mut query: Query<(&mut MyWidgetProps, &mut KStyle)>, ) -> bool { - if my_resource.is_changed() || my_resource.is_added() { - if let Ok((mut my_widget, mut style)) = query.get_mut(entity) { - my_widget.foo = my_resource.0; - dbg!(my_widget.foo); - style.render_command = StyleProp::Value(RenderCommand::Text { - content: format!("My number is: {}", my_widget.foo).to_string(), - alignment: Alignment::Start, - }); - return true; - } + if let Ok((mut my_widget, mut style)) = query.get_mut(entity) { + my_widget.foo = my_resource.0; + dbg!(my_widget.foo); + // Note: We will see two updates because of the mutable change to styles. + // Which means when foo changes MyWidget will render twice! + style.render_command = StyleProp::Value(RenderCommand::Text { + content: format!("My number is: {}", my_widget.foo).to_string(), + alignment: Alignment::Start, + }); } - false + true +} + +// Our own version of widget_update that handles resource change events. +pub fn widget_update_with_resource< + Props: PartialEq + Component + Clone, + State: PartialEq + Component + Clone, +>( + In((widget_context, entity, previous_entity)): In<(KayakWidgetContext, Entity, Entity)>, + my_resource: Res<MyResource>, + widget_param: WidgetParam<Props, State>, +) -> bool { + widget_param.has_changed(&widget_context, entity, previous_entity) || my_resource.is_changed() } impl Widget for MyWidgetProps {} @@ -68,8 +73,8 @@ fn startup( widget_context.add_widget_data::<MyWidgetProps, EmptyState>(); widget_context.add_widget_system( MyWidgetProps::default().get_name(), - widget_update::<MyWidgetProps, EmptyState>, - my_widget_1_update, + widget_update_with_resource::<MyWidgetProps, EmptyState>, + my_widget_1_render, ); rsx! { <KayakAppBundle><MyWidgetBundle props={MyWidgetProps { foo: 0 }} /></KayakAppBundle> @@ -84,7 +89,7 @@ fn update_resource(keyboard_input: Res<Input<KeyCode>>, mut my_resource: ResMut< } fn main() { - BevyApp::new() + App::new() .add_plugins(DefaultPlugins) .add_plugin(KayakContextPlugin) .add_plugin(KayakWidgets) diff --git a/examples/text_box.rs b/examples/text_box.rs index 707d43da49baa888cfc62d2ac45ac8c6d1e8275a..0e3f4096df13a6f75dad816c2e113cb9b9599016 100644 --- a/examples/text_box.rs +++ b/examples/text_box.rs @@ -1,10 +1,4 @@ -use bevy::{ - prelude::{ - App as BevyApp, AssetServer, Bundle, Commands, Component, Entity, In, Query, Res, ResMut, - Vec2, - }, - DefaultPlugins, -}; +use bevy::prelude::*; use kayak_ui::prelude::{widgets::*, *}; #[derive(Component, Default, Clone, PartialEq)] @@ -126,7 +120,7 @@ fn startup( } fn main() { - BevyApp::new() + App::new() .add_plugins(DefaultPlugins) .add_plugin(KayakContextPlugin) .add_plugin(KayakWidgets) diff --git a/examples/texture_atlas.rs b/examples/texture_atlas.rs index b609a879ebc0d456cda7f2455a92c018b47abead..369ad473a0268377c27e891f6ef47cd6c4116cc7 100644 --- a/examples/texture_atlas.rs +++ b/examples/texture_atlas.rs @@ -1,7 +1,4 @@ -use bevy::{ - prelude::{App as BevyApp, AssetServer, Commands, ImageSettings, Res, ResMut}, - DefaultPlugins, -}; +use bevy::prelude::*; use kayak_ui::prelude::{widgets::*, KStyle, *}; fn startup( @@ -37,7 +34,7 @@ fn startup( let parent_id = None; let atlas_styles = KStyle { - position_type: StyleProp::Value(PositionType::ParentDirected), + position_type: StyleProp::Value(KPositionType::ParentDirected), width: StyleProp::Value(Units::Pixels(200.0)), height: StyleProp::Value(Units::Pixels(200.0)), ..KStyle::default() @@ -54,7 +51,7 @@ fn startup( rsx! { <KayakAppBundle> <TextureAtlasBundle - atlas={TextureAtlas { + atlas={TextureAtlasProps { handle: image_handle.clone(), position: sign_position, tile_size: sign_size, @@ -62,7 +59,7 @@ fn startup( styles={atlas_styles.clone()} /> <TextureAtlasBundle - atlas={TextureAtlas { + atlas={TextureAtlasProps { handle: image_handle.clone(), position: flower_position, tile_size: flower_size, @@ -76,9 +73,8 @@ fn startup( } fn main() { - BevyApp::new() - .insert_resource(ImageSettings::default_nearest()) - .add_plugins(DefaultPlugins) + App::new() + .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest())) .add_plugin(KayakContextPlugin) .add_plugin(KayakWidgets) .add_startup_system(startup) diff --git a/examples/todo/items.rs b/examples/todo/items.rs index 900eee4c2cbefcfaca09d565d1326b34fa8d7e2a..789589c306bbe73d8050815952f6ba7ec31d553c 100644 --- a/examples/todo/items.rs +++ b/examples/todo/items.rs @@ -34,80 +34,76 @@ pub fn render_todo_items( In((widget_context, entity)): In<(KayakWidgetContext, Entity)>, mut commands: Commands, todo_list: Res<TodoList>, - query: Query<&TodoItemsProps, Or<(Changed<Style>, Changed<TodoItemsProps>, With<Mounted>)>>, ) -> bool { - if query.is_empty() || todo_list.is_changed() { - let parent_id = Some(entity); - rsx! { - <ElementBundle - styles={KStyle { - height: Units::Auto.into(), - ..Default::default() - }} - > - {todo_list.items.iter().enumerate().for_each(|(index, content)| { - let handle_click = OnEvent::new( - move |In((event_dispatcher_context, _, event, _)): In<( - EventDispatcherContext, - WidgetState, - Event, - Entity, - )>, - mut todo_list: ResMut<TodoList>,| { - match event.event_type { - EventType::Click(..) => { - todo_list.items.remove(index); - }, - _ => {} - } - (event_dispatcher_context, event) - }, - ); - constructor! { - <ElementBundle + let parent_id = Some(entity); + rsx! { + <ElementBundle + styles={KStyle { + height: Units::Auto.into(), + ..Default::default() + }} + > + {todo_list.items.iter().enumerate().for_each(|(index, content)| { + let handle_click = OnEvent::new( + move |In((event_dispatcher_context, _, event, _)): In<( + EventDispatcherContext, + WidgetState, + Event, + Entity, + )>, + mut todo_list: ResMut<TodoList>,| { + match event.event_type { + EventType::Click(..) => { + todo_list.items.remove(index); + }, + _ => {} + } + (event_dispatcher_context, event) + }, + ); + constructor! { + <ElementBundle + styles={KStyle { + render_command: StyleProp::Value(RenderCommand::Quad), + background_color: StyleProp::Value(Color::rgba(0.0781, 0.0898, 0.101, 1.0)), + border_radius: StyleProp::Value(Corner::all(3.0)), + bottom: StyleProp::Value(Units::Pixels(5.0)), + height: StyleProp::Value(Units::Auto), + padding: StyleProp::Value(Edge::all(Units::Pixels(10.0))), + layout_type: StyleProp::Value(LayoutType::Row), + ..Default::default() + }} + > + <TextWidgetBundle + text={TextProps { + content: content.clone(), + ..Default::default() + }} styles={KStyle { - render_command: StyleProp::Value(RenderCommand::Quad), - background_color: StyleProp::Value(Color::rgba(0.0781, 0.0898, 0.101, 1.0)), - border_radius: StyleProp::Value(Corner::all(3.0)), - bottom: StyleProp::Value(Units::Pixels(5.0)), - height: StyleProp::Value(Units::Auto), - padding: StyleProp::Value(Edge::all(Units::Pixels(10.0))), - layout_type: StyleProp::Value(LayoutType::Row), + right: StyleProp::Value(Units::Stretch(1.0)), + top: StyleProp::Value(Units::Stretch(1.0)), + bottom: StyleProp::Value(Units::Stretch(1.0)), ..Default::default() }} + /> + <KButtonBundle + styles={KStyle { + width: StyleProp::Value(Units::Pixels(32.0)), + height: StyleProp::Value(Units::Pixels(32.0)), + left: StyleProp::Value(Units::Pixels(15.0)), + ..Default::default() + }} + on_event={handle_click} > - <TextWidgetBundle - text={TextProps { - content: content.clone(), - ..Default::default() - }} - styles={KStyle { - right: StyleProp::Value(Units::Stretch(1.0)), - top: StyleProp::Value(Units::Stretch(1.0)), - bottom: StyleProp::Value(Units::Stretch(1.0)), - ..Default::default() - }} - /> - <KButtonBundle - styles={KStyle { - width: StyleProp::Value(Units::Pixels(32.0)), - height: StyleProp::Value(Units::Pixels(32.0)), - left: StyleProp::Value(Units::Pixels(15.0)), - ..Default::default() - }} - on_event={handle_click} - > - <TextWidgetBundle text={TextProps { - content: "X".into(), - ..Default::default() - }} /> - </KButtonBundle> - </ElementBundle> - } - })} - </ElementBundle> - } - return true; + <TextWidgetBundle text={TextProps { + content: "X".into(), + ..Default::default() + }} /> + </KButtonBundle> + </ElementBundle> + } + })} + </ElementBundle> } - false + true } diff --git a/examples/vec.rs b/examples/vec.rs index fa25565a4e060e5f73ebea999b41fa227a5127da..732cb9079b947e7e9104246377d0bd1d4f9bd15b 100644 --- a/examples/vec.rs +++ b/examples/vec.rs @@ -1,10 +1,4 @@ -use bevy::{ - prelude::{ - App as BevyApp, AssetServer, Bundle, Changed, Commands, Component, Entity, In, Or, Query, - Res, ResMut, With, - }, - DefaultPlugins, -}; +use bevy::prelude::*; use kayak_ui::prelude::{widgets::*, KStyle, *}; #[derive(Component, Default, PartialEq, Clone)] @@ -84,7 +78,8 @@ fn startup( } fn main() { - BevyApp::new() + App::new() + .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0))) .add_plugins(DefaultPlugins) .add_plugin(KayakContextPlugin) .add_plugin(KayakWidgets) diff --git a/examples/widget_template.rs b/examples/widget_template.rs deleted file mode 100644 index 5743a9c557b9e274e9219789ae54156c3155078d..0000000000000000000000000000000000000000 --- a/examples/widget_template.rs +++ /dev/null @@ -1,51 +0,0 @@ -/// This is a simple widget template. -/// It'll auto update if the props change. -/// Don't forget to register the update system with kayak! -use bevy::prelude::*; -use kayak_ui::prelude::*; - -#[derive(Component, Default)] -pub struct WidgetProps; - -impl Widget for WidgetProps {} - -#[derive(Bundle)] -pub struct WidgetBundle { - pub widget: WidgetProps, - pub styles: KStyle, - pub children: KChildren, - pub widget_name: WidgetName, -} - -impl Default for WidgetBundle { - fn default() -> Self { - Self { - widget: WidgetProps::default(), - styles: KStyle { - render_command: StyleProp::Value(RenderCommand::Clip), - height: StyleProp::Value(Units::Stretch(1.0)), - width: StyleProp::Value(Units::Stretch(1.0)), - ..KStyle::default() - }, - children: KChildren::default(), - widget_name: WidgetProps::default().get_name(), - } - } -} - -pub fn update_widget( - In((widget_context, entity)): In<(KayakWidgetContext, Entity)>, - _: Commands, - mut query: Query< - (&Style, &KChildren), - Or<(Changed<Style>, Changed<WidgetProps>, With<Mounted>)>, - >, -) -> bool { - if let Ok((_, children)) = query.get_mut(entity) { - children.process(&widget_context, Some(entity)); - return true; - } - false -} - -fn main() {} diff --git a/kayak_font/Cargo.toml b/kayak_font/Cargo.toml index 40ce386105a13f85af6e765cf4590fdaeb21023e..305c83cd2cdf1328bf60af9168b28cb874cf50f2 100644 --- a/kayak_font/Cargo.toml +++ b/kayak_font/Cargo.toml @@ -15,8 +15,8 @@ unicode-segmentation = "1.9" # Provides UAX #14 line break segmentation xi-unicode = "0.3" -bevy = { git = "https://github.com/bevyengine/bevy", rev="9423cb6a8d0c140e11364eb23c8feb7e576baa8c", optional = true, default-features = false, features = ["bevy_asset", "bevy_render", "bevy_core_pipeline"] } +bevy = { git = "https://github.com/bevyengine/bevy", rev="4bcf49b2ea6fb5f42388b0e15d204020053ee5c7", optional = true, default-features = false, features = ["bevy_asset", "bevy_render", "bevy_core_pipeline"] } [dev-dependencies] -bevy = { git = "https://github.com/bevyengine/bevy", rev="9423cb6a8d0c140e11364eb23c8feb7e576baa8c" } +bevy = { git = "https://github.com/bevyengine/bevy", rev="4bcf49b2ea6fb5f42388b0e15d204020053ee5c7" } bytemuck = "1.12.0" diff --git a/kayak_font/examples/bevy.rs b/kayak_font/examples/bevy.rs index 728456696f90fc0bbaf60eff9eba29c4a2267b67..5eb6a1a737feddb92d39cc455164e673ee81c1d3 100644 --- a/kayak_font/examples/bevy.rs +++ b/kayak_font/examples/bevy.rs @@ -2,10 +2,10 @@ use bevy::{ math::Vec2, prelude::{ App as BevyApp, AssetServer, Camera2dBundle, Commands, Component, Handle, Input, KeyCode, - Query, Res, ResMut, Sprite, SpriteBundle, Transform, With, Without, + PluginGroup, Query, Res, ResMut, Sprite, SpriteBundle, Transform, With, Without, }, render::color::Color, - window::WindowDescriptor, + window::{WindowDescriptor, WindowPlugin}, DefaultPlugins, }; @@ -119,13 +119,15 @@ fn control_text( fn main() { BevyApp::new() - .insert_resource(WindowDescriptor { - width: 1270.0, - height: 720.0, - title: String::from("UI Example"), + .add_plugins(DefaultPlugins.set(WindowPlugin { + window: WindowDescriptor { + width: 1270.0, + height: 720.0, + title: String::from("UI Example"), + ..Default::default() + }, ..Default::default() - }) - .add_plugins(DefaultPlugins) + })) .add_plugin(KayakFontPlugin) .add_plugin(FontRenderPlugin) .add_startup_system(startup) diff --git a/kayak_ui_macros/Cargo.toml b/kayak_ui_macros/Cargo.toml index 3b234a31669e451983001584659bff8c399ecb15..d0438b1bbbfe2408d5fc04963608808c5b66ed05 100644 --- a/kayak_ui_macros/Cargo.toml +++ b/kayak_ui_macros/Cargo.toml @@ -17,4 +17,4 @@ proc-macro-crate = "1.1" [dev-dependencies] kayak_ui = { path = "../", version = "0.1.0" } pretty_assertions = "1.2.1" -bevy = { git = "https://github.com/bevyengine/bevy", rev="9423cb6a8d0c140e11364eb23c8feb7e576baa8c" } \ No newline at end of file +bevy = { git = "https://github.com/bevyengine/bevy", rev="4bcf49b2ea6fb5f42388b0e15d204020053ee5c7" } \ No newline at end of file diff --git a/src/camera/camera.rs b/src/camera/camera.rs index 99a13402e4b2ef55524e4780a2dd768e46312634..f04d3ab9d966fc4e25c072132e7b31c9a42f0ede 100644 --- a/src/camera/camera.rs +++ b/src/camera/camera.rs @@ -1,6 +1,6 @@ use bevy::{ ecs::query::QueryItem, - prelude::{Bundle, Component, GlobalTransform, Transform, With}, + prelude::{Bundle, Camera2d, Component, GlobalTransform, Transform, With}, render::{ camera::{Camera, CameraProjection, CameraRenderGraph, WindowOrigin}, extract_component::ExtractComponent, @@ -28,6 +28,7 @@ impl ExtractComponent for CameraUiKayak { #[derive(Bundle)] pub struct UICameraBundle { pub camera: Camera, + pub camera_2d: Camera2d, pub camera_render_graph: CameraRenderGraph, pub orthographic_projection: UIOrthographicProjection, pub visible_entities: VisibleEntities, @@ -65,11 +66,12 @@ impl UICameraBundle { priority: isize::MAX - 1, ..Default::default() }, - camera_render_graph: CameraRenderGraph::new(crate::render::draw_ui_graph::NAME), + camera_render_graph: CameraRenderGraph::new(bevy::core_pipeline::core_2d::graph::NAME), orthographic_projection, frustum, visible_entities: VisibleEntities::default(), transform, + camera_2d: Camera2d::default(), global_transform: Default::default(), marker: CameraUiKayak, } diff --git a/src/input.rs b/src/input.rs index c3eb172770f19104e544464e9052da5b1f5c0344..3ef2709154f228f2dcbf4a71268562d02823348a 100644 --- a/src/input.rs +++ b/src/input.rs @@ -14,17 +14,17 @@ 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; - } - } else { - // log::warn!("Couldn't find primiary window!"); - return; - }; + // 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; + // } + // } else { + // // log::warn!("Couldn't find primiary window!"); + // return; + // }; let mut input_events = Vec::new(); @@ -64,7 +64,7 @@ pub(crate) fn process_events(world: &mut World) { // Currently, we can only handle a single MouseMoved event at a time so everything but the last needs to be skipped input_events.push(InputEvent::MouseMoved(( event.position.x as f32, - window_size.y - event.position.y as f32, + event.position.y as f32, ))); } diff --git a/src/render/mod.rs b/src/render/mod.rs index d014cc5629669b33f7ed53024c81ecd606f7000c..40bbbe75855aba8092424f37328e8521231c4708 100644 --- a/src/render/mod.rs +++ b/src/render/mod.rs @@ -1,7 +1,7 @@ use bevy::{ - prelude::{Commands, Entity, Plugin, Query, With}, + prelude::{App, Commands, Entity, Plugin, Query, With}, render::{ - render_graph::{RenderGraph, SlotInfo, SlotType}, + render_graph::{RenderGraph, RunGraphOnViewNode, SlotInfo, SlotType}, render_phase::{DrawFunctions, RenderPhase}, Extract, RenderApp, RenderStage, }, @@ -46,26 +46,99 @@ impl Plugin for BevyKayakUIRenderPlugin { .add_system_to_stage(RenderStage::Extract, extract_core_pipeline_camera_phases); // .add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<TransparentUI>); - let pass_node_ui = MainPassUINode::new(&mut render_app.world); - let mut graph = render_app.world.get_resource_mut::<RenderGraph>().unwrap(); + // let pass_node_ui = MainPassUINode::new(&mut render_app.world); + // let mut graph = render_app.world.get_resource_mut::<RenderGraph>().unwrap(); - let mut draw_ui_graph = RenderGraph::default(); - draw_ui_graph.add_node(draw_ui_graph::node::MAIN_PASS, pass_node_ui); - let input_node_id = draw_ui_graph.set_input(vec![SlotInfo::new( - draw_ui_graph::input::VIEW_ENTITY, - SlotType::Entity, - )]); - draw_ui_graph - .add_slot_edge( - input_node_id, - draw_ui_graph::input::VIEW_ENTITY, + // let mut draw_ui_graph = RenderGraph::default(); + // draw_ui_graph.add_node(draw_ui_graph::node::MAIN_PASS, pass_node_ui); + // let input_node_id = draw_ui_graph.set_input(vec![SlotInfo::new( + // draw_ui_graph::input::VIEW_ENTITY, + // SlotType::Entity, + // )]); + // draw_ui_graph + // .add_slot_edge( + // input_node_id, + // draw_ui_graph::input::VIEW_ENTITY, + // draw_ui_graph::node::MAIN_PASS, + // MainPassUINode::IN_VIEW, + // ) + // .unwrap(); + // graph.add_sub_graph(draw_ui_graph::NAME, draw_ui_graph); + + // // graph.add_node_edge(MAIN_PASS, draw_ui_graph::NAME).unwrap(); + + // Render graph + let ui_graph_2d = get_ui_graph(render_app); + let ui_graph_3d = get_ui_graph(render_app); + let mut graph = render_app.world.resource_mut::<RenderGraph>(); + + if let Some(graph_2d) = graph.get_sub_graph_mut(bevy::core_pipeline::core_2d::graph::NAME) { + graph_2d.add_sub_graph(draw_ui_graph::NAME, ui_graph_2d); + graph_2d.add_node( draw_ui_graph::node::MAIN_PASS, - MainPassUINode::IN_VIEW, - ) - .unwrap(); - graph.add_sub_graph(draw_ui_graph::NAME, draw_ui_graph); + 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.add_node_edge(MAIN_PASS, draw_ui_graph::NAME).unwrap(); + if let Some(graph_3d) = graph.get_sub_graph_mut(bevy::core_pipeline::core_3d::graph::NAME) { + graph_3d.add_sub_graph(draw_ui_graph::NAME, ui_graph_3d); + graph_3d.add_node( + 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(); + } app.add_plugin(font::TextRendererPlugin) .add_plugin(UnifiedRenderPlugin) @@ -73,6 +146,25 @@ impl Plugin for BevyKayakUIRenderPlugin { } } +fn get_ui_graph(render_app: &mut App) -> RenderGraph { + let ui_pass_node = MainPassUINode::new(&mut render_app.world); + let mut ui_graph = RenderGraph::default(); + ui_graph.add_node(draw_ui_graph::node::MAIN_PASS, ui_pass_node); + let input_node_id = ui_graph.set_input(vec![SlotInfo::new( + 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 +} + pub fn extract_core_pipeline_camera_phases( mut commands: Commands, active_camera: Extract<Query<Entity, With<CameraUiKayak>>>, diff --git a/src/render/ui_pass.rs b/src/render/ui_pass.rs index bc9ff4f60ef7a0b12abe3592760a4c937e25c819..559536748a0556c619081471e526e0533089b260 100644 --- a/src/render/ui_pass.rs +++ b/src/render/ui_pass.rs @@ -1,6 +1,6 @@ use bevy::ecs::prelude::*; use bevy::render::render_phase::{DrawFunctionId, PhaseItem}; -use bevy::render::render_resource::{CachedRenderPipelineId, RenderPassColorAttachment}; +use bevy::render::render_resource::CachedRenderPipelineId; use bevy::render::{ render_graph::{Node, NodeRunError, RenderGraphContext, SlotInfo, SlotType}, render_phase::{DrawFunctions, RenderPhase, TrackedRenderPass}, @@ -72,14 +72,10 @@ impl Node for MainPassUINode { { let pass_descriptor = RenderPassDescriptor { label: Some("main_transparent_pass_UI"), - color_attachments: &[Some(RenderPassColorAttachment { - view: &target.view, - resolve_target: None, - ops: Operations { - load: LoadOp::Load, //Clear(clear_color.0.into()), - store: true, - }, - })], + color_attachments: &[Some(target.get_unsampled_color_attachment(Operations { + load: LoadOp::Load, + store: true, + }))], depth_stencil_attachment: None, }; diff --git a/src/render/unified/mod.rs b/src/render/unified/mod.rs index e62e6708e1a45b265310ab04b55f4c8acd3b63fa..b592ed32f060c0e40a737c7cee6bb6eb156c0c76 100644 --- a/src/render/unified/mod.rs +++ b/src/render/unified/mod.rs @@ -2,7 +2,9 @@ use bevy::{ prelude::{Assets, Commands, HandleUntyped, Plugin, Res, Resource}, reflect::TypeUuid, render::{ - render_phase::DrawFunctions, render_resource::Shader, Extract, RenderApp, RenderStage, + render_phase::DrawFunctions, + render_resource::{Shader, SpecializedRenderPipelines}, + Extract, RenderApp, RenderStage, }, window::Windows, }; @@ -37,6 +39,7 @@ impl Plugin for UnifiedRenderPlugin { render_app .init_resource::<ImageBindGroups>() .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) diff --git a/src/render/unified/pipeline.rs b/src/render/unified/pipeline.rs index 570c3e7924497088839e5068749fae9048987dff..235d1c419e92391b86a59c140d3401532cb60766 100644 --- a/src/render/unified/pipeline.rs +++ b/src/render/unified/pipeline.rs @@ -1,5 +1,7 @@ -use bevy::prelude::{Rect, Resource}; -use bevy::render::render_resource::{DynamicUniformBuffer, ShaderType}; +use bevy::prelude::{Msaa, Rect, Resource}; +use bevy::render::render_resource::{ + DynamicUniformBuffer, ShaderType, SpecializedRenderPipeline, SpecializedRenderPipelines, +}; use bevy::utils::FloatOrd; use bevy::{ ecs::system::{ @@ -16,13 +18,12 @@ use bevy::{ BindGroup, BindGroupDescriptor, BindGroupEntry, BindGroupLayout, BindGroupLayoutDescriptor, BindGroupLayoutEntry, BindingResource, BindingType, BlendComponent, BlendFactor, BlendOperation, BlendState, BufferBindingType, BufferSize, - BufferUsages, BufferVec, CachedRenderPipelineId, ColorTargetState, ColorWrites, - Extent3d, FragmentState, FrontFace, MultisampleState, PipelineCache, PolygonMode, - PrimitiveState, PrimitiveTopology, RenderPipelineDescriptor, SamplerBindingType, - SamplerDescriptor, Shader, ShaderStages, TextureDescriptor, TextureDimension, - TextureFormat, TextureSampleType, TextureUsages, TextureViewDescriptor, - TextureViewDimension, VertexAttribute, VertexBufferLayout, VertexFormat, VertexState, - VertexStepMode, + BufferUsages, BufferVec, ColorTargetState, ColorWrites, Extent3d, FragmentState, + FrontFace, MultisampleState, PipelineCache, PolygonMode, PrimitiveState, + PrimitiveTopology, RenderPipelineDescriptor, SamplerBindingType, SamplerDescriptor, + Shader, ShaderStages, TextureDescriptor, TextureDimension, TextureFormat, + TextureSampleType, TextureUsages, TextureViewDescriptor, TextureViewDimension, + VertexAttribute, VertexBufferLayout, VertexFormat, VertexState, VertexStepMode, }, renderer::{RenderDevice, RenderQueue}, texture::{BevyDefault, GpuImage, Image}, @@ -47,7 +48,6 @@ pub struct UnifiedPipeline { types_layout: BindGroupLayout, pub(crate) font_image_layout: BindGroupLayout, image_layout: BindGroupLayout, - pipeline: CachedRenderPipelineId, empty_font_texture: (GpuImage, BindGroup), default_image: (GpuImage, BindGroup), } @@ -67,11 +67,33 @@ impl FontRenderingPipeline for UnifiedPipeline { } } +bitflags::bitflags! { + #[repr(transparent)] + pub struct UnifiedPipelineKey: u32 { + const NONE = 0; + const MSAA_RESERVED_BITS = Self::MSAA_MASK_BITS << Self::MSAA_SHIFT_BITS; + } +} + +impl UnifiedPipelineKey { + const MSAA_MASK_BITS: u32 = 0b111; + const MSAA_SHIFT_BITS: u32 = 32 - Self::MSAA_MASK_BITS.count_ones(); + + pub fn from_msaa_samples(msaa_samples: u32) -> Self { + let msaa_bits = + (msaa_samples.trailing_zeros() & Self::MSAA_MASK_BITS) << Self::MSAA_SHIFT_BITS; + Self::from_bits(msaa_bits).unwrap() + } + + pub fn msaa_samples(&self) -> u32 { + 1 << ((self.bits >> Self::MSAA_SHIFT_BITS) & Self::MSAA_MASK_BITS) + } +} + impl FromWorld for UnifiedPipeline { fn from_world(world: &mut World) -> Self { let world = world.cell(); let render_device = world.get_resource::<RenderDevice>().unwrap(); - let mut pipeline_cache = world.get_resource_mut::<PipelineCache>().unwrap(); let view_layout = render_device.create_bind_group_layout(&BindGroupLayoutDescriptor { entries: &[BindGroupLayoutEntry { @@ -151,6 +173,76 @@ impl FromWorld for UnifiedPipeline { label: Some("image_layout"), }); + let empty_font_texture = FontTextureCache::get_empty(&render_device, &font_image_layout); + + let texture_descriptor = TextureDescriptor { + label: Some("font_texture_array"), + size: Extent3d { + width: 1, + height: 1, + depth_or_array_layers: 1, + }, + mip_level_count: 1, + sample_count: 1, + dimension: TextureDimension::D2, + format: TextureFormat::Rgba8UnormSrgb, + usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST, + }; + + let sampler_descriptor = SamplerDescriptor::default(); + + let texture = render_device.create_texture(&texture_descriptor); + let sampler = render_device.create_sampler(&sampler_descriptor); + + let texture_view = texture.create_view(&TextureViewDescriptor { + label: Some("font_texture_array_view"), + format: Some(TextureFormat::Rgba8UnormSrgb), + dimension: Some(TextureViewDimension::D2), + aspect: bevy::render::render_resource::TextureAspect::All, + base_mip_level: 0, + base_array_layer: 0, + mip_level_count: None, + array_layer_count: None, + }); + + let image = GpuImage { + texture, + sampler, + texture_view, + size: Vec2::new(1.0, 1.0), + texture_format: TextureFormat::Rgba8UnormSrgb, + }; + + let binding = render_device.create_bind_group(&BindGroupDescriptor { + label: Some("text_image_bind_group"), + entries: &[ + BindGroupEntry { + binding: 0, + resource: BindingResource::TextureView(&image.texture_view), + }, + BindGroupEntry { + binding: 1, + resource: BindingResource::Sampler(&image.sampler), + }, + ], + layout: &image_layout, + }); + + UnifiedPipeline { + view_layout, + font_image_layout, + empty_font_texture, + types_layout, + image_layout, + default_image: (image, binding), + } + } +} + +impl SpecializedRenderPipeline for UnifiedPipeline { + type Key = UnifiedPipelineKey; + + fn specialize(&self, _key: Self::Key) -> RenderPipelineDescriptor { let vertex_buffer_layout = VertexBufferLayout { array_stride: 60, step_mode: VertexStepMode::Vertex, @@ -178,9 +270,7 @@ impl FromWorld for UnifiedPipeline { ], }; - let empty_font_texture = FontTextureCache::get_empty(&render_device, &font_image_layout); - - let pipeline_desc = RenderPipelineDescriptor { + RenderPipelineDescriptor { vertex: VertexState { shader: UNIFIED_SHADER_HANDLE.typed::<Shader>(), entry_point: "vertex".into(), @@ -209,10 +299,10 @@ impl FromWorld for UnifiedPipeline { })], }), layout: Some(vec![ - view_layout.clone(), - font_image_layout.clone(), - types_layout.clone(), - image_layout.clone(), + self.view_layout.clone(), + self.font_image_layout.clone(), + self.types_layout.clone(), + self.image_layout.clone(), ]), primitive: PrimitiveState { front_face: FrontFace::Ccw, @@ -230,69 +320,6 @@ impl FromWorld for UnifiedPipeline { alpha_to_coverage_enabled: false, }, label: Some("unified_pipeline".into()), - }; - - let texture_descriptor = TextureDescriptor { - label: Some("font_texture_array"), - size: Extent3d { - width: 1, - height: 1, - depth_or_array_layers: 1, - }, - mip_level_count: 1, - sample_count: 1, - dimension: TextureDimension::D2, - format: TextureFormat::Rgba8UnormSrgb, - usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST, - }; - - let sampler_descriptor = SamplerDescriptor::default(); - - let texture = render_device.create_texture(&texture_descriptor); - let sampler = render_device.create_sampler(&sampler_descriptor); - - let texture_view = texture.create_view(&TextureViewDescriptor { - label: Some("font_texture_array_view"), - format: Some(TextureFormat::Rgba8UnormSrgb), - dimension: Some(TextureViewDimension::D2), - aspect: bevy::render::render_resource::TextureAspect::All, - base_mip_level: 0, - base_array_layer: 0, - mip_level_count: None, - array_layer_count: None, - }); - - let image = GpuImage { - texture, - sampler, - texture_view, - size: Vec2::new(1.0, 1.0), - texture_format: TextureFormat::Rgba8UnormSrgb, - }; - - let binding = render_device.create_bind_group(&BindGroupDescriptor { - label: Some("text_image_bind_group"), - entries: &[ - BindGroupEntry { - binding: 0, - resource: BindingResource::TextureView(&image.texture_view), - }, - BindGroupEntry { - binding: 1, - resource: BindingResource::Sampler(&image.sampler), - }, - ], - layout: &image_layout, - }); - - UnifiedPipeline { - pipeline: pipeline_cache.queue_render_pipeline(pipeline_desc), - view_layout, - font_image_layout, - empty_font_texture, - types_layout, - image_layout, - default_image: (image, binding), } } } @@ -495,11 +522,14 @@ pub fn queue_quads( mut sprite_meta: ResMut<QuadMeta>, view_uniforms: Res<ViewUniforms>, quad_pipeline: Res<UnifiedPipeline>, + mut pipelines: ResMut<SpecializedRenderPipelines<UnifiedPipeline>>, + mut pipeline_cache: ResMut<PipelineCache>, mut extracted_sprites: Query<(Entity, &ExtractedQuad)>, mut views: Query<&mut RenderPhase<TransparentUI>>, mut image_bind_groups: ResMut<ImageBindGroups>, unified_pipeline: Res<UnifiedPipeline>, gpu_images: Res<RenderAssets<Image>>, + msaa: Res<Msaa>, ) { if let Some(type_binding) = sprite_meta.types_buffer.binding() { sprite_meta.types_bind_group = @@ -523,6 +553,9 @@ pub fn queue_quads( layout: &quad_pipeline.view_layout, })); + 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(); for mut transparent_phase in views.iter_mut() { for (entity, quad) in extracted_sprites.iter_mut() { @@ -553,7 +586,7 @@ pub fn queue_quads( } transparent_phase.add(TransparentUI { draw_function: draw_quad, - pipeline: quad_pipeline.pipeline, + pipeline: spec_pipeline, entity, sort_key: FloatOrd(quad.z_index), }); diff --git a/src/styles/style.rs b/src/styles/style.rs index f02b5678e7dd0df71bdd9aea64ee02f7d274494e..dc8bb057393ea0a9319017dc48f876d51526ffcd 100644 --- a/src/styles/style.rs +++ b/src/styles/style.rs @@ -5,7 +5,7 @@ use std::ops::Add; use bevy::prelude::Color; use bevy::prelude::Component; use bevy::window::CursorIcon; -pub use morphorm::{LayoutType, PositionType, Units}; +pub use morphorm::{LayoutType, PositionType as KPositionType, Units}; use crate::cursor::PointerEvents; @@ -348,7 +348,7 @@ define_styles! { /// the event to "pass through" to widgets below. pub pointer_events: StyleProp<PointerEvents>, /// The position type of the widget relative to its parent - pub position_type: StyleProp<PositionType>, + pub position_type: StyleProp<KPositionType>, /// The render method for this widget /// /// This controls what actually gets rendered and how it's rendered. diff --git a/src/widgets/image.rs b/src/widgets/image.rs index 2e8d9349e44d991ac344c41bd26c6d119d306c16..375d52dfd6839adfb618b0746c1f99735879f669 100644 --- a/src/widgets/image.rs +++ b/src/widgets/image.rs @@ -1,7 +1,7 @@ -use bevy::prelude::{Bundle, Changed, Component, Entity, Handle, In, Or, Query, With}; +use bevy::prelude::{Bundle, Component, Entity, Handle, In, Query}; use crate::{ - context::{Mounted, WidgetName}, + context::WidgetName, prelude::KayakWidgetContext, styles::{KStyle, RenderCommand, StyleProp}, widget::Widget, @@ -15,13 +15,13 @@ pub struct Image(pub Handle<bevy::prelude::Image>); impl Widget for Image {} #[derive(Bundle)] -pub struct ImageBundle { +pub struct KImageBundle { pub image: Image, pub style: KStyle, pub widget_name: WidgetName, } -impl Default for ImageBundle { +impl Default for KImageBundle { fn default() -> Self { Self { image: Default::default(), @@ -33,13 +33,12 @@ impl Default for ImageBundle { pub fn image_render( In((_widget_context, entity)): In<(KayakWidgetContext, Entity)>, - mut query: Query<(&mut KStyle, &Image), Or<((Changed<Image>, Changed<KStyle>), With<Mounted>)>>, + mut query: Query<(&mut KStyle, &Image)>, ) -> bool { if let Ok((mut style, image)) = query.get_mut(entity) { style.render_command = StyleProp::Value(RenderCommand::Image { handle: image.0.clone_weak(), }); - return true; } - false + true } diff --git a/src/widgets/mod.rs b/src/widgets/mod.rs index 8ff16809a39145dc4833a52dabb22e802bffce15..019759133340be8cd1885bbf7af9e7ae91aa8b5e 100644 --- a/src/widgets/mod.rs +++ b/src/widgets/mod.rs @@ -40,7 +40,7 @@ pub use background::{Background, BackgroundBundle}; pub use button::{KButton, KButtonBundle}; pub use clip::{Clip, ClipBundle}; pub use element::{Element, ElementBundle}; -pub use image::{Image, ImageBundle}; +pub use image::{Image, KImageBundle}; pub use nine_patch::{NinePatch, NinePatchBundle}; pub use scroll::{ scroll_bar::{ScrollBarBundle, ScrollBarProps}, @@ -52,7 +52,7 @@ pub use scroll::{ }; pub use text::{TextProps, TextWidgetBundle}; pub use text_box::{TextBoxBundle, TextBoxProps, TextBoxState}; -pub use texture_atlas::{TextureAtlas, TextureAtlasBundle}; +pub use texture_atlas::{TextureAtlasBundle, TextureAtlasProps}; pub use window::{KWindow, WindowBundle}; use app::{app_render, app_update}; @@ -94,7 +94,7 @@ fn add_widget_systems(mut context: ResMut<KayakRootContext>) { context.add_widget_data::<Background, EmptyState>(); context.add_widget_data::<Clip, EmptyState>(); context.add_widget_data::<Image, EmptyState>(); - context.add_widget_data::<TextureAtlas, EmptyState>(); + context.add_widget_data::<TextureAtlasProps, EmptyState>(); context.add_widget_data::<NinePatch, EmptyState>(); context.add_widget_data::<Element, EmptyState>(); context.add_widget_data::<ScrollBarProps, EmptyState>(); @@ -135,8 +135,8 @@ fn add_widget_systems(mut context: ResMut<KayakRootContext>) { image_render, ); context.add_widget_system( - TextureAtlas::default().get_name(), - widget_update::<TextureAtlas, EmptyState>, + TextureAtlasProps::default().get_name(), + widget_update::<TextureAtlasProps, EmptyState>, texture_atlas_render, ); context.add_widget_system( diff --git a/src/widgets/nine_patch.rs b/src/widgets/nine_patch.rs index 68d7d05c3cc6802ffc51d5c7b35b3f9fe07800af..bd3014a8f37756df85322adf9a976c3fdb042ed1 100644 --- a/src/widgets/nine_patch.rs +++ b/src/widgets/nine_patch.rs @@ -78,8 +78,7 @@ pub fn nine_patch_render( }); children.process(&widget_context, Some(entity)); - - return true; } - false + + true } diff --git a/src/widgets/scroll/scroll_bar.rs b/src/widgets/scroll/scroll_bar.rs index 81ef57f5811bf865012ffa27fbd85f7408a46e7c..f56c75471b9341eea014458a50d4625bc30d362f 100644 --- a/src/widgets/scroll/scroll_bar.rs +++ b/src/widgets/scroll/scroll_bar.rs @@ -7,7 +7,7 @@ use crate::{ event_dispatcher::EventDispatcherContext, on_event::OnEvent, prelude::{KChildren, KayakWidgetContext}, - styles::{Corner, Edge, KStyle, PositionType, RenderCommand, Units}, + styles::{Corner, Edge, KPositionType, KStyle, RenderCommand, Units}, widget::Widget, widget_state::WidgetState, widgets::{BackgroundBundle, ClipBundle}, @@ -156,7 +156,7 @@ pub fn scroll_bar_render( let mut thumb_style = KStyle::default() .with_style(KStyle { - position_type: PositionType::SelfDirected.into(), + position_type: KPositionType::SelfDirected.into(), ..Default::default() }) .with_style(&thumb_styles) diff --git a/src/widgets/scroll/scroll_box.rs b/src/widgets/scroll/scroll_box.rs index dba219b779088cf09b7b4ed414118227959287ab..b294e4aa8084011719aade89ac1dfc82c789a579 100644 --- a/src/widgets/scroll/scroll_box.rs +++ b/src/widgets/scroll/scroll_box.rs @@ -10,7 +10,7 @@ use crate::{ on_event::OnEvent, on_layout::OnLayout, prelude::{constructor, rsx, KayakWidgetContext}, - styles::{KStyle, LayoutType, PositionType, RenderCommand, Units}, + styles::{KPositionType, KStyle, LayoutType, RenderCommand, Units}, widget::Widget, widget_state::WidgetState, widgets::{ @@ -165,7 +165,7 @@ pub fn scroll_box_render( }); let content_styles = KStyle::default().with_style(KStyle { - position_type: PositionType::SelfDirected.into(), + position_type: KPositionType::SelfDirected.into(), top: Units::Pixels(scroll_y).into(), left: Units::Pixels(scroll_x).into(), ..Default::default() diff --git a/src/widgets/texture_atlas.rs b/src/widgets/texture_atlas.rs index 8e410c0e19a8161564f389a3553aa39b24e18131..eab78bf4d6cbc1a91b733096dd627f3fc4119d48 100644 --- a/src/widgets/texture_atlas.rs +++ b/src/widgets/texture_atlas.rs @@ -1,7 +1,7 @@ -use bevy::prelude::{Bundle, Changed, Component, Entity, Handle, Image, In, Or, Query, Vec2, With}; +use bevy::prelude::{Bundle, Component, Entity, Handle, Image, In, Query, Vec2}; use crate::{ - context::{Mounted, WidgetName}, + context::WidgetName, prelude::KayakWidgetContext, styles::{KStyle, RenderCommand, StyleProp}, widget::Widget, @@ -23,7 +23,7 @@ use crate::{ /// | `focusable` | ✅ | /// #[derive(Component, PartialEq, Clone, Default, Debug)] -pub struct TextureAtlas { +pub struct TextureAtlasProps { /// The handle to image pub handle: Handle<Image>, /// The position of the tile (in pixels) @@ -32,12 +32,12 @@ pub struct TextureAtlas { pub tile_size: Vec2, } -impl Widget for TextureAtlas {} +impl Widget for TextureAtlasProps {} /// A widget that renders a bevy texture atlas #[derive(Bundle)] pub struct TextureAtlasBundle { - pub atlas: TextureAtlas, + pub atlas: TextureAtlasProps, pub styles: KStyle, pub widget_name: WidgetName, } @@ -47,17 +47,14 @@ impl Default for TextureAtlasBundle { Self { atlas: Default::default(), styles: Default::default(), - widget_name: TextureAtlas::default().get_name(), + widget_name: TextureAtlasProps::default().get_name(), } } } pub fn texture_atlas_render( In((_widget_context, entity)): In<(KayakWidgetContext, Entity)>, - mut query: Query< - (&mut KStyle, &TextureAtlas), - Or<(Changed<TextureAtlas>, Changed<KStyle>, With<Mounted>)>, - >, + mut query: Query<(&mut KStyle, &TextureAtlasProps)>, ) -> bool { if let Ok((mut styles, texture_atlas)) = query.get_mut(entity) { *styles = KStyle { @@ -68,9 +65,7 @@ pub fn texture_atlas_render( }), ..styles.clone() }; - - return true; } - false + true } diff --git a/src/widgets/window.rs b/src/widgets/window.rs index 1a6dc82a89d5b585a3ab99f04d7ebf25eb735fe7..5fa45fd556661b53d350c9104800ac18adb36a9f 100644 --- a/src/widgets/window.rs +++ b/src/widgets/window.rs @@ -11,7 +11,7 @@ use crate::{ event_dispatcher::EventDispatcherContext, on_event::OnEvent, prelude::KayakWidgetContext, - styles::{Corner, Edge, KCursorIcon, KStyle, PositionType, RenderCommand, StyleProp, Units}, + styles::{Corner, Edge, KCursorIcon, KPositionType, KStyle, RenderCommand, StyleProp, Units}, widget::Widget, widget_state::WidgetState, }; @@ -95,7 +95,7 @@ pub fn window_render( border: StyleProp::Value(Edge::all(4.0)), border_radius: StyleProp::Value(Corner::all(5.0)), render_command: StyleProp::Value(RenderCommand::Quad), - position_type: StyleProp::Value(PositionType::SelfDirected), + position_type: StyleProp::Value(KPositionType::SelfDirected), left: StyleProp::Value(Units::Pixels(state.position.x)), top: StyleProp::Value(Units::Pixels(state.position.y)), width: StyleProp::Value(Units::Pixels(window.size.x)),