Skip to main content

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}