Skip to content

Commit 6429248

Browse files
committed
TextBuffer with DerefMut.
1 parent 7a79c70 commit 6429248

File tree

4 files changed

+71
-4
lines changed

4 files changed

+71
-4
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,6 +1305,7 @@ dependencies = [
13051305
"ahash",
13061306
"backtrace",
13071307
"bitflags 2.9.4",
1308+
"bytemuck",
13081309
"document-features",
13091310
"emath",
13101311
"epaint",

crates/egui/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ epaint = { workspace = true, default-features = false }
7474
accesskit.workspace = true
7575
ahash.workspace = true
7676
bitflags.workspace = true
77+
bytemuck.workspace = true
7778
log.workspace = true
7879
nohash-hasher.workspace = true
7980
profiling.workspace = true

crates/egui/src/widgets/text_edit/builder.rs

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
use std::sync::Arc;
1+
use std::{ops::DerefMut, sync::Arc};
22

3+
use bytemuck::TransparentWrapper as _;
34
use emath::{Rect, TSTransform};
45
use epaint::{
56
StrokeKind,
@@ -12,8 +13,11 @@ use crate::{
1213
TextStyle, TextWrapMode, Ui, Vec2, Widget, WidgetInfo, WidgetText, WidgetWithState, epaint,
1314
os::OperatingSystem,
1415
output::OutputEvent,
15-
response, text_selection,
16-
text_selection::{CCursorRange, text_cursor_state::cursor_rect, visuals::paint_text_selection},
16+
response,
17+
text_edit::text_buffer::TextBufferRef,
18+
text_selection::{
19+
self, CCursorRange, text_cursor_state::cursor_rect, visuals::paint_text_selection,
20+
},
1721
vec2,
1822
};
1923

@@ -116,6 +120,14 @@ impl<'t> TextEdit<'t> {
116120
}
117121
}
118122

123+
pub fn singleline_ref<T>(smart_ptr: &'t mut T) -> Self
124+
where
125+
T: DerefMut,
126+
T::Target: TextBuffer,
127+
{
128+
Self::singleline(TextBufferRef::wrap_mut(smart_ptr))
129+
}
130+
119131
/// A [`TextEdit`] for multiple lines. Pressing enter key will create a new line by default (can be changed with [`return_key`](TextEdit::return_key)).
120132
pub fn multiline(text: &'t mut dyn TextBuffer) -> Self {
121133
Self {
@@ -151,6 +163,14 @@ impl<'t> TextEdit<'t> {
151163
}
152164
}
153165

166+
pub fn multilne_ref<T>(smart_ptr: &'t mut T) -> Self
167+
where
168+
T: DerefMut,
169+
T::Target: TextBuffer,
170+
{
171+
Self::multiline(TextBufferRef::wrap_mut(smart_ptr))
172+
}
173+
154174
/// Build a [`TextEdit`] focused on code editing.
155175
/// By default it comes with:
156176
/// - monospaced font

crates/egui/src/widgets/text_edit/text_buffer.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use std::{borrow::Cow, ops::Range};
1+
use std::{
2+
borrow::Cow,
3+
ops::{Deref, DerefMut, Range},
4+
};
25

36
use epaint::{
47
Galley,
@@ -315,3 +318,45 @@ impl TextBuffer for &str {
315318
std::any::TypeId::of::<&str>()
316319
}
317320
}
321+
322+
#[repr(transparent)]
323+
#[derive(bytemuck::TransparentWrapper)]
324+
pub struct TextBufferRef<T: ?Sized>(pub T);
325+
326+
impl<T> TextBuffer for TextBufferRef<T>
327+
where
328+
T: DerefMut + ?Sized,
329+
<T as Deref>::Target: TextBuffer,
330+
{
331+
fn is_mutable(&self) -> bool {
332+
self.0.is_mutable()
333+
}
334+
335+
fn as_str(&self) -> &str {
336+
self.0.as_str()
337+
}
338+
339+
fn insert_text(&mut self, text: &str, char_index: usize) -> usize {
340+
self.0.insert_text(text, char_index)
341+
}
342+
343+
fn delete_char_range(&mut self, char_range: Range<usize>) {
344+
self.0.delete_char_range(char_range);
345+
}
346+
347+
fn clear(&mut self) {
348+
self.0.clear();
349+
}
350+
351+
fn replace_with(&mut self, text: &str) {
352+
self.0.replace_with(text);
353+
}
354+
355+
fn take(&mut self) -> String {
356+
self.0.take()
357+
}
358+
359+
fn type_id(&self) -> std::any::TypeId {
360+
std::any::TypeId::of::<()>()
361+
}
362+
}

0 commit comments

Comments
 (0)