fyne-io / developer.fyne.io

Fyne developer documentation website

Home Page:https://developer.fyne.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

proposal for a more generic Select widget

claudio-ortega opened this issue · comments

Hi there,
I am working on some app to connect musicians with extremely low delay over the internet.
I am attaching a working proposal that would allow handling generic elements in Select widgets.
Keep it up, this is a fantastic library!!
Claudio

package widgets

import (
	"fmt"
	"fyne.io/fyne/widget"
)

type Anything interface {}

type SelectInfo struct {
	Widget   *widget.Select
	infoMap  map[string]Anything
	callback func(string)
	stringer func(Anything) string
}

func NewSelectInfo(
	stringer func(Anything) string,
	changed func(Anything)) *SelectInfo {

	c := &SelectInfo{
		stringer: stringer,
		infoMap:  make(map[string]Anything),
	}

	c.Widget = widget.NewSelect(
		make([]string, 0),
		func(s string) {
			changed(c.inverseStringer(s))
		})

	return c
}

func (c *SelectInfo) Selected() Anything {
	return c.infoMap[c.Widget.Selected]
}

func (c *SelectInfo) Reset() {
	c.Widget.Options = make([]string, 0)
	c.infoMap = make(map[string]Anything)
}

func (c *SelectInfo) LoadInfo(x Anything) error {
	key := c.stringer(x)
	_, found := c.infoMap[key]
	if found {
		return fmt.Errorf("key:[%s] already in the map", key)
	}

	c.infoMap[key] = x
	c.Widget.Options = append(c.Widget.Options, key)

	return nil
}

func (c *SelectInfo) SelectInfo(x Anything) {
	c.SelectText(c.stringer(x))
}

func (c *SelectInfo) SelectText(s string) {

	if len(c.infoMap) == 0 {
		return
	}

	_, found := c.infoMap[s]
	if !found {
		c.Widget.SetSelectedIndex(0)
	}

	c.Widget.SetSelected(s)
}

func (c *SelectInfo) inverseStringer(in string) Anything {
	v, _ := c.infoMap[in]
	return v
}

I would recommend opening this over at https://github.com/fyne-io/fyne or perhaps https://github.com/fyne-io/fyne-x (if you would like to include it as a PR) instead. It feels a little out of place in the developer documentation website and will not get seen as easily by other developers.

Yes this request belongs on the ‘fyne’ repository so it can be tracked. We can probably make use of the new data binding work to address this somehow, but it will require some thought.