-
sam edelsten authored
* remove unused `num` deps * skip inserting `SwashCache`, it's inserted by `bevy_text` * add focus observer to example * unify plugin patterns * typos + remove some commented out code * prevent widget console spam * fix password example crash
Unverifiede4c7dc14
focus.rs 2.81 KiB
//! Manages the [`FocusedWidget`] resource
//!
//! Makes sure that the focused widget has a [`CosmicEditor`] component
//! if its focused
use crate::prelude::*;
/// System set for focus systems. Runs in `PostUpdate`
#[derive(SystemSet, Debug, Clone, PartialEq, Eq, Hash)]
pub(crate) struct FocusSet;
pub(crate) fn plugin(app: &mut App) {
app.add_systems(
PostUpdate,
(drop_editor_unfocused, add_editor_to_focused)
.chain()
.in_set(FocusSet),
)
.init_resource::<FocusedWidget>()
.register_type::<FocusedWidget>();
}
/// Resource struct that keeps track of the currently active editor entity.
///
/// The focussed entity must have a [`CosmicEditBuffer`], and should have a
/// [`CosmicEditor`] component as well if it can be mutated (i.e. isn't [`Readonly`]).
#[derive(Resource, Reflect, Default, Deref, DerefMut)]
#[reflect(Resource)]
pub struct FocusedWidget(pub Option<Entity>);
/// Adds [`CosmicEditor`] by copying from existing [`CosmicEditBuffer`].
pub(crate) fn add_editor_to_focused(
mut commands: Commands,
active_editor: Res<FocusedWidget>,
q: Query<&CosmicEditBuffer, Without<CosmicEditor>>,
) {
if let Some(e) = active_editor.0 {
let Ok(buffer) = q.get(e) else {
return;
};
let editor = CosmicEditor::clone_from_buffer(buffer);
trace!("Adding editor to focused widget");
commands.entity(e).insert(editor);
}
}
/// Removes [`CosmicEditor`]
pub(crate) fn drop_editor_unfocused(
mut commands: Commands,
active_editor: Res<FocusedWidget>,
mut q: Query<(Entity, &mut CosmicEditBuffer, &CosmicEditor)>,
) {
match active_editor.0 {
None => {
for (e, mut buffer, editor) in q.iter_mut() {
*buffer = CosmicEditBuffer::from_downgrading_editor(editor);
trace!("Removing editor from all entities as there is no focussed widget",);
commands.entity(e).remove::<CosmicEditor>();
}
}
Some(focused) => {
for (e, mut b, editor) in q.iter_mut() {
if e != focused {
*b = CosmicEditBuffer::from_downgrading_editor(editor);
trace!("Removing editor from entity as its not focussed anymore",);
commands.entity(e).remove::<CosmicEditor>();
}
}
}
}
}
/// Placed as on_remove hook for [`CosmicEditBuffer`] and [`CosmicEditor`]
pub(crate) fn remove_focus_from_entity(
mut world: bevy::ecs::world::DeferredWorld,
entity: Entity,
_: bevy::ecs::component::ComponentId,
) {
if let Some(mut focused_widget) = world.get_resource_mut::<FocusedWidget>() {
if let Some(focused) = focused_widget.0 {
if focused == entity {
focused_widget.0 = None;
}
}
}
}