Skip to content

Commit

Permalink
Reworked autofocus, it's now a property on the button.
Browse files Browse the repository at this point in the history
  • Loading branch information
viridia committed Feb 13, 2024
1 parent 4c3c0c8 commit 52706bd
Show file tree
Hide file tree
Showing 6 changed files with 24 additions and 21 deletions.
2 changes: 1 addition & 1 deletion TODO.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

* Text input.
* Change tab handling to use bubbled events.
* Dialogs should focus.
* ESC to close dialog.
* Restore focus when dialog closes.
* Rounded corners for sliders.
* Memoized Signals
* Verify Razing / Despawning doesn't leak
Expand Down
6 changes: 5 additions & 1 deletion crates/obsidian_ui/src/controls/button.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::{
focus::{KeyPressEvent, TabIndex},
focus::{AutoFocus, KeyPressEvent, TabIndex},
hooks::CreateFocusSignal,
RoundedCorners,
};
Expand Down Expand Up @@ -60,6 +60,9 @@ pub struct ButtonProps {

/// Which corners to render rounded.
pub corners: RoundedCorners,

/// If true, set focus to this button when it's added to the UI.
pub autofocus: bool,
}

fn style_button(ss: &mut StyleBuilder) {
Expand Down Expand Up @@ -171,6 +174,7 @@ pub fn button(cx: &mut Cx<ButtonProps>) -> Element<NodeBundle> {
}
}),
))
.insert_if(cx.props.autofocus, AutoFocus)
.children((
Element::<MaterialNodeBundle<RoundedRectMaterial>>::new()
.insert(material.clone())
Expand Down
3 changes: 1 addition & 2 deletions crates/obsidian_ui/src/controls/dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use bevy_reactor::*;
use crate::{
animation::{AnimatedBackgroundColor, AnimatedTransition},
colors,
focus::{TabGroup, TabNavigation},
focus::TabGroup,
hooks::{BistableTransitionState, CreateBistableTransition},
typography::text_default,
};
Expand Down Expand Up @@ -123,7 +123,6 @@ pub fn dialog(cx: &mut Cx<DialogProps>) -> impl View {
.insert(TabGroup {
order: 0,
modal: true,
auto_focus: true,
})
.with_styles(style_dialog)
.with_child(&children),
Expand Down
23 changes: 6 additions & 17 deletions crates/obsidian_ui/src/focus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ pub struct KeyPressEvent {
#[derive(Debug, Default, Component, Copy, Clone)]
pub struct TabIndex(pub i32);

/// Indicates that this widget should automatically receive focus when it's added.
#[derive(Debug, Default, Component, Copy, Clone)]
pub struct AutoFocus;

/// A component used to mark a tree of entities as containing tabbable elements.
#[derive(Debug, Default, Component, Copy, Clone)]
pub struct TabGroup {
Expand All @@ -67,10 +71,6 @@ pub struct TabGroup {
/// of this group. If false, then tabbing within the group will cycle through all non-modal
/// tab groups.
pub modal: bool,

/// If true, then the group will automatically focus the first focusable entity when this
/// component is added to the entity.
pub auto_focus: bool,
}

/// An injectable object that provides tab navigation functionality.
Expand Down Expand Up @@ -120,16 +120,6 @@ impl TabNavigation<'_, '_> {
self.navigate_in_group(tabgroup, focus, reverse)
}

/// Automatically focus the first focusable entity in the given tab group.
fn auto_focus(&self, tabgroup_entity: Entity) -> Option<Entity> {
if let Ok((_, tabgroup, _)) = self.tabgroup.get(tabgroup_entity) {
if tabgroup.auto_focus {
return self.navigate_in_group(Some((tabgroup_entity, tabgroup)), None, false);
}
}
None
}

fn navigate_in_group(
&self,
tabgroup: Option<(Entity, &TabGroup)>,
Expand Down Expand Up @@ -221,12 +211,11 @@ fn compare_tab_indices(a: &(Entity, TabIndex), b: &(Entity, TabIndex)) -> std::c
}

fn handle_auto_focus(
nav: TabNavigation,
mut focus: ResMut<Focus>,
query: Query<Entity, Added<TabGroup>>,
query: Query<Entity, (With<TabIndex>, Added<AutoFocus>)>,
) {
if let Some(entity) = query.iter().next() {
focus.0 = nav.auto_focus(entity);
focus.0 = Some(entity);
}
}

Expand Down
1 change: 1 addition & 0 deletions examples/complex/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ fn ui_main(cx: &mut Cx) -> impl View {
button.bind(ButtonProps {
children: "Close".into(),
variant: Signal::Constant(ButtonVariant::Primary),
autofocus: true,
on_click: Some(cx.create_callback(move |cx| {
checked_1.set(cx, false);
})),
Expand Down
10 changes: 10 additions & 0 deletions src/element.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,16 @@ impl<B: Bundle + Default> Element<B> {
self
}

/// Add a static bundle to the element, if a condition is true.
pub fn insert_if<T: Bundle>(mut self, cond: bool, bundle: T) -> Self {
if cond {
self.add_effect(Box::new(InsertBundleEffect {
bundle: Some(bundle),
}));
}
self
}

/// Add a computed bundle to the element.
pub fn insert_computed<T: Bundle, F: Send + Sync + 'static + FnMut(&mut Rcx) -> T>(
mut self,
Expand Down

0 comments on commit 52706bd

Please sign in to comment.