agg_gui/widgets/text_area/callbacks.rs
1//! Change-notification wiring for [`TextArea`], split out of `text_area.rs`
2//! to keep that file under the project's 800-line cap.
3//!
4//! Mirrors `TextField`'s `on_change` semantics (see
5//! `text_field/filter.rs::notify_change`): a `FnMut(&str)` callback that fires
6//! after every text mutation, letting a caller capture edits back into a shared
7//! cell. The dispatcher is invoked from the two internal mutation funnels
8//! ([`TextArea::insert_str`] and [`TextArea::delete`]) and, when the content
9//! epoch advances, from the pre-default key-chord interceptor in `widget_impl`.
10
11use super::*;
12
13impl TextArea {
14 /// Install a callback fired after every text change.
15 ///
16 /// Fires for: typing, Enter, Tab-insert, backspace/delete, paste, cut, and
17 /// key-intercept edits that advance the content epoch. It does NOT fire for
18 /// purely programmatic mutations pushed straight into the shared
19 /// [`TextEditState`] from outside the widget (those bypass the mutation
20 /// funnel; the epoch mechanism still re-wraps them on the next layout).
21 pub fn on_change(mut self, cb: impl FnMut(&str) + 'static) -> Self {
22 self.on_change = Some(Box::new(cb));
23 self
24 }
25
26 /// Invoke the change callback with the current text. Callers must have
27 /// already applied the mutation (and any `note_text_change`) before calling
28 /// this so the callback observes the final content.
29 pub(crate) fn notify_change(&mut self) {
30 if let Some(mut cb) = self.on_change.take() {
31 let t = self.edit.borrow().text.clone();
32 cb(&t);
33 self.on_change = Some(cb);
34 }
35 }
36}