egui/widgets/text_edit/
state.rs1use std::sync::Arc;
2
3use crate::mutex::Mutex;
4
5use crate::{
6 Context, Id, Vec2,
7 text_selection::{CCursorRange, TextCursorState},
8};
9
10pub type TextEditUndoer = crate::util::undoer::Undoer<(CCursorRange, String)>;
11
12#[derive(Clone, Default)]
34#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
35#[cfg_attr(feature = "serde", serde(default))]
36pub struct TextEditState {
37 pub cursor: TextCursorState,
39
40 #[cfg_attr(feature = "serde", serde(skip))]
42 pub(crate) undoer: Arc<Mutex<TextEditUndoer>>,
43
44 #[cfg_attr(feature = "serde", serde(skip))]
46 pub(crate) ime_enabled: bool,
47
48 #[cfg_attr(feature = "serde", serde(skip))]
50 pub(crate) ime_cursor_range: CCursorRange,
51
52 #[cfg_attr(feature = "serde", serde(skip))]
55 pub(crate) text_offset: Vec2,
56
57 #[cfg_attr(feature = "serde", serde(skip))]
60 pub(crate) last_interaction_time: f64,
61}
62
63impl TextEditState {
64 pub fn load(ctx: &Context, id: Id) -> Option<Self> {
65 ctx.data_mut(|d| d.get_persisted(id))
66 }
67
68 pub fn store(self, ctx: &Context, id: Id) {
69 ctx.data_mut(|d| d.insert_persisted(id, self));
70 }
71
72 pub fn undoer(&self) -> TextEditUndoer {
73 self.undoer.lock().clone()
74 }
75
76 #[expect(clippy::needless_pass_by_ref_mut)] pub fn set_undoer(&mut self, undoer: TextEditUndoer) {
78 *self.undoer.lock() = undoer;
79 }
80
81 pub fn clear_undoer(&mut self) {
82 self.set_undoer(TextEditUndoer::default());
83 }
84}