[Gtk4] how to properly store hybrid data in one ListStore?

I’ve been working on a gtk4 launcher recently, and I know there are many similar programs on the market, but they may not meet my requirements, and I’d like to take this opportunity to learn gtk development skills.

My goal is to have something like soptlight on macOS, which should support software list, window list, clipboard, calculator, firefox history, etc. in one list, i.e. my interface should look something like this.

Since this list will probably be quite large, I’d like to use gtk::ListView to display the data, and I’m a bit hesitant about how to store so many types of data in one ListStore. (For example, the application launcher is a box with an icon, a name and a description, the window switcher has a title and a preview window, the clipboard manager might be a text or an image).

What would be a better way to implement this situation?

I can think of two solutions, but I don’t know the feasibility of

  1. multiple types of processors return multiple ListModels, then use FlattenListModel to merge them (which also involves sorting multiple types of items)
  2. encapsulate the data of these types into a uniform structure and put it into a ListModel (but with different activations for different types of data).

Am I on the right track?

Thanks in advance for any tip.

It’s not totally clear from your description what an ‘average’ list model item will look like, but I imagine you probably want to use your option 2, and make the items complex GObjects, of a type that will implement all common functionality (launching) and may optionally implement handling clipboard, etc. (perhaps via an interface that can return a way to handle clipboard if relevant, otherwise NULL).

For showing these visually you may be interested in the relatively recently added Sections functionality.

2 Likes

Thanks for the reply, I finally deal it with BoxedAnyObject

pub trait PluginResult {
    // ...
    
    fn to_launcher_row(&self) -> gtk::Box;
    
    // ...
}

let list_store = gio::ListStore::new(BoxedAnyObject::static_type());
let mut plugins: Vec<Box<dyn Plugin>> = vec![];

{
    let list_store = list_store.clone();
    plugins.iter().for_each(|plugin| {
        let results: Vec<Box<dyn PluginResult>> = plugin.handle_input(&user_input);

        for pr in results {
            list_store.append(&BoxedAnyObject::new(pr));
        }
    });
}
1 Like

This topic was automatically closed 45 days after the last reply. New replies are no longer allowed.