Skip to content

Commit

Permalink
add Dom request_focus API (#146)
Browse files Browse the repository at this point in the history
  • Loading branch information
Uriopass authored Mar 16, 2024
1 parent 6263f57 commit ab36b38
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 2 deletions.
14 changes: 13 additions & 1 deletion crates/yakui-core/src/dom/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use anymap::AnyMap;
use thunderdome::Arena;

use crate::id::WidgetId;
use crate::input::InputState;
use crate::response::Response;
use crate::widget::{ErasedWidget, Widget};

Expand All @@ -32,6 +33,7 @@ struct DomInner {
removed_nodes: RefCell<Vec<WidgetId>>,
root: WidgetId,
globals: RefCell<AnyMap>,
pending_focus_request: RefCell<Option<WidgetId>>,
}

/// A node in the [`Dom`].
Expand Down Expand Up @@ -75,13 +77,17 @@ impl Dom {
}

/// End the DOM's build phase.
pub fn finish(&self) {
pub fn finish(&self, input: &InputState) {
log::debug!("Dom::finish()");

let mut nodes = self.inner.nodes.borrow_mut();
let mut removed_nodes = self.inner.removed_nodes.borrow_mut();
let root = self.inner.root;
trim_children(&mut nodes, &mut removed_nodes, root);

if let Some(widget_id) = self.inner.pending_focus_request.borrow_mut().take() {
input.set_selection(Some(widget_id));
}
}

/// Tells how many nodes are currently in the DOM.
Expand All @@ -99,6 +105,11 @@ impl Dom {
self.inner.root
}

/// Request focus for the given widget id
pub fn request_focus(&self, id: WidgetId) {
*self.inner.pending_focus_request.borrow_mut() = Some(id);
}

/// Gives a list of all of the nodes that were removed in the last update.
/// This is used for synchronizing state with the primary DOM storage.
pub(crate) fn removed_nodes(&self) -> Ref<'_, [WidgetId]> {
Expand Down Expand Up @@ -258,6 +269,7 @@ impl DomInner {
removed_nodes: RefCell::new(Vec::new()),
stack: RefCell::new(Vec::new()),
root: WidgetId::new(root),
pending_focus_request: RefCell::new(None),
}
}
}
Expand Down
5 changes: 5 additions & 0 deletions crates/yakui-core/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,11 @@ impl<T> Response<T> {
pub fn into_inner(self) -> T {
self.inner
}

/// Request that the widget with this response should receive focus.
pub fn request_focus(&self) {
crate::context::dom().request_focus(self.id);
}
}

impl<T> Deref for Response<T> {
Expand Down
2 changes: 1 addition & 1 deletion crates/yakui-core/src/state.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl Yakui {
pub fn finish(&mut self) {
context::unbind_dom();

self.dom.finish();
self.dom.finish(&self.input);
self.layout.sync_removals(&self.dom.removed_nodes());
self.layout.calculate_all(&self.dom, &self.input);
self.input.finish();
Expand Down
29 changes: 29 additions & 0 deletions crates/yakui/examples/autofocus.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use yakui::widgets::{Pad, TextBox};
use yakui::{center, use_state};

pub fn run() {
let text = use_state(|| "".to_owned());
let autofocus = use_state(|| false);

center(|| {
let mut box1 = TextBox::new(text.borrow().as_str());
box1.style.font_size = 60.0;
box1.padding = Pad::all(50.0);
box1.placeholder = "placeholder".into();

let response = box1.show();

if !autofocus.get() {
autofocus.set(true);
response.request_focus();
}

if let Some(new_text) = response.into_inner().text {
text.set(new_text);
}
});
}

fn main() {
bootstrap::start(run as fn());
}

0 comments on commit ab36b38

Please sign in to comment.