-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Use TextBuffer
for layouter
in TextEdit
instead of &str
#5712
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense
6b999e0
to
868db92
Compare
added suggested change |
} | ||
|
||
/// Immutable view of a `&str`! | ||
impl TextBuffer for &str { | ||
impl TextBuffer for &'static str { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why were these changed to 'static? Wouldn't this mean some_string.as_str()
stops implementing TextBuffer with this change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
std::any::Any
only works for static types, so that's the downside of using it. If this isn't acceptable we can revert back to the type id implementation, unless you have a better idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see, that's annoying 🤔 What do you need Any for?
I think I'd prefer not having the 'static limitation, if the type_id thing works well enough for your usecase
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any is useful for downcasting without writing unsafe code:
pub fn downcast_post_buffer(buffer: &dyn TextBuffer) -> Option<&PostBuffer> {
buffer.as_any().downcast_ref::<PostBuffer>()
}
But with using type_id we need:
pub fn downcast_post_buffer(buffer: &dyn TextBuffer) -> Option<&PostBuffer> {
let mut hasher = DefaultHasher::new();
TypeId::of::<PostBuffer>().hash(&mut hasher);
let post_id = hasher.finish() as usize;
if buffer.type_id() == post_id {
unsafe { Some(&*(buffer as *const dyn TextBuffer as *const PostBuffer)) }
} else {
None
}
}
That's understandable to not want the 'static limitation, I can certainly revert back to using type_id instead of Any
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@emilk what do you prefer, considering the 'static limitation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The 'static
limitation is annoying; I din't foresee that.
I suggest we either go with @kernelkind ideas of returning a std::any::TypeId
, or we return an Option<&dyn std::any::Any>
that returns None
for non-'static
types
Preview available at https://egui-pr-preview.github.io/pr/5712-updatelayouter |
Signed-off-by: kernelkind <[email protected]>
868db92
to
306c5cb
Compare
reverted to 6b999e0 and rebased with master |
I think it would be better to use fn type_id(&self) -> std::any::TypeId {
std::any::TypeId::of::<Self>()
} instead of: fn type_id(&self) -> usize {
let mut hasher = DefaultHasher::new();
std::any::TypeId::of::<Self>().hash(&mut hasher);
hasher.finish() as usize
} though we would lose the trait level implementation, so all implementers would be forced to implement type_id |
This change allows
layouter
to use theTextBuffer
instead of&str
in the closure. It is necessary when layout decisions depend on more than just the raw string content, such as metadata stored in the concrete type implementingTextBuffer
.In our use case, we needed this to support mention highlighting when a user selects a mention. Since mentions can contain spaces, determining mention boundaries from the
&str
alone is impossible. Instead, we use theTextBuffer
implementation to retrieve the correct bounds.See the video below for a demonstration:
Screen.Recording.2025-02-11.at.4.30.13.PM.mov
Breaking change
This PR introduces a breaking change to the
layouter
function inTextEdit
.Previous API:
New API:
Impact on Existing Code
• Any existing usage of
layouter
will no longer compile.• Callers must update their closures to use
&dyn TextBuffer
instead of&str
.Migration Guide
Before:
After: