Provide ctx in the draw closure of Canvas#1552
Conversation
| pub fn update_scene( | ||
| this: &mut WidgetMut<'_, Self>, | ||
| f: impl FnOnce(&mut MutateCtx<'_>, &mut Scene, Size), | ||
| ) { |
There was a problem hiding this comment.
I think using PaintCtx would make more sense?
MutateCtx can do a lot of things that this widget wouldn't need.
There was a problem hiding this comment.
I agree, but that isn't really a problem with this PR per-se. This whole update_scene method seems weird. Why isn't this user-provided function a field of the widget struct that then gets called in paint?
I haven't read through the four canvas PRs, maybe I should do that to find an answer.
There was a problem hiding this comment.
I haven't read through the four canvas PRs, maybe I should do that to find an answer.
I've explained it in #1519 (comment)
Regarding context type, I think it might even make sense to create a separate type specifically for this function that has a limited API.
But to use a PaintCtx here, something like this is necessary in masonry_core (as the fields are private):
impl MutateCtx<'_> {
pub fn paint_mut(&mut self) -> PaintCtx<'_> {
PaintCtx {
global_state: self.global_state,
widget_state: self.widget_state,
children: self.children.reborrow_mut(),
}
}
}There was a problem hiding this comment.
But to use a PaintCtx here, something like this is necessary in masonry_core (as the fields are private):
I... kind of don't want to add that.
If we don't have an immediate solution, we might want to accept this PR now and rethink the canvas API later. I do think the current API is a bit weird (why pass a callback instead of a scene directly?), but this PR isn't responsible for it.
|
To clarify, I don't know if this is the correct way to do it as it's my first PR for this repo. But it works without issues for my use case on Linux. |
|
The PR has a merge conflict that needs to be resolved. I suggest rebasing on |
xStrom
left a comment
There was a problem hiding this comment.
Yeah let's merge this and open a new issue for the context type.
In a project I'm working on, I needed to draw text inside a
Canvaswidget. I initially created aFontContextand aLayoutContextinside the draw closure. I usedmasonry::core::render_textto render my text layout to the VelloScene. While theoretically functionnal, my solution was extremely slow and wrong.After realizing that both
FontContextandLayoutContextare meant to be global resources created only once per application, I set out to tinker with the source code of theCanvaswidget. What I came up with allowed me to do this:I updated the
FnOnceclosure to accept a new ctx parameter. Then in Masonry, inside theCanvas::update_scenefunction, I got the ctx from theWidgetMut<'_, Canvas>and passed it as a mutable reference to the closure. In Xilem, I simply pass the ctx from the closure to the draw closure.This PR includes the addition of a new screenshot test. The text_canvas test renders a 200x200 image with the text 'Canvas' stretched to fit inside.