1use std::{any::TypeId, ops::Range};
2
3use crate::{EguiProbe, Style, option::option_probe_with};
4
5impl EguiProbe for String {
6 #[inline(always)]
7 fn probe(&mut self, ui: &mut egui::Ui, _: &Style) -> egui::Response {
8 ui.add(egui::TextEdit::singleline(self))
9 }
10}
11
12impl EguiProbe for &str {
13 #[inline(always)]
14 fn probe(&mut self, ui: &mut egui::Ui, _: &Style) -> egui::Response {
15 ui.add(egui::TextEdit::singleline(self))
16 }
17}
18
19struct CharBuffer {
20 ch: char,
21 buf: [u8; 4],
22}
23
24impl CharBuffer {
25 const fn new(ch: char) -> Self {
26 let mut buf = [0; 4];
27 let _ = ch.encode_utf8(&mut buf);
28 CharBuffer { ch, buf }
29 }
30}
31
32impl Default for CharBuffer {
33 fn default() -> Self {
34 Self::new('\0')
35 }
36}
37
38impl egui::text_edit::TextBuffer for CharBuffer {
39 fn is_mutable(&self) -> bool {
40 true
41 }
42
43 fn as_str(&self) -> &str {
44 unsafe { std::str::from_utf8_unchecked(&self.buf[..self.ch.len_utf8()]) }
46 }
47
48 fn insert_text(&mut self, text: &str, char_index: usize) -> usize {
49 if char_index > 1 {
50 return 0;
51 }
52 match text.chars().next() {
53 None => 0,
54 Some(c) => {
55 self.ch = c;
56 let _ = c.encode_utf8(&mut self.buf);
57 1
58 }
59 }
60 }
61
62 fn delete_char_range(&mut self, _char_range: Range<usize>) {}
63
64 fn type_id(&self) -> TypeId {
65 TypeId::of::<Self>()
66 }
67}
68
69impl EguiProbe for char {
70 #[inline(always)]
71 fn probe(&mut self, ui: &mut egui::Ui, _: &Style) -> egui::Response {
72 let mut buf = CharBuffer::new(*self);
73 let r = ui.add(egui::TextEdit::singleline(&mut buf));
74 if r.changed() {
75 *self = buf.ch;
76 }
77 r
78 }
79}
80
81pub struct EguiProbeMultiline<'a, T> {
83 pub string: &'a mut T,
84}
85
86impl EguiProbe for EguiProbeMultiline<'_, String> {
87 #[inline(always)]
88 fn probe(&mut self, ui: &mut egui::Ui, _: &Style) -> egui::Response {
89 ui.add(egui::TextEdit::multiline(self.string))
90 }
91}
92
93impl EguiProbe for EguiProbeMultiline<'_, &str> {
94 #[inline(always)]
95 fn probe(&mut self, ui: &mut egui::Ui, _: &Style) -> egui::Response {
96 ui.add(egui::TextEdit::multiline(self.string))
97 }
98}
99
100impl EguiProbe for EguiProbeMultiline<'_, Option<String>> {
101 #[inline(always)]
102 fn probe(&mut self, ui: &mut egui::Ui, style: &Style) -> egui::Response {
103 option_probe_with(self.string, ui, style, String::new, |string, ui, _| {
104 ui.add(egui::TextEdit::multiline(string))
105 })
106 }
107}
108
109impl EguiProbe for EguiProbeMultiline<'_, Option<&str>> {
110 #[inline(always)]
111 fn probe(&mut self, ui: &mut egui::Ui, style: &Style) -> egui::Response {
112 option_probe_with(
113 self.string,
114 ui,
115 style,
116 || "",
117 |string, ui, _| ui.add(egui::TextEdit::multiline(string)),
118 )
119 }
120}