Skip to content

Rebuild component after its overlay changes its state - #3536

Open
airstrike wants to merge 1 commit into
iced-rs:masterfrom
airstrike:fix/component-overlay-rebuild
Open

airstrike wants to merge 1 commit into
iced-rs:masterfrom
airstrike:fix/component-overlay-rebuild

Conversation

@airstrike

Copy link
Copy Markdown
Contributor

When an event comes through a component's overlay (like picking an option in a pick_list), Component::update runs but the view is only rebuilt in diff, which invalidate_layout never triggers. If update returns no message, the old view stays on screen until something else rebuilds the interface.

use iced::Widget;
use iced::widget::{Component, column, component, pick_list, text};

pub fn main() -> iced::Result {
    iced::run(|_: &mut (), _: ()| {}, view)
}

fn view(_state: &()) -> impl Widget<()> {
    component(Picker)
}

struct Picker;

impl<'a> Component<'a, ()> for Picker {
    type State = Option<&'static str>;
    type Event = &'static str;

    fn update(
        &self,
        state: &mut Self::State,
        event: Self::Event,
        _renderer: &iced::Renderer,
    ) -> Option<()> {
        *state = Some(event);
        None
    }

    fn view(&self, state: &Self::State) -> impl Widget<Self::Event> + 'a {
        column![
            pick_list(*state, ["A", "B", "C"], ToString::to_string).on_select(|s| s),
            text!("Selected: {state:?}"),
        ]
    }
}

Picking an option leaves the text at None. Invalidating the widgets instead of the layout fixes it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant