From 3172593f87d0ea575009e01d70c8ce745bc6edcc Mon Sep 17 00:00:00 2001 From: Daniel Wiesenberg Date: Tue, 19 Jan 2021 15:38:57 +0100 Subject: [PATCH 01/27] Use EventReader directly, which was made possible by Bevy PR #1244 --- src/egui_node.rs | 7 +++---- src/lib.rs | 12 +----------- src/systems.rs | 18 +++++++++--------- 3 files changed, 13 insertions(+), 24 deletions(-) diff --git a/src/egui_node.rs b/src/egui_node.rs index b69627983..dd98e7184 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -3,7 +3,7 @@ use crate::{ EGUI_TEXTURE_RESOURCE_BINDING_NAME, EGUI_TRANSFORM_RESOURCE_BINDING_NAME, }; use bevy::{ - app::{EventReader, Events}, + app::{Events, ManualEventReader}, asset::{AssetEvent, Assets, Handle}, core::AsBytes, ecs::{Resources, World}, @@ -48,7 +48,6 @@ pub struct EguiNode { egui_texture_version: Option, texture_bind_group_descriptor: Option, texture_resources: HashMap, TextureResource>, - event_reader: EventReader>, vertex_buffer: Option, index_buffer: Option, @@ -133,7 +132,6 @@ impl EguiNode { egui_texture_version: None, texture_bind_group_descriptor: None, texture_resources: Default::default(), - event_reader: Default::default(), vertex_buffer: None, index_buffer: None, color_resolve_target_indices, @@ -425,7 +423,8 @@ impl EguiNode { texture_assets: &mut Assets, ) { let mut changed_assets: HashMap, &Texture> = HashMap::new(); - for event in self.event_reader.iter(asset_events) { + let mut asset_event_reader = ManualEventReader::>::default(); + for event in asset_event_reader.iter(asset_events) { let handle = match event { AssetEvent::Created { ref handle } | AssetEvent::Modified { ref handle } diff --git a/src/lib.rs b/src/lib.rs index d9539912c..7122c329e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,10 +58,9 @@ mod transform_node; use crate::{egui_node::EguiNode, systems::*, transform_node::EguiTransformNode}; use bevy::{ - app::{stage as bevy_stage, AppBuilder, EventReader, Plugin}, + app::{stage as bevy_stage, AppBuilder, Plugin}, asset::{Assets, Handle, HandleUntyped}, ecs::{IntoSystem, SystemStage}, - input::mouse::MouseWheel, log, reflect::TypeUuid, render::{ @@ -221,12 +220,7 @@ pub struct EguiContext { /// Egui context. pub ctx: egui::CtxRef, egui_textures: HashMap>, - mouse_position: Option<(f32, f32)>, - cursor_left: EventReader, - cursor_moved: EventReader, - mouse_wheel: EventReader, - received_character: EventReader, } impl EguiContext { @@ -235,10 +229,6 @@ impl EguiContext { ctx: Default::default(), egui_textures: Default::default(), mouse_position: Some((0.0, 0.0)), - cursor_left: Default::default(), - cursor_moved: Default::default(), - mouse_wheel: Default::default(), - received_character: Default::default(), } } diff --git a/src/systems.rs b/src/systems.rs index 1f7f951ad..1491b3ce8 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -1,6 +1,6 @@ use crate::{EguiContext, EguiInput, EguiOutput, EguiSettings, EguiShapes, WindowSize}; use bevy::{ - app::Events, + app::EventReader, core::Time, ecs::{Res, ResMut}, input::{ @@ -18,10 +18,10 @@ pub fn process_input( mut egui_context: ResMut, mut egui_input: ResMut, #[cfg(feature = "manage_clipboard")] egui_clipboard: Res, - ev_cursor_left: Res>, - ev_cursor_moved: Res>, - ev_mouse_wheel: Res>, - ev_received_character: Res>, + mut ev_cursor_left: EventReader, + mut ev_cursor: EventReader, + mut ev_mouse_wheel: EventReader, + mut ev_received_character: EventReader, mouse_button_input: Res>, keyboard_input: Res>, mut window_size: ResMut, @@ -51,7 +51,7 @@ pub fn process_input( egui_input.raw_input.pixels_per_point = Some(window_size.scale_factor * egui_settings.scale_factor as f32); - for event in egui_context.mouse_wheel.iter(&ev_mouse_wheel) { + for event in ev_mouse_wheel.iter() { let mut delta = egui::vec2(event.x, event.y); if let MouseScrollUnit::Line = event.unit { // TODO: https://github.com/emilk/egui/blob/b869db728b6bbefa098ac987a796b2b0b836c7cd/egui_glium/src/lib.rs#L141 @@ -81,13 +81,13 @@ pub fn process_input( command, }; - for cursor_entered in egui_context.cursor_left.iter(&ev_cursor_left) { + for cursor_entered in ev_cursor_left.iter() { if cursor_entered.id.is_primary() { egui_input.raw_input.events.push(egui::Event::PointerGone); egui_context.mouse_position = None; } } - if let Some(cursor_moved) = egui_context.cursor_moved.latest(&ev_cursor_moved) { + if let Some(cursor_moved) = ev_cursor.iter().next_back() { if cursor_moved.id.is_primary() { let scale_factor = egui_settings.scale_factor as f32; let mut mouse_position: (f32, f32) = (cursor_moved.position / scale_factor).into(); @@ -129,7 +129,7 @@ pub fn process_input( } if !ctrl && !win { - for event in egui_context.received_character.iter(&ev_received_character) { + for event in ev_received_character.iter() { if event.id.is_primary() && !event.char.is_control() { egui_input .raw_input From 0e3a9d2598c1add58dbce031b4a3e1785bf12bbf Mon Sep 17 00:00:00 2001 From: Daniel Wiesenberg Date: Tue, 19 Jan 2021 17:43:50 +0100 Subject: [PATCH 02/27] Track Bevy master branch --- Cargo.toml | 4 ++-- examples/ui.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b503181ba..2258d10db 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,8 +16,8 @@ manage_clipboard = ["clipboard", "thread_local"] open_url = ["webbrowser"] [dependencies] -bevy = { version = "0.4", default-features = false, features = ["render"] } -bevy_winit = "0.4.0" +bevy = { git = "https://github.com/bevyengine/bevy", default-features = false, features = ["render"] } +bevy_winit = { git = "https://github.com/bevyengine/bevy" } egui = "0.9.0" webbrowser = { version = "0.5.5", optional = true } winit = { version = "0.24.0", features = ["x11"], default-features = false } diff --git a/examples/ui.rs b/examples/ui.rs index 4714bdf2a..e9d508075 100644 --- a/examples/ui.rs +++ b/examples/ui.rs @@ -5,8 +5,8 @@ const BEVY_TEXTURE_ID: u64 = 0; fn main() { App::build() - .add_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0))) - .add_resource(Msaa { samples: 4 }) + .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0))) + .insert_resource(Msaa { samples: 4 }) .add_plugins(DefaultPlugins) .add_plugin(EguiPlugin) .add_startup_system(load_assets.system()) From 37145b218482b9f767422860b50fbb15596dbaea Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Mon, 25 Jan 2021 10:33:40 +0100 Subject: [PATCH 03/27] add BufferMapMode to map_buffer (#5) --- src/transform_node.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transform_node.rs b/src/transform_node.rs index 7acd8dbf7..27264a71c 100644 --- a/src/transform_node.rs +++ b/src/transform_node.rs @@ -5,7 +5,7 @@ use bevy::{ render::{ render_graph::{CommandQueue, Node, ResourceSlots, SystemNode}, renderer::{ - BufferId, BufferInfo, BufferUsage, RenderContext, RenderResourceBinding, + BufferId, BufferInfo, BufferMapMode, BufferUsage, RenderContext, RenderResourceBinding, RenderResourceBindings, RenderResourceContext, }, }, @@ -83,7 +83,7 @@ fn transform_node_system( let transform_data_size = std::mem::size_of::<[[f32; 2]; 2]>(); let staging_buffer = if let Some(staging_buffer) = state.staging_buffer { - render_resource_context.map_buffer(staging_buffer); + render_resource_context.map_buffer(staging_buffer, BufferMapMode::Write); staging_buffer } else { let buffer = render_resource_context.create_buffer(BufferInfo { From 159143701c29fa12e489674a1ef6ac83469af5bf Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Mon, 8 Feb 2021 23:34:38 +0100 Subject: [PATCH 04/27] update bevy to new wgpu api --- src/egui_node.rs | 15 +++++++-------- src/lib.rs | 47 +++++++++++++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/egui_node.rs b/src/egui_node.rs index dd98e7184..df0a76484 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -2,6 +2,7 @@ use crate::{ EguiContext, EguiSettings, EguiShapes, WindowSize, EGUI_PIPELINE_HANDLE, EGUI_TEXTURE_RESOURCE_BINDING_NAME, EGUI_TRANSFORM_RESOURCE_BINDING_NAME, }; +use bevy::render::pipeline::{VertexAttribute, VertexBufferLayout}; use bevy::{ app::{Events, ManualEventReader}, asset::{AssetEvent, Assets, Handle}, @@ -15,8 +16,7 @@ use bevy::{ }, pipeline::{ BindGroupDescriptor, IndexFormat, InputStepMode, PipelineCompiler, PipelineDescriptor, - PipelineLayout, PipelineSpecialization, VertexAttributeDescriptor, - VertexBufferDescriptor, VertexFormat, + PipelineLayout, PipelineSpecialization, VertexFormat, }, render_graph::{base::Msaa, Node, ResourceSlotInfo, ResourceSlots}, renderer::{ @@ -235,7 +235,7 @@ impl Node for EguiNode { &mut |render_pass| { render_pass.set_pipeline(self.pipeline_descriptor.as_ref().unwrap()); render_pass.set_vertex_buffer(0, self.vertex_buffer.unwrap(), 0); - render_pass.set_index_buffer(self.index_buffer.unwrap(), 0); + render_pass.set_index_buffer(self.index_buffer.unwrap(), 0, IndexFormat::Uint32); render_pass.set_bind_group( 0, self.transform_bind_group_descriptor.as_ref().unwrap().id, @@ -342,19 +342,19 @@ impl EguiNode { let mut pipeline_compiler = resources.get_mut::().unwrap(); let attributes = vec![ - VertexAttributeDescriptor { + VertexAttribute { name: Cow::from("Vertex_Position"), offset: 0, format: VertexFormat::Float2, shader_location: 0, }, - VertexAttributeDescriptor { + VertexAttribute { name: Cow::from("Vertex_Uv"), offset: VertexFormat::Float2.get_size(), format: VertexFormat::Float2, shader_location: 1, }, - VertexAttributeDescriptor { + VertexAttribute { name: Cow::from("Vertex_Color"), offset: VertexFormat::Float2.get_size() + VertexFormat::Float2.get_size(), format: VertexFormat::Float4, @@ -367,7 +367,7 @@ impl EguiNode { &mut shaders, &EGUI_PIPELINE_HANDLE.typed(), &PipelineSpecialization { - vertex_buffer_descriptor: VertexBufferDescriptor { + vertex_buffer_layout: VertexBufferLayout { name: Cow::from("EguiVertex"), stride: attributes .iter() @@ -375,7 +375,6 @@ impl EguiNode { step_mode: InputStepMode::Vertex, attributes, }, - index_format: IndexFormat::Uint32, sample_count: msaa.samples, ..PipelineSpecialization::default() }, diff --git a/src/lib.rs b/src/lib.rs index 7122c329e..c9101ba42 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -57,6 +57,10 @@ mod systems; mod transform_node; use crate::{egui_node::EguiNode, systems::*, transform_node::EguiTransformNode}; +use bevy::render::pipeline::{ + BlendState, ColorTargetState, CullMode, FrontFace, PrimitiveState, StencilFaceState, + StencilState, +}; use bevy::{ app::{stage as bevy_stage, AppBuilder, Plugin}, asset::{Assets, Handle, HandleUntyped}, @@ -65,17 +69,14 @@ use bevy::{ reflect::TypeUuid, render::{ pipeline::{ - BlendDescriptor, BlendFactor, BlendOperation, ColorStateDescriptor, ColorWrite, - CompareFunction, CullMode, DepthStencilStateDescriptor, FrontFace, IndexFormat, - PipelineDescriptor, RasterizationStateDescriptor, StencilStateDescriptor, - StencilStateFaceDescriptor, + BlendFactor, BlendOperation, ColorWrite, CompareFunction, DepthBiasState, + DepthStencilState, MultisampleState, PipelineDescriptor, }, render_graph::{base, base::Msaa, RenderGraph, WindowSwapChainNode, WindowTextureNode}, shader::{Shader, ShaderStage, ShaderStages}, stage as bevy_render_stage, texture::{Texture, TextureFormat}, }, - window::{CursorLeft, CursorMoved, ReceivedCharacter}, }; #[cfg(all(feature = "manage_clipboard", not(target_arch = "wasm32")))] use clipboard::{ClipboardContext, ClipboardProvider}; @@ -401,41 +402,47 @@ impl Plugin for EguiPlugin { fn build_egui_pipeline(shaders: &mut Assets, sample_count: u32) -> PipelineDescriptor { PipelineDescriptor { - rasterization_state: Some(RasterizationStateDescriptor { + primitive: PrimitiveState { front_face: FrontFace::Cw, cull_mode: CullMode::None, - depth_bias: 0, - depth_bias_slope_scale: 0.0, - depth_bias_clamp: 0.0, - clamp_depth: false, - }), - depth_stencil_state: Some(DepthStencilStateDescriptor { + ..Default::default() + }, + depth_stencil: Some(DepthStencilState { format: TextureFormat::Depth32Float, depth_write_enabled: true, depth_compare: CompareFunction::LessEqual, - stencil: StencilStateDescriptor { - front: StencilStateFaceDescriptor::IGNORE, - back: StencilStateFaceDescriptor::IGNORE, + stencil: StencilState { + front: StencilFaceState::IGNORE, + back: StencilFaceState::IGNORE, read_mask: 0, write_mask: 0, }, + bias: DepthBiasState { + constant: 0, + slope_scale: 0.0, + clamp: 0.0, + }, + clamp_depth: false, }), - color_states: vec![ColorStateDescriptor { + color_target_states: vec![ColorTargetState { format: TextureFormat::default(), - color_blend: BlendDescriptor { + color_blend: BlendState { src_factor: BlendFactor::One, dst_factor: BlendFactor::OneMinusSrcAlpha, operation: BlendOperation::Add, }, - alpha_blend: BlendDescriptor { + alpha_blend: BlendState { src_factor: BlendFactor::One, dst_factor: BlendFactor::OneMinusSrcAlpha, operation: BlendOperation::Add, }, write_mask: ColorWrite::ALL, }], - index_format: IndexFormat::Uint32, - sample_count, + multisample: MultisampleState { + count: sample_count, + mask: !0, + alpha_to_coverage_enabled: false, + }, ..PipelineDescriptor::new(ShaderStages { vertex: shaders.add(Shader::from_glsl( ShaderStage::Vertex, From bf3347b57f14f8484ae34e53d3f204f33e529ad8 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Wed, 17 Feb 2021 20:44:54 +0100 Subject: [PATCH 05/27] don't use exclusive systems in ui example --- examples/ui.rs | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/examples/ui.rs b/examples/ui.rs index e9d508075..3e3a047d3 100644 --- a/examples/ui.rs +++ b/examples/ui.rs @@ -7,6 +7,7 @@ fn main() { App::build() .insert_resource(ClearColor(Color::rgb(0.0, 0.0, 0.0))) .insert_resource(Msaa { samples: 4 }) + .init_resource::() .add_plugins(DefaultPlugins) .add_plugin(EguiPlugin) .add_startup_system(load_assets.system()) @@ -23,11 +24,8 @@ struct UiState { inverted: bool, } -fn load_assets(_world: &mut World, resources: &mut Resources) { - let mut egui_context = resources.get_mut::().unwrap(); - let asset_server = resources.get::().unwrap(); - - let texture_handle = asset_server.load("icon.png"); +fn load_assets(mut egui_context: ResMut, assets: Res) { + let texture_handle = assets.load("icon.png"); egui_context.set_egui_texture(BEVY_TEXTURE_ID, texture_handle); } @@ -37,12 +35,12 @@ fn update_ui_scale_factor(mut egui_settings: ResMut, windows: Res< } } -fn ui_example(_world: &mut World, resources: &mut Resources) { - resources.get_or_insert_with(UiState::default); - - let mut egui_ctx = resources.get_mut::().unwrap(); +fn ui_example( + mut egui_ctx: ResMut, + mut ui_state: ResMut, + assets: Res, +) { let ctx = &mut egui_ctx.ctx; - let mut ui_state = resources.get_mut::().unwrap(); let mut load = false; let mut remove = false; @@ -121,11 +119,10 @@ fn ui_example(_world: &mut World, resources: &mut Resources) { ui_state.inverted = !ui_state.inverted; } if load || invert { - let asset_server = resources.get::().unwrap(); let texture_handle = if ui_state.inverted { - asset_server.load("icon_inverted.png") + assets.load("icon_inverted.png") } else { - asset_server.load("icon.png") + assets.load("icon.png") }; egui_ctx.set_egui_texture(BEVY_TEXTURE_ID, texture_handle); } From 7420b31d7904d69f7543ffa5a5b941b8d9a1dcff Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Wed, 17 Feb 2021 20:45:15 +0100 Subject: [PATCH 06/27] add bevy to dev-dependencies to fix wasm-bindgen resolution error --- Cargo.toml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 2258d10db..ed51604ad 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,10 +26,13 @@ winit = { version = "0.24.0", features = ["x11"], default-features = false } clipboard = { version = "0.5.0", optional = true } thread_local = { version = "1.1.0", optional = true } +[dev-dependencies] +bevy = { git = "https://github.com/bevyengine/bevy", default-features = false, features = ["x11", "bevy_wgpu"] } + [[example]] name = "ui" path = "examples/ui.rs" -required-features = ["bevy/x11", "bevy/png", "bevy/bevy_wgpu"] +required-features = ["bevy/png"] [package.metadata.docs.rs] no-default-features = true # clipboard crate fails the build currently https://github.com/rust-lang/docs.rs/issues/695 From fd9af839a80ef2d80f558fa598f31218c3ede253 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Wed, 17 Feb 2021 20:59:09 +0100 Subject: [PATCH 07/27] make sure bevy UI is rendered before egui --- src/lib.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c9101ba42..89e6a99e0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -57,10 +57,6 @@ mod systems; mod transform_node; use crate::{egui_node::EguiNode, systems::*, transform_node::EguiTransformNode}; -use bevy::render::pipeline::{ - BlendState, ColorTargetState, CullMode, FrontFace, PrimitiveState, StencilFaceState, - StencilState, -}; use bevy::{ app::{stage as bevy_stage, AppBuilder, Plugin}, asset::{Assets, Handle, HandleUntyped}, @@ -69,8 +65,9 @@ use bevy::{ reflect::TypeUuid, render::{ pipeline::{ - BlendFactor, BlendOperation, ColorWrite, CompareFunction, DepthBiasState, - DepthStencilState, MultisampleState, PipelineDescriptor, + BlendFactor, BlendOperation, BlendState, ColorTargetState, ColorWrite, CompareFunction, + CullMode, DepthBiasState, DepthStencilState, FrontFace, MultisampleState, + PipelineDescriptor, PrimitiveState, StencilFaceState, StencilState, }, render_graph::{base, base::Msaa, RenderGraph, WindowSwapChainNode, WindowTextureNode}, shader::{Shader, ShaderStage, ShaderStages}, @@ -358,6 +355,10 @@ impl Plugin for EguiPlugin { render_graph .add_node_edge(base::node::MAIN_PASS, node::EGUI_PASS) .unwrap(); + render_graph + // hardcodede until https://github.com/bevyengine/bevy/pull/1464 is merged + .add_node_edge("ui_pass", node::EGUI_PASS) + .unwrap(); render_graph .add_slot_edge( From 6044dead5acd2197a31c72623006baee98c2dafa Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Thu, 18 Feb 2021 23:22:09 +0100 Subject: [PATCH 08/27] update bevy stage labels --- src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 89e6a99e0..4e068ae06 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,7 +58,7 @@ mod transform_node; use crate::{egui_node::EguiNode, systems::*, transform_node::EguiTransformNode}; use bevy::{ - app::{stage as bevy_stage, AppBuilder, Plugin}, + app::{AppBuilder, CoreStage, Plugin}, asset::{Assets, Handle, HandleUntyped}, ecs::{IntoSystem, SystemStage}, log, @@ -71,8 +71,8 @@ use bevy::{ }, render_graph::{base, base::Msaa, RenderGraph, WindowSwapChainNode, WindowTextureNode}, shader::{Shader, ShaderStage, ShaderStages}, - stage as bevy_render_stage, texture::{Texture, TextureFormat}, + RenderStage, }, }; #[cfg(all(feature = "manage_clipboard", not(target_arch = "wasm32")))] @@ -313,11 +313,11 @@ pub mod stage { impl Plugin for EguiPlugin { fn build(&self, app: &mut AppBuilder) { - app.add_stage_after(bevy_stage::EVENT, stage::INPUT, SystemStage::parallel()); + app.add_stage_after(CoreStage::Event, stage::INPUT, SystemStage::parallel()); app.add_stage_after(stage::INPUT, stage::POST_INPUT, SystemStage::parallel()); app.add_stage_after(stage::POST_INPUT, stage::UI_FRAME, SystemStage::parallel()); app.add_stage_before( - bevy_render_stage::RENDER_RESOURCE, + RenderStage::RenderResource, stage::UI_FRAME_END, SystemStage::parallel(), ); From 909eca6d9e847d4a949a1c67fb1b502ea374c89c Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Sat, 20 Feb 2021 14:18:06 +0100 Subject: [PATCH 09/27] fmt --- src/egui_node.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/egui_node.rs b/src/egui_node.rs index df0a76484..f5fed5bf1 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -2,7 +2,6 @@ use crate::{ EguiContext, EguiSettings, EguiShapes, WindowSize, EGUI_PIPELINE_HANDLE, EGUI_TEXTURE_RESOURCE_BINDING_NAME, EGUI_TRANSFORM_RESOURCE_BINDING_NAME, }; -use bevy::render::pipeline::{VertexAttribute, VertexBufferLayout}; use bevy::{ app::{Events, ManualEventReader}, asset::{AssetEvent, Assets, Handle}, @@ -16,7 +15,8 @@ use bevy::{ }, pipeline::{ BindGroupDescriptor, IndexFormat, InputStepMode, PipelineCompiler, PipelineDescriptor, - PipelineLayout, PipelineSpecialization, VertexFormat, + PipelineLayout, PipelineSpecialization, VertexAttribute, VertexBufferLayout, + VertexFormat, }, render_graph::{base::Msaa, Node, ResourceSlotInfo, ResourceSlots}, renderer::{ From 4ac85f03659da7e0aacc9eea5dd2d85f3504c078 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Fri, 26 Feb 2021 12:13:08 +0100 Subject: [PATCH 10/27] wip: port to ecs v2 --- src/egui_node.rs | 43 +++++++++++++++++++++++-------------------- src/lib.rs | 30 +++++++++++++++++------------- src/systems.rs | 29 ++++++++++++++++++----------- src/transform_node.rs | 15 ++++++--------- 4 files changed, 64 insertions(+), 53 deletions(-) diff --git a/src/egui_node.rs b/src/egui_node.rs index f5fed5bf1..e24cacb1d 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -6,8 +6,8 @@ use bevy::{ app::{Events, ManualEventReader}, asset::{AssetEvent, Assets, Handle}, core::AsBytes, - ecs::{Resources, World}, log, + prelude::*, render::{ pass::{ ClearColor, LoadOp, Operations, PassDescriptor, @@ -153,27 +153,28 @@ impl Node for EguiNode { fn update( &mut self, - _world: &World, - resources: &Resources, + world: &World, render_context: &mut dyn RenderContext, input: &ResourceSlots, _output: &mut ResourceSlots, ) { - self.process_attachments(input, resources); - self.init_pipeline(render_context, resources); + self.process_attachments(input, world); + self.init_pipeline(render_context, world); - let window_size = resources.get::().unwrap(); - let egui_settings = resources.get::().unwrap(); - let mut egui_shapes = resources.get_mut::().unwrap(); + let window_size = world.get_resource::().unwrap(); + let egui_settings = world.get_resource::().unwrap(); + let mut egui_shapes = world.get_resource_mut::().unwrap(); - let render_resource_bindings = resources.get::().unwrap(); + let render_resource_bindings = world.get_resource::().unwrap(); self.init_transform_bind_group(render_context, &render_resource_bindings); - let mut texture_assets = resources.get_mut::>().unwrap(); - let asset_events = resources.get_mut::>>().unwrap(); + let mut texture_assets = world.get_resource_mut::>().unwrap(); + let asset_events = world + .get_resource_mut::>>() + .unwrap(); - let mut egui_context = resources.get_mut::().unwrap(); + let mut egui_context = world.get_resource_mut::().unwrap(); self.process_asset_events( render_context, @@ -182,7 +183,7 @@ impl Node for EguiNode { &mut texture_assets, ); self.remove_unused_textures(render_context, &egui_context); - self.init_textures(render_context, &mut egui_context, &mut texture_assets); + // self.init_textures(render_context, &mut egui_context, &mut texture_assets); let mut shapes = Vec::new(); std::mem::swap(&mut egui_shapes.shapes, &mut shapes); @@ -295,7 +296,7 @@ impl Node for EguiNode { } impl EguiNode { - fn process_attachments(&mut self, input: &ResourceSlots, resources: &Resources) { + fn process_attachments(&mut self, input: &ResourceSlots, world: &World) { if let Some(input_index) = self.depth_stencil_attachment_input_index { self.pass_descriptor .depth_stencil_attachment @@ -312,7 +313,7 @@ impl EguiNode { .enumerate() { if self.default_clear_color_inputs.contains(&i) { - if let Some(default_clear_color) = resources.get::() { + if let Some(default_clear_color) = world.get_resource::() { color_attachment.ops.load = LoadOp::Clear(default_clear_color.0); } } @@ -328,18 +329,20 @@ impl EguiNode { } } - fn init_pipeline(&mut self, render_context: &mut dyn RenderContext, resources: &Resources) { + fn init_pipeline(&mut self, render_context: &mut dyn RenderContext, world: &World) { if self.pipeline_descriptor.is_some() { return; } - let mut pipelines = resources.get_mut::>().unwrap(); - let mut shaders = resources.get_mut::>().unwrap(); - let msaa = resources.get::().unwrap(); + let mut pipelines = world + .get_resource_mut::>() + .unwrap(); + let mut shaders = world.get_resource_mut::>().unwrap(); + let msaa = world.get_resource::().unwrap(); let pipeline_descriptor_handle = { let render_resource_context = render_context.resources(); - let mut pipeline_compiler = resources.get_mut::().unwrap(); + let mut pipeline_compiler = world.get_resource_mut::().unwrap(); let attributes = vec![ VertexAttribute { diff --git a/src/lib.rs b/src/lib.rs index 4e068ae06..c435d4c23 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,8 +60,8 @@ use crate::{egui_node::EguiNode, systems::*, transform_node::EguiTransformNode}; use bevy::{ app::{AppBuilder, CoreStage, Plugin}, asset::{Assets, Handle, HandleUntyped}, - ecs::{IntoSystem, SystemStage}, log, + prelude::*, reflect::TypeUuid, render::{ pipeline::{ @@ -331,25 +331,29 @@ impl Plugin for EguiPlugin { app.add_system_to_stage(stage::UI_FRAME, begin_frame.system()); app.add_system_to_stage(stage::UI_FRAME_END, process_output.system()); - let resources = app.resources_mut(); - resources.get_or_insert_with(EguiSettings::default); - resources.get_or_insert_with(EguiInput::default); - resources.get_or_insert_with(EguiOutput::default); - resources.get_or_insert_with(EguiShapes::default); + let world = app.world_mut(); + world.get_resource_or_insert_with(EguiSettings::default); + world.get_resource_or_insert_with(EguiInput::default); + world.get_resource_or_insert_with(EguiOutput::default); + world.get_resource_or_insert_with(EguiShapes::default); #[cfg(feature = "manage_clipboard")] - resources.get_or_insert_with(EguiClipboard::default); - resources.insert(EguiContext::new()); - resources.insert(WindowSize::new(0.0, 0.0, 0.0)); + world.get_resource_or_insert_with(EguiClipboard::default); + world.insert_resource(EguiContext::new()); + world.insert_resource(WindowSize::new(0.0, 0.0, 0.0)); - let mut pipelines = resources.get_mut::>().unwrap(); - let mut shaders = resources.get_mut::>().unwrap(); - let msaa = resources.get::().unwrap(); + let world = world.cell(); + + let mut pipelines = world + .get_resource_mut::>() + .unwrap(); + let msaa = world.get_resource::().unwrap(); + let mut shaders = world.get_resource_mut::>().unwrap(); pipelines.set_untracked( EGUI_PIPELINE_HANDLE, build_egui_pipeline(&mut shaders, msaa.samples), ); - let mut render_graph = resources.get_mut::().unwrap(); + let mut render_graph = world.get_resource_mut::().unwrap(); render_graph.add_node(node::EGUI_PASS, EguiNode::new(&msaa)); render_graph diff --git a/src/systems.rs b/src/systems.rs index 1491b3ce8..d7345ff73 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -2,26 +2,33 @@ use crate::{EguiContext, EguiInput, EguiOutput, EguiSettings, EguiShapes, Window use bevy::{ app::EventReader, core::Time, - ecs::{Res, ResMut}, + ecs::system::SystemParam, input::{ keyboard::KeyCode, mouse::{MouseButton, MouseScrollUnit, MouseWheel}, Input, }, log, + prelude::*, window::{CursorLeft, CursorMoved, ReceivedCharacter, Windows}, }; use bevy_winit::WinitWindows; +#[derive(SystemParam)] +struct InputEvents<'a> { + #[cfg(feature = "manage_clipboard")] + egui_clipboard: Res<'a, crate::EguiClipboard>, + ev_cursor_left: EventReader<'a, CursorLeft>, + ev_cursor: EventReader<'a, CursorMoved>, + ev_mouse_wheel: EventReader<'a, MouseWheel>, + ev_received_character: EventReader<'a, ReceivedCharacter>, +} + #[allow(clippy::too_many_arguments)] pub fn process_input( mut egui_context: ResMut, mut egui_input: ResMut, - #[cfg(feature = "manage_clipboard")] egui_clipboard: Res, - mut ev_cursor_left: EventReader, - mut ev_cursor: EventReader, - mut ev_mouse_wheel: EventReader, - mut ev_received_character: EventReader, + mut input_events: InputEvents, mouse_button_input: Res>, keyboard_input: Res>, mut window_size: ResMut, @@ -51,7 +58,7 @@ pub fn process_input( egui_input.raw_input.pixels_per_point = Some(window_size.scale_factor * egui_settings.scale_factor as f32); - for event in ev_mouse_wheel.iter() { + for event in input_events.ev_mouse_wheel.iter() { let mut delta = egui::vec2(event.x, event.y); if let MouseScrollUnit::Line = event.unit { // TODO: https://github.com/emilk/egui/blob/b869db728b6bbefa098ac987a796b2b0b836c7cd/egui_glium/src/lib.rs#L141 @@ -81,13 +88,13 @@ pub fn process_input( command, }; - for cursor_entered in ev_cursor_left.iter() { + for cursor_entered in input_events.ev_cursor_left.iter() { if cursor_entered.id.is_primary() { egui_input.raw_input.events.push(egui::Event::PointerGone); egui_context.mouse_position = None; } } - if let Some(cursor_moved) = ev_cursor.iter().next_back() { + if let Some(cursor_moved) = input_events.ev_cursor.iter().next_back() { if cursor_moved.id.is_primary() { let scale_factor = egui_settings.scale_factor as f32; let mut mouse_position: (f32, f32) = (cursor_moved.position / scale_factor).into(); @@ -129,7 +136,7 @@ pub fn process_input( } if !ctrl && !win { - for event in ev_received_character.iter() { + for event in input_events.ev_received_character.iter() { if event.id.is_primary() && !event.char.is_control() { egui_input .raw_input @@ -167,7 +174,7 @@ pub fn process_input( egui_input.raw_input.events.push(egui::Event::Cut); } if command && keyboard_input.just_pressed(KeyCode::V) { - if let Some(contents) = egui_clipboard.get_contents() { + if let Some(contents) = input_events.egui_clipboard.get_contents() { egui_input .raw_input .events diff --git a/src/transform_node.rs b/src/transform_node.rs index 27264a71c..d7bb8198f 100644 --- a/src/transform_node.rs +++ b/src/transform_node.rs @@ -1,7 +1,7 @@ use crate::{EguiSettings, WindowSize, EGUI_TRANSFORM_RESOURCE_BINDING_NAME}; use bevy::{ core::AsBytes, - ecs::{Commands, IntoSystem, Local, Res, ResMut, Resources, System, World}, + prelude::*, render::{ render_graph::{CommandQueue, Node, ResourceSlots, SystemNode}, renderer::{ @@ -28,7 +28,6 @@ impl Node for EguiTransformNode { fn update( &mut self, _world: &World, - _resources: &Resources, render_context: &mut dyn RenderContext, _input: &ResourceSlots, _output: &mut ResourceSlots, @@ -38,18 +37,16 @@ impl Node for EguiTransformNode { } impl SystemNode for EguiTransformNode { - fn get_system(&self, commands: &mut Commands) -> Box> { - let system = transform_node_system.system(); - commands.insert_local_resource( - system.id(), - TransformNodeState { + fn get_system(&self) -> Box> { + let system = transform_node_system.system().config(|c| { + c.0 = Some(TransformNodeState { command_queue: self.command_queue.clone(), transform_buffer: None, staging_buffer: None, prev_window_size: WindowSize::new(0.0, 0.0, 0.0), prev_scale_factor: 0.0, - }, - ); + }); + }); Box::new(system) } } From 531076c68b81ca406bb9e2ab3536453efed7fecf Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Sat, 27 Feb 2021 12:11:22 +0100 Subject: [PATCH 11/27] update to ecs v2 --- src/egui_node.rs | 133 ++++++++++++++++++++++++++++++----------------- src/systems.rs | 2 +- 2 files changed, 87 insertions(+), 48 deletions(-) diff --git a/src/egui_node.rs b/src/egui_node.rs index e24cacb1d..4480c8227 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -18,15 +18,17 @@ use bevy::{ PipelineLayout, PipelineSpecialization, VertexAttribute, VertexBufferLayout, VertexFormat, }, - render_graph::{base::Msaa, Node, ResourceSlotInfo, ResourceSlots}, + render_graph::{base::Msaa, CommandQueue, Node, ResourceSlotInfo, ResourceSlots}, renderer::{ BindGroup, BufferId, BufferInfo, BufferUsage, RenderContext, RenderResourceBinding, - RenderResourceBindings, RenderResourceType, SamplerId, TextureId, + RenderResourceBindings, RenderResourceContext, RenderResourceType, SamplerId, + TextureId, }, shader::Shader, texture::{Extent3d, Texture, TextureDescriptor, TextureDimension, TextureFormat}, }, }; +use egui::paint::ClippedShape; use std::{ borrow::Cow, collections::{HashMap, HashSet}, @@ -51,6 +53,9 @@ pub struct EguiNode { vertex_buffer: Option, index_buffer: Option, + + shapes: Vec, + render_commands: CommandQueue, } #[derive(Debug)] @@ -135,6 +140,8 @@ impl EguiNode { vertex_buffer: None, index_buffer: None, color_resolve_target_indices, + shapes: Vec::new(), + render_commands: Default::default(), } } } @@ -151,6 +158,36 @@ impl Node for EguiNode { &self.inputs } + fn prepare(&mut self, world: &mut World) { + self.init_pipeline(world); + + let world = world.cell(); + + let mut texture_assets = world.get_resource_mut::>().unwrap(); + let asset_events = world.get_resource::>>().unwrap(); + let mut render_resource_context = world + .get_resource_mut::>() + .unwrap(); + let render_resource_context = &mut **render_resource_context; + let mut egui_context = world.get_resource_mut::().unwrap(); + + self.process_asset_events( + render_resource_context, + &mut egui_context, + &asset_events, + &mut texture_assets, + ); + self.remove_unused_textures(render_resource_context, &egui_context); + self.init_textures( + render_resource_context, + &mut egui_context, + &mut texture_assets, + ); + + let mut egui_shapes = world.get_resource_mut::().unwrap(); + self.shapes = std::mem::take(&mut egui_shapes.shapes); + } + fn update( &mut self, world: &World, @@ -158,35 +195,20 @@ impl Node for EguiNode { input: &ResourceSlots, _output: &mut ResourceSlots, ) { + self.render_commands.execute(render_context); + self.process_attachments(input, world); - self.init_pipeline(render_context, world); let window_size = world.get_resource::().unwrap(); let egui_settings = world.get_resource::().unwrap(); - let mut egui_shapes = world.get_resource_mut::().unwrap(); let render_resource_bindings = world.get_resource::().unwrap(); self.init_transform_bind_group(render_context, &render_resource_bindings); - let mut texture_assets = world.get_resource_mut::>().unwrap(); - let asset_events = world - .get_resource_mut::>>() - .unwrap(); + let egui_context = world.get_resource::().unwrap(); - let mut egui_context = world.get_resource_mut::().unwrap(); - - self.process_asset_events( - render_context, - &mut egui_context, - &asset_events, - &mut texture_assets, - ); - self.remove_unused_textures(render_context, &egui_context); - // self.init_textures(render_context, &mut egui_context, &mut texture_assets); - - let mut shapes = Vec::new(); - std::mem::swap(&mut egui_shapes.shapes, &mut shapes); + let shapes = std::mem::take(&mut self.shapes); let egui_paint_jobs = egui_context.ctx.tessellate(shapes); let mut vertex_buffer = Vec::::new(); @@ -329,7 +351,13 @@ impl EguiNode { } } - fn init_pipeline(&mut self, render_context: &mut dyn RenderContext, world: &World) { + fn init_pipeline(&mut self, world: &mut World) { + let world = world.cell(); + + let render_resource_context = world + .get_resource::>() + .unwrap(); + if self.pipeline_descriptor.is_some() { return; } @@ -341,7 +369,6 @@ impl EguiNode { let msaa = world.get_resource::().unwrap(); let pipeline_descriptor_handle = { - let render_resource_context = render_context.resources(); let mut pipeline_compiler = world.get_resource_mut::().unwrap(); let attributes = vec![ @@ -365,7 +392,7 @@ impl EguiNode { }, ]; pipeline_compiler.compile_pipeline( - render_resource_context, + &**render_resource_context, &mut pipelines, &mut shaders, &EGUI_PIPELINE_HANDLE.typed(), @@ -419,7 +446,7 @@ impl EguiNode { fn process_asset_events( &mut self, - render_context: &mut dyn RenderContext, + render_resource_context: &mut dyn RenderResourceContext, egui_context: &mut EguiContext, asset_events: &Events>, texture_assets: &mut Assets, @@ -453,14 +480,14 @@ impl EguiNode { } AssetEvent::Removed { ref handle } => { egui_context.remove_texture(handle); - self.remove_texture(render_context, handle); + self.remove_texture(render_resource_context, handle); // If an asset was modified and removed in the same update, ignore the modification. changed_assets.remove(&handle); } } } for (texture_handle, texture) in changed_assets { - self.update_texture(render_context, texture, texture_handle); + self.update_texture(render_resource_context, texture, texture_handle); } let egui_texture = egui_context.ctx.texture(); @@ -469,14 +496,14 @@ impl EguiNode { if let Some(egui_texture_handle) = self.egui_texture.clone() { let texture_asset = texture_assets.get_mut(&egui_texture_handle).unwrap(); *texture_asset = as_bevy_texture(&egui_texture); - self.update_texture(render_context, &texture_asset, egui_texture_handle); + self.update_texture(render_resource_context, &texture_asset, egui_texture_handle); } } } fn remove_unused_textures( &mut self, - render_context: &mut dyn RenderContext, + render_resource_context: &mut dyn RenderResourceContext, egui_context: &EguiContext, ) { let texture_handles = egui_context.egui_textures.values().collect::>(); @@ -490,13 +517,13 @@ impl EguiNode { } } for texture_to_remove in textures_to_remove { - self.remove_texture(render_context, &texture_to_remove); + self.remove_texture(render_resource_context, &texture_to_remove); } } fn init_textures( &mut self, - render_context: &mut dyn RenderContext, + render_resource_context: &mut dyn RenderResourceContext, egui_context: &mut EguiContext, texture_assets: &mut Assets, ) { @@ -512,13 +539,17 @@ impl EguiNode { } for texture in egui_context.egui_textures.values() { - self.create_texture(render_context, texture_assets, texture.clone_weak()); + self.create_texture( + render_resource_context, + texture_assets, + texture.clone_weak(), + ); } } fn update_texture( &mut self, - render_context: &mut dyn RenderContext, + render_resource_context: &mut dyn RenderResourceContext, texture_asset: &Texture, texture_handle: Handle, ) { @@ -536,21 +567,26 @@ impl EguiNode { texture_handle ); // If a texture descriptor is updated, we'll re-create the texture in `init_textures`. - self.remove_texture(render_context, &texture_handle); + self.remove_texture(render_resource_context, &texture_handle); return; } - Self::copy_texture(render_context, &texture_resource, texture_asset); + Self::copy_texture( + &mut self.render_commands, + render_resource_context, + &texture_resource, + texture_asset, + ); } fn create_texture( &mut self, - render_context: &mut dyn RenderContext, + render_resource_context: &mut dyn RenderResourceContext, texture_assets: &Assets, texture_handle: Handle, ) { if let Some(texture_resource) = self.texture_resources.get(&texture_handle) { // bevy_webgl2 seems to clean bind groups each frame. - render_context.resources().create_bind_group( + render_resource_context.create_bind_group( self.texture_bind_group_descriptor.as_ref().unwrap().id, &texture_resource.bind_group, ); @@ -565,8 +601,6 @@ impl EguiNode { log::debug!("Creating a texture: ${:?}", texture_handle); - let render_resource_context = render_context.resources(); - let texture_descriptor: TextureDescriptor = texture_asset.into(); let texture = render_resource_context.create_texture(texture_descriptor); let sampler = render_resource_context.create_sampler(&texture_asset.sampler); @@ -587,7 +621,12 @@ impl EguiNode { sampler, bind_group: texture_bind_group, }; - Self::copy_texture(render_context, &texture_resource, texture_asset); + Self::copy_texture( + &mut self.render_commands, + render_resource_context, + &texture_resource, + texture_asset, + ); log::debug!("Texture created: {:?}", texture_resource); self.texture_resources .insert(texture_handle, texture_resource); @@ -595,7 +634,7 @@ impl EguiNode { fn remove_texture( &mut self, - render_context: &mut dyn RenderContext, + render_resource_context: &mut dyn RenderResourceContext, texture_handle: &Handle, ) { let texture_resource = match self.texture_resources.remove(texture_handle) { @@ -604,18 +643,18 @@ impl EguiNode { }; log::debug!("Removing a texture: ${:?}", texture_handle); - let render_resource_context = render_context.resources(); render_resource_context.remove_texture(texture_resource.texture); render_resource_context.remove_sampler(texture_resource.sampler); } fn copy_texture( - render_context: &mut dyn RenderContext, + render_commands: &mut CommandQueue, + render_resource_context: &mut dyn RenderResourceContext, texture_resource: &TextureResource, texture: &Texture, ) { let width = texture.size.width as usize; - let aligned_width = render_context.resources().get_aligned_texture_size(width); + let aligned_width = render_resource_context.get_aligned_texture_size(width); let format_size = texture.format.pixel_size(); let mut aligned_data = vec![ 0; @@ -632,7 +671,7 @@ impl EguiNode { let offset = index * aligned_width * format_size; aligned_data[offset..(offset + width * format_size)].copy_from_slice(row); }); - let texture_buffer = render_context.resources().create_buffer_with_data( + let texture_buffer = render_resource_context.create_buffer_with_data( BufferInfo { buffer_usage: BufferUsage::COPY_SRC, ..Default::default() @@ -640,7 +679,7 @@ impl EguiNode { &aligned_data, ); - render_context.copy_buffer_to_texture( + render_commands.copy_buffer_to_texture( texture_buffer, 0, (format_size * aligned_width) as u32, @@ -649,7 +688,7 @@ impl EguiNode { 0, texture_resource.descriptor.size, ); - render_context.resources().remove_buffer(texture_buffer); + render_commands.free_buffer(texture_buffer); } fn update_buffers( diff --git a/src/systems.rs b/src/systems.rs index d7345ff73..5e0829bf7 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -15,7 +15,7 @@ use bevy::{ use bevy_winit::WinitWindows; #[derive(SystemParam)] -struct InputEvents<'a> { +pub struct InputEvents<'a> { #[cfg(feature = "manage_clipboard")] egui_clipboard: Res<'a, crate::EguiClipboard>, ev_cursor_left: EventReader<'a, CursorLeft>, From caa7eacac1126a9cc670136131a16c7456fdb6ec Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Sat, 6 Mar 2021 12:33:21 +0100 Subject: [PATCH 12/27] only connect UI_PASS node if it exists --- src/lib.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index c435d4c23..17bce89ea 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -359,10 +359,12 @@ impl Plugin for EguiPlugin { render_graph .add_node_edge(base::node::MAIN_PASS, node::EGUI_PASS) .unwrap(); - render_graph - // hardcodede until https://github.com/bevyengine/bevy/pull/1464 is merged - .add_node_edge("ui_pass", node::EGUI_PASS) - .unwrap(); + + if let Ok(ui_pass) = render_graph.get_node_id(bevy::ui::node::UI_PASS) { + render_graph + .add_node_edge(ui_pass, node::EGUI_PASS) + .unwrap(); + } render_graph .add_slot_edge( From fb800be9301c3b548c6a550ad8287a8ac8d6bf1d Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Sat, 6 Mar 2021 12:41:53 +0100 Subject: [PATCH 13/27] undo dev-dependencies change as that breaks wasm dependencies --- Cargo.toml | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index ed51604ad..b2a21f34f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -26,13 +26,15 @@ winit = { version = "0.24.0", features = ["x11"], default-features = false } clipboard = { version = "0.5.0", optional = true } thread_local = { version = "1.1.0", optional = true } -[dev-dependencies] -bevy = { git = "https://github.com/bevyengine/bevy", default-features = false, features = ["x11", "bevy_wgpu"] } - [[example]] name = "ui" path = "examples/ui.rs" -required-features = ["bevy/png"] +required-features = ["bevy/x11", "bevy/bevy_wgpu", "bevy/png"] + +[[example]] +name = "simple" +path = "examples/simple.rs" +required-features = ["bevy/x11", "bevy/bevy_wgpu"] [package.metadata.docs.rs] no-default-features = true # clipboard crate fails the build currently https://github.com/rust-lang/docs.rs/issues/695 From 5726c83d3dc465881f077341d4d7b39cbdb03ca9 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Sun, 7 Mar 2021 15:43:27 +0100 Subject: [PATCH 14/27] use the bevy_winit feature instead of the crate this way, when patching bevy using [patch.crates-io] only one crate needs to be patched and no confusing "expected WinitPlugin, got WinitPlugin" errors occur --- Cargo.toml | 3 +-- src/systems.rs | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b2a21f34f..775bc9b1d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,8 +16,7 @@ manage_clipboard = ["clipboard", "thread_local"] open_url = ["webbrowser"] [dependencies] -bevy = { git = "https://github.com/bevyengine/bevy", default-features = false, features = ["render"] } -bevy_winit = { git = "https://github.com/bevyengine/bevy" } +bevy = { git = "https://github.com/bevyengine/bevy", default-features = false, features = ["render", "bevy_winit"] } egui = "0.9.0" webbrowser = { version = "0.5.5", optional = true } winit = { version = "0.24.0", features = ["x11"], default-features = false } diff --git a/src/systems.rs b/src/systems.rs index 5e0829bf7..8fce5cc6f 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -12,7 +12,7 @@ use bevy::{ prelude::*, window::{CursorLeft, CursorMoved, ReceivedCharacter, Windows}, }; -use bevy_winit::WinitWindows; +use bevy::winit::WinitWindows; #[derive(SystemParam)] pub struct InputEvents<'a> { From 92943b7c3e6e11c413af07c55f5e78c78dffa343 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Fri, 12 Mar 2021 11:49:15 +0100 Subject: [PATCH 15/27] update bevy, use system dependencies instead of stages --- src/lib.rs | 52 +++++++++++++++++++++++++++++--------------------- src/systems.rs | 2 +- 2 files changed, 31 insertions(+), 23 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 17bce89ea..5542ae0f1 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -60,6 +60,7 @@ use crate::{egui_node::EguiNode, systems::*, transform_node::EguiTransformNode}; use bevy::{ app::{AppBuilder, CoreStage, Plugin}, asset::{Assets, Handle, HandleUntyped}, + input::InputSystem, log, prelude::*, reflect::TypeUuid, @@ -297,39 +298,46 @@ pub mod node { pub const EGUI_TRANSFORM: &str = "egui_transform"; } +#[derive(StageLabel, Clone, Hash, Debug, Eq, PartialEq)] /// The names of `bevy_egui` stages. -pub mod stage { - /// Runs after [bevy::app::stage::EVENT]. This is where `bevy_egui` translates Bevy's input events to Egui. - pub const INPUT: &str = "input"; - /// Runs after [INPUT]. - pub const POST_INPUT: &str = "post_input"; - /// Runs after [POST_INPUT]. All Egui widgets should be added during or after this stage and before [UI_FRAME_END]. - pub const UI_FRAME: &str = "ui_frame"; +pub enum EguiStage { /// Runs before [bevy::render::stage::RENDER_RESOURCE]. This is where we read Egui's output. - pub const UI_FRAME_END: &str = "ui_frame_end"; - /// Runs after [UI_FRAME_END]. - pub const POST_UI_FRAME_END: &str = "post_ui_frame_end"; + UiFrameEnd, +} + +#[derive(SystemLabel, Clone, Hash, Debug, Eq, PartialEq)] +enum EguiSystem { + ProcessInput, + BeginFrame, + ProcessOutput, } impl Plugin for EguiPlugin { fn build(&self, app: &mut AppBuilder) { - app.add_stage_after(CoreStage::Event, stage::INPUT, SystemStage::parallel()); - app.add_stage_after(stage::INPUT, stage::POST_INPUT, SystemStage::parallel()); - app.add_stage_after(stage::POST_INPUT, stage::UI_FRAME, SystemStage::parallel()); app.add_stage_before( RenderStage::RenderResource, - stage::UI_FRAME_END, - SystemStage::parallel(), - ); - app.add_stage_after( - stage::UI_FRAME_END, - stage::POST_UI_FRAME_END, + EguiStage::UiFrameEnd, SystemStage::parallel(), ); - app.add_system_to_stage(stage::INPUT, process_input.system()); - app.add_system_to_stage(stage::UI_FRAME, begin_frame.system()); - app.add_system_to_stage(stage::UI_FRAME_END, process_output.system()); + app.add_system_to_stage( + CoreStage::PreUpdate, + process_input + .system() + .label(EguiSystem::ProcessInput) + .after(InputSystem), + ); + app.add_system_to_stage( + CoreStage::PreUpdate, + begin_frame + .system() + .label(EguiSystem::BeginFrame) + .after(EguiSystem::ProcessInput), + ); + app.add_system_to_stage( + EguiStage::UiFrameEnd, + process_output.system().label(EguiSystem::ProcessOutput), + ); let world = app.world_mut(); world.get_resource_or_insert_with(EguiSettings::default); diff --git a/src/systems.rs b/src/systems.rs index 8fce5cc6f..f7e84b4a4 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -11,8 +11,8 @@ use bevy::{ log, prelude::*, window::{CursorLeft, CursorMoved, ReceivedCharacter, Windows}, + winit::WinitWindows, }; -use bevy::winit::WinitWindows; #[derive(SystemParam)] pub struct InputEvents<'a> { From 6411ba31a1e99e483973daa1c49be3fb018c0d7f Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Fri, 12 Mar 2021 11:49:15 +0100 Subject: [PATCH 16/27] specify bevy main branch --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index 775bc9b1d..aa2d14615 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,7 +16,7 @@ manage_clipboard = ["clipboard", "thread_local"] open_url = ["webbrowser"] [dependencies] -bevy = { git = "https://github.com/bevyengine/bevy", default-features = false, features = ["render", "bevy_winit"] } +bevy = { git = "https://github.com/bevyengine/bevy", branch = "main", default-features = false, features = ["render", "bevy_winit"] } egui = "0.9.0" webbrowser = { version = "0.5.5", optional = true } winit = { version = "0.24.0", features = ["x11"], default-features = false } From 0ed4e17619dfe7db898ac07163ef32db65db15e4 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Fri, 12 Mar 2021 11:57:08 +0100 Subject: [PATCH 17/27] make EguiSystem public --- src/lib.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 5542ae0f1..ed80ade5d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -306,9 +306,16 @@ pub enum EguiStage { } #[derive(SystemLabel, Clone, Hash, Debug, Eq, PartialEq)] -enum EguiSystem { +/// The names of egui systems. +pub enum EguiSystem { + /// Reads keyboard, mouse etc. input and write it into the [`EguiInput`] resource + /// + /// To modify the input, specify + /// `system.after(EguiSystem::ProcessInput).before(EguiSystem::BeginFrame)`. ProcessInput, + /// Begins the `egui` frame BeginFrame, + /// Processes the [`EguiOutput`] resource ProcessOutput, } From 0e8335a119cd99d073c2af7940f7edf2846a5685 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Fri, 12 Mar 2021 11:58:48 +0100 Subject: [PATCH 18/27] fix doc links --- src/lib.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index ed80ade5d..20c3db15d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -121,7 +121,7 @@ impl Default for EguiSettings { } /// A resource that stores the input passed to Egui. -/// It gets reset during the [stage::UI_FRAME] stage. +/// It gets reset during the [EguiSystem::ProcessInput] system #[derive(Clone, Debug, Default)] pub struct EguiInput { /// Egui's raw input. @@ -203,14 +203,14 @@ impl EguiClipboard { pub struct EguiShapes { /// Pairs of rectangles and paint commands. /// - /// The field gets populated during the [stage::UI_FRAME_END] stage and reset during `EguiNode::update`. + /// The field gets populated during the [EguiStage::UiFrameEnd] stage and reset during `EguiNode::update`. pub shapes: Vec, } /// A resource for storing Egui output. #[derive(Clone, Default)] pub struct EguiOutput { - /// The field gets updated during the [stage::UI_FRAME_END] stage. + /// The field gets updated during the [EguiStage::UiFrameEnd] stage. pub output: egui::Output, } @@ -301,7 +301,7 @@ pub mod node { #[derive(StageLabel, Clone, Hash, Debug, Eq, PartialEq)] /// The names of `bevy_egui` stages. pub enum EguiStage { - /// Runs before [bevy::render::stage::RENDER_RESOURCE]. This is where we read Egui's output. + /// Runs before [bevy::render::RenderStage::RenderResource]. This is where we read Egui's output. UiFrameEnd, } From 606989dae0c3e03d4bac9bb60d3b513f34fc1857 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Fri, 26 Mar 2021 18:07:45 +0100 Subject: [PATCH 19/27] use v2 resolver and specify bevy as dev-dependency this should solve the wasm_bindgen version selection failures and also allows `cargo run --example` without features. --- Cargo.toml | 12 +++--------- README.md | 2 +- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 0830c87a9..bb2a88911 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ license = "MIT" edition = "2018" repository = "https://github.com/mvlabat/bevy_egui" exclude = ["assets/**/*", ".github/**/*"] +resolver = "2" [package.metadata.docs.rs] no-default-features = true # clipboard crate fails the build currently https://github.com/rust-lang/docs.rs/issues/695 @@ -31,12 +32,5 @@ thread_local = { version = "1.1.0", optional = true } [dev-dependencies] version-sync = "0.9.2" -[[example]] -name = "ui" -path = "examples/ui.rs" -required-features = ["bevy/x11", "bevy/png", "bevy/bevy_wgpu"] - -[[example]] -name = "simple" -path = "examples/simple.rs" -required-features = ["bevy/x11", "bevy/bevy_wgpu"] \ No newline at end of file +[target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] +bevy = { git = "https://github.com/bevyengine/bevy", branch = "main", default-features = false, features = ["bevy_wgpu", "x11", "png"] } \ No newline at end of file diff --git a/README.md b/README.md index 9b5e5a33e..2086fb253 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ fn ui_example(mut egui_context: ResMut) { For a more advanced example, see [examples/ui.rs](examples/ui.rs). ```bash -cargo run --example ui --features="bevy/x11 bevy/png bevy/bevy_wgpu" +cargo run --example ui ``` ## See also From 9f18bb6cfd1d26e3a95b96e1ce01f5a9287bfc63 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Wed, 7 Apr 2021 08:51:33 +0200 Subject: [PATCH 20/27] use bevy 0.5 --- Cargo.toml | 4 ++-- README.md | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index bb2a88911..8e23605bc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ manage_clipboard = ["clipboard", "thread_local"] open_url = ["webbrowser"] [dependencies] -bevy = { git = "https://github.com/bevyengine/bevy", branch = "main", default-features = false, features = ["render", "bevy_winit"] } +bevy = { version = "0.5", default-features = false, features = ["render", "bevy_winit"] } egui = "0.10.0" webbrowser = { version = "0.5.5", optional = true } winit = { version = "0.24.0", features = ["x11"], default-features = false } @@ -33,4 +33,4 @@ thread_local = { version = "1.1.0", optional = true } version-sync = "0.9.2" [target.'cfg(not(target_arch = "wasm32"))'.dev-dependencies] -bevy = { git = "https://github.com/bevyengine/bevy", branch = "main", default-features = false, features = ["bevy_wgpu", "x11", "png"] } \ No newline at end of file +bevy = { version = "0.5", default-features = false, features = ["bevy_wgpu", "x11", "png"] } diff --git a/README.md b/README.md index 2086fb253..16500cb9e 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ Here's a minimal usage example: ```toml # Cargo.toml [dependencies] -bevy = "0.4" +bevy = "0.5" bevy_egui = "0.3" ``` @@ -64,3 +64,10 @@ cargo run --example ui - [`jakobhellermann/bevy-inspector-egui`](https://github.com/jakobhellermann/bevy-inspector-egui) - [`mvlabat/bevy_megaui`](https://github.com/mvlabat/bevy_megaui) + +## Bevy support table + +|bevy|bevy_egui| +|---|---| +|0.5|0.4| +|0.4|0.1-0.3| From 5cea17be22116c029939b27fe4359a819029727b Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Wed, 7 Apr 2021 21:15:50 +0200 Subject: [PATCH 21/27] Apply suggestions from code review Co-authored-by: Vladyslav Batyrenko --- src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 3deea4992..fed48c085 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -121,7 +121,7 @@ impl Default for EguiSettings { } /// A resource that stores the input passed to Egui. -/// It gets reset during the [EguiSystem::ProcessInput] system +/// It gets reset during the [EguiSystem::ProcessInput] system. #[derive(Clone, Debug, Default)] pub struct EguiInput { /// Egui's raw input. From 177ac26f0e99802a100ce184cec395e485e06985 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Wed, 7 Apr 2021 21:21:15 +0200 Subject: [PATCH 22/27] explicit prelude imports --- src/egui_node.rs | 2 +- src/lib.rs | 2 +- src/systems.rs | 2 +- src/transform_node.rs | 3 ++- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/egui_node.rs b/src/egui_node.rs index 4480c8227..b9843f595 100644 --- a/src/egui_node.rs +++ b/src/egui_node.rs @@ -7,7 +7,7 @@ use bevy::{ asset::{AssetEvent, Assets, Handle}, core::AsBytes, log, - prelude::*, + prelude::World, render::{ pass::{ ClearColor, LoadOp, Operations, PassDescriptor, diff --git a/src/lib.rs b/src/lib.rs index fed48c085..65bb21ed8 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -62,7 +62,7 @@ use bevy::{ asset::{Assets, Handle, HandleUntyped}, input::InputSystem, log, - prelude::*, + prelude::{IntoSystem, ParallelSystemDescriptorCoercion, StageLabel, SystemLabel, SystemStage}, reflect::TypeUuid, render::{ pipeline::{ diff --git a/src/systems.rs b/src/systems.rs index f7e84b4a4..beb2f0b61 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -9,7 +9,7 @@ use bevy::{ Input, }, log, - prelude::*, + prelude::{Res, ResMut}, window::{CursorLeft, CursorMoved, ReceivedCharacter, Windows}, winit::WinitWindows, }; diff --git a/src/transform_node.rs b/src/transform_node.rs index d7bb8198f..6fa7e8263 100644 --- a/src/transform_node.rs +++ b/src/transform_node.rs @@ -1,7 +1,8 @@ use crate::{EguiSettings, WindowSize, EGUI_TRANSFORM_RESOURCE_BINDING_NAME}; use bevy::{ core::AsBytes, - prelude::*, + ecs::world::World, + prelude::{IntoSystem, Local, Res, ResMut, System}, render::{ render_graph::{CommandQueue, Node, ResourceSlots, SystemNode}, renderer::{ From 7a1e24096dce2500e044c76b13e2ee346c0eb858 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Wed, 7 Apr 2021 21:22:37 +0200 Subject: [PATCH 23/27] simplify ci features --- .github/workflows/check.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml index 67ceb59fd..608a08383 100644 --- a/.github/workflows/check.yml +++ b/.github/workflows/check.yml @@ -31,10 +31,10 @@ jobs: matrix: os: [ubuntu-latest, macos-latest, windows-latest] features: [ - 'bevy/x11,bevy/png,bevy/bevy_wgpu', - 'bevy/x11,bevy/png,bevy/bevy_wgpu,manage_clipboard', - 'bevy/x11,bevy/png,bevy/bevy_wgpu,open_url', - 'bevy/x11,bevy/png,bevy/bevy_wgpu,manage_clipboard,open_url', + '', + 'manage_clipboard', + 'open_url', + 'manage_clipboard,open_url', ] steps: - uses: actions/checkout@v2 From a84623c78e1c3f9b8d1f3f2c3881de705db84982 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Fri, 9 Apr 2021 13:09:13 +0200 Subject: [PATCH 24/27] update bevy_webgl2 version --- README.md | 2 +- src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 16500cb9e..4ff0f562e 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ that require additional crates, can be disabled. An example WASM project is live at [mvlabat.github.io/bevy_egui_web_showcase](https://mvlabat.github.io/bevy_egui_web_showcase/index.html) [[source](https://github.com/mvlabat/bevy_egui_web_showcase)]. -**Note** that in order to use `bevy_egui`in WASM you need [bevy_webgl2](https://github.com/mrk-its/bevy_webgl2) of at least `0.4.1` version. +**Note** that in order to use `bevy_egui`in WASM you need [bevy_webgl2](https://github.com/mrk-its/bevy_webgl2) of at least `0.5.0` version. ## Usage diff --git a/src/lib.rs b/src/lib.rs index 65bb21ed8..be2086d3f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,7 +14,7 @@ //! //! An example WASM project is live at [mvlabat.github.io/bevy_egui_web_showcase](https://mvlabat.github.io/bevy_egui_web_showcase/index.html) [[source](https://github.com/mvlabat/bevy_egui_web_showcase)]. //! -//! **Note** that in order to use `bevy_egui`in WASM you need [bevy_webgl2](https://github.com/mrk-its/bevy_webgl2) of at least `0.4.1` version. +//! **Note** that in order to use `bevy_egui`in WASM you need [bevy_webgl2](https://github.com/mrk-its/bevy_webgl2) of at least `0.5.0` version. //! //! ## Usage //! From 2e822b7f6fbcfeb7aaadbb3f08d05c33605a8700 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Fri, 9 Apr 2021 13:16:45 +0200 Subject: [PATCH 25/27] update egui to 0.11 --- Cargo.toml | 2 +- examples/ui.rs | 2 +- src/systems.rs | 48 +++++++++++++++++++++++++++++++++++------------- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 8e23605bc..c1d38c363 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ open_url = ["webbrowser"] [dependencies] bevy = { version = "0.5", default-features = false, features = ["render", "bevy_winit"] } -egui = "0.10.0" +egui = "0.11.0" webbrowser = { version = "0.5.5", optional = true } winit = { version = "0.24.0", features = ["x11"], default-features = false } diff --git a/examples/ui.rs b/examples/ui.rs index 3e3a047d3..d050e808b 100644 --- a/examples/ui.rs +++ b/examples/ui.rs @@ -54,7 +54,7 @@ fn ui_example( ui.text_edit_singleline(&mut ui_state.label); }); - ui.add(egui::Slider::f32(&mut ui_state.value, 0.0..=10.0).text("value")); + ui.add(egui::Slider::new(&mut ui_state.value, 0.0..=10.0).text("value")); if ui.button("Increment").clicked() { ui_state.value += 1.0; } diff --git a/src/systems.rs b/src/systems.rs index beb2f0b61..17c7b5a97 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -211,7 +211,13 @@ pub fn process_output( if let Some(window) = windows.get_primary() { if let Some(winit_window) = winit_windows.get_window(window.id()) { - winit_window.set_cursor_icon(egui_to_winit_cursor_icon(output.cursor_icon)); + match egui_to_winit_cursor_icon(output.cursor_icon) { + None => winit_window.set_cursor_visible(false), + Some(icon) => { + winit_window.set_cursor_visible(true); + winit_window.set_cursor_icon(icon); + } + } } else { log::error!("No winit window found for the primary window"); } @@ -221,23 +227,39 @@ pub fn process_output( #[cfg(feature = "open_url")] if let Some(url) = output.open_url { - if let Err(err) = webbrowser::open(&url) { - log::error!("Failed to open '{}': {:?}", url, err); + if let Err(err) = webbrowser::open(&url.url) { + log::error!("Failed to open '{}': {:?}", &url.url, err); } } } -fn egui_to_winit_cursor_icon(cursor_icon: egui::CursorIcon) -> winit::window::CursorIcon { +fn egui_to_winit_cursor_icon(cursor_icon: egui::CursorIcon) -> Option { match cursor_icon { - egui::CursorIcon::Default => winit::window::CursorIcon::Default, - egui::CursorIcon::PointingHand => winit::window::CursorIcon::Hand, - egui::CursorIcon::ResizeHorizontal => winit::window::CursorIcon::EwResize, - egui::CursorIcon::ResizeNeSw => winit::window::CursorIcon::NeswResize, - egui::CursorIcon::ResizeNwSe => winit::window::CursorIcon::NwseResize, - egui::CursorIcon::ResizeVertical => winit::window::CursorIcon::NsResize, - egui::CursorIcon::Text => winit::window::CursorIcon::Text, - egui::CursorIcon::Grab => winit::window::CursorIcon::Grab, - egui::CursorIcon::Grabbing => winit::window::CursorIcon::Grabbing, + egui::CursorIcon::Default => Some(winit::window::CursorIcon::Default), + egui::CursorIcon::PointingHand => Some(winit::window::CursorIcon::Hand), + egui::CursorIcon::ResizeHorizontal => Some(winit::window::CursorIcon::EwResize), + egui::CursorIcon::ResizeNeSw => Some(winit::window::CursorIcon::NeswResize), + egui::CursorIcon::ResizeNwSe => Some(winit::window::CursorIcon::NwseResize), + egui::CursorIcon::ResizeVertical => Some(winit::window::CursorIcon::NsResize), + egui::CursorIcon::Text => Some(winit::window::CursorIcon::Text), + egui::CursorIcon::Grab => Some(winit::window::CursorIcon::Grab), + egui::CursorIcon::Grabbing => Some(winit::window::CursorIcon::Grabbing), + egui::CursorIcon::ContextMenu => Some(winit::window::CursorIcon::ContextMenu), + egui::CursorIcon::Help => Some(winit::window::CursorIcon::Help), + egui::CursorIcon::Progress => Some(winit::window::CursorIcon::Progress), + egui::CursorIcon::Wait => Some(winit::window::CursorIcon::Wait), + egui::CursorIcon::Cell => Some(winit::window::CursorIcon::Cell), + egui::CursorIcon::Crosshair => Some(winit::window::CursorIcon::Crosshair), + egui::CursorIcon::VerticalText => Some(winit::window::CursorIcon::VerticalText), + egui::CursorIcon::Alias => Some(winit::window::CursorIcon::Alias), + egui::CursorIcon::Copy => Some(winit::window::CursorIcon::Copy), + egui::CursorIcon::Move => Some(winit::window::CursorIcon::Move), + egui::CursorIcon::NoDrop => Some(winit::window::CursorIcon::NoDrop), + egui::CursorIcon::NotAllowed => Some(winit::window::CursorIcon::NotAllowed), + egui::CursorIcon::AllScroll => Some(winit::window::CursorIcon::AllScroll), + egui::CursorIcon::ZoomIn => Some(winit::window::CursorIcon::ZoomIn), + egui::CursorIcon::ZoomOut => Some(winit::window::CursorIcon::ZoomOut), + egui::CursorIcon::None => None, } } From 79459cb1d6518ab9870e734b9c2bef3703543715 Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Sat, 10 Apr 2021 13:14:19 +0200 Subject: [PATCH 26/27] only set cursor icon if not none --- src/systems.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/systems.rs b/src/systems.rs index 17c7b5a97..9a0831889 100644 --- a/src/systems.rs +++ b/src/systems.rs @@ -211,12 +211,8 @@ pub fn process_output( if let Some(window) = windows.get_primary() { if let Some(winit_window) = winit_windows.get_window(window.id()) { - match egui_to_winit_cursor_icon(output.cursor_icon) { - None => winit_window.set_cursor_visible(false), - Some(icon) => { - winit_window.set_cursor_visible(true); - winit_window.set_cursor_icon(icon); - } + if let Some(icon) = egui_to_winit_cursor_icon(output.cursor_icon) { + winit_window.set_cursor_icon(icon); } } else { log::error!("No winit window found for the primary window"); From 880deebb252f764ed070025b1a0dff017aa1979b Mon Sep 17 00:00:00 2001 From: Jakob Hellermann Date: Sat, 10 Apr 2021 13:39:51 +0200 Subject: [PATCH 27/27] work around egui layouting bug --- examples/ui.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/examples/ui.rs b/examples/ui.rs index d050e808b..8533d1641 100644 --- a/examples/ui.rs +++ b/examples/ui.rs @@ -59,7 +59,8 @@ fn ui_example( ui_state.value += 1.0; } - ui.with_layout(egui::Layout::left_to_right(), |ui| { + ui.allocate_space(egui::Vec2::new(1.0, 100.0)); + ui.horizontal(|ui| { load = ui.button("Load").clicked(); invert = ui.button("Invert").clicked(); remove = ui.button("Remove").clicked();