From 522ee6099fd349521b492922a145795db0410b90 Mon Sep 17 00:00:00 2001
From: Svart Adam Solander
Date: Tue, 20 Sep 2022 15:33:37 +0200
Subject: [PATCH 1/4] "Added custom binding 'DisableableBinding' and added it
to README.md."
---
README.md | 16 ++++++--
data/binding/disableableBinding.go | 61 ++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+), 3 deletions(-)
create mode 100644 data/binding/disableableBinding.go
diff --git a/README.md b/README.md
index 69ee797a..0fb176e3 100644
--- a/README.md
+++ b/README.md
@@ -46,7 +46,7 @@ Optionally, Each canvas object can be encapsulated with `Responsive()` function
```go
layout := NewResponsiveLayout(
Responsive(object1), // all sizes to 100%
- Responsive(object2, 0.5, 0.75), // small to 50%, medium to 75%, all others to 100%
+ Responsive(object2, 0.5, 0.75), // small to 50%, medium to 75%, all others to 100%
)
```
@@ -59,7 +59,7 @@ Community contributed widgets.
### Calendar
-
+
A date picker which returns a [time](https://pkg.go.dev/time) object with the selected date.
@@ -69,7 +69,7 @@ A date picker which returns a [time](https://pkg.go.dev/time) object with the se
-
+
To use create a new calendar with a given time and a callback function:
@@ -224,6 +224,16 @@ if err := token.Error(); err != nil {
s, err := binding.NewMqttString(client, "fyne.io/x/string")
```
+### DisableableBinding
+
+A `DisableableBinding` creates a `Bool` data binding which accepts `Disableable` targets to control.
+When the `bool` binding is changed, all targets `Enable` or `Disable` methods will be executed depending on the settings.
+
+The binding accepts targets when created with `NewDisableableBinding` or via the method `AddTargets`.
+The behaviour of the binding can be inverted, so true disables and false enables. This is done through method `Invert`.
+
+All targets are updated when either `AddTargets` or `Invert` is executed.
+
## Data Validation
Community contributed validators.
diff --git a/data/binding/disableableBinding.go b/data/binding/disableableBinding.go
new file mode 100644
index 00000000..11ad236d
--- /dev/null
+++ b/data/binding/disableableBinding.go
@@ -0,0 +1,61 @@
+package binding
+
+import (
+ "log"
+
+ "fyne.io/fyne/v2"
+ "fyne.io/fyne/v2/data/binding"
+)
+
+type disableableBinding struct {
+ binding.Bool
+
+ inverted bool
+ targets []fyne.Disableable
+}
+
+// NewDisableableBinding returns a `Bool` binding which accepts Disableable targets.
+// When the Bool changes, the targets Enable or Disable method will be executed.
+func NewDisableableBinding(targets ...fyne.Disableable) *disableableBinding {
+ newBinding := &disableableBinding{
+ Bool: binding.NewBool(),
+ targets: targets,
+ }
+
+ // Add default listener
+ newBinding.AddListener(binding.NewDataListener(newBinding.update))
+
+ return newBinding
+}
+
+// Adding targets to the binding.
+// This will update the Disable status of the targets immediately.
+func (b *disableableBinding) AddTargets(targets ...fyne.Disableable) {
+ b.targets = append(b.targets, targets...)
+ b.update()
+}
+
+// Invert will switch the behavior of when the targets will be Enabled or Disabled.
+// This will update the Disable status of the targets immediately.
+func (b *disableableBinding) Invert(inverted bool) {
+ b.inverted = inverted
+ b.update()
+}
+
+func (b *disableableBinding) update() {
+ val, err := b.Get()
+ if err != nil {
+ log.Println(err)
+ return
+ }
+
+ if (!b.inverted && val) || (b.inverted && !val) {
+ for _, target := range b.targets {
+ target.Enable()
+ }
+ } else {
+ for _, target := range b.targets {
+ target.Disable()
+ }
+ }
+}
From ba137c2fc4fecef25e11be90178dffe089b84a42 Mon Sep 17 00:00:00 2001
From: Svart Adam Solander
Date: Thu, 22 Sep 2022 09:41:45 +0200
Subject: [PATCH 2/4] "Substituted the name 'targets' for 'widgets'
consistantly throughout the disableable binding and in the information for it
in README.md."
---
README.md | 8 ++++----
data/binding/disableableBinding.go | 32 +++++++++++++++---------------
2 files changed, 20 insertions(+), 20 deletions(-)
diff --git a/README.md b/README.md
index 0fb176e3..ec2d4cac 100644
--- a/README.md
+++ b/README.md
@@ -226,13 +226,13 @@ s, err := binding.NewMqttString(client, "fyne.io/x/string")
### DisableableBinding
-A `DisableableBinding` creates a `Bool` data binding which accepts `Disableable` targets to control.
-When the `bool` binding is changed, all targets `Enable` or `Disable` methods will be executed depending on the settings.
+A `DisableableBinding` creates a `Bool` data binding which accepts `Disableable` widgets to control.
+When the `bool` binding is changed, all widgets `Enable` or `Disable` methods will be executed depending on the settings.
-The binding accepts targets when created with `NewDisableableBinding` or via the method `AddTargets`.
+The binding accepts widgets when created with `NewDisableableBinding` or via the method `AddWidgets`.
The behaviour of the binding can be inverted, so true disables and false enables. This is done through method `Invert`.
-All targets are updated when either `AddTargets` or `Invert` is executed.
+All widgets are updated when either `AddWidgets` or `Invert` is executed.
## Data Validation
diff --git a/data/binding/disableableBinding.go b/data/binding/disableableBinding.go
index 11ad236d..7183f037 100644
--- a/data/binding/disableableBinding.go
+++ b/data/binding/disableableBinding.go
@@ -11,15 +11,15 @@ type disableableBinding struct {
binding.Bool
inverted bool
- targets []fyne.Disableable
+ widgets []fyne.Disableable
}
-// NewDisableableBinding returns a `Bool` binding which accepts Disableable targets.
-// When the Bool changes, the targets Enable or Disable method will be executed.
-func NewDisableableBinding(targets ...fyne.Disableable) *disableableBinding {
+// NewDisableableBinding returns a `Bool` binding which accepts Disableable widgets.
+// When the Bool changes, the widgets Enable or Disable method will be executed.
+func NewDisableableBinding(widgets ...fyne.Disableable) *disableableBinding {
newBinding := &disableableBinding{
Bool: binding.NewBool(),
- targets: targets,
+ widgets: widgets,
}
// Add default listener
@@ -28,16 +28,16 @@ func NewDisableableBinding(targets ...fyne.Disableable) *disableableBinding {
return newBinding
}
-// Adding targets to the binding.
-// This will update the Disable status of the targets immediately.
-func (b *disableableBinding) AddTargets(targets ...fyne.Disableable) {
- b.targets = append(b.targets, targets...)
+// Adding widgets to the binding.
+// This will update the Disable status of the widgets immediately.
+func (b *disableableBinding) AddWidgets(widgets ...fyne.Disableable) {
+ b.widgets = append(b.widgets, widgets...)
b.update()
}
-// Invert will switch the behavior of when the targets will be Enabled or Disabled.
-// This will update the Disable status of the targets immediately.
-func (b *disableableBinding) Invert(inverted bool) {
+// SetInverted will switch the behavior of when the widgets will be Enabled or Disabled.
+// This will update the Disable status of the widgets immediately.
+func (b *disableableBinding) SetInverted(inverted bool) {
b.inverted = inverted
b.update()
}
@@ -50,12 +50,12 @@ func (b *disableableBinding) update() {
}
if (!b.inverted && val) || (b.inverted && !val) {
- for _, target := range b.targets {
- target.Enable()
+ for _, widget := range b.widgets {
+ widget.Enable()
}
} else {
- for _, target := range b.targets {
- target.Disable()
+ for _, widget := range b.widgets {
+ widget.Disable()
}
}
}
From a3744b376a14dd9aea033de0a67808819102d22f Mon Sep 17 00:00:00 2001
From: Svart Adam Solander
Date: Wed, 28 Sep 2022 11:33:16 +0200
Subject: [PATCH 3/4] "NewDisableableBinding now returns an interface."
---
data/binding/disableableBinding.go | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/data/binding/disableableBinding.go b/data/binding/disableableBinding.go
index 7183f037..a29a4977 100644
--- a/data/binding/disableableBinding.go
+++ b/data/binding/disableableBinding.go
@@ -7,7 +7,15 @@ import (
"fyne.io/fyne/v2/data/binding"
)
-type disableableBinding struct {
+// DisableableBinding is a `Bool` binding with accept Disableable widgets that it will control the Disabled status of.
+type DisableableBinding interface {
+ binding.Bool
+
+ AddWidgets(...fyne.Disableable)
+ SetInverted(bool)
+}
+
+type boundDisableable struct {
binding.Bool
inverted bool
@@ -16,8 +24,8 @@ type disableableBinding struct {
// NewDisableableBinding returns a `Bool` binding which accepts Disableable widgets.
// When the Bool changes, the widgets Enable or Disable method will be executed.
-func NewDisableableBinding(widgets ...fyne.Disableable) *disableableBinding {
- newBinding := &disableableBinding{
+func NewDisableableBinding(widgets ...fyne.Disableable) DisableableBinding {
+ newBinding := &boundDisableable{
Bool: binding.NewBool(),
widgets: widgets,
}
@@ -30,19 +38,19 @@ func NewDisableableBinding(widgets ...fyne.Disableable) *disableableBinding {
// Adding widgets to the binding.
// This will update the Disable status of the widgets immediately.
-func (b *disableableBinding) AddWidgets(widgets ...fyne.Disableable) {
+func (b *boundDisableable) AddWidgets(widgets ...fyne.Disableable) {
b.widgets = append(b.widgets, widgets...)
b.update()
}
// SetInverted will switch the behavior of when the widgets will be Enabled or Disabled.
// This will update the Disable status of the widgets immediately.
-func (b *disableableBinding) SetInverted(inverted bool) {
+func (b *boundDisableable) SetInverted(inverted bool) {
b.inverted = inverted
b.update()
}
-func (b *disableableBinding) update() {
+func (b *boundDisableable) update() {
val, err := b.Get()
if err != nil {
log.Println(err)
From cd41cfdad5c09d2152422a266712fb94aadcbac4 Mon Sep 17 00:00:00 2001
From: Svart Adam Solander
Date: Wed, 28 Sep 2022 11:33:40 +0200
Subject: [PATCH 4/4] "Added test for DisableableBinding."
---
data/binding/disableableBinding_test.go | 64 +++++++++++++++++++++++++
1 file changed, 64 insertions(+)
create mode 100644 data/binding/disableableBinding_test.go
diff --git a/data/binding/disableableBinding_test.go b/data/binding/disableableBinding_test.go
new file mode 100644
index 00000000..eda6eb0f
--- /dev/null
+++ b/data/binding/disableableBinding_test.go
@@ -0,0 +1,64 @@
+package binding
+
+import (
+ "testing"
+ "time"
+
+ "fyne.io/fyne/v2/test"
+ "fyne.io/fyne/v2/widget"
+)
+
+// Since it's a callback we're testing, we let it process for some time before checking for result.
+const callbackWait = 10 * time.Millisecond
+
+func TestDisableableBinding(t *testing.T) {
+ test.NewApp()
+
+ bound := NewDisableableBinding()
+ widget1 := widget.NewEntry()
+ widget2 := widget.NewSelectEntry([]string{"test1", "test2"})
+
+ if widget1.Disabled() || widget2.Disabled() {
+ t.Errorf("test ended early because of wrong initial values on widgets.")
+ return
+ }
+
+ // Adding widgets
+ bound.AddWidgets(widget1, widget2)
+
+ boundCheck := widget.NewCheckWithData("My bound checkbox", bound)
+
+ // Checking not inverted
+ boundCheck.SetChecked(true)
+
+ // Since it's a callback we're testing, we let it process for some time before checking for result.
+ <-time.After(callbackWait)
+ if widget1.Disabled() || widget2.Disabled() {
+ t.Errorf("Widget1 or 2 was not enabled.")
+ return
+ }
+
+ boundCheck.SetChecked(false)
+ <-time.After(callbackWait)
+ if !widget1.Disabled() || !widget2.Disabled() {
+ t.Errorf("Widget1 or 2 was not disabled.")
+ return
+ }
+
+ // Checking inverted
+ bound.SetInverted(true)
+
+ boundCheck.SetChecked(true)
+ <-time.After(callbackWait)
+ if !widget1.Disabled() || !widget2.Disabled() {
+ t.Errorf("Widget1 or 2 was not disabled.")
+ return
+ }
+
+ boundCheck.SetChecked(false)
+ <-time.After(callbackWait)
+ if widget1.Disabled() || widget2.Disabled() {
+ t.Errorf("Widget1 or 2 was not enabled.")
+ return
+ }
+}