Skip to content

Commit

Permalink
feat(pkg/widgets)!: Add DropDown and PointerDropDown types
Browse files Browse the repository at this point in the history
  • Loading branch information
Tom5521 committed May 26, 2024
1 parent 89227aa commit b60b434
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 15 deletions.
93 changes: 78 additions & 15 deletions pkg/widgets/dropdown.go
Original file line number Diff line number Diff line change
@@ -1,34 +1,97 @@
package widgets

import "github.com/diamondburned/gotk4/pkg/gtk/v4"
import (
"slices"

type DropDown struct {
"github.com/diamondburned/gotk4/pkg/core/gioutil"
"github.com/diamondburned/gotk4/pkg/gtk/v4"
)

type DropDown[T any] struct {
*gtk.DropDown
Items []string

OnSelected func(selected uint)
Items []T
Model *gioutil.ListModel[T]
Factory *gtk.SignalListItemFactory

OnChanged func(index int)

Setup FactorySetup
Bind ListBind[T]
}

func NewDropDown(items []string) *DropDown {
d := &DropDown{
Items: items,
DropDown: gtk.NewDropDownFromStrings(items),
func NewDropDown[T any](
items []T,
setup FactorySetup,
bind ListBind[T],
) *DropDown[T] {
d := &DropDown[T]{
Items: items,
Model: gioutil.NewListModel[T](),
Factory: gtk.NewSignalListItemFactory(),

Setup: setup,
Bind: bind,
}
d.reConnectOnSelected()

d.RefreshModel()
d.connectFactory()

d.DropDown = gtk.NewDropDown(d.Model.ListModel, nil)
d.SetFactory(&d.Factory.ListItemFactory)

d.connectChanged()

return d
}

func (d *DropDown) Refresh() {
d.reConnectOnSelected()
func (d *DropDown[T]) Append(v T) {
d.Items = append(d.Items, v)
d.Model.Append(v)
}

func (d *DropDown[T]) Remove(index int) {
d.Items = slices.Delete(d.Items, index, index+1)
d.Model.Remove(index)
}

func (d *DropDown[T]) Splice(pos, rms int, values ...T) {
d.Items = splice(d.Items, pos, rms, values)
d.Model.Splice(pos, rms, values...)
}

// Internal functions
func (d *DropDown[T]) RefreshModel() {
if d.Model.NItems() == 0 {
for _, i := range d.Items {
d.Model.Append(i)
}
return
}
d.Model.Splice(0, 0, d.Items...)
}

func (d *DropDown) reConnectOnSelected() {
// Private methods.

func (d *DropDown[T]) connectChanged() {
d.ConnectAfter("notify::selected", func() {
if d.OnSelected == nil {
if d.OnChanged == nil {
return
}
d.OnChanged(int(d.Selected()))
})
}

func (d *DropDown[T]) connectFactory() {
d.Factory.ConnectSetup(func(listitem *gtk.ListItem) {
if d.Setup == nil {
return
}
d.Setup(listitem)
})
d.Factory.ConnectBind(func(listitem *gtk.ListItem) {
if d.Bind == nil {
return
}
d.OnSelected(d.Selected())
d.Bind(listitem, d.Items[listitem.Position()])
})
}
81 changes: 81 additions & 0 deletions pkg/widgets/pointer-dropdown.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
package widgets

import (
"slices"

"github.com/diamondburned/gotk4/pkg/core/gioutil"
"github.com/diamondburned/gotk4/pkg/gtk/v4"
)

type PointerDropDown[T any] struct {
*DropDown[T]

Items *[]T
}

func NewPointerDropDown[T any](
items *[]T,
setup FactorySetup,
bind ListBind[T],
) *PointerDropDown[T] {
d := &PointerDropDown[T]{
DropDown: &DropDown[T]{
Model: gioutil.NewListModel[T](),
Factory: gtk.NewSignalListItemFactory(),

Setup: setup,
Bind: bind,
},
Items: items,
}

d.RefreshModel()
d.connectFactory()

d.DropDown.DropDown = gtk.NewDropDown(d.Model.ListModel, nil)
d.SetFactory(&d.Factory.ListItemFactory)

d.connectChanged()

return d
}

func (d *PointerDropDown[T]) Append(v T) {
*d.Items = append(*d.Items, v)
d.Model.Append(v)
}

func (d *PointerDropDown[T]) Remove(index int) {
*d.Items = slices.Delete(*d.Items, index, index+1)
d.Model.Remove(index)
}

func (d *PointerDropDown[T]) Splice(pos, rms int, values ...T) {
*d.Items = splice(*d.Items, pos, rms, values)
d.Model.Splice(pos, rms, values...)
}

func (d *PointerDropDown[T]) RefreshModel() {
if d.Model.NItems() == 0 {
for _, i := range *d.Items {
d.Model.Append(i)
}
return
}
d.Model.Splice(0, 0, *d.Items...)
}

func (d *PointerDropDown[T]) connectFactory() {
d.Factory.ConnectSetup(func(listitem *gtk.ListItem) {
if d.Setup == nil {
return
}
d.Setup(listitem)
})
d.Factory.ConnectBind(func(listitem *gtk.ListItem) {
if d.Bind == nil {
return
}
d.Bind(listitem, (*d.Items)[listitem.Position()])
})
}

0 comments on commit b60b434

Please sign in to comment.