pub struct EguiPlugin {
pub enable_multipass_for_primary_context: bool,
}
Expand description
Adds all Egui resources and render graph nodes.
Fields§
§enable_multipass_for_primary_context: bool
§About Egui multi-pass mode
From the Egui documentation:
By default, egui usually only does one pass for each rendered frame.
However, egui supports multi-pass immediate mode.
Another pass can be requested with egui::Context::request_discard
.
This is used by some widgets to cover up “first-frame jitters”.
For instance, the egui::Grid
needs to know the width of all columns before it can properly place the widgets.
But it cannot know the width of widgets to come.
So it stores the max widths of previous frames and uses that.
This means the first time a Grid
is shown it will guess the widths of the columns, and will usually guess wrong.
This means the contents of the grid will be wrong for one frame, before settling to the correct places.
Therefore Grid
calls egui::Context::request_discard
when it is first shown, so the wrong placement is never
visible to the end user.
§Usage
Set this to true
to enable an experimental support for the Egui multi-pass mode.
Enabling the multi-pass mode will require your app to use the new EguiContextPass
schedule:
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(EguiPlugin { enable_multipass_for_primary_context: true })
.add_systems(EguiContextPass, ui_example_system)
.run();
}
fn ui_example_system(contexts: EguiContexts) {
// ...
}
If you create multiple contexts (for example, when using multiple windows or rendering to an image), you need to define a custom schedule and assign it to additional contexts manually:
#[derive(ScheduleLabel, Clone, Debug, PartialEq, Eq, Hash)]
pub struct SecondWindowContextPass;
fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugins(EguiPlugin { enable_multipass_for_primary_context: true })
.add_systems(Startup, create_new_window_system)
.add_systems(EguiContextPass, ui_example_system)
.add_systems(SecondWindowContextPass, ui_example_system)
.run();
}
fn create_new_window_system(mut commands: Commands) {
commands.spawn((Window::default(), EguiMultipassSchedule::new(SecondWindowContextPass)));
}
fn ui_example_system(contexts: EguiContexts) {
// ...
}
In the future, the multi-pass mode will likely phase the single-pass one out.
§Note to developers of public plugins
If your plugin depends on bevy_egui
, here are some hints on how to implement the support of both single-pass and multi-pass modes
(with respect to the EguiPlugin::enable_multipass_for_primary_context
flag):
- Don’t initialize
EguiPlugin
for the user, i.e. DO NOT useadd_plugins(EguiPlugin { ... })
in your code, users should be able to opt in or opt out of the multi-pass mode on their own. - If you add UI systems, make sure they go into the
EguiContextPass
schedule - this will guarantee your plugin supports both the single-pass and multi-pass modes.
Your plugin code might look like this:
pub struct MyPlugin;
impl Plugin for MyPlugin {
fn build(&self, app: &mut App) {
// Don't add the plugin for users, let them chose the default mode themselves
// and just make sure they initialize EguiPlugin before yours.
assert!(app.is_plugin_added::<EguiPlugin>());
app.add_systems(EguiContextPass, ui_system);
}
}
fn ui_system(contexts: EguiContexts) {
// ...
}
Trait Implementations§
Source§impl Plugin for EguiPlugin
impl Plugin for EguiPlugin
Source§fn finish(&self, app: &mut App)
fn finish(&self, app: &mut App)
App
, once all plugins registered are ready. This can
be useful for plugins that depends on another plugin asynchronous setup, like the renderer.Source§fn ready(&self, _app: &App) -> bool
fn ready(&self, _app: &App) -> bool
finish
should be called.Source§fn cleanup(&self, _app: &mut App)
fn cleanup(&self, _app: &mut App)
Auto Trait Implementations§
impl Freeze for EguiPlugin
impl RefUnwindSafe for EguiPlugin
impl Send for EguiPlugin
impl Sync for EguiPlugin
impl Unpin for EguiPlugin
impl UnwindSafe for EguiPlugin
Blanket Implementations§
Source§impl<T, U> AsBindGroupShaderType<U> for T
impl<T, U> AsBindGroupShaderType<U> for T
Source§fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
fn as_bind_group_shader_type(&self, _images: &RenderAssets<GpuImage>) -> U
T
ShaderType
for self
. When used in AsBindGroup
derives, it is safe to assume that all images in self
exist.Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
, which can then be
downcast
into Box<dyn ConcreteType>
where ConcreteType
implements Trait
.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
, which can then be further
downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.Source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
Source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.Source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.Source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.Source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.Source§impl<T> DowncastSend for T
impl<T> DowncastSend for T
Source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read more