Skip to content

Commit

Permalink
Merge pull request #4790 from Dorbmon/develop
Browse files Browse the repository at this point in the history
Add IntToFloat (and FloatToInt) in bindings
  • Loading branch information
andydotxyz committed Apr 23, 2024
2 parents 38523de + 9362be8 commit 49609e6
Show file tree
Hide file tree
Showing 3 changed files with 261 additions and 1 deletion.
105 changes: 105 additions & 0 deletions data/binding/convert.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ import (
"fyne.io/fyne/v2"
)

func internalFloatToInt(val float64) (int, error) {
return int(val), nil
}

func internalIntToFloat(val int) (float64, error) {
return float64(val), nil
}

type stringFromBool struct {
base

Expand Down Expand Up @@ -183,6 +191,103 @@ func (s *stringFromFloat) DataChanged() {
s.trigger()
}

type intToFloat struct {
base
from Int
}

// IntToFloat creates a binding that connects an Int data item to a Float.
//
// Since: 2.5
func IntToFloat(val Int) Float {
v := &intToFloat{from: val}
val.AddListener(v)
return v
}

func (s *intToFloat) Get() (float64, error) {
val, err := s.from.Get()
if err != nil {
return 0.0, err
}
return internalIntToFloat(val)
}

func (s *intToFloat) Set(val float64) error {
i, err := internalFloatToInt(val)
if err != nil {
return err
}
old, err := s.from.Get()
if i == old {
return nil
}
if err != nil {
return err
}
if err = s.from.Set(i); err != nil {
return err
}

s.DataChanged()
return nil
}

func (s *intToFloat) DataChanged() {
s.lock.RLock()
defer s.lock.RUnlock()
s.trigger()
}

type intFromFloat struct {
base
from Float
}

// FloatToInt creates a binding that connects a Float data item to an Int.
//
// Since: 2.5
func FloatToInt(v Float) Int {
i := &intFromFloat{from: v}
v.AddListener(i)
return i
}

func (s *intFromFloat) Get() (int, error) {
val, err := s.from.Get()
if err != nil {
return 0, err
}
return internalFloatToInt(val)
}

func (s *intFromFloat) Set(v int) error {
val, err := internalIntToFloat(v)
if err != nil {
return err
}

old, err := s.from.Get()
if err != nil {
return err
}
if val == old {
return nil
}
if err = s.from.Set(val); err != nil {
return err
}

s.DataChanged()
return nil
}

func (s *intFromFloat) DataChanged() {
s.lock.RLock()
defer s.lock.RUnlock()
s.trigger()
}

type stringFromInt struct {
base

Expand Down
40 changes: 40 additions & 0 deletions data/binding/convert_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -363,3 +363,43 @@ func TestURIToString(t *testing.T) {
assert.Nil(t, err)
assert.Equal(t, "file:///tmp/test.txt", v2.String())
}

func TestFloatToInt(t *testing.T) {
f := NewFloat()
i := FloatToInt(f)
v, err := i.Get()
assert.Nil(t, err)
assert.Equal(t, 0, v)

err = f.Set(0.3)
assert.Nil(t, err)
v, err = i.Get()
assert.Nil(t, err)
assert.Equal(t, 0, v)

err = i.Set(5)
assert.Nil(t, err)
v2, err := f.Get()
assert.Nil(t, err)
assert.Equal(t, 5.0, v2)
}

func TestIntToFloat(t *testing.T) {
i := NewInt()
f := IntToFloat(i)
v, err := f.Get()
assert.Nil(t, err)
assert.Equal(t, 0.0, v)

err = i.Set(3)
assert.Nil(t, err)
v, err = f.Get()
assert.Nil(t, err)
assert.Equal(t, 3.0, v)

err = f.Set(5)
assert.Nil(t, err)
v2, err := i.Get()
assert.Nil(t, err)
assert.Equal(t, 5, v2)
}
117 changes: 116 additions & 1 deletion data/binding/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,105 @@ func (s *stringFrom{{ .Name }}) DataChanged() {
s.trigger()
}
`
const toIntTemplate = `
type intFrom{{ .Name }} struct {
base
from {{ .Name }}
}
// {{ .Name }}ToInt creates a binding that connects a {{ .Name }} data item to an Int.
//
// Since: 2.5
func {{ .Name }}ToInt(v {{ .Name }}) Int {
i := &intFrom{{ .Name }}{from: v}
v.AddListener(i)
return i
}
func (s *intFrom{{ .Name }}) Get() (int, error) {
val, err := s.from.Get()
if err != nil {
return 0, err
}
return {{ .ToInt }}(val)
}
func (s *intFrom{{ .Name }}) Set(v int) error {
val, err := {{ .FromInt }}(v)
if err != nil {
return err
}
old, err := s.from.Get()
if err != nil {
return err
}
if val == old {
return nil
}
if err = s.from.Set(val); err != nil {
return err
}
s.DataChanged()
return nil
}
func (s *intFrom{{ .Name }}) DataChanged() {
s.lock.RLock()
defer s.lock.RUnlock()
s.trigger()
}
`
const fromIntTemplate = `
type intTo{{ .Name }} struct {
base
from Int
}
// IntTo{{ .Name }} creates a binding that connects an Int data item to a {{ .Name }}.
//
// Since: 2.5
func IntTo{{ .Name }}(val Int) {{ .Name }} {
v := &intTo{{ .Name }}{from: val}
val.AddListener(v)
return v
}
func (s *intTo{{ .Name }}) Get() ({{ .Type }}, error) {
val, err := s.from.Get()
if err != nil {
return {{ .Default }}, err
}
return {{ .FromInt }}(val)
}
func (s *intTo{{ .Name }}) Set(val {{ .Type }}) error {
i, err := {{ .ToInt }}(val)
if err != nil {
return err
}
old, err := s.from.Get()
if i == old {
return nil
}
if err != nil {
return err
}
if err = s.from.Set(i); err != nil {
return err
}
s.DataChanged()
return nil
}
func (s *intTo{{ .Name }}) DataChanged() {
s.lock.RLock()
defer s.lock.RUnlock()
s.trigger()
}
`
const fromStringTemplate = `
type stringTo{{ .Name }} struct {
base
Expand Down Expand Up @@ -961,6 +1059,7 @@ type bindValues struct {
SupportsPreferences bool
FromString, ToString string // function names...
Comparator string // comparator function name
FromInt, ToInt string // function names...
}

func newFile(name string) (*os.File, error) {
Expand Down Expand Up @@ -1011,6 +1110,14 @@ import (
"fyne.io/fyne/v2"
)
func internalFloatToInt(val float64) (int, error) {
return int(val), nil
}
func internalIntToFloat(val int) (float64, error) {
return float64(val), nil
}
`)
prefFile, err := newFile("preference")
if err != nil {
Expand Down Expand Up @@ -1055,14 +1162,16 @@ import (

item := template.Must(template.New("item").Parse(itemBindTemplate))
fromString := template.Must(template.New("fromString").Parse(fromStringTemplate))
fromInt := template.Must(template.New("fromInt").Parse(fromIntTemplate))
toInt := template.Must(template.New("toInt").Parse(toIntTemplate))
toString := template.Must(template.New("toString").Parse(toStringTemplate))
preference := template.Must(template.New("preference").Parse(prefTemplate))
list := template.Must(template.New("list").Parse(listBindTemplate))
tree := template.Must(template.New("tree").Parse(treeBindTemplate))
binds := []bindValues{
{Name: "Bool", Type: "bool", Default: "false", Format: "%t", SupportsPreferences: true},
{Name: "Bytes", Type: "[]byte", Default: "nil", Since: "2.2", Comparator: "bytes.Equal"},
{Name: "Float", Type: "float64", Default: "0.0", Format: "%f", SupportsPreferences: true},
{Name: "Float", Type: "float64", Default: "0.0", Format: "%f", SupportsPreferences: true, ToInt: "internalFloatToInt", FromInt: "internalIntToFloat"},
{Name: "Int", Type: "int", Default: "0", Format: "%d", SupportsPreferences: true},
{Name: "Rune", Type: "rune", Default: "rune(0)"},
{Name: "String", Type: "string", Default: "\"\"", SupportsPreferences: true},
Expand All @@ -1088,6 +1197,12 @@ import (
if b.Format != "" || b.ToString != "" {
writeFile(convertFile, toString, b)
}
if b.FromInt != "" {
writeFile(convertFile, fromInt, b)
}
if b.ToInt != "" {
writeFile(convertFile, toInt, b)
}
}
// add StringTo... at the bottom of the convertFile for correct ordering
for _, b := range binds {
Expand Down

0 comments on commit 49609e6

Please sign in to comment.