-
Notifications
You must be signed in to change notification settings - Fork 570
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
Linkable text in RichText. #1627
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.
Interesting! this looks quite promising, I think.
I don't mind passing events to the richtext, although the signature doesn't need to exactly match the signature in Widget
. For instance, it might be easier to just have mouse_moved
and mouse_clicked
methods, or something?
I guess we need an API for launching other applications and opening links, etc? 😬
Let me know where you'd like to go with this, I think it's on a good path.
druid/src/text/rich_text.rs
Outdated
pub struct RichText { | ||
buffer: ArcStr, | ||
attrs: Arc<AttributeSpans>, | ||
links: Arc<[(Range<usize>, Box<dyn Fn(&mut EventCtx, &Env)>)]>, |
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.
instead of storing the text ranges I would be inclined to store the actual hit-boxes? it just feels like a small simplification.
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.
We don't have hit boxes when we create RichText
. So we need to add widget_added or something, to compute the hit boxes. But still we will have to store text ranges.
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.
right, that make sense.
Maybe we would want to store the hit boxes in the TextLayout
object, and compute them whenever we rebuild the layout?
I am storing |
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.
Okay I think I maybe misunderstood previously, and I see now how having the event handlers be on RichText
confuses things. Having the Data
associated type feels hacky, and it is a sign to me that we are not adequately "separating our concerns".
That said, I think this is pretty easy to deal with.
- The
RichText
stuff looks correct; in addition to the spans that piet knows about, we separately track our links. - Instead of storing handler functions, I would make a link just store a
Command
. This should be enough flexibility that the user can do whatever they need. - the
TextStorage
trait gets a method likelinks(&self) -> &[Link]
. - the
TextLayout
does all the work. When it lays itself out, it builds its own internalRc<[Rect]>
(question: I guess a single link can resolve to multiple rects? in which case maybe it storesRc<[(Rect, usize)]>
where theusize
corresponds to the index of the link that is referred to. - The
TextLayout
exposes these rects, and then theRawLabel
can check them in its event methods. There are some options here. I think what might be easiest is a single method,this could be used both to check if we're over a link (on hover) or to retrieve the link (on click)fn link_for_mouse_pos(&self, pos: &Point) -> Option<&Link> { ..}
Does this make sense? It feels to me like a cleaner separation of concerns, and likely a simpler implementation. If I'm overlooking anything, please let me know!
Sorry about the runaround. 😒
This looks better and simpler! Is |
Yes, we expect |
@maan2003 can you add a few links to one of the examples, so that I can play around with this a little bit for testing? |
|
I think for now I would have the links be 'dummy' links, and not actually open anything? Maybe just log to the console? I'm more interested in seeing that that the hover works and the command is received than what we actually do with it. |
Given that this example doesn't work on web anyways, I have removed dev dependency on |
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.
Okay I have a bunch of doc fixups but overall this is great, thanks for taking it on and sorry for the run-around on the implementation. :)
_data: &mut T, | ||
_env: &Env, | ||
) -> Handled { | ||
if let Some(url) = cmd.get(OPEN_LINK) { |
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.
This is so cool!
Co-authored-by: Colin Rofls <[email protected]>
thanks for that, it lead to better code and thanks for the doc comments help :) |
* Linkable text in RichText. * Suggestions from review * Suggestions from review * Fix build * Implement links in markdown_preview example * Fix wasm build * Fix wasm build again * Remove unused import * Apply suggestions from code review Co-authored-by: Colin Rofls <[email protected]> * Fix compiler error * Fix doc links Co-authored-by: Colin Rofls <[email protected]>
I am not sure if adding event function to
TextStorage
is a good thing.