diff --git a/dialog/form.go b/dialog/form.go index 67cea6ceef..306fd588d9 100644 --- a/dialog/form.go +++ b/dialog/form.go @@ -46,14 +46,9 @@ func (d *formDialog) validateItems(err error) { // // Since: 2.0 func NewForm(title, confirm, dismiss string, items []*widget.FormItem, callback func(bool), parent fyne.Window) Dialog { - var itemObjects = make([]fyne.CanvasObject, len(items)*2) - for i, item := range items { - itemObjects[i*2] = widget.NewLabel(item.Text) - itemObjects[i*2+1] = item.Widget - } - content := container.New(layout.NewFormLayout(), itemObjects...) + form := widget.NewForm(items...) - d := &dialog{content: content, callback: callback, title: title, parent: parent} + d := &dialog{content: form, callback: callback, title: title, parent: parent} d.layout = &dialogLayout{d: d} d.dismiss = &widget.Button{Text: dismiss, Icon: theme.CancelIcon(), OnTapped: d.Hide, @@ -70,11 +65,8 @@ func NewForm(title, confirm, dismiss string, items []*widget.FormItem, callback formDialog.validateItems(nil) - for _, item := range items { - if validatable, ok := item.Widget.(fyne.Validatable); ok { - validatable.SetOnValidationChanged(formDialog.validateItems) - } - } + form.SetOnValidationChanged(formDialog.validateItems) + d.create(container.NewHBox(layout.NewSpacer(), d.dismiss, confirmBtn, layout.NewSpacer())) return formDialog } diff --git a/dialog/form_test.go b/dialog/form_test.go index b913f46f2c..8a46383ce5 100644 --- a/dialog/form_test.go +++ b/dialog/form_test.go @@ -6,8 +6,10 @@ import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/test" + "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) // formDialogResult is the result of the test form dialog callback. @@ -81,6 +83,42 @@ func TestFormDialog_CanCancelNoValidation(t *testing.T) { assert.Equal(t, formDialogCancel, result, "Expected cancel result") } +func TestFormDialog_Hints(t *testing.T) { + + test.NewApp() + defer test.NewApp() + test.ApplyTheme(t, theme.LightTheme()) + w := test.NewWindow(nil) + w.SetFullScreen(true) + + var result formDialogResult + fd := hintsFormDialog(&result, w) + w.Resize(fd.MinSize()) + fd.Show() + assert.False(t, fd.win.Hidden) + + assert.True(t, fd.confirm.Disabled(), "Confirm button should be disabled due to validation state") + + test.AssertImageMatches(t, "form/hint_initial.png", w.Canvas().Capture()) + + validatingEntry, ok := fd.items[0].Widget.(*widget.Entry) + require.True(t, ok, "First item's widget should be an Entry (check hintsFormDialog)") + + validatingEntry.SetText("n") + test.AssertImageMatches(t, "form/hint_invalid.png", w.Canvas().Capture()) + assert.True(t, fd.confirm.Disabled()) + + validatingEntry.SetText("abc") + test.AssertImageMatches(t, "form/hint_valid.png", w.Canvas().Capture()) + assert.False(t, fd.confirm.Disabled()) + + test.Tap(fd.confirm) + assert.Equal(t, formDialogConfirm, result, "Valid form should be able to be confirmed") + + test.Tap(fd.dismiss) + assert.Equal(t, formDialogCancel, result, "Expected cancel result") +} + func validatingFormDialog(result *formDialogResult, parent fyne.Window) *formDialog { validatingEntry := widget.NewEntry() validatingEntry.Validator = func(input string) error { @@ -129,3 +167,27 @@ func controlFormDialog(result *formDialogResult, parent fyne.Window) *formDialog } }, parent).(*formDialog) } + +func hintsFormDialog(result *formDialogResult, parent fyne.Window) *formDialog { + validatingEntry := widget.NewEntry() + validatingEntry.Validator = func(input string) error { + if input != "abc" { + return errors.New("only accepts 'abc'") + } + return nil + } + validatingItem := &widget.FormItem{ + Text: "Only accepts 'abc'", + Widget: validatingEntry, + HintText: "Type abc", + } + + items := []*widget.FormItem{validatingItem} + return NewForm("Validating Form Dialog With Hints", "Submit", "Cancel", items, func(confirm bool) { + if confirm { + *result = formDialogConfirm + } else { + *result = formDialogCancel + } + }, parent).(*formDialog) +} diff --git a/dialog/testdata/form/hint_initial.png b/dialog/testdata/form/hint_initial.png new file mode 100644 index 0000000000..7c8f9438ee Binary files /dev/null and b/dialog/testdata/form/hint_initial.png differ diff --git a/dialog/testdata/form/hint_invalid.png b/dialog/testdata/form/hint_invalid.png new file mode 100644 index 0000000000..c8a0f4949d Binary files /dev/null and b/dialog/testdata/form/hint_invalid.png differ diff --git a/dialog/testdata/form/hint_valid.png b/dialog/testdata/form/hint_valid.png new file mode 100644 index 0000000000..e97dc33aac Binary files /dev/null and b/dialog/testdata/form/hint_valid.png differ