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

How to use GTK 4 GridView with gio.ListStore and gtk.BuilderListItemFactory #118

Open
coderkun opened this issue Nov 12, 2023 · 2 comments

Comments

@coderkun
Copy link

I want to use the GTK 4 GridView with a gio.ListStore and a BuilderListItemFactory but cannot figure out how to add an item.

This is my test code:

package main

import (
	"os"

	coreglib "github.com/diamondburned/gotk4/pkg/core/glib"
	"github.com/diamondburned/gotk4/pkg/gio/v2"
	"github.com/diamondburned/gotk4/pkg/glib/v2"
	"github.com/diamondburned/gotk4/pkg/gtk/v4"
)

var factoryXML = `<?xml version='1.0' encoding='UTF-8'?>
<interface>
    <template class="GtkListItem">
        <property name="child">
            <object class="GtkLabel">
                <property name="xalign">0</property>
                <property name="label">Test</property>
                <binding name="label">
                    <lookup name="label">
                        <lookup name="item">GtkListItem</lookup>
                    </lookup>
                </binding>
            </object>
        </property>
    </template>
</interface>`

type Item struct {
	*coreglib.Object
	Label string
}

func main() {
	app := gtk.NewApplication("test.test", gio.ApplicationFlagsNone)
	app.ConnectActivate(func() { activate(app) })

	if code := app.Run(os.Args); code > 0 {
		os.Exit(int(code))
	}
}

func activate(app *gtk.Application) {
	store := gio.NewListStore(coreglib.TypeObject)
	selection := gtk.NewMultiSelection(store)
	factory := &gtk.NewBuilderListItemFactoryFromBytes(gtk.NewBuilderCScope(), glib.NewBytes([]byte(factoryXML))).ListItemFactory
	gridview := gtk.NewGridView(selection, factory)

	item := &Item{
		Label: "Test 1",
	}
	store.Append(item.Object)

	window := gtk.NewWindow()
	window.SetTitle("GridView Test")
	window.SetChild(gridview)
	app.AddWindow(window)
	window.Show()
}

This code panics. I guess I am creating the item incorrectly. Or do I have to define my own coreglib.Type like in the GTK C demo?

Any help would be much appreciated. If we can make this work, I will submit a PR to add an example for the GridView. Thanks a lot.

@nsw42
Copy link

nsw42 commented Feb 24, 2024

This isn't really an answer, because I'm only currently working with strings, but I'm going through a similar process of trying to get model binding working with the dynamic GTK4 gridviews. In case it's helpful, I've got a version of your code working using a backing gtk.StringList, rather than the gio.ListStore:

Rather than calling gio.NewListStore and then appending an item to it, I create a StringList with:

store := gtk.NewStringList([]string{"Test 1", "Test 2"})

and then the only other relevant change is the data binding, so replacing <lookup name="label"> with <lookup name="string" type="GtkStringObject">.

After that, I get a view that shows two text labels as expected ("Test 1" and "Test 2").

I'll also need to build a more complex / custom data model, so I'll keep working on this, too.

@diamondburned
Copy link
Owner

You can't create an object like that. gotk4 unfortunately doesn't support subclassing.

You could try to use gioutil.ListModel[T].

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

3 participants