Skip to content
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

Missing: Information trees #141

Open
kendellfab opened this issue Apr 25, 2024 · 14 comments
Open

Missing: Information trees #141

kendellfab opened this issue Apr 25, 2024 · 14 comments

Comments

@kendellfab
Copy link

I've been working on migrating TreeViews to ListViews with TreeListModels. I'm finding though that there is a lack of information of how to accomplish this. Specifically with regards to TreeListModelCreateModelFunc on the NewTreeListModel. How do I properly use the item *coreglib.Object to know what child listmodel I need to return?

@diamondburned
Copy link
Owner

diamondburned commented Apr 25, 2024

You could either use gioutil.ListModel[T] to pass in arbitrary Go pointers or gtk.StringList to pass in strings. Each of these list model types have their own functions to get the underlying data from *Object.

We do have an ongoing PR somewhere to add a ListView example, but the code for that is quite outdated at the moment, unfortunately.

@kendellfab
Copy link
Author

I have been able to successfully use those structs you mentioned above to build flat lists.

However, I've been looking at building trees, displaying trees.

Which it would look like a developer would need to use a tree model. It is both this tree model and the TreeListModelCreateModelFunc that expose item *coreglib.Object that I can't figure out how to turn into my model like I was able to with the gioutil.ListModel[T].

@diamondburned
Copy link
Owner

You could see how Dissent does it:

https://github.com/diamondburned/dissent/blob/main/internal/sidebar/channels/channels_model.go

It still uses the legacy StringList model; I haven't had the time to port it over yet. It should be similar either way though.

@kendellfab
Copy link
Author

I think this is where I'm stuck, looking at your code here you're casting the item to a *gtk.StringObject.

I have a non-gtk struct that I need to cast to, and I get an error. So is it not possible to bring our own types to the TreeModel at this point?

@diamondburned
Copy link
Owner

diamondburned commented Apr 25, 2024

If you're using gioutil.ListModel[T], you'd want to use gioutil.ObjectValue[T](obj) to get your Go object back.

You can get additional type safety by using gio.ListModelType[T] which wraps both at once:

var goModelType = gioutil.NewListModelType[goModel]()

var gtkModel = goModelType.New()
var goValue = goModelType.ObjectValue(obj)

@kendellfab
Copy link
Author

Thank you. I'll give that a try. I'm curious, is there a way to update the rows that contain in the list views? I've seen some GTK forums discussing bound properties, but in go we don't have bound properties like someone in C would have, unless I'm missing something.

@diamondburned
Copy link
Owner

is there a way to update the rows that contain in the list views

What do you mean? Each row in the list view should reflect data from some Go model, so to change that data, you'd just change the data in the model.

The way you're supposed to use ListView is to treat it like a transformation pipeline: you have a list of data represented in a certain order (the list model), which then gets transformed (the widget builder) into widgets to be displayed by the view.

@kendellfab
Copy link
Author

I suppose I'm just trying to figure out the listmodel/listview combo and the ins and outs. I have a ListModel, that displays a label. I updated the value that gets set on the label in my go struct, but I'm unsure how to get the bind to happen again.

Perhaps it is a mater of me needing to learn more of the specifics.

@diamondburned
Copy link
Owner

I updated the value that gets set on the label in my go struct, but I'm unsure how to get the bind to happen again.

You will probably have to Splice the list again to set the changed value into the list:

var n int
var v Value
list.Splice(n, 1, v)

A (*gio.ListModel[T]).Set(int, T) function would definitely make this easier, so that might be worth adding.

@diamondburned
Copy link
Owner

(You can consider each item in the ListModel immutable: modifying each item separately, even if they're pointers, won't cause the list to actually update until you intentionally set it again.)

@kendellfab
Copy link
Author

OK, that makes sense. I did see the splice method. Is there an availability to splice with a TreeListModel?

@diamondburned
Copy link
Owner

OK, that makes sense. I did see the splice method. Is there an availability to splice with a TreeListModel?

You'd splice one of the relevant list models within the tree model and the change will automatically propagate to the entire tree.

@kendellfab
Copy link
Author

I think I could have asked a better question. How do I find and access the underlying ListModel from the tree model? I have the root ListModel saved, but I haven't seen any API for accessing child ListModels.

@diamondburned
Copy link
Owner

You'd probably use TreeListModel.get_child_row for that. Normally, GTK signals should give you the right child row as part of the parameters though.

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

No branches or pull requests

2 participants