-
Notifications
You must be signed in to change notification settings - Fork 569
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
Documentation on when to send WidgetAdded events to children #1329
Comments
If I understood this correctly, your issue is that use druid::*;
use druid::widget::*;
const CHANGE_VIEW: Selector<()> = Selector::new("change_view");
fn controlled_widget() -> ControllerHost<Container<u32>, ViewController> {
ControllerHost::new(Container::new(Label::new("Original")), ViewController)
}
struct Delegate;
impl AppDelegate<u32> for Delegate {
fn event(&mut self, ctx: &mut DelegateCtx, window_id: WindowId, event: Event, _: &mut u32, _: &Env) -> Option<Event> {
if let Event::KeyDown(_) = event {
ctx.submit_command(Command::new(CHANGE_VIEW, (), window_id));
None
}
else {
Some(event)
}
}
}
struct ViewController;
impl Controller<u32, Container<u32>> for ViewController {
fn event(&mut self, child: &mut Container<u32>, ctx: &mut EventCtx, event: &Event, data: &mut u32, env: &Env) {
if let Event::Command(ref cmd) = *event {
if let Some(()) = cmd.get(CHANGE_VIEW) {
*child = Container::new(Label::new("New Label"));
ctx.children_changed();
return;
}
}
child.event(ctx, event, data, env)
}
}
fn main() -> Result<(), PlatformError> {
AppLauncher::with_window(WindowDesc::new(controlled_widget))
.delegate(Delegate)
.use_simple_logger()
.launch(0)
} If you have just Replacing children the way you did here will likely cause problems though. Technically it would be possible to do the same with I suppose the morale of this is that if you add / replace widgets that are not inside a |
To rephrase what I think you said, a "complete widget" for a lack of a better term typically consists of a The smallest unit that Druid supports the replacement of is a complete widget. Your modification makes this happen by making the first complete widget be a set of I can definitely work with this and it seems like a fine model, but it feels like it needs documenting and maybe some thought put into the right terminology. |
When I replace the child of a
Controller
and callctx.children_changed()
the new child never receives aWidgetAdded
event (first version of the code below). If I've understood the code correctly the fix is to listen forInternalLifeCycle::RouteWidgetAdded
lifecycle events in the controller and route them to the child (i.e. the modifications in the final code block).Assuming this is the intended behavior, it should probably be documented somewhere, perhaps in the documentation of
Controller
. It would also be nice if the error message included this as a potential cause (but I'm not sure if that's possible to fix generally for all widgets). The current error message is as follows:If I can generally get a confirmation that the documentation I'm suggesting would be a good idea, and that the updated version of the code is legal and reasonable idiomatic, I'd be happy to submit a pr (or I'd be equally happy if someone else updated it).
A bit of an aside, but #1259 unfortunately does not fix this issue despite being closely related. Running on #1259 merged into master I get the same error message as above. Running on on #1259 directly instead of crashing entirely I get the following warning and no text appearing
Test code:
Replacing
ViewController
with the following fixes the errorThe text was updated successfully, but these errors were encountered: