antoyo / relm

Idiomatic, GTK+-based, GUI library, inspired by Elm, written in Rust
MIT License
2.43k stars 78 forks source link

Problems re-inflating TreeView #205

Closed MGlolenstine closed 4 years ago

MGlolenstine commented 4 years ago

So I'm inflating TreeView{} once and then when the Refresh button is pressed, I fill a new store_model and apply it to the tree_view. My problem is, that at the start of the program everything works, and when I click the Refresh button, if the data changed, it changes in the tree_view, but my problem is if the data is an empty Vec<u16>, which would mean, that there's no data, it doesn't display it. But that's all working as wanted, but whenever the data is in the array, after the press on Refresh, tree_view still shows no data. At first, I thought that the problem was in the button below the tree_view covering it up when it resets to no elements, but even if I add 500 elements, there still isn't going to be any displayed. I have a counter in the create_and_fill_model for debugging purposes, and yes, it does run as many times, as there are elements, but there's still none displayed.

fn update(&mut self, event: Msg) {
    match event {
        Msg::Quit => gtk::main_quit(),
        Msg::Refresh => {
            self.model.ports = get_data();
            self.update_list();
        }
    }
}

fn init_view(&mut self) {
    let column = gtk::TreeViewColumn::new();
    let cell = gtk::CellRendererText::new();
    column.pack_start(&cell, true);
    column.add_attribute(&cell, "text", 0);
    self.tree_view.append_column(&column);
    self.update_list();
}

fn update_list(&mut self) {
    let store_model = self
        .create_and_fill_model(self.model.clone())
        .expect("create_and_fill_model failed");
    self.tree_view.set_model(Some(&store_model));
}

fn create_and_fill_model(&self, data: O2IInfo) -> std::io::Result<gtk::ListStore> {
    let model = gtk::ListStore::new(&[String::static_type()]);
    let mut counter = 0;
    for p in data.ports {
        model.insert_with_values(Some(counter), &[0 as u32], &[&format!("Value is {}", p)]);
        counter+=1;
    }
    Ok(model)
}
antoyo commented 4 years ago

That seems to be a gtk+ related question, not a relm question, so you might be able to get better help elsewhere.

Did you put your treeview in a vbox or something so that it can be expanded? Also, you might not need to call set_model() and create a new ListStore on refresh, you might be able to reuse the first model.

MGlolenstine commented 4 years ago

I did put my tree_view into a box, that has orientation set to Vertical.

   view! {
        #[name="window"]
        gtk::Window {
            gtk::Box {
                orientation: Vertical,
                hexpand: true,
                vexpand: true,
                #[name="public_ip"]
                gtk::Label{
                    justify: Justification::Left,
                    halign: Align::Start,
                },
                #[name="local_ip"]
                gtk::Label{
                    justify: Justification::Left,
                    halign: Align::Start,
                },
                #[name="refresh_button"]
                gtk::Button{
                    label: "Refresh",
                    clicked => Msg::Refresh,
                    halign: Align::Start,
                },
                #[name="tree_view"]
                gtk::TreeView{
                },
                gtk::Button{
                    clicked => Msg::ApplyPort,
                    label: "Apply"
                },
            },
            // Use a tuple when you want to both send a message and return a value to
            // the GTK+ callback.
            delete_event(_, _) => (Msg::Quit, Inhibit(false)),
        }
    }
antoyo commented 4 years ago

Maybe set vexpand: true on the treeview?

MGlolenstine commented 4 years ago

If I set vexpand: true, the tree_view doesn't vanish when there's no data image , but it's still not updating.

antoyo commented 4 years ago

There might be a problem with the model then. Have you tried the other idea I mentionned in a previous message?

MGlolenstine commented 4 years ago

I'm sorry, I was wrong. The vexpand: true did solve it for me, it's just that I didn't test it correctly.

I didn't try the other idea, but it will be good to look at it when I get to the optimisation.

Thanks for your help.