diff --git a/widget/entry_validation.go b/widget/entry_validation.go index 09a16904a6..f525588374 100644 --- a/widget/entry_validation.go +++ b/widget/entry_validation.go @@ -60,9 +60,10 @@ func (e *Entry) setValidationError(err error) bool { return false } + changed := e.validationError != err e.validationError = err - if e.onValidationChanged != nil { + if e.onValidationChanged != nil && changed { e.onValidationChanged(err) } diff --git a/widget/form.go b/widget/form.go index dcebd3a009..c24fd01039 100644 --- a/widget/form.go +++ b/widget/form.go @@ -26,6 +26,7 @@ type FormItem struct { validationError error invalid bool helperOutput *canvas.Text + wasFocused bool } // NewFormItem creates a new form item with the specified label text and input widget @@ -351,9 +352,15 @@ func (f *Form) updateHelperText(item *FormItem) { return // testing probably, either way not rendered yet } showHintIfError := false - if e, ok := item.Widget.(*Entry); ok && (!e.dirty || e.focused) { - showHintIfError = true + if e, ok := item.Widget.(*Entry); ok { + if !e.dirty || (e.focused && !item.wasFocused) { + showHintIfError = true + } + if e.dirty && !e.focused { + item.wasFocused = true + } } + if item.validationError == nil || showHintIfError { item.helperOutput.Text = item.HintText item.helperOutput.Color = th.Color(theme.ColorNamePlaceHolder, v) @@ -361,6 +368,12 @@ func (f *Form) updateHelperText(item *FormItem) { item.helperOutput.Text = item.validationError.Error() item.helperOutput.Color = th.Color(theme.ColorNameError, v) } + + if item.helperOutput.Text == "" { + item.helperOutput.Hide() + } else { + item.helperOutput.Show() + } item.helperOutput.Refresh() } @@ -472,5 +485,11 @@ func (f formItemLayout) MinSize(objs []fyne.CanvasObject) fyne.Size { min1 := objs[1].MinSize() minWidth := fyne.Max(min0.Width, min1.Width) - return fyne.NewSize(minWidth, min0.Height+min1.Height+innerPad) + height := min0.Height + + items := objs[1].(*fyne.Container).Objects + if len(items) > 0 && items[0].(*canvas.Text).Text != "" { + height += min1.Height + innerPad + } + return fyne.NewSize(minWidth, height) } diff --git a/widget/form_test.go b/widget/form_test.go index 2a5bb98b42..bb5f7711ae 100644 --- a/widget/form_test.go +++ b/widget/form_test.go @@ -177,12 +177,15 @@ func TestForm_Hints(t *testing.T) { w := test.NewWindow(form) defer w.Close() + w.Resize(form.MinSize().Add(fyne.NewSquareSize(theme.Padding() * 2))) test.AssertImageMatches(t, "form/hint_initial.png", w.Canvas().Capture()) test.Type(entry2, "n") + w.Resize(form.MinSize().Add(fyne.NewSquareSize(theme.Padding() * 2))) test.AssertImageMatches(t, "form/hint_invalid.png", w.Canvas().Capture()) test.Type(entry2, "ot-") + w.Resize(form.MinSize().Add(fyne.NewSquareSize(theme.Padding() * 2))) test.AssertImageMatches(t, "form/hint_valid.png", w.Canvas().Capture()) } @@ -301,17 +304,21 @@ func TestForm_Disable_Validation(t *testing.T) { w := test.NewWindow(form) defer w.Close() + w.Resize(form.MinSize().Add(fyne.NewSquareSize(theme.Padding() * 2))) test.AssertImageMatches(t, "form/disable_validation_initial.png", w.Canvas().Capture()) form.Disable() + w.Resize(form.MinSize().Add(fyne.NewSquareSize(theme.Padding() * 2))) test.AssertImageMatches(t, "form/disable_validation_disabled_invalid.png", w.Canvas().Capture()) form.Enable() + w.Resize(form.MinSize().Add(fyne.NewSquareSize(theme.Padding() * 2))) test.AssertImageMatches(t, "form/disable_validation_enabled_invalid.png", w.Canvas().Capture()) entry.SetText("15-true") + w.Resize(form.MinSize().Add(fyne.NewSquareSize(theme.Padding() * 2))) test.AssertImageMatches(t, "form/disable_validation_enabled_valid.png", w.Canvas().Capture()) // ensure we don't re-enable the form when entering something valid @@ -319,6 +326,7 @@ func TestForm_Disable_Validation(t *testing.T) { form.Disable() entry.SetText("15-true") + w.Resize(form.MinSize().Add(fyne.NewSquareSize(theme.Padding() * 2))) test.AssertImageMatches(t, "form/disable_validation_disabled_valid.png", w.Canvas().Capture()) } diff --git a/widget/testdata/form/disable_validation_disabled_valid.png b/widget/testdata/form/disable_validation_disabled_valid.png index 791c045ba8..9fd36d8279 100644 Binary files a/widget/testdata/form/disable_validation_disabled_valid.png and b/widget/testdata/form/disable_validation_disabled_valid.png differ diff --git a/widget/testdata/form/disable_validation_enabled_valid.png b/widget/testdata/form/disable_validation_enabled_valid.png index 57b2f739d2..d4ca185ef0 100644 Binary files a/widget/testdata/form/disable_validation_enabled_valid.png and b/widget/testdata/form/disable_validation_enabled_valid.png differ diff --git a/widget/testdata/form/hint_invalid.png b/widget/testdata/form/hint_invalid.png index f4747cfb9c..ea447c8ed4 100644 Binary files a/widget/testdata/form/hint_invalid.png and b/widget/testdata/form/hint_invalid.png differ diff --git a/widget/testdata/form/hint_valid.png b/widget/testdata/form/hint_valid.png index 51bb93b912..6600e02767 100644 Binary files a/widget/testdata/form/hint_valid.png and b/widget/testdata/form/hint_valid.png differ diff --git a/widget/testdata/form/validation_entry_first_type_initial.png b/widget/testdata/form/validation_entry_first_type_initial.png index cd6c83a86e..3f43296610 100644 Binary files a/widget/testdata/form/validation_entry_first_type_initial.png and b/widget/testdata/form/validation_entry_first_type_initial.png differ diff --git a/widget/testdata/form/validation_entry_first_type_invalid.png b/widget/testdata/form/validation_entry_first_type_invalid.png index 6bbbf07d2a..cb28bb1329 100644 Binary files a/widget/testdata/form/validation_entry_first_type_invalid.png and b/widget/testdata/form/validation_entry_first_type_invalid.png differ diff --git a/widget/testdata/form/validation_entry_first_type_valid.png b/widget/testdata/form/validation_entry_first_type_valid.png index 0dccbff58e..05169ca668 100644 Binary files a/widget/testdata/form/validation_entry_first_type_valid.png and b/widget/testdata/form/validation_entry_first_type_valid.png differ diff --git a/widget/testdata/form/validation_initial.png b/widget/testdata/form/validation_initial.png index e8fe0ec588..6b18ac3ea4 100644 Binary files a/widget/testdata/form/validation_initial.png and b/widget/testdata/form/validation_initial.png differ diff --git a/widget/testdata/form/validation_invalid.png b/widget/testdata/form/validation_invalid.png index 478177d243..c898866a0d 100644 Binary files a/widget/testdata/form/validation_invalid.png and b/widget/testdata/form/validation_invalid.png differ diff --git a/widget/testdata/form/validation_valid.png b/widget/testdata/form/validation_valid.png index 8cbf5b95e0..e1475ef9d6 100644 Binary files a/widget/testdata/form/validation_valid.png and b/widget/testdata/form/validation_valid.png differ