From 638a49345b52aba6c72b8267f4b656c5869b7799 Mon Sep 17 00:00:00 2001 From: Jacob Date: Sat, 18 May 2024 22:35:56 +0200 Subject: [PATCH 01/78] Introduce test.NewTempWindow() to avoid memory leak with windows that stay alive --- container/innerwindow_test.go | 2 +- container/tabs_test.go | 2 +- dialog/color_button_test.go | 4 +- dialog/color_channel_test.go | 4 +- dialog/color_picker_test.go | 16 ++------ dialog/color_preview_test.go | 4 +- dialog/color_test.go | 19 +++------ dialog/color_wheel_test.go | 4 +- dialog/confirm_test.go | 10 ++--- dialog/custom_test.go | 14 +++---- dialog/entry_test.go | 4 +- dialog/file_test.go | 28 ++++++------- dialog/folder_test.go | 2 +- dialog/form_test.go | 14 +++---- dialog/information_test.go | 6 +-- internal/widget/simple_renderer_test.go | 2 +- test/testwindow.go | 11 +++++ widget/accordion_test.go | 8 +--- widget/activity_internal_test.go | 2 +- widget/card_test.go | 6 +-- widget/check_group_test.go | 4 +- widget/check_test.go | 4 +- widget/entry_internal_test.go | 6 +-- widget/entry_test.go | 53 +++++-------------------- widget/entry_validation_test.go | 6 +-- widget/fileicon_test.go | 4 +- widget/form_test.go | 8 ++-- widget/hyperlink_test.go | 4 +- widget/icon_test.go | 4 +- widget/list_test.go | 16 ++++---- widget/popup_menu_desktop_test.go | 3 +- widget/popup_menu_test.go | 29 ++++++-------- widget/popup_test.go | 22 +++++----- widget/radio_group_test.go | 4 +- widget/richtext_test.go | 2 +- widget/select_test.go | 4 +- widget/slider_test.go | 2 +- widget/table_test.go | 2 +- widget/tree_internal_test.go | 4 +- widget/widget_test.go | 8 +--- 40 files changed, 135 insertions(+), 216 deletions(-) diff --git a/container/innerwindow_test.go b/container/innerwindow_test.go index 463844f2fa..55d1436ded 100644 --- a/container/innerwindow_test.go +++ b/container/innerwindow_test.go @@ -14,7 +14,7 @@ import ( func TestInnerWindow_Close(t *testing.T) { w := NewInnerWindow("Thing", widget.NewLabel("Content")) - outer := test.NewWindow(w) + outer := test.NewTempWindow(t, w) outer.SetPadded(false) outer.Resize(w.MinSize()) assert.True(t, w.Visible()) diff --git a/container/tabs_test.go b/container/tabs_test.go index f50e78336a..88cbe3e7c8 100644 --- a/container/tabs_test.go +++ b/container/tabs_test.go @@ -33,7 +33,7 @@ func TestTab_ThemeChange(t *testing.T) { tabs := NewAppTabs( NewTabItem("a", widget.NewLabel("a")), NewTabItem("b", widget.NewLabel("b"))) - w := test.NewWindow(tabs) + w := test.NewTempWindow(t, tabs) w.Resize(fyne.NewSize(180, 120)) initial := w.Canvas().Capture() diff --git a/dialog/color_button_test.go b/dialog/color_button_test.go index 741d9124f8..70d1cba15b 100644 --- a/dialog/color_button_test.go +++ b/dialog/color_button_test.go @@ -33,12 +33,10 @@ func Test_colorButton_Layout(t *testing.T) { color.MouseIn(nil) } - window := test.NewWindow(container.NewCenter(color)) + window := test.NewTempWindow(t, container.NewCenter(color)) window.Resize(color.MinSize().Max(fyne.NewSize(50, 50))) test.AssertRendersToImage(t, "color/button_layout_"+name+".png", window.Canvas()) - - window.Close() }) } } diff --git a/dialog/color_channel_test.go b/dialog/color_channel_test.go index 9bca175afd..8a07521a1f 100644 --- a/dialog/color_channel_test.go +++ b/dialog/color_channel_test.go @@ -36,11 +36,9 @@ func Test_colorChannel_Layout(t *testing.T) { color := newColorChannel(tt.name, min, max, tt.value, nil) color.Resize(size) - window := test.NewWindow(color) + window := test.NewTempWindow(t, color) test.AssertRendersToImage(t, "color/channel_layout_"+name+".png", window.Canvas()) - - window.Close() }) } } diff --git a/dialog/color_picker_test.go b/dialog/color_picker_test.go index c146c900dc..83b684bb57 100644 --- a/dialog/color_picker_test.go +++ b/dialog/color_picker_test.go @@ -15,12 +15,10 @@ func Test_colorGreyscalePicker_Layout(t *testing.T) { color := newColorGreyscalePicker(nil) - window := test.NewWindow(container.NewCenter(color)) + window := test.NewTempWindow(t, container.NewCenter(color)) window.Resize(color.MinSize().Max(fyne.NewSize(360, 60))) test.AssertRendersToImage(t, "color/picker_layout_greyscale.png", window.Canvas()) - - window.Close() } func Test_colorBasicPicker_Layout(t *testing.T) { @@ -29,12 +27,10 @@ func Test_colorBasicPicker_Layout(t *testing.T) { color := newColorBasicPicker(nil) - window := test.NewWindow(container.NewCenter(color)) + window := test.NewTempWindow(t, container.NewCenter(color)) window.Resize(color.MinSize().Max(fyne.NewSize(360, 60))) test.AssertRendersToImage(t, "color/picker_layout_basic.png", window.Canvas()) - - window.Close() } func Test_colorRecentPicker_Layout(t *testing.T) { @@ -46,12 +42,10 @@ func Test_colorRecentPicker_Layout(t *testing.T) { color := newColorRecentPicker(nil) - window := test.NewWindow(container.NewCenter(color)) + window := test.NewTempWindow(t, container.NewCenter(color)) window.Resize(color.MinSize().Max(fyne.NewSize(360, 60))) test.AssertRendersToImage(t, "color/picker_layout_recent.png", window.Canvas()) - - window.Close() } func Test_colorAdvancedPicker_Layout(t *testing.T) { @@ -62,10 +56,8 @@ func Test_colorAdvancedPicker_Layout(t *testing.T) { color.Refresh() - window := test.NewWindow(container.NewCenter(color)) + window := test.NewTempWindow(t, container.NewCenter(color)) window.Resize(color.MinSize().Max(fyne.NewSize(200, 200))) test.AssertRendersToImage(t, "color/picker_layout_advanced.png", window.Canvas()) - - window.Close() } diff --git a/dialog/color_preview_test.go b/dialog/color_preview_test.go index 538679ff1f..fc4532113e 100644 --- a/dialog/color_preview_test.go +++ b/dialog/color_preview_test.go @@ -15,11 +15,9 @@ func Test_colorPreview_Color(t *testing.T) { preview := newColorPreview(color.RGBA{53, 113, 233, 255}) preview.SetColor(color.RGBA{90, 206, 80, 180}) - window := test.NewWindow(preview) + window := test.NewTempWindow(t, preview) padding := theme.Padding() * 2 window.Resize(fyne.NewSize(128+padding, 64+padding)) test.AssertRendersToImage(t, "color/preview_color.png", window.Canvas()) - - window.Close() } diff --git a/dialog/color_test.go b/dialog/color_test.go index 311132f2de..927efed9f6 100644 --- a/dialog/color_test.go +++ b/dialog/color_test.go @@ -16,7 +16,7 @@ func TestColorDialog_Theme(t *testing.T) { test.NewApp() defer test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(1000, 800)) d := NewColorPicker("Color Picker", "Pick a Color", nil, w) @@ -36,8 +36,6 @@ func TestColorDialog_Theme(t *testing.T) { test.ApplyTheme(t, test.NewTheme()) test.AssertRendersToImage(t, "color/dialog_expanded_theme_ugly.png", w.Canvas()) - - w.Close() } func TestColorDialog_Recents(t *testing.T) { @@ -47,7 +45,7 @@ func TestColorDialog_Recents(t *testing.T) { // Inject recent preferences a.Preferences().SetString("color_recents", "#2196f3,#4caf50,#f44336") - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(800, 600)) d := NewColorPicker("Color Picker", "Pick a Color", nil, w) @@ -59,13 +57,11 @@ func TestColorDialog_Recents(t *testing.T) { test.ApplyTheme(t, test.NewTheme()) test.AssertRendersToImage(t, "color/dialog_recents_theme_ugly.png", w.Canvas()) - - w.Close() } func TestColorDialog_SetColor(t *testing.T) { - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(800, 600)) col := color.RGBA{70, 210, 200, 255} @@ -98,14 +94,13 @@ func TestColorDialog_SetColor(t *testing.T) { assert.Equal(t, 244, d.picker.Alpha) d.Show() - w.Close() } func TestColorDialogSimple_Theme(t *testing.T) { test.NewApp() defer test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(600, 400)) d := NewColorPicker("Color Picker", "Pick a Color", nil, w) @@ -115,8 +110,6 @@ func TestColorDialogSimple_Theme(t *testing.T) { test.ApplyTheme(t, test.NewTheme()) test.AssertRendersToImage(t, "color/dialog_simple_theme_ugly.png", w.Canvas()) - - w.Close() } func TestColorDialogSimple_Recents(t *testing.T) { @@ -126,7 +119,7 @@ func TestColorDialogSimple_Recents(t *testing.T) { // Inject recent preferences a.Preferences().SetString("color_recents", "#2196f3,#4caf50,#f44336") - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(600, 400)) d := NewColorPicker("Color Picker", "Pick a Color", nil, w) @@ -136,8 +129,6 @@ func TestColorDialogSimple_Recents(t *testing.T) { test.ApplyTheme(t, test.NewTheme()) test.AssertRendersToImage(t, "color/dialog_simple_recents_theme_ugly.png", w.Canvas()) - - w.Close() } func Test_recent_color(t *testing.T) { diff --git a/dialog/color_wheel_test.go b/dialog/color_wheel_test.go index 39d85036b5..dd2b35e0a8 100644 --- a/dialog/color_wheel_test.go +++ b/dialog/color_wheel_test.go @@ -13,11 +13,9 @@ func Test_colorWheel_Layout(t *testing.T) { wheel := newColorWheel(nil) wheel.SetHSLA(180, 100, 50, 255) - window := test.NewWindow(wheel) + window := test.NewTempWindow(t, wheel) window.Resize(wheel.MinSize().Max(fyne.NewSize(100, 100))) test.AssertRendersToImage(t, "color/wheel_layout.png", window.Canvas()) test.AssertRendersToMarkup(t, "color/wheel_layout.xml", window.Canvas()) - - window.Close() } diff --git a/dialog/confirm_test.go b/dialog/confirm_test.go index fba7ab22c6..b4b88adf73 100644 --- a/dialog/confirm_test.go +++ b/dialog/confirm_test.go @@ -17,7 +17,7 @@ func TestDialog_ConfirmDoubleCallback(t *testing.T) { ch := make(chan int) cnf := NewConfirm("Test", "Test", func(_ bool) { ch <- 42 - }, test.NewWindow(nil)) + }, test.NewTempWindow(t, nil)) cnf.SetDismissText("No") cnf.SetConfirmText("Yes") cnf.SetOnClosed(func() { @@ -34,7 +34,7 @@ func TestDialog_ConfirmDoubleCallback(t *testing.T) { func TestDialog_ConfirmCallbackOnlyOnClosed(t *testing.T) { ch := make(chan int) - cnf := NewConfirm("Test", "Test", nil, test.NewWindow(nil)) + cnf := NewConfirm("Test", "Test", nil, test.NewTempWindow(t, nil)) cnf.SetDismissText("No") cnf.SetConfirmText("Yes") cnf.SetOnClosed(func() { @@ -52,7 +52,7 @@ func TestDialog_ConfirmCallbackOnlyOnConfirm(t *testing.T) { ch := make(chan int) cnf := NewConfirm("Test", "Test", func(_ bool) { ch <- 42 - }, test.NewWindow(nil)) + }, test.NewTempWindow(t, nil)) cnf.SetDismissText("No") cnf.SetConfirmText("Yes") cnf.Show() @@ -65,8 +65,8 @@ func TestDialog_ConfirmCallbackOnlyOnConfirm(t *testing.T) { func TestConfirmDialog_Resize(t *testing.T) { window := test.NewWindow(nil) - window.Resize(fyne.NewSize(600, 400)) defer window.Close() + window.Resize(fyne.NewSize(600, 400)) d := NewConfirm("Test", "Test", nil, window) theDialog := d.dialog @@ -109,7 +109,7 @@ func TestConfirmDialog_Resize(t *testing.T) { func TestConfirm_Importance(t *testing.T) { test.NewApp() defer test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) size := fyne.NewSize(200, 300) w.Resize(size) diff --git a/dialog/custom_test.go b/dialog/custom_test.go index d94b016a63..fc525d4a54 100644 --- a/dialog/custom_test.go +++ b/dialog/custom_test.go @@ -17,7 +17,7 @@ func TestShowCustom_ApplyTheme(t *testing.T) { test.NewApp() defer test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) label := widget.NewLabel("Content") label.Alignment = fyne.TextAlignCenter @@ -36,7 +36,7 @@ func TestShowCustom_ApplyTheme(t *testing.T) { } func TestShowCustom_Resize(t *testing.T) { - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(300, 300)) label := widget.NewLabel("Content") @@ -52,7 +52,7 @@ func TestShowCustom_Resize(t *testing.T) { func TestCustom_ApplyThemeOnShow(t *testing.T) { test.NewApp() defer test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(200, 300)) label := widget.NewLabel("Content") @@ -78,7 +78,7 @@ func TestCustom_ApplyThemeOnShow(t *testing.T) { func TestCustom_ResizeOnShow(t *testing.T) { test.NewApp() defer test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) size := fyne.NewSize(200, 300) w.Resize(size) @@ -100,7 +100,7 @@ func TestCustom_ResizeOnShow(t *testing.T) { func TestConfirm_SetButtons(t *testing.T) { test.NewApp() defer test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) size := fyne.NewSize(200, 300) w.Resize(size) @@ -123,7 +123,7 @@ func TestConfirm_SetButtons(t *testing.T) { func TestConfirmWithoutButtons(t *testing.T) { test.NewApp() defer test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) size := fyne.NewSize(200, 300) w.Resize(size) @@ -136,7 +136,7 @@ func TestConfirmWithoutButtons(t *testing.T) { func TestCustomConfirm_Importance(t *testing.T) { test.NewApp() defer test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) size := fyne.NewSize(200, 300) w.Resize(size) diff --git a/dialog/entry_test.go b/dialog/entry_test.go index 329ddb3977..d53e80fcdf 100644 --- a/dialog/entry_test.go +++ b/dialog/entry_test.go @@ -11,7 +11,7 @@ func TestEntryDialog_Confirm(t *testing.T) { value := "" ed := NewEntryDialog("Test", "message", func(v string) { value = v - }, test.NewWindow(nil)) + }, test.NewTempWindow(t, nil)) ed.Show() test.Type(ed.entry, "123") test.Tap(ed.confirm) @@ -23,7 +23,7 @@ func TestEntryDialog_Dismiss(t *testing.T) { value := "123" ed := NewEntryDialog("Test", "message", func(v string) { value = v - }, test.NewWindow(nil)) + }, test.NewTempWindow(t, nil)) ed.Show() test.Type(ed.entry, "XYZ") test.Tap(ed.cancel) diff --git a/dialog/file_test.go b/dialog/file_test.go index 0c67fe767a..5df7519873 100644 --- a/dialog/file_test.go +++ b/dialog/file_test.go @@ -108,7 +108,7 @@ func TestEffectiveStartingDir(t *testing.T) { } func TestFileDialogResize(t *testing.T) { - win := test.NewWindow(widget.NewLabel("Content")) + win := test.NewTempWindow(t, widget.NewLabel("Content")) win.Resize(fyne.NewSize(600, 400)) file := NewFileOpen(func(file fyne.URIReadCloser, err error) {}, win) file.SetFilter(storage.NewExtensionFileFilter([]string{".png"})) @@ -161,7 +161,7 @@ func TestFileDialogResize(t *testing.T) { func TestShowFileOpen(t *testing.T) { var chosen fyne.URIReadCloser var openErr error - win := test.NewWindow(widget.NewLabel("Content")) + win := test.NewTempWindow(t, widget.NewLabel("Content")) d := NewFileOpen(func(file fyne.URIReadCloser, err error) { chosen = file openErr = err @@ -260,7 +260,7 @@ func TestHiddenFiles(t *testing.T) { t.Error("Failed to hide .hidden", err) } - win := test.NewWindow(widget.NewLabel("Content")) + win := test.NewTempWindow(t, widget.NewLabel("Content")) d := NewFileOpen(func(file fyne.URIReadCloser, err error) { }, win) d.SetLocation(dir) @@ -310,7 +310,7 @@ func TestHiddenFiles(t *testing.T) { func TestShowFileSave(t *testing.T) { var chosen fyne.URIWriteCloser var saveErr error - win := test.NewWindow(widget.NewLabel("Content")) + win := test.NewTempWindow(t, widget.NewLabel("Content")) saver := NewFileSave(func(file fyne.URIWriteCloser, err error) { chosen = file saveErr = err @@ -386,7 +386,7 @@ func TestShowFileSave(t *testing.T) { } func TestFileFilters(t *testing.T) { - win := test.NewWindow(widget.NewLabel("Content")) + win := test.NewTempWindow(t, widget.NewLabel("Content")) f := NewFileOpen(func(file fyne.URIReadCloser, err error) { }, win) @@ -449,7 +449,7 @@ func TestFileFilters(t *testing.T) { } func TestView(t *testing.T) { - win := test.NewWindow(widget.NewLabel("Content")) + win := test.NewTempWindow(t, widget.NewLabel("Content")) dlg := NewFileOpen(func(reader fyne.URIReadCloser, err error) { assert.Nil(t, err) @@ -506,7 +506,7 @@ func TestView(t *testing.T) { } func TestSetView(t *testing.T) { - win := test.NewWindow(widget.NewLabel("Content")) + win := test.NewTempWindow(t, widget.NewLabel("Content")) fyne.CurrentApp().Preferences().SetInt(viewLayoutKey, int(defaultView)) @@ -556,7 +556,7 @@ func TestSetView(t *testing.T) { } func TestSetViewPreferences(t *testing.T) { - win := test.NewWindow(widget.NewLabel("Content")) + win := test.NewTempWindow(t, widget.NewLabel("Content")) prefs := fyne.CurrentApp().Preferences() @@ -590,7 +590,7 @@ func TestSetViewPreferences(t *testing.T) { } func TestViewPreferences(t *testing.T) { - win := test.NewWindow(widget.NewLabel("Content")) + win := test.NewTempWindow(t, widget.NewLabel("Content")) prefs := fyne.CurrentApp().Preferences() @@ -631,7 +631,7 @@ func TestViewPreferences(t *testing.T) { } func TestFileFavorites(t *testing.T) { - win := test.NewWindow(widget.NewLabel("Content")) + win := test.NewTempWindow(t, widget.NewLabel("Content")) dlg := NewFileOpen(func(reader fyne.URIReadCloser, err error) { assert.Nil(t, err) @@ -676,7 +676,7 @@ func TestFileFavorites(t *testing.T) { } func TestSetFileNameBeforeShow(t *testing.T) { - win := test.NewWindow(widget.NewLabel("Content")) + win := test.NewTempWindow(t, widget.NewLabel("Content")) dSave := NewFileSave(func(fyne.URIWriteCloser, error) {}, win) dSave.SetFileName("testfile.zip") dSave.Show() @@ -694,7 +694,7 @@ func TestSetFileNameBeforeShow(t *testing.T) { func TestSetFileNameAfterShow(t *testing.T) { - win := test.NewWindow(widget.NewLabel("Content")) + win := test.NewTempWindow(t, widget.NewLabel("Content")) dSave := NewFileSave(func(fyne.URIWriteCloser, error) {}, win) dSave.Show() dSave.SetFileName("testfile.zip") @@ -711,7 +711,7 @@ func TestSetFileNameAfterShow(t *testing.T) { } func TestCreateNewFolderInDir(t *testing.T) { - win := test.NewWindow(widget.NewLabel("Content")) + win := test.NewTempWindow(t, widget.NewLabel("Content")) folderDialog := NewFolderOpen(func(lu fyne.ListableURI, err error) { assert.Nil(t, err) @@ -757,7 +757,7 @@ func TestCreateNewFolderInDir(t *testing.T) { } func TestSetOnClosedBeforeShow(t *testing.T) { - win := test.NewWindow(widget.NewLabel("Content")) + win := test.NewTempWindow(t, widget.NewLabel("Content")) d := NewFileSave(func(fyne.URIWriteCloser, error) {}, win) onClosedCalled := false d.SetOnClosed(func() { onClosedCalled = true }) diff --git a/dialog/folder_test.go b/dialog/folder_test.go index 768caf9ac5..887bf5a754 100644 --- a/dialog/folder_test.go +++ b/dialog/folder_test.go @@ -16,7 +16,7 @@ import ( func TestShowFolderOpen(t *testing.T) { var chosen fyne.ListableURI var openErr error - win := test.NewWindow(widget.NewLabel("OpenDir")) + win := test.NewTempWindow(t, widget.NewLabel("OpenDir")) d := NewFolderOpen(func(file fyne.ListableURI, err error) { chosen = file openErr = err diff --git a/dialog/form_test.go b/dialog/form_test.go index 5c7074319f..339d41db0a 100644 --- a/dialog/form_test.go +++ b/dialog/form_test.go @@ -25,7 +25,7 @@ const ( func TestFormDialog_Control(t *testing.T) { var result formDialogResult - fd := controlFormDialog(&result, test.NewWindow(nil)) + fd := controlFormDialog(&result, test.NewTempWindow(t, nil)) fd.Show() test.Tap(fd.confirm) @@ -34,7 +34,7 @@ func TestFormDialog_Control(t *testing.T) { func TestFormDialog_InvalidCannotSubmit(t *testing.T) { var result formDialogResult - fd := validatingFormDialog(&result, test.NewWindow(nil)) + fd := validatingFormDialog(&result, test.NewTempWindow(t, nil)) fd.Show() assert.False(t, fd.win.Hidden) @@ -46,7 +46,7 @@ func TestFormDialog_InvalidCannotSubmit(t *testing.T) { func TestFormDialog_ValidCanSubmit(t *testing.T) { var result formDialogResult - fd := validatingFormDialog(&result, test.NewWindow(nil)) + fd := validatingFormDialog(&result, test.NewTempWindow(t, nil)) fd.Show() assert.False(t, fd.win.Hidden) @@ -65,7 +65,7 @@ func TestFormDialog_ValidCanSubmit(t *testing.T) { func TestFormDialog_CanCancelInvalid(t *testing.T) { var result formDialogResult - fd := validatingFormDialog(&result, test.NewWindow(nil)) + fd := validatingFormDialog(&result, test.NewTempWindow(t, nil)) fd.Show() assert.False(t, fd.win.Hidden) @@ -76,7 +76,7 @@ func TestFormDialog_CanCancelInvalid(t *testing.T) { func TestFormDialog_CanCancelNoValidation(t *testing.T) { var result formDialogResult - fd := controlFormDialog(&result, test.NewWindow(nil)) + fd := controlFormDialog(&result, test.NewTempWindow(t, nil)) fd.Show() assert.False(t, fd.win.Hidden) @@ -90,7 +90,7 @@ func TestFormDialog_Hints(t *testing.T) { test.NewApp() defer test.NewApp() test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) - w := test.NewWindow(nil) + w := test.NewTempWindow(t, nil) w.SetFullScreen(true) var result formDialogResult @@ -136,7 +136,7 @@ func TestFormDialog_Submit(t *testing.T) { items := []*widget.FormItem{validatingItem} form := NewForm("Validating Form Dialog", "Submit", "Cancel", items, func(confirm bool) { confirmed = confirm - }, test.NewWindow(nil)) + }, test.NewTempWindow(t, nil)) form.Show() validatingEntry.SetText("cba") diff --git a/dialog/information_test.go b/dialog/information_test.go index c1fc2c4c76..285e4c187b 100644 --- a/dialog/information_test.go +++ b/dialog/information_test.go @@ -65,7 +65,7 @@ func TestDialog_Resize(t *testing.T) { } func TestDialog_TextWrapping(t *testing.T) { - window := test.NewWindow(nil) + window := test.NewTempWindow(t, nil) window.Resize(fyne.NewSize(600, 400)) d := NewInformation("Title", "This is a really really long message that will be used to test the dialog text wrapping capabilities", window) @@ -84,7 +84,7 @@ func TestDialog_TextWrapping(t *testing.T) { } func TestDialog_InformationCallback(t *testing.T) { - d := NewInformation("Information", "Hello World", test.NewWindow(nil)) + d := NewInformation("Information", "Hello World", test.NewTempWindow(t, nil)) tapped := false d.SetOnClosed(func() { tapped = true }) d.Show() @@ -98,7 +98,7 @@ func TestDialog_InformationCallback(t *testing.T) { func TestDialog_ErrorCallback(t *testing.T) { err := errors.New("Error message") - d := NewError(err, test.NewWindow(nil)) + d := NewError(err, test.NewTempWindow(t, nil)) tapped := false d.SetOnClosed(func() { tapped = true }) d.Show() diff --git a/internal/widget/simple_renderer_test.go b/internal/widget/simple_renderer_test.go index 6445ea097f..d738af19c0 100644 --- a/internal/widget/simple_renderer_test.go +++ b/internal/widget/simple_renderer_test.go @@ -14,7 +14,7 @@ func TestNewSimpleRenderer(t *testing.T) { r := canvas.NewRectangle(color.Transparent) o := &simpleWidget{obj: r} o.ExtendBaseWidget(o) - w := test.NewWindow(o) + w := test.NewTempWindow(t, o) w.Resize(fyne.NewSize(100, 100)) test.AssertRendersToMarkup(t, "simple_renderer.xml", w.Canvas()) diff --git a/test/testwindow.go b/test/testwindow.go index eeee940941..d26c2205f8 100644 --- a/test/testwindow.go +++ b/test/testwindow.go @@ -1,6 +1,8 @@ package test import ( + "testing" + "fyne.io/fyne/v2" ) @@ -18,6 +20,15 @@ type testWindow struct { menu *fyne.MainMenu } +// NewTempWindow creates and registers a new window for test purposes. +// This window will get removed automatically once the test ends. +func NewTempWindow(t testing.TB, content fyne.CanvasObject) fyne.Window { + window := fyne.CurrentApp().NewWindow("") + window.SetContent(content) + t.Cleanup(window.Close) + return window +} + // NewWindow creates and registers a new window for test purposes func NewWindow(content fyne.CanvasObject) fyne.Window { window := fyne.CurrentApp().NewWindow("") diff --git a/widget/accordion_test.go b/widget/accordion_test.go index 68704071c3..a49c5af509 100644 --- a/widget/accordion_test.go +++ b/widget/accordion_test.go @@ -207,12 +207,10 @@ func TestAccordion_Layout(t *testing.T) { accordion.Open(o) } - window := test.NewWindow(&fyne.Container{Layout: layout.NewCenterLayout(), Objects: []fyne.CanvasObject{accordion}}) + window := test.NewTempWindow(t, &fyne.Container{Layout: layout.NewCenterLayout(), Objects: []fyne.CanvasObject{accordion}}) window.Resize(accordion.MinSize().Add(fyne.NewSquareSize(theme.Padding() * 2))) test.AssertRendersToMarkup(t, "accordion/layout_"+name+".xml", window.Canvas()) - - window.Close() }) } } @@ -325,12 +323,10 @@ func TestAccordion_Layout_Expanded(t *testing.T) { accordion.Open(o) } - window := test.NewWindow(&fyne.Container{Layout: layout.NewCenterLayout(), Objects: []fyne.CanvasObject{accordion}}) + window := test.NewTempWindow(t, &fyne.Container{Layout: layout.NewCenterLayout(), Objects: []fyne.CanvasObject{accordion}}) window.Resize(accordion.MinSize().Max(fyne.NewSize(150, 280))) test.AssertRendersToMarkup(t, "accordion/layout_"+name+".xml", window.Canvas()) - - window.Close() }) } } diff --git a/widget/activity_internal_test.go b/widget/activity_internal_test.go index 13372186da..a16c1f22bb 100644 --- a/widget/activity_internal_test.go +++ b/widget/activity_internal_test.go @@ -13,8 +13,8 @@ func TestActivity_Animation(t *testing.T) { a := NewActivity() w := test.NewWindow(a) - w.SetPadded(false) defer w.Close() + w.SetPadded(false) w.Resize(a.MinSize()) render := test.WidgetRenderer(a).(*activityRenderer) diff --git a/widget/card_test.go b/widget/card_test.go index 1765040a63..c95a85439f 100644 --- a/widget/card_test.go +++ b/widget/card_test.go @@ -104,15 +104,13 @@ func TestCard_Layout(t *testing.T) { Content: tt.content, } - window := test.NewWindow(card) + window := test.NewTempWindow(t, card) size := card.MinSize().Max(fyne.NewSize(80, 0)) // give a little width for image only tests window.Resize(size.Add(fyne.NewSize(theme.InnerPadding(), theme.InnerPadding()))) if tt.content != nil { assert.Equal(t, float32(10), tt.content.Size().Height) } test.AssertRendersToMarkup(t, "card/layout_"+name+".xml", window.Canvas()) - - window.Close() }) } } @@ -128,7 +126,7 @@ func TestCard_MinSize(t *testing.T) { func TestCard_Refresh(t *testing.T) { text := widget.NewLabel("Test") card := widget.NewCard("", "", text) - w := test.NewWindow(card) + w := test.NewTempWindow(t, card) test.AssertRendersToMarkup(t, "card/content_label.xml", w.Canvas()) text.Text = "Changed" diff --git a/widget/check_group_test.go b/widget/check_group_test.go index 8605ccb806..584fde8572 100644 --- a/widget/check_group_test.go +++ b/widget/check_group_test.go @@ -154,12 +154,10 @@ func TestCheckGroup_Layout(t *testing.T) { check.Disable() } - window := test.NewWindow(check) + window := test.NewTempWindow(t, check) window.Resize(check.MinSize().Max(fyne.NewSize(150, 200))) test.AssertRendersToMarkup(t, "check_group/layout_"+name+".xml", window.Canvas()) - - window.Close() }) } } diff --git a/widget/check_test.go b/widget/check_test.go index 6b4210e926..dcd9bebb1e 100644 --- a/widget/check_test.go +++ b/widget/check_test.go @@ -72,12 +72,10 @@ func TestCheck_Layout(t *testing.T) { check.Disable() } - window := test.NewWindow(&fyne.Container{Layout: layout.NewCenterLayout(), Objects: []fyne.CanvasObject{check}}) + window := test.NewTempWindow(t, &fyne.Container{Layout: layout.NewCenterLayout(), Objects: []fyne.CanvasObject{check}}) window.Resize(check.MinSize().Max(fyne.NewSize(150, 200))) test.AssertRendersToMarkup(t, "check/layout_"+name+".xml", window.Canvas()) - - window.Close() }) } } diff --git a/widget/entry_internal_test.go b/widget/entry_internal_test.go index 57313ca48f..b770924197 100644 --- a/widget/entry_internal_test.go +++ b/widget/entry_internal_test.go @@ -391,7 +391,7 @@ func TestEntry_PlaceholderTextStyle(t *testing.T) { e := NewEntry() e.TextStyle = fyne.TextStyle{Bold: true, Italic: true} - w := test.NewWindow(e) + w := test.NewTempWindow(t, e) assert.Equal(t, e.TextStyle, e.placeholder.Segments[0].(*TextSegment).Style.TextStyle) w.Canvas().Focus(e) @@ -409,7 +409,7 @@ func TestEntry_Tab(t *testing.T) { assert.Equal(t, "a", r.Objects()[0].(*canvas.Text).Text) assert.Equal(t, "\tb", r.Objects()[1].(*canvas.Text).Text) - w := test.NewWindow(e) + w := test.NewTempWindow(t, e) w.Resize(fyne.NewSize(86, 86)) w.Canvas().Focus(e) test.AssertImageMatches(t, "entry/tab-content.png", w.Canvas().Capture()) @@ -428,7 +428,7 @@ func TestEntry_TabSelection(t *testing.T) { assert.Equal(t, "\tb", e.SelectedText()) - w := test.NewWindow(e) + w := test.NewTempWindow(t, e) w.Resize(fyne.NewSize(86, 86)) w.Canvas().Focus(e) test.AssertImageMatches(t, "entry/tab-select.png", w.Canvas().Capture()) diff --git a/widget/entry_test.go b/widget/entry_test.go index 588ee00bfe..ce56f4c4e6 100644 --- a/widget/entry_test.go +++ b/widget/entry_test.go @@ -78,7 +78,6 @@ func TestEntry_Binding_Replace(t *testing.T) { func TestEntry_Clicked(t *testing.T) { entry, window := setupImageTest(t, true) - defer teardownImageTest(window) c := window.Canvas() entry.SetText("MMM\nWWW\n") @@ -252,7 +251,7 @@ func TestEntry_CursorColumn_Wrap2(t *testing.T) { entry.SetText("1234") entry.CursorColumn = 3 - w := test.NewWindow(entry) + w := test.NewTempWindow(t, entry) w.Resize(fyne.NewSize(72, 64)) test.Type(entry, "a") @@ -302,7 +301,6 @@ func TestEntry_CursorRow(t *testing.T) { func TestEntry_Disableable(t *testing.T) { entry, window := setupImageTest(t, false) - defer teardownImageTest(window) c := window.Canvas() assert.False(t, entry.Disabled()) @@ -343,7 +341,6 @@ func TestEntry_Disableable(t *testing.T) { func TestEntry_Disabled_TextSelection(t *testing.T) { entry, window := setupImageTest(t, false) - defer teardownImageTest(window) entry.SetText("Testing") entry.Disable() c := window.Canvas() @@ -386,7 +383,6 @@ func TestEntry_EmptySelection(t *testing.T) { func TestEntry_Focus(t *testing.T) { entry, window := setupImageTest(t, false) - defer teardownImageTest(window) c := window.Canvas() entry.FocusGained() @@ -401,7 +397,6 @@ func TestEntry_Focus(t *testing.T) { func TestEntry_FocusWithPopUp(t *testing.T) { entry, window := setupImageTest(t, false) - defer teardownImageTest(window) c := window.Canvas() test.TapSecondaryAt(entry, fyne.NewPos(1, 1)) @@ -498,7 +493,6 @@ func TestEntryMultiline_SetMinRowsVisible(t *testing.T) { func TestEntry_MultilineSelect(t *testing.T) { e, window := setupSelection(t, false) - defer teardownImageTest(window) c := window.Canvas() // Extend the selection down one row @@ -817,7 +811,6 @@ func TestEntry_OnKeyDown_Insert(t *testing.T) { func TestEntry_OnKeyDown_Newline(t *testing.T) { entry, window := setupImageTest(t, true) - defer teardownImageTest(window) c := window.Canvas() entry.SetText("Hi") @@ -924,7 +917,6 @@ func TestEntry_OnPaste(t *testing.T) { func TestEntry_PageUpDown(t *testing.T) { t.Run("single line", func(*testing.T) { e, window := setupImageTest(t, false) - defer teardownImageTest(window) c := window.Canvas() c.Focus(e) @@ -955,7 +947,6 @@ func TestEntry_PageUpDown(t *testing.T) { t.Run("page down single line", func(*testing.T) { e, window := setupImageTest(t, true) - defer teardownImageTest(window) c := window.Canvas() c.Focus(e) @@ -1021,8 +1012,8 @@ func TestEntry_Placeholder(t *testing.T) { entry.Text = "Text" entry.PlaceHolder = "Placehold" - window := test.NewWindow(entry) - defer teardownImageTest(window) + window := test.NewTempWindow(t, entry) + defer test.NewApp() c := window.Canvas() assert.Equal(t, "Text", entry.Text) @@ -1175,7 +1166,6 @@ func TestEntry_Select(t *testing.T) { } { t.Run(name, func(t *testing.T) { entry, window := setupSelection(t, tt.setupReverse) - defer teardownImageTest(window) c := window.Canvas() if tt.text != "" { @@ -1192,7 +1182,6 @@ func TestEntry_Select(t *testing.T) { func TestEntry_SelectAll(t *testing.T) { e, window := setupImageTest(t, true) - defer teardownImageTest(window) c := window.Canvas() c.Focus(e) @@ -1215,7 +1204,6 @@ func TestEntry_SelectAll_EmptyEntry(t *testing.T) { func TestEntry_SelectEndWithoutShift(t *testing.T) { e, window := setupSelection(t, false) - defer teardownImageTest(window) c := window.Canvas() // end after releasing shift @@ -1226,7 +1214,6 @@ func TestEntry_SelectEndWithoutShift(t *testing.T) { func TestEntry_SelectHomeEnd(t *testing.T) { e, window := setupSelection(t, false) - defer teardownImageTest(window) c := window.Canvas() // Hold shift to continue selection @@ -1245,7 +1232,6 @@ func TestEntry_SelectHomeEnd(t *testing.T) { func TestEntry_SelectHomeWithoutShift(t *testing.T) { e, window := setupSelection(t, false) - defer teardownImageTest(window) c := window.Canvas() // home after releasing shift @@ -1257,7 +1243,6 @@ func TestEntry_SelectHomeWithoutShift(t *testing.T) { func TestEntry_SelectSnapDown(t *testing.T) { // down snaps to end, but it also moves e, window := setupSelection(t, false) - defer teardownImageTest(window) c := window.Canvas() assert.Equal(t, 1, e.CursorRow) @@ -1272,7 +1257,6 @@ func TestEntry_SelectSnapDown(t *testing.T) { func TestEntry_SelectSnapLeft(t *testing.T) { e, window := setupSelection(t, false) - defer teardownImageTest(window) c := window.Canvas() assert.Equal(t, 1, e.CursorRow) @@ -1287,7 +1271,6 @@ func TestEntry_SelectSnapLeft(t *testing.T) { func TestEntry_SelectSnapRight(t *testing.T) { e, window := setupSelection(t, false) - defer teardownImageTest(window) c := window.Canvas() assert.Equal(t, 1, e.CursorRow) @@ -1303,7 +1286,6 @@ func TestEntry_SelectSnapRight(t *testing.T) { func TestEntry_SelectSnapUp(t *testing.T) { // up snaps to start, but it also moves e, window := setupSelection(t, false) - defer teardownImageTest(window) c := window.Canvas() assert.Equal(t, 1, e.CursorRow) @@ -1329,7 +1311,6 @@ func TestEntry_Select_TripleTap(t *testing.T) { func TestEntry_SelectedText(t *testing.T) { e, window := setupImageTest(t, false) - defer teardownImageTest(window) c := window.Canvas() c.Focus(e) @@ -1362,7 +1343,6 @@ func TestEntry_SelectedText(t *testing.T) { func TestEntry_SelectionHides(t *testing.T) { e, window := setupSelection(t, false) - defer teardownImageTest(window) c := window.Canvas() c.Unfocus() @@ -1376,7 +1356,6 @@ func TestEntry_SelectionHides(t *testing.T) { func TestEntry_SetPlaceHolder(t *testing.T) { entry, window := setupImageTest(t, false) - defer teardownImageTest(window) c := window.Canvas() assert.Equal(t, 0, len(entry.Text)) @@ -1392,7 +1371,6 @@ func TestEntry_SetPlaceHolder(t *testing.T) { func TestEntry_SetPlaceHolder_ByField(t *testing.T) { entry, window := setupImageTest(t, false) - defer teardownImageTest(window) c := window.Canvas() assert.Equal(t, 0, len(entry.Text)) @@ -1422,7 +1400,6 @@ func TestEntry_Disable_KeyDown(t *testing.T) { func TestEntry_Disable_OnFocus(t *testing.T) { entry, window := setupImageTest(t, false) - defer teardownImageTest(window) c := window.Canvas() entry.Disable() @@ -1459,7 +1436,6 @@ func TestEntry_SetText_EmptyString(t *testing.T) { func TestEntry_SetText_Manual(t *testing.T) { entry, window := setupImageTest(t, false) - defer teardownImageTest(window) c := window.Canvas() entry.Text = "Test" @@ -1525,7 +1501,6 @@ func TestEntry_SetText_Overflow_Multiline(t *testing.T) { func TestEntry_SetTextStyle(t *testing.T) { entry, window := setupImageTest(t, false) - defer teardownImageTest(window) c := window.Canvas() entry.Text = "Styled Text" @@ -1665,7 +1640,6 @@ func TestTabable(t *testing.T) { func TestEntry_TappedSecondary(t *testing.T) { entry, window := setupImageTest(t, false) - defer teardownImageTest(window) c := window.Canvas() tapPos := fyne.NewPos(20, 10) @@ -1746,7 +1720,6 @@ func TestEntry_TextWrap(t *testing.T) { } { t.Run(name, func(t *testing.T) { e, window := setupImageTest(t, tt.multiLine) - defer teardownImageTest(window) c := window.Canvas() c.Focus(e) @@ -1764,7 +1737,6 @@ func TestEntry_TextWrap(t *testing.T) { func TestEntry_TextWrap_Changed(t *testing.T) { e, window := setupImageTest(t, false) - defer teardownImageTest(window) c := window.Canvas() c.Focus(e) @@ -1824,8 +1796,7 @@ func TestPasswordEntry_ActionItemSizeAndPlacement(t *testing.T) { } func TestPasswordEntry_Disabled(t *testing.T) { - entry, window := setupPasswordTest(t) - defer teardownImageTest(window) + entry, _ := setupPasswordTest(t) entry.Disable() test.Tap(entry.ActionItem.(fyne.Tappable)) @@ -1845,7 +1816,6 @@ func TestPasswordEntry_NewlineIgnored(t *testing.T) { func TestPasswordEntry_Obfuscation(t *testing.T) { entry, window := setupPasswordTest(t) - defer teardownImageTest(window) c := window.Canvas() test.Type(entry, "Hié™שרה") @@ -1855,7 +1825,6 @@ func TestPasswordEntry_Obfuscation(t *testing.T) { func TestPasswordEntry_Placeholder(t *testing.T) { entry, window := setupPasswordTest(t) - defer teardownImageTest(window) c := window.Canvas() test.AssertRendersToMarkup(t, "password_entry/initial.xml", window.Canvas()) @@ -1977,7 +1946,7 @@ func TestEntry_CarriageReturn(t *testing.T) { entry.Wrapping = fyne.TextWrapOff entry.Scroll = container.ScrollNone entry.SetText("\r\n\r") - w := test.NewWindow(entry) + w := test.NewTempWindow(t, entry) w.Resize(fyne.NewSize(64, 64)) test.AssertImageMatches(t, "entry/carriage_return_empty.png", w.Canvas().Capture()) entry.SetText("\rH\re\rl\rl\ro\r\n\rW\ro\rr\rl\rd\r!\r") @@ -1987,7 +1956,6 @@ func TestEntry_CarriageReturn(t *testing.T) { func TestEntry_UndoRedo(t *testing.T) { e, window := setupImageTest(t, true) window.Resize(fyne.NewSize(128, 128)) - defer teardownImageTest(window) c := window.Canvas() c.Focus(e) @@ -2077,6 +2045,7 @@ func checkNewlineIgnored(t *testing.T, entry *widget.Entry) { func setupImageTest(t *testing.T, multiLine bool) (*widget.Entry, fyne.Window) { test.NewApp() + t.Cleanup(func() { test.NewApp() }) var entry *widget.Entry if multiLine { @@ -2084,7 +2053,7 @@ func setupImageTest(t *testing.T, multiLine bool) (*widget.Entry, fyne.Window) { } else { entry = &widget.Entry{Wrapping: fyne.TextWrapOff, Scroll: container.ScrollNone} } - w := test.NewWindow(entry) + w := test.NewTempWindow(t, entry) w.Resize(fyne.NewSize(150, 200)) if multiLine { @@ -2105,9 +2074,10 @@ func setupImageTest(t *testing.T, multiLine bool) (*widget.Entry, fyne.Window) { func setupPasswordTest(t *testing.T) (*widget.Entry, fyne.Window) { test.NewApp() + t.Cleanup(func() { test.NewApp() }) entry := widget.NewPasswordEntry() - w := test.NewWindow(entry) + w := test.NewTempWindow(t, entry) w.Resize(fyne.NewSize(150, 100)) entry.Resize(entry.MinSize().Max(fyne.NewSize(130, 0))) @@ -2142,11 +2112,6 @@ func setupSelection(t *testing.T, reverse bool) (*widget.Entry, fyne.Window) { return e, window } -func teardownImageTest(w fyne.Window) { - w.Close() - test.NewApp() -} - func waitForBinding() { time.Sleep(time.Millisecond * 100) // data resolves on background thread } diff --git a/widget/entry_validation_test.go b/widget/entry_validation_test.go index b8f4aa1509..ac05c61c59 100644 --- a/widget/entry_validation_test.go +++ b/widget/entry_validation_test.go @@ -17,7 +17,6 @@ var validator = validation.NewRegexp(`^\d{4}-\d{2}-\d{2}$`, "Input is not a vali func TestEntry_DisabledHideValidation(t *testing.T) { entry, window := setupImageTest(t, false) - defer teardownImageTest(window) c := window.Canvas() entry.Validator = validator @@ -29,7 +28,6 @@ func TestEntry_DisabledHideValidation(t *testing.T) { func TestEntry_ValidatedEntry(t *testing.T) { entry, window := setupImageTest(t, false) - defer teardownImageTest(window) c := window.Canvas() r := validation.NewRegexp(`^\d{4}-\d{2}-\d{2}`, "Input is not a valid date") @@ -73,8 +71,7 @@ func TestEntry_NotEmptyValidator(t *testing.T) { } return nil } - w := test.NewWindow(entry) - defer w.Close() + w := test.NewTempWindow(t, entry) test.AssertRendersToMarkup(t, "entry/validator_not_empty_initial.xml", w.Canvas()) @@ -90,7 +87,6 @@ func TestEntry_NotEmptyValidator(t *testing.T) { func TestEntry_SetValidationError(t *testing.T) { entry, window := setupImageTest(t, false) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) - defer teardownImageTest(window) c := window.Canvas() entry.Validator = validator diff --git a/widget/fileicon_test.go b/widget/fileicon_test.go index a655e39e41..9de6632883 100644 --- a/widget/fileicon_test.go +++ b/widget/fileicon_test.go @@ -27,7 +27,7 @@ func TestFileIcon_NewFileIcon_Rendered(t *testing.T) { icon := widget.NewFileIcon(nil) - w := test.NewWindow(icon) + w := test.NewTempWindow(t, icon) w.Resize(fyne.NewSize(150, 150)) test.AssertImageMatches(t, "fileicon/fileicon_nil.png", w.Canvas().Capture()) @@ -59,8 +59,6 @@ func TestFileIcon_NewFileIcon_Rendered(t *testing.T) { w.SetContent(icon5) w.Resize(fyne.NewSize(150, 150)) test.AssertImageMatches(t, "fileicon/fileicon_folder.png", w.Canvas().Capture()) - - w.Close() } func TestFileIcon_Icon(t *testing.T) { diff --git a/widget/form_test.go b/widget/form_test.go index efa32a0e07..acf73f3013 100644 --- a/widget/form_test.go +++ b/widget/form_test.go @@ -212,12 +212,12 @@ func TestForm_Validation(t *testing.T) { test.Type(entry2, "not-") entry1.SetText("incorrect") - w = test.NewWindow(form) + w = test.NewTempWindow(t, form) test.AssertImageMatches(t, "form/validation_invalid.png", w.Canvas().Capture()) entry1.SetText("15-true") - w = test.NewWindow(form) + w = test.NewTempWindow(t, form) test.AssertImageMatches(t, "form/validation_valid.png", w.Canvas().Capture()) } @@ -251,13 +251,13 @@ func TestForm_EntryValidation_FirstTypeValid(t *testing.T) { test.Type(entry2, "L") entry1.focused = false entry1.Refresh() - w = test.NewWindow(form) + w = test.NewTempWindow(t, form) test.AssertImageMatches(t, "form/validation_entry_first_type_valid.png", w.Canvas().Capture()) entry1.SetText("") entry2.SetText("") - w = test.NewWindow(form) + w = test.NewTempWindow(t, form) test.AssertImageMatches(t, "form/validation_entry_first_type_invalid.png", w.Canvas().Capture()) } diff --git a/widget/hyperlink_test.go b/widget/hyperlink_test.go index 03bbe7048d..6a6fbbaeed 100644 --- a/widget/hyperlink_test.go +++ b/widget/hyperlink_test.go @@ -79,8 +79,8 @@ func TestHyperlink_Focus(t *testing.T) { hyperlink := &Hyperlink{Text: "Test"} w := test.NewWindow(hyperlink) - w.SetPadded(false) defer w.Close() + w.SetPadded(false) w.Resize(hyperlink.MinSize()) test.AssertImageMatches(t, "hyperlink/initial.png", w.Canvas().Capture()) @@ -175,8 +175,8 @@ func TestHyperlink_ThemeOverride(t *testing.T) { bg := canvas.NewRectangle(color.Gray{Y: 0xc0}) w := test.NewWindow(&fyne.Container{Layout: layout.NewStackLayout(), Objects: []fyne.CanvasObject{bg, hyperlink}}) - w.SetPadded(false) defer w.Close() + w.SetPadded(false) w.Resize(hyperlink.MinSize()) light := w.Canvas().Capture() diff --git a/widget/icon_test.go b/widget/icon_test.go index b4c369326d..42b168294a 100644 --- a/widget/icon_test.go +++ b/widget/icon_test.go @@ -27,12 +27,10 @@ func TestIcon_Layout(t *testing.T) { Resource: tt.resource, } - window := test.NewWindow(&fyne.Container{Layout: layout.NewCenterLayout(), Objects: []fyne.CanvasObject{icon}}) + window := test.NewTempWindow(t, &fyne.Container{Layout: layout.NewCenterLayout(), Objects: []fyne.CanvasObject{icon}}) window.Resize(icon.MinSize().Max(fyne.NewSize(150, 200))) test.AssertRendersToMarkup(t, "icon/layout_"+name+".xml", window.Canvas()) - - window.Close() }) } } diff --git a/widget/list_test.go b/widget/list_test.go index 74f2019ece..4d0c11c9ff 100644 --- a/widget/list_test.go +++ b/widget/list_test.go @@ -126,7 +126,7 @@ func TestList_SetItemHeight(t *testing.T) { assert.Equal(t, fyne.NewSize(10, 10*5+(4*theme.Padding())+40), lay.MinSize()) list.Select(2) - w := test.NewWindow(list) + w := test.NewTempWindow(t, list) w.Resize(fyne.NewSize(200, 200)) test.AssertImageMatches(t, "list/list_item_height.png", w.Canvas().Capture()) } @@ -161,7 +161,7 @@ func TestList_OffsetChange(t *testing.T) { defer test.NewApp() list := createList(1000) - w := test.NewWindow(list) + w := test.NewTempWindow(t, list) w.Resize(fyne.NewSize(200, 400)) assert.Equal(t, float32(0), list.offsetY) @@ -406,7 +406,7 @@ func TestList_SmallList(t *testing.T) { item.(*fyne.Container).Objects[1].(*Label).SetText(data[id]) }, ) - w := test.NewWindow(list) + w := test.NewTempWindow(t, list) w.Resize(fyne.NewSize(200, 400)) visibleCount := len(list.scroller.Content.(*fyne.Container).Layout.(*listLayout).children) @@ -457,7 +457,7 @@ func TestList_RemoveItem(t *testing.T) { item.(*fyne.Container).Objects[1].(*Label).SetText(data[id]) }, ) - w := test.NewWindow(list) + w := test.NewTempWindow(t, list) w.Resize(fyne.NewSize(200, 400)) visibleCount := len(list.scroller.Content.(*fyne.Container).Layout.(*listLayout).children) @@ -491,7 +491,7 @@ func TestList_ScrollThenShrink(t *testing.T) { item.(*Label).SetText(data[id]) }, ) - w := test.NewWindow(list) + w := test.NewTempWindow(t, list) w.Resize(fyne.NewSize(300, 300)) visibles := list.scroller.Content.(*fyne.Container).Layout.(*listLayout).children @@ -531,7 +531,7 @@ func TestList_ScrollThenResizeWindow(t *testing.T) { item.(*Label).SetText(data[id]) }, ) - w := test.NewWindow(list) + w := test.NewTempWindow(t, list) w.Resize(fyne.NewSize(300, 300)) list.scroller.ScrollToBottom() @@ -547,7 +547,7 @@ func TestList_ScrollThenResizeWindow(t *testing.T) { func TestList_NoFunctionsSet(t *testing.T) { list := &List{} - w := test.NewWindow(list) + w := test.NewTempWindow(t, list) w.Resize(fyne.NewSize(200, 400)) list.Refresh() } @@ -620,7 +620,7 @@ func changeData(list *List) { func setupList(t *testing.T) (*List, fyne.Window) { test.NewApp() list := createList(1000) - w := test.NewWindow(list) + w := test.NewTempWindow(t, list) w.Resize(fyne.NewSize(200, 400)) test.AssertRendersToMarkup(t, "list/initial.xml", w.Canvas()) return list, w diff --git a/widget/popup_menu_desktop_test.go b/widget/popup_menu_desktop_test.go index beddddfebe..98d756bfaa 100644 --- a/widget/popup_menu_desktop_test.go +++ b/widget/popup_menu_desktop_test.go @@ -14,8 +14,7 @@ import ( func TestPopUpMenu_KeyboardControl(t *testing.T) { var lastTriggered string - m, w := setupPopUpMenuWithSubmenusTest(func(triggered string) { lastTriggered = triggered }) - defer tearDownPopUpMenuTest(w) + m, w := setupPopUpMenuWithSubmenusTest(t, func(triggered string) { lastTriggered = triggered }) c := w.Canvas() m.ShowAtPosition(fyne.NewPos(13, 45)) diff --git a/widget/popup_menu_test.go b/widget/popup_menu_test.go index bd1bec1dc5..b6b2018d2d 100644 --- a/widget/popup_menu_test.go +++ b/widget/popup_menu_test.go @@ -13,8 +13,7 @@ import ( ) func TestPopUpMenu_Move(t *testing.T) { - m, w := setupPopUpMenuTest() - defer tearDownPopUpMenuTest(w) + m, w := setupPopUpMenuTest(t) c := w.Canvas() m.Show() @@ -31,8 +30,7 @@ func TestPopUpMenu_Move(t *testing.T) { } func TestPopUpMenu_Resize(t *testing.T) { - m, w := setupPopUpMenuTest() - defer tearDownPopUpMenuTest(w) + m, w := setupPopUpMenuTest(t) c := w.Canvas() m.ShowAtPosition(fyne.NewPos(10, 10)) @@ -48,8 +46,7 @@ func TestPopUpMenu_Resize(t *testing.T) { } func TestPopUpMenu_Show(t *testing.T) { - m, w := setupPopUpMenuTest() - defer tearDownPopUpMenuTest(w) + m, w := setupPopUpMenuTest(t) c := w.Canvas() test.AssertRendersToMarkup(t, "popup_menu/hidden.xml", c) @@ -59,8 +56,7 @@ func TestPopUpMenu_Show(t *testing.T) { } func TestPopUpMenu_ShowAtPosition(t *testing.T) { - m, w := setupPopUpMenuTest() - defer tearDownPopUpMenuTest(w) + m, w := setupPopUpMenuTest(t) c := w.Canvas() test.AssertRendersToMarkup(t, "popup_menu/hidden.xml", c) @@ -90,10 +86,12 @@ func TestPopUpMenu_ShowAtPosition(t *testing.T) { assert.Equal(t, fyne.NewSize(menuSize.Width, c.Size().Height), m.Size(), "width is larger than canvas; height is limited by canvas (menu scrolls)") } -func setupPopUpMenuTest() (*widget.PopUpMenu, fyne.Window) { +func setupPopUpMenuTest(t *testing.T) (*widget.PopUpMenu, fyne.Window) { test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.NRGBA{G: 150, B: 150, A: 255})) + w := test.NewTempWindow(t, canvas.NewRectangle(color.NRGBA{G: 150, B: 150, A: 255})) + t.Cleanup(func() { test.NewApp() }) + w.Resize(fyne.NewSize(200, 200)) m := widget.NewPopUpMenu(fyne.NewMenu( "", @@ -103,10 +101,12 @@ func setupPopUpMenuTest() (*widget.PopUpMenu, fyne.Window) { return m, w } -func setupPopUpMenuWithSubmenusTest(callback func(string)) (*widget.PopUpMenu, fyne.Window) { +func setupPopUpMenuWithSubmenusTest(t *testing.T, callback func(string)) (*widget.PopUpMenu, fyne.Window) { test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.NRGBA{G: 150, B: 150, A: 255})) + w := test.NewTempWindow(t, canvas.NewRectangle(color.NRGBA{G: 150, B: 150, A: 255})) + t.Cleanup(func() { test.NewApp() }) + w.Resize(fyne.NewSize(800, 600)) itemA := fyne.NewMenuItem("Option A", func() { callback("Option A") }) itemB := fyne.NewMenuItem("Option B", func() { callback("Option B") }) @@ -119,8 +119,3 @@ func setupPopUpMenuWithSubmenusTest(callback func(string)) (*widget.PopUpMenu, f m := widget.NewPopUpMenu(fyne.NewMenu("", itemA, itemB), w.Canvas()) return m, w } - -func tearDownPopUpMenuTest(w fyne.Window) { - w.Close() - test.NewApp() -} diff --git a/widget/popup_test.go b/widget/popup_test.go index 8a955ec236..9f0a824366 100644 --- a/widget/popup_test.go +++ b/widget/popup_test.go @@ -33,7 +33,7 @@ func TestShowPopUp(t *testing.T) { test.NewApp() defer test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(200, 200)) require.Nil(t, w.Canvas().Overlays().Top()) @@ -69,8 +69,8 @@ func TestShowPopUpAtRelativePosition(t *testing.T) { label := NewLabel("Hi") parent1 := NewLabel("Parent1") parent2 := NewLabel("Parent2") - w := test.NewWindow( - &fyne.Container{Layout: layout.NewVBoxLayout(), Objects: []fyne.CanvasObject{parent1, parent2}}) + w := test.NewTempWindow( + t, &fyne.Container{Layout: layout.NewVBoxLayout(), Objects: []fyne.CanvasObject{parent1, parent2}}) w.Resize(fyne.NewSize(100, 200)) ShowPopUpAtRelativePosition(label, w.Canvas(), pos, parent2) @@ -86,7 +86,7 @@ func TestShowModalPopUp(t *testing.T) { test.NewApp() defer test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(200, 199)) require.Nil(t, w.Canvas().Overlays().Top()) @@ -328,7 +328,7 @@ func TestPopUp_Layout(t *testing.T) { func TestPopUp_ApplyThemeOnShow(t *testing.T) { test.NewApp() defer test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(200, 300)) pop := NewPopUp(NewLabel("Label"), w.Canvas()) @@ -352,7 +352,7 @@ func TestPopUp_ApplyThemeOnShow(t *testing.T) { func TestPopUp_ResizeOnShow(t *testing.T) { test.NewApp() defer test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) size := fyne.NewSize(200, 300) w.Resize(size) @@ -376,7 +376,7 @@ func TestPopUp_ResizeBeforeShow_CanvasSizeZero(t *testing.T) { // Simulate canvas size {0,0} rect := canvas.NewRectangle(color.Black) rect.SetMinSize(fyne.NewSize(0, 0)) - w := test.NewWindow(rect) + w := test.NewTempWindow(t, rect) w.SetPadded(false) w.Resize(fyne.NewSize(0, 0)) assert.Zero(t, w.Canvas().Size()) @@ -443,7 +443,7 @@ func TestModalPopUp_Resize(t *testing.T) { func TestModalPopUp_Resize_Constrained(t *testing.T) { label := NewLabel("Hi") - win := test.NewWindow(NewLabel("OK")) + win := test.NewTempWindow(t, NewLabel("OK")) win.Resize(fyne.NewSize(80, 80)) pop := NewModalPopUp(label, win.Canvas()) @@ -457,7 +457,7 @@ func TestModalPopUp_Resize_Constrained(t *testing.T) { func TestModalPopUp_ApplyThemeOnShow(t *testing.T) { test.NewApp() defer test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(200, 300)) pop := NewModalPopUp(NewLabel("Label"), w.Canvas()) @@ -481,7 +481,7 @@ func TestModalPopUp_ApplyThemeOnShow(t *testing.T) { func TestModalPopUp_ResizeOnShow(t *testing.T) { test.NewApp() defer test.NewApp() - w := test.NewWindow(canvas.NewRectangle(color.Transparent)) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) size := fyne.NewSize(200, 300) w.Resize(size) @@ -505,7 +505,7 @@ func TestModelPopUp_ResizeBeforeShow_CanvasSizeZero(t *testing.T) { // Simulate canvas size {0,0} rect := canvas.NewRectangle(color.Black) rect.SetMinSize(fyne.NewSize(0, 0)) - w := test.NewWindow(rect) + w := test.NewTempWindow(t, rect) w.SetPadded(false) w.Resize(fyne.NewSize(0, 0)) assert.Zero(t, w.Canvas().Size()) diff --git a/widget/radio_group_test.go b/widget/radio_group_test.go index a51639b29a..82606c709d 100644 --- a/widget/radio_group_test.go +++ b/widget/radio_group_test.go @@ -155,12 +155,10 @@ func TestRadioGroup_Layout(t *testing.T) { radio.Disable() } - window := test.NewWindow(&fyne.Container{Layout: layout.NewCenterLayout(), Objects: []fyne.CanvasObject{radio}}) + window := test.NewTempWindow(t, &fyne.Container{Layout: layout.NewCenterLayout(), Objects: []fyne.CanvasObject{radio}}) window.Resize(radio.MinSize().Max(fyne.NewSize(150, 200))) test.AssertRendersToMarkup(t, "radio_group/layout_"+name+".xml", window.Canvas()) - - window.Close() }) } } diff --git a/widget/richtext_test.go b/widget/richtext_test.go index eaff83bd0b..26cb4a6e20 100644 --- a/widget/richtext_test.go +++ b/widget/richtext_test.go @@ -348,7 +348,7 @@ func TestText_Multiline(t *testing.T) { &TextSegment{Text: "line1\nli", Style: RichTextStyleStrong}, &TextSegment{Text: "ne2\nline3", Style: RichTextStyleInline}) - w := test.NewWindow(text) + w := test.NewTempWindow(t, text) w.Resize(fyne.NewSize(64, 90)) test.AssertImageMatches(t, "richtext/richtext_multiline.png", w.Canvas().Capture()) } diff --git a/widget/select_test.go b/widget/select_test.go index 3bf972628f..7fd07bd225 100644 --- a/widget/select_test.go +++ b/widget/select_test.go @@ -550,15 +550,13 @@ func TestSelect_Layout(t *testing.T) { Selected: tt.selected, } - window := test.NewWindow(&fyne.Container{Layout: layout.NewCenterLayout(), Objects: []fyne.CanvasObject{combo}}) + window := test.NewTempWindow(t, &fyne.Container{Layout: layout.NewCenterLayout(), Objects: []fyne.CanvasObject{combo}}) if tt.expanded { test.Tap(combo) } window.Resize(combo.MinSize().Max(fyne.NewSize(150, 200))) assertRendersToPlatformMarkup(t, "select/%s/layout_"+name+".xml", window.Canvas()) - - window.Close() }) } } diff --git a/widget/slider_test.go b/widget/slider_test.go index 8521ebed30..1688c60251 100644 --- a/widget/slider_test.go +++ b/widget/slider_test.go @@ -295,7 +295,7 @@ func TestSlider_FocusDesktop(t *testing.T) { return } slider := NewSlider(0, 10) - win := test.NewWindow(slider) + win := test.NewTempWindow(t, slider) test.Tap(slider) assert.Equal(t, win.Canvas().Focused(), slider) diff --git a/widget/table_test.go b/widget/table_test.go index b634f532a8..e72d4d9adc 100644 --- a/widget/table_test.go +++ b/widget/table_test.go @@ -315,7 +315,7 @@ func TestTable_Resize(t *testing.T) { }, func(TableCellID, fyne.CanvasObject) {}) - w := test.NewWindow(table) + w := test.NewTempWindow(t, table) w.Resize(fyne.NewSize(100, 100)) test.AssertImageMatches(t, "table/resize.png", w.Canvas().Capture()) } diff --git a/widget/tree_internal_test.go b/widget/tree_internal_test.go index 2107b4c982..d901c970b8 100644 --- a/widget/tree_internal_test.go +++ b/widget/tree_internal_test.go @@ -878,8 +878,8 @@ func TestTree_RefreshItem(t *testing.T) { } tree.OpenBranch("foo") - c := test.NewWindow(tree) - c.Resize(fyne.NewSize(100, 100)) + w := test.NewTempWindow(t, tree) + w.Resize(fyne.NewSize(100, 100)) r := test.WidgetRenderer(tree.scroller.Content.(*treeContent)).(*treeContentRenderer) diff --git a/widget/widget_test.go b/widget/widget_test.go index 780ff2ec8e..6f1a96a84b 100644 --- a/widget/widget_test.go +++ b/widget/widget_test.go @@ -34,7 +34,7 @@ func (m *myWidget) CreateRenderer() fyne.WidgetRenderer { func TestApplyThemeCalled(t *testing.T) { widget := &myWidget{refreshed: make(chan bool)} - window := test.NewWindow(widget) + test.NewTempWindow(t, widget) fyne.CurrentApp().Settings().SetTheme(internalTest.LightTheme(theme.DefaultTheme())) func() { @@ -44,15 +44,13 @@ func TestApplyThemeCalled(t *testing.T) { assert.Fail(t, "Timed out waiting for theme apply") } }() - - window.Close() } func TestApplyThemeCalledChild(t *testing.T) { child := &myWidget{refreshed: make(chan bool)} parent := &fyne.Container{Layout: layout.NewVBoxLayout(), Objects: []fyne.CanvasObject{child}} - window := test.NewWindow(parent) + test.NewTempWindow(t, parent) fyne.CurrentApp().Settings().SetTheme(internalTest.LightTheme(theme.DefaultTheme())) func() { select { @@ -61,8 +59,6 @@ func TestApplyThemeCalledChild(t *testing.T) { assert.Fail(t, "Timed out waiting for child theme apply") } }() - - window.Close() } func TestSimpleRenderer(t *testing.T) { From 68aaa24512f97e203b4748e4bf47ff2666e06cb6 Mon Sep 17 00:00:00 2001 From: Jacob Date: Sat, 18 May 2024 22:38:58 +0200 Subject: [PATCH 02/78] Add a Since: line --- test/testwindow.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/testwindow.go b/test/testwindow.go index d26c2205f8..9092c5f5d0 100644 --- a/test/testwindow.go +++ b/test/testwindow.go @@ -21,7 +21,9 @@ type testWindow struct { } // NewTempWindow creates and registers a new window for test purposes. -// This window will get removed automatically once the test ends. +// This window will get removed automatically once the running test ends. +// +// Since: 2.5 func NewTempWindow(t testing.TB, content fyne.CanvasObject) fyne.Window { window := fyne.CurrentApp().NewWindow("") window.SetContent(content) From 48034e05485eb2357e23eec5f7d84d567566389c Mon Sep 17 00:00:00 2001 From: Jacob Date: Sat, 18 May 2024 22:53:21 +0200 Subject: [PATCH 03/78] Add test.NewTempApp() to tear down app at the end of the test --- canvas/text_test.go | 6 +-- container/apptabs_desktop_flakey_test.go | 6 +-- container/apptabs_desktop_test.go | 21 ++++------- container/apptabs_mobile_flakey_test.go | 6 +-- container/apptabs_mobile_test.go | 21 ++++------- container/doctabs_desktop_test.go | 27 +++++--------- container/doctabs_mobile_test.go | 27 +++++--------- container/tabs_test.go | 3 +- dialog/color_button_test.go | 3 +- dialog/color_channel_test.go | 3 +- dialog/color_picker_test.go | 12 ++---- dialog/color_preview_test.go | 3 +- dialog/color_test.go | 28 +++++--------- dialog/color_wheel_test.go | 3 +- dialog/confirm_test.go | 3 +- dialog/custom_test.go | 18 +++------ dialog/form_test.go | 3 +- internal/driver/common/canvas_test.go | 3 +- internal/driver/glfw/menu_bar_test.go | 6 +-- internal/painter/image_test.go | 3 +- internal/widget/shadow_test.go | 15 +++----- test/testapp.go | 10 +++++ widget/accordion_test.go | 3 +- widget/activity_internal_test.go | 3 +- widget/activity_test.go | 6 +-- widget/button_internal_test.go | 3 +- widget/button_test.go | 18 +++------ widget/check_test.go | 3 +- widget/entry_password_extend_test.go | 3 +- widget/entry_test.go | 3 +- widget/entry_validation_test.go | 3 +- widget/fileicon_test.go | 3 +- widget/form_test.go | 30 +++++---------- widget/gridwrap_test.go | 2 +- widget/hyperlink_test.go | 6 +-- widget/icon_test.go | 3 +- widget/label_test.go | 6 +-- widget/list_test.go | 29 ++++++--------- widget/menu_desktop_test.go | 9 ++--- widget/menu_mobile_test.go | 6 +-- widget/menu_test.go | 6 +-- widget/popup_test.go | 24 ++++-------- widget/select_entry_internal_test.go | 18 +++------ widget/select_internal_test.go | 3 +- widget/select_test.go | 30 +++++---------- widget/slider_test.go | 6 +-- widget/table_desktop_test.go | 3 +- widget/table_test.go | 47 ++++++++---------------- widget/tree_internal_test.go | 9 ++--- widget/tree_test.go | 9 ++--- widget/widget_test.go | 3 +- 51 files changed, 184 insertions(+), 343 deletions(-) diff --git a/canvas/text_test.go b/canvas/text_test.go index 00fe12aab9..bc3ec9c197 100644 --- a/canvas/text_test.go +++ b/canvas/text_test.go @@ -35,8 +35,7 @@ func TestText_MinSize_NoMultiLine(t *testing.T) { } func TestText_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) for name, tt := range map[string]struct { text string @@ -115,8 +114,7 @@ func TestText_Layout(t *testing.T) { } func TestText_CarriageReturn(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) for name, tt := range map[string]struct { text string diff --git a/container/apptabs_desktop_flakey_test.go b/container/apptabs_desktop_flakey_test.go index d888a18636..774d68ac61 100644 --- a/container/apptabs_desktop_flakey_test.go +++ b/container/apptabs_desktop_flakey_test.go @@ -12,8 +12,7 @@ import ( ) func TestAppTabs_ApplyTheme(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow( container.NewAppTabs(&container.TabItem{Text: "Test", Content: widget.NewLabel("Text")}), @@ -30,8 +29,7 @@ func TestAppTabs_ApplyTheme(t *testing.T) { } func TestAppTabs_ChangeItemContent(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text2")} diff --git a/container/apptabs_desktop_test.go b/container/apptabs_desktop_test.go index a327a2a7d0..2b8c494173 100644 --- a/container/apptabs_desktop_test.go +++ b/container/apptabs_desktop_test.go @@ -17,8 +17,7 @@ import ( ) func TestAppTabs_ChangeItemIcon(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Icon: theme.CancelIcon(), Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Icon: theme.ConfirmIcon(), Content: widget.NewLabel("Text2")} @@ -41,8 +40,7 @@ func TestAppTabs_ChangeItemIcon(t *testing.T) { } func TestAppTabs_ChangeItemText(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text2")} @@ -65,8 +63,7 @@ func TestAppTabs_ChangeItemText(t *testing.T) { } func TestAppTabs_DynamicTabs(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text 1")} tabs := container.NewAppTabs(item1) @@ -117,8 +114,7 @@ func TestAppTabs_DynamicTabs(t *testing.T) { } func TestAppTabs_HoverButtons(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text2")} @@ -148,8 +144,7 @@ func TestAppTabs_HoverButtons(t *testing.T) { } func TestAppTabs_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(nil) defer w.Close() @@ -248,8 +243,7 @@ func TestAppTabs_Layout(t *testing.T) { } func TestAppTabs_SetTabLocation(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text 1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text 2")} @@ -281,8 +275,7 @@ func TestAppTabs_SetTabLocation(t *testing.T) { } func TestAppTabs_Tapped(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text 1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text 2")} diff --git a/container/apptabs_mobile_flakey_test.go b/container/apptabs_mobile_flakey_test.go index 8de37b101f..6134913e61 100644 --- a/container/apptabs_mobile_flakey_test.go +++ b/container/apptabs_mobile_flakey_test.go @@ -12,8 +12,7 @@ import ( ) func TestAppTabs_ApplyTheme(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow( container.NewAppTabs(&container.TabItem{Text: "Test", Content: widget.NewLabel("Text")}), @@ -30,8 +29,7 @@ func TestAppTabs_ApplyTheme(t *testing.T) { } func TestAppTabs_ChangeItemContent(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text2")} diff --git a/container/apptabs_mobile_test.go b/container/apptabs_mobile_test.go index 1d1ff8f90d..8c8672dee7 100644 --- a/container/apptabs_mobile_test.go +++ b/container/apptabs_mobile_test.go @@ -18,8 +18,7 @@ import ( ) func TestAppTabs_ChangeItemIcon(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Icon: theme.CancelIcon(), Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Icon: theme.ConfirmIcon(), Content: widget.NewLabel("Text2")} @@ -42,8 +41,7 @@ func TestAppTabs_ChangeItemIcon(t *testing.T) { } func TestAppTabs_ChangeItemText(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text2")} @@ -66,8 +64,7 @@ func TestAppTabs_ChangeItemText(t *testing.T) { } func TestAppTabs_DynamicTabs(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text 1")} tabs := container.NewAppTabs(item1) @@ -118,8 +115,7 @@ func TestAppTabs_DynamicTabs(t *testing.T) { } func TestAppTabs_HoverButtons(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text1")} @@ -144,8 +140,7 @@ func TestAppTabs_HoverButtons(t *testing.T) { } func TestAppTabs_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(nil) defer w.Close() @@ -244,8 +239,7 @@ func TestAppTabs_Layout(t *testing.T) { } func TestAppTabs_SetTabLocation(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text 1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text 2")} @@ -277,8 +271,7 @@ func TestAppTabs_SetTabLocation(t *testing.T) { } func TestAppTabs_Tapped(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text 1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text 2")} diff --git a/container/doctabs_desktop_test.go b/container/doctabs_desktop_test.go index dc2949de02..b81786cebe 100644 --- a/container/doctabs_desktop_test.go +++ b/container/doctabs_desktop_test.go @@ -17,8 +17,7 @@ import ( ) func TestDocTabs_ApplyTheme(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow( container.NewDocTabs(&container.TabItem{Text: "Test", Content: widget.NewLabel("Text")}), @@ -35,8 +34,7 @@ func TestDocTabs_ApplyTheme(t *testing.T) { } func TestDocTabs_ChangeItemContent(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text2")} @@ -59,8 +57,7 @@ func TestDocTabs_ChangeItemContent(t *testing.T) { } func TestDocTabs_ChangeItemIcon(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Icon: theme.CancelIcon(), Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Icon: theme.ConfirmIcon(), Content: widget.NewLabel("Text2")} @@ -83,8 +80,7 @@ func TestDocTabs_ChangeItemIcon(t *testing.T) { } func TestDocTabs_ChangeItemText(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text2")} @@ -113,8 +109,7 @@ func TestDocTabs_ChangeItemText(t *testing.T) { } func TestDocTabs_DynamicTabs(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text 1")} tabs := container.NewDocTabs(item1) @@ -165,8 +160,7 @@ func TestDocTabs_DynamicTabs(t *testing.T) { } func TestDocTabs_HoverButtons(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text2")} @@ -202,8 +196,7 @@ func TestDocTabs_HoverButtons(t *testing.T) { } func TestDocTabs_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(nil) defer w.Close() @@ -302,8 +295,7 @@ func TestDocTabs_Layout(t *testing.T) { } func TestDocTabs_SetTabLocation(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text 1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text 2")} @@ -335,8 +327,7 @@ func TestDocTabs_SetTabLocation(t *testing.T) { } func TestDocTabs_Tapped(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text 1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text 2")} diff --git a/container/doctabs_mobile_test.go b/container/doctabs_mobile_test.go index 6dd788404c..2679c510fd 100644 --- a/container/doctabs_mobile_test.go +++ b/container/doctabs_mobile_test.go @@ -18,8 +18,7 @@ import ( ) func TestDocTabs_ApplyTheme(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow( container.NewDocTabs(&container.TabItem{Text: "Test", Content: widget.NewLabel("Text")}), @@ -36,8 +35,7 @@ func TestDocTabs_ApplyTheme(t *testing.T) { } func TestDocTabs_ChangeItemContent(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text2")} @@ -60,8 +58,7 @@ func TestDocTabs_ChangeItemContent(t *testing.T) { } func TestDocTabs_ChangeItemIcon(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Icon: theme.CancelIcon(), Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Icon: theme.ConfirmIcon(), Content: widget.NewLabel("Text2")} @@ -84,8 +81,7 @@ func TestDocTabs_ChangeItemIcon(t *testing.T) { } func TestDocTabs_ChangeItemText(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text2")} @@ -108,8 +104,7 @@ func TestDocTabs_ChangeItemText(t *testing.T) { } func TestDocTabs_DynamicTabs(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text 1")} tabs := container.NewDocTabs(item1) @@ -160,8 +155,7 @@ func TestDocTabs_DynamicTabs(t *testing.T) { } func TestDocTabs_HoverButtons(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text1")} @@ -195,8 +189,7 @@ func TestDocTabs_HoverButtons(t *testing.T) { } func TestDocTabs_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(nil) defer w.Close() @@ -296,8 +289,7 @@ func TestDocTabs_Layout(t *testing.T) { } func TestDocTabs_SetTabLocation(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text 1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text 2")} @@ -329,8 +321,7 @@ func TestDocTabs_SetTabLocation(t *testing.T) { } func TestDocTabs_Tapped(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text 1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text 2")} diff --git a/container/tabs_test.go b/container/tabs_test.go index f50e78336a..87647193c8 100644 --- a/container/tabs_test.go +++ b/container/tabs_test.go @@ -26,8 +26,7 @@ func TestTabButton_Icon_Change(t *testing.T) { } func TestTab_ThemeChange(t *testing.T) { - a := test.NewApp() - defer test.NewApp() + a := test.NewTempApp(t) a.Settings().SetTheme(internalTest.LightTheme(theme.DefaultTheme())) tabs := NewAppTabs( diff --git a/dialog/color_button_test.go b/dialog/color_button_test.go index 741d9124f8..bb7e240922 100644 --- a/dialog/color_button_test.go +++ b/dialog/color_button_test.go @@ -11,8 +11,7 @@ import ( ) func Test_colorButton_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) for name, tt := range map[string]struct { color color.Color diff --git a/dialog/color_channel_test.go b/dialog/color_channel_test.go index 9bca175afd..053d871e48 100644 --- a/dialog/color_channel_test.go +++ b/dialog/color_channel_test.go @@ -8,8 +8,7 @@ import ( ) func Test_colorChannel_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) min := 0 max := 100 diff --git a/dialog/color_picker_test.go b/dialog/color_picker_test.go index c146c900dc..f475f1ad15 100644 --- a/dialog/color_picker_test.go +++ b/dialog/color_picker_test.go @@ -10,8 +10,7 @@ import ( ) func Test_colorGreyscalePicker_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) color := newColorGreyscalePicker(nil) @@ -24,8 +23,7 @@ func Test_colorGreyscalePicker_Layout(t *testing.T) { } func Test_colorBasicPicker_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) color := newColorBasicPicker(nil) @@ -38,8 +36,7 @@ func Test_colorBasicPicker_Layout(t *testing.T) { } func Test_colorRecentPicker_Layout(t *testing.T) { - a := test.NewApp() - defer test.NewApp() + a := test.NewTempApp(t) // Inject recent preferences a.Preferences().SetString("color_recents", "#0000FF,#008000,#FF0000") @@ -55,8 +52,7 @@ func Test_colorRecentPicker_Layout(t *testing.T) { } func Test_colorAdvancedPicker_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) color := newColorAdvancedPicker(theme.PrimaryColor(), nil) diff --git a/dialog/color_preview_test.go b/dialog/color_preview_test.go index 538679ff1f..a9bb5a13d4 100644 --- a/dialog/color_preview_test.go +++ b/dialog/color_preview_test.go @@ -10,8 +10,7 @@ import ( ) func Test_colorPreview_Color(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) preview := newColorPreview(color.RGBA{53, 113, 233, 255}) preview.SetColor(color.RGBA{90, 206, 80, 180}) diff --git a/dialog/color_test.go b/dialog/color_test.go index 311132f2de..820aba89a0 100644 --- a/dialog/color_test.go +++ b/dialog/color_test.go @@ -13,8 +13,7 @@ import ( ) func TestColorDialog_Theme(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(1000, 800)) @@ -41,9 +40,7 @@ func TestColorDialog_Theme(t *testing.T) { } func TestColorDialog_Recents(t *testing.T) { - a := test.NewApp() - defer test.NewApp() - + a := test.NewTempApp(t) // Inject recent preferences a.Preferences().SetString("color_recents", "#2196f3,#4caf50,#f44336") @@ -102,8 +99,7 @@ func TestColorDialog_SetColor(t *testing.T) { } func TestColorDialogSimple_Theme(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(600, 400)) @@ -120,8 +116,7 @@ func TestColorDialogSimple_Theme(t *testing.T) { } func TestColorDialogSimple_Recents(t *testing.T) { - a := test.NewApp() - defer test.NewApp() + a := test.NewTempApp(t) // Inject recent preferences a.Preferences().SetString("color_recents", "#2196f3,#4caf50,#f44336") @@ -142,22 +137,19 @@ func TestColorDialogSimple_Recents(t *testing.T) { func Test_recent_color(t *testing.T) { t.Run("Empty", func(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) colors := readRecentColors() assert.Equal(t, 0, len(colors)) }) t.Run("Single", func(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) writeRecentColor("#ff0000") // Red colors := readRecentColors() assert.Equal(t, 1, len(colors)) assert.Equal(t, "#ff0000", colors[0]) }) t.Run("Order", func(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) // Recents are last in, first out writeRecentColor("#ff0000") // Red writeRecentColor("#00ff00") // Green @@ -169,8 +161,7 @@ func Test_recent_color(t *testing.T) { assert.Equal(t, "#ff0000", colors[2]) }) t.Run("Deduplicate", func(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) // Ensure no duplicates writeRecentColor("#ff0000") // Red writeRecentColor("#00ff00") // Green @@ -183,8 +174,7 @@ func Test_recent_color(t *testing.T) { assert.Equal(t, "#00ff00", colors[2]) // Green }) t.Run("Limit", func(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) // Max recents is 7 writeRecentColor("#000000") // Black writeRecentColor("#bbbbbb") // Dark Grey diff --git a/dialog/color_wheel_test.go b/dialog/color_wheel_test.go index 39d85036b5..481c096d1c 100644 --- a/dialog/color_wheel_test.go +++ b/dialog/color_wheel_test.go @@ -8,8 +8,7 @@ import ( ) func Test_colorWheel_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) wheel := newColorWheel(nil) wheel.SetHSLA(180, 100, 50, 255) diff --git a/dialog/confirm_test.go b/dialog/confirm_test.go index fba7ab22c6..45a32fb745 100644 --- a/dialog/confirm_test.go +++ b/dialog/confirm_test.go @@ -107,8 +107,7 @@ func TestConfirmDialog_Resize(t *testing.T) { } func TestConfirm_Importance(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) size := fyne.NewSize(200, 300) w.Resize(size) diff --git a/dialog/custom_test.go b/dialog/custom_test.go index d94b016a63..51069e0890 100644 --- a/dialog/custom_test.go +++ b/dialog/custom_test.go @@ -14,8 +14,7 @@ import ( ) func TestShowCustom_ApplyTheme(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) @@ -50,8 +49,7 @@ func TestShowCustom_Resize(t *testing.T) { } func TestCustom_ApplyThemeOnShow(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(200, 300)) @@ -76,8 +74,7 @@ func TestCustom_ApplyThemeOnShow(t *testing.T) { } func TestCustom_ResizeOnShow(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) size := fyne.NewSize(200, 300) w.Resize(size) @@ -98,8 +95,7 @@ func TestCustom_ResizeOnShow(t *testing.T) { } func TestConfirm_SetButtons(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) size := fyne.NewSize(200, 300) w.Resize(size) @@ -121,8 +117,7 @@ func TestConfirm_SetButtons(t *testing.T) { } func TestConfirmWithoutButtons(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) size := fyne.NewSize(200, 300) w.Resize(size) @@ -134,8 +129,7 @@ func TestConfirmWithoutButtons(t *testing.T) { } func TestCustomConfirm_Importance(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) size := fyne.NewSize(200, 300) w.Resize(size) diff --git a/dialog/form_test.go b/dialog/form_test.go index 5c7074319f..69f17f37f2 100644 --- a/dialog/form_test.go +++ b/dialog/form_test.go @@ -87,8 +87,7 @@ func TestFormDialog_CanCancelNoValidation(t *testing.T) { func TestFormDialog_Hints(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) w := test.NewWindow(nil) w.SetFullScreen(true) diff --git a/internal/driver/common/canvas_test.go b/internal/driver/common/canvas_test.go index b43fbd0e5e..e9398c56fb 100644 --- a/internal/driver/common/canvas_test.go +++ b/internal/driver/common/canvas_test.go @@ -15,8 +15,7 @@ import ( ) func TestCanvas_walkTree(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) leftObj1 := canvas.NewRectangle(color.Gray16{Y: 1}) leftObj2 := canvas.NewRectangle(color.Gray16{Y: 2}) diff --git a/internal/driver/glfw/menu_bar_test.go b/internal/driver/glfw/menu_bar_test.go index 64b3729fa0..e897369d42 100644 --- a/internal/driver/glfw/menu_bar_test.go +++ b/internal/driver/glfw/menu_bar_test.go @@ -17,8 +17,7 @@ import ( ) func TestMenuBar(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) var lastAction string @@ -450,8 +449,7 @@ func TestMenuBar(t *testing.T) { } func TestMenuBar_Toggle(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) m1i1 := fyne.NewMenuItem("New", nil) m1i2 := fyne.NewMenuItem("Open", nil) diff --git a/internal/painter/image_test.go b/internal/painter/image_test.go index 14c1efb2ba..2272e090ec 100644 --- a/internal/painter/image_test.go +++ b/internal/painter/image_test.go @@ -39,8 +39,7 @@ func TestPaintImageWithBadSVGElement(t *testing.T) { } func TestPaintImage_SVG(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) for name, tt := range map[string]struct { width float32 diff --git a/internal/widget/shadow_test.go b/internal/widget/shadow_test.go index e27e7cbafc..0b1abdbc0c 100644 --- a/internal/widget/shadow_test.go +++ b/internal/widget/shadow_test.go @@ -13,8 +13,7 @@ import ( var shadowLevel = widget.ElevationLevel(5) func TestShadow_ApplyTheme(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) s := widget.NewShadow(widget.ShadowAround, shadowLevel) w := test.NewWindow(s) @@ -30,8 +29,7 @@ func TestShadow_ApplyTheme(t *testing.T) { } func TestShadow_AroundShadow(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) s := widget.NewShadow(widget.ShadowAround, shadowLevel) w := test.NewWindow(s) @@ -44,8 +42,7 @@ func TestShadow_AroundShadow(t *testing.T) { } func TestShadow_Transparency(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) s := widget.NewShadow(widget.ShadowAround, shadowLevel) w := test.NewWindow(s) @@ -62,8 +59,7 @@ func TestShadow_Transparency(t *testing.T) { } func TestShadow_BottomShadow(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) s := widget.NewShadow(widget.ShadowBottom, shadowLevel) w := test.NewWindow(s) @@ -80,8 +76,7 @@ func TestShadow_MinSize(t *testing.T) { } func TestShadow_TopShadow(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) s := widget.NewShadow(widget.ShadowTop, shadowLevel) w := test.NewWindow(s) diff --git a/test/testapp.go b/test/testapp.go index 6c54eee35d..bd89e0dd8b 100644 --- a/test/testapp.go +++ b/test/testapp.go @@ -4,6 +4,7 @@ package test // import "fyne.io/fyne/v2/test" import ( "net/url" "sync" + "testing" "fyne.io/fyne/v2" "fyne.io/fyne/v2/internal" @@ -146,6 +147,15 @@ func (a *testApp) transitionCloud(p fyne.CloudProvider) { a.settings.apply() } +// NewTempApp returns a new dummy app and tears it down at the end of the test. +// +// Since: 2.5 +func NewTempApp(t testing.TB) fyne.App { + app := NewApp() + t.Cleanup(func() { NewApp() }) + return app +} + // NewApp returns a new dummy app used for testing. // It loads a test driver which creates a virtual window in memory for testing. func NewApp() fyne.App { diff --git a/widget/accordion_test.go b/widget/accordion_test.go index 68704071c3..fee7cec1aa 100644 --- a/widget/accordion_test.go +++ b/widget/accordion_test.go @@ -32,8 +32,7 @@ func TestAccordion_Append(t *testing.T) { } func TestAccordion_ChangeTheme(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) ac := widget.NewAccordion() ac.Append(widget.NewAccordionItem("foo0", widget.NewLabel("foobar0"))) diff --git a/widget/activity_internal_test.go b/widget/activity_internal_test.go index 13372186da..1d5a90195a 100644 --- a/widget/activity_internal_test.go +++ b/widget/activity_internal_test.go @@ -7,8 +7,7 @@ import ( ) func TestActivity_Animation(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, test.NewTheme()) a := NewActivity() diff --git a/widget/activity_test.go b/widget/activity_test.go index a758af384f..a0d94bf254 100644 --- a/widget/activity_test.go +++ b/widget/activity_test.go @@ -10,8 +10,7 @@ import ( ) func TestActivity_Start(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, test.NewTheme()) a := NewActivity() @@ -29,8 +28,7 @@ func TestActivity_Start(t *testing.T) { } func TestActivity_Stop(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, test.NewTheme()) a := NewActivity() diff --git a/widget/button_internal_test.go b/widget/button_internal_test.go index 72c401aa81..b70a9de3d6 100644 --- a/widget/button_internal_test.go +++ b/widget/button_internal_test.go @@ -210,8 +210,7 @@ func TestButtonRenderer_ApplyTheme(t *testing.T) { } func TestButtonRenderer_TapAnimation(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, test.NewTheme()) button := NewButton("Hi", func() {}) diff --git a/widget/button_test.go b/widget/button_test.go index c13b2a841f..7f2765466e 100644 --- a/widget/button_test.go +++ b/widget/button_test.go @@ -66,8 +66,7 @@ func TestButton_Tapped(t *testing.T) { } func TestButton_Disable(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) tapped := false @@ -123,8 +122,7 @@ func TestButton_Disabled(t *testing.T) { } func TestButton_LowImportance(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) b := &widget.Button{Text: "Text", Icon: theme.HomeIcon(), Importance: widget.LowImportance} w := test.NewWindow(b) @@ -137,8 +135,7 @@ func TestButton_LowImportance(t *testing.T) { } func TestButton_Hover(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) b := widget.NewButtonWithIcon("Test", theme.HomeIcon(), func() {}) @@ -166,8 +163,7 @@ func TestButton_Hover(t *testing.T) { } func TestButton_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) for name, tt := range map[string]struct { text string @@ -294,8 +290,7 @@ func TestButton_Layout(t *testing.T) { } func TestButton_ChangeTheme(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) b := widget.NewButton("Test", func() {}) w := test.NewWindow(b) @@ -323,8 +318,7 @@ func TestButtonCompatImportance(t *testing.T) { } func TestButtonSuccess(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) b := widget.NewButtonWithIcon("Test", theme.HomeIcon(), func() {}) diff --git a/widget/check_test.go b/widget/check_test.go index 6b4210e926..38351fb688 100644 --- a/widget/check_test.go +++ b/widget/check_test.go @@ -38,8 +38,7 @@ func TestCheck_Binding(t *testing.T) { } func TestCheck_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) for name, tt := range map[string]struct { text string diff --git a/widget/entry_password_extend_test.go b/widget/entry_password_extend_test.go index 71f4011413..9173e5c382 100644 --- a/widget/entry_password_extend_test.go +++ b/widget/entry_password_extend_test.go @@ -15,8 +15,7 @@ type extendEntry struct { } func TestEntry_Password_Extended_CreateRenderer(t *testing.T) { - a := test.NewApp() - defer test.NewApp() + a := test.NewTempApp(t) w := a.NewWindow("") entry := &extendEntry{} entry.ExtendBaseWidget(entry) diff --git a/widget/entry_test.go b/widget/entry_test.go index 588ee00bfe..00072e52db 100644 --- a/widget/entry_test.go +++ b/widget/entry_test.go @@ -1869,8 +1869,7 @@ func TestPasswordEntry_Placeholder(t *testing.T) { } func TestPasswordEntry_Reveal(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) t.Run("NewPasswordEntry constructor", func(t *testing.T) { entry := widget.NewPasswordEntry() diff --git a/widget/entry_validation_test.go b/widget/entry_validation_test.go index b8f4aa1509..2d0642e221 100644 --- a/widget/entry_validation_test.go +++ b/widget/entry_validation_test.go @@ -64,8 +64,7 @@ func TestEntry_Validate(t *testing.T) { } func TestEntry_NotEmptyValidator(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) entry := widget.NewEntry() entry.Validator = func(s string) error { if s == "" { diff --git a/widget/fileicon_test.go b/widget/fileicon_test.go index a655e39e41..5397398e67 100644 --- a/widget/fileicon_test.go +++ b/widget/fileicon_test.go @@ -16,8 +16,7 @@ import ( ) func TestFileIcon_NewFileIcon_Rendered(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) workingDir, err := os.Getwd() if err != nil { diff --git a/widget/form_test.go b/widget/form_test.go index efa32a0e07..d8aaac88ee 100644 --- a/widget/form_test.go +++ b/widget/form_test.go @@ -98,8 +98,7 @@ func TestForm_AddRemoveButton(t *testing.T) { } func TestForm_Renderer(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) form := &Form{ Items: []*FormItem{ @@ -127,8 +126,7 @@ func TestForm_ChangeText(t *testing.T) { } func TestForm_ChangeTheme(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) form := &Form{ Items: []*FormItem{ @@ -149,8 +147,7 @@ func TestForm_ChangeTheme(t *testing.T) { } func TestForm_Disabled(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) disabled := NewEntry() @@ -166,8 +163,7 @@ func TestForm_Disabled(t *testing.T) { } func TestForm_Hints(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) entry1 := &Entry{} @@ -191,8 +187,7 @@ func TestForm_Hints(t *testing.T) { } func TestForm_Validation(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) entry1 := &Entry{Validator: validation.NewRegexp(`^\d{2}-\w{4}$`, "Input is not valid"), Text: "15-true"} @@ -223,8 +218,7 @@ func TestForm_Validation(t *testing.T) { } func TestForm_EntryValidation_FirstTypeValid(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) notEmptyValidator := func(s string) error { @@ -263,8 +257,7 @@ func TestForm_EntryValidation_FirstTypeValid(t *testing.T) { } func TestForm_DisableEnable(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) form := &Form{ @@ -299,8 +292,7 @@ func TestForm_DisableEnable(t *testing.T) { } func TestForm_Disable_Validation(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) entry := &Entry{Validator: validation.NewRegexp(`^\d{2}-\w{4}$`, "Input is not valid"), Text: "wrong"} @@ -331,8 +323,7 @@ func TestForm_Disable_Validation(t *testing.T) { } func TestForm_HintsRendered(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) f := NewForm() @@ -421,8 +412,7 @@ func TestForm_SetOnValidationChanged(t *testing.T) { func TestForm_ExtendedEntry(t *testing.T) { extendedEntry := NewSelectEntry([]string{""}) - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) form := &Form{ Items: []*FormItem{ diff --git a/widget/gridwrap_test.go b/widget/gridwrap_test.go index 29dd28f060..91da46ccef 100644 --- a/widget/gridwrap_test.go +++ b/widget/gridwrap_test.go @@ -10,7 +10,7 @@ import ( ) func TestGridWrap_Focus(t *testing.T) { - defer test.NewApp() + test.NewTempApp(t) list := createGridWrap(100) window := test.NewWindow(list) defer window.Close() diff --git a/widget/hyperlink_test.go b/widget/hyperlink_test.go index 03bbe7048d..9fd083ad4a 100644 --- a/widget/hyperlink_test.go +++ b/widget/hyperlink_test.go @@ -73,8 +73,7 @@ func TestHyperlink_Hide(t *testing.T) { } func TestHyperlink_Focus(t *testing.T) { - app := test.NewApp() - defer test.NewApp() + app := test.NewTempApp(t) app.Settings().SetTheme(internalTest.LightTheme(theme.DefaultTheme())) hyperlink := &Hyperlink{Text: "Test"} @@ -167,8 +166,7 @@ func TestHyperlink_SetUrl(t *testing.T) { } func TestHyperlink_ThemeOverride(t *testing.T) { - _ = test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) hyperlink := &Hyperlink{Text: "Test"} diff --git a/widget/icon_test.go b/widget/icon_test.go index b4c369326d..5d12ce3f14 100644 --- a/widget/icon_test.go +++ b/widget/icon_test.go @@ -11,8 +11,7 @@ import ( ) func TestIcon_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) for name, tt := range map[string]struct { resource fyne.Resource diff --git a/widget/label_test.go b/widget/label_test.go index d359683d96..e09e110605 100644 --- a/widget/label_test.go +++ b/widget/label_test.go @@ -183,8 +183,7 @@ func TestLabel_CreateRendererDoesNotAffectSize(t *testing.T) { } func TestLabel_ChangeTruncate(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) c := test.NewCanvasWithPainter(software.NewPainter()) c.SetPadded(false) @@ -210,8 +209,7 @@ func TestNewLabelWithData(t *testing.T) { } func TestLabelImportance(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) lbl := NewLabel("hello, fyne") diff --git a/widget/list_test.go b/widget/list_test.go index 74f2019ece..2d339dbf09 100644 --- a/widget/list_test.go +++ b/widget/list_test.go @@ -84,7 +84,7 @@ func TestList_MinSize(t *testing.T) { } func TestList_Resize(t *testing.T) { - defer test.NewApp() + test.NewTempApp(t) list, w := setupList(t) assert.Equal(t, float32(0), list.offsetY) @@ -157,8 +157,7 @@ func TestList_SetItemHeight_InUpdate(t *testing.T) { } func TestList_OffsetChange(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) list := createList(1000) w := test.NewWindow(list) @@ -345,8 +344,7 @@ func TestList_Unselect(t *testing.T) { } func TestList_DataChange(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) list, w := setupList(t) children := list.scroller.Content.(*fyne.Container).Layout.(*listLayout).children @@ -360,8 +358,7 @@ func TestList_DataChange(t *testing.T) { } func TestList_ItemDataChange(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) list, _ := setupList(t) children := list.scroller.Content.(*fyne.Container).Layout.(*listLayout).children @@ -373,7 +370,7 @@ func TestList_ItemDataChange(t *testing.T) { } func TestList_ThemeChange(t *testing.T) { - defer test.NewApp() + test.NewTempApp(t) list, w := setupList(t) test.AssertImageMatches(t, "list/list_initial.png", w.Canvas().Capture()) @@ -386,8 +383,7 @@ func TestList_ThemeChange(t *testing.T) { } func TestList_SmallList(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) var data []string data = append(data, "Test Item 0") @@ -422,7 +418,7 @@ func TestList_SmallList(t *testing.T) { } func TestList_ClearList(t *testing.T) { - defer test.NewApp() + test.NewTempApp(t) list, w := setupList(t) assert.Equal(t, 1000, list.Length()) @@ -438,8 +434,7 @@ func TestList_ClearList(t *testing.T) { } func TestList_RemoveItem(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) data := []string{"Test Item 0", "Test Item 1", "Test Item 2"} @@ -472,8 +467,7 @@ func TestList_RemoveItem(t *testing.T) { } func TestList_ScrollThenShrink(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) data := make([]string, 0, 20) for i := 0; i < 20; i++ { @@ -512,8 +506,7 @@ func TestList_ScrollThenShrink(t *testing.T) { } func TestList_ScrollThenResizeWindow(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) data := make([]string, 0, 20) for i := 0; i < 20; i++ { @@ -553,7 +546,7 @@ func TestList_NoFunctionsSet(t *testing.T) { } func TestList_Focus(t *testing.T) { - defer test.NewApp() + test.NewTempApp(t) list := createList(10) window := test.NewWindow(list) defer window.Close() diff --git a/widget/menu_desktop_test.go b/widget/menu_desktop_test.go index 4d4f5743a2..abecb879fc 100644 --- a/widget/menu_desktop_test.go +++ b/widget/menu_desktop_test.go @@ -20,8 +20,7 @@ import ( ) func TestMenu_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) defer w.Close() @@ -198,8 +197,7 @@ func TestMenu_Layout(t *testing.T) { } func TestMenu_Scrolling(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) defer w.Close() @@ -239,8 +237,7 @@ func TestMenu_Scrolling(t *testing.T) { } func TestMenu_TraverseMenu(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := fyne.CurrentApp().NewWindow("") defer w.Close() diff --git a/widget/menu_mobile_test.go b/widget/menu_mobile_test.go index 9c81ed0381..cbaa8f91c6 100644 --- a/widget/menu_mobile_test.go +++ b/widget/menu_mobile_test.go @@ -15,8 +15,7 @@ import ( ) func TestMenu_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) defer w.Close() @@ -135,8 +134,7 @@ func TestMenu_Layout(t *testing.T) { } func TestMenu_Dragging(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) defer w.Close() diff --git a/widget/menu_test.go b/widget/menu_test.go index ab8be3979d..13bf6bcab7 100644 --- a/widget/menu_test.go +++ b/widget/menu_test.go @@ -13,8 +13,7 @@ import ( ) func TestMenu_RefreshOptions(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := fyne.CurrentApp().NewWindow("") defer w.Close() @@ -65,8 +64,7 @@ func TestMenu_RefreshOptions(t *testing.T) { } func TestMenu_TappedPaddingOrSeparator(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := fyne.CurrentApp().NewWindow("") defer w.Close() diff --git a/widget/popup_test.go b/widget/popup_test.go index 8a955ec236..a7277c28c5 100644 --- a/widget/popup_test.go +++ b/widget/popup_test.go @@ -30,8 +30,7 @@ func TestNewPopUp(t *testing.T) { } func TestShowPopUp(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(200, 200)) @@ -83,8 +82,7 @@ func TestShowPopUpAtRelativePosition(t *testing.T) { } func TestShowModalPopUp(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(200, 199)) @@ -326,8 +324,7 @@ func TestPopUp_Layout(t *testing.T) { } func TestPopUp_ApplyThemeOnShow(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(200, 300)) @@ -350,8 +347,7 @@ func TestPopUp_ApplyThemeOnShow(t *testing.T) { } func TestPopUp_ResizeOnShow(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) size := fyne.NewSize(200, 300) w.Resize(size) @@ -370,8 +366,7 @@ func TestPopUp_ResizeOnShow(t *testing.T) { } func TestPopUp_ResizeBeforeShow_CanvasSizeZero(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) // Simulate canvas size {0,0} rect := canvas.NewRectangle(color.Black) @@ -455,8 +450,7 @@ func TestModalPopUp_Resize_Constrained(t *testing.T) { } func TestModalPopUp_ApplyThemeOnShow(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(200, 300)) @@ -479,8 +473,7 @@ func TestModalPopUp_ApplyThemeOnShow(t *testing.T) { } func TestModalPopUp_ResizeOnShow(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) w := test.NewWindow(canvas.NewRectangle(color.Transparent)) size := fyne.NewSize(200, 300) w.Resize(size) @@ -499,8 +492,7 @@ func TestModalPopUp_ResizeOnShow(t *testing.T) { } func TestModelPopUp_ResizeBeforeShow_CanvasSizeZero(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) // Simulate canvas size {0,0} rect := canvas.NewRectangle(color.Black) diff --git a/widget/select_entry_internal_test.go b/widget/select_entry_internal_test.go index 0a14466d41..fac8c3e3db 100644 --- a/widget/select_entry_internal_test.go +++ b/widget/select_entry_internal_test.go @@ -11,8 +11,7 @@ import ( ) func TestSelectEntry_Disableable(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) options := []string{"A", "B", "C"} e := NewSelectEntry(options) @@ -49,8 +48,7 @@ func TestSelectEntry_Disableable(t *testing.T) { } func TestSelectEntry_DropDown(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) options := []string{"A", "B", "C"} e := NewSelectEntry(options) @@ -81,8 +79,7 @@ func TestSelectEntry_DropDown(t *testing.T) { } func TestSelectEntry_DropDownMove(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) e := NewSelectEntry([]string{"one"}) w := test.NewWindow(e) @@ -112,8 +109,7 @@ func TestSelectEntry_DropDownMove(t *testing.T) { } func TestSelectEntry_DropDownResize(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) options := []string{"A", "B", "C"} e := NewSelectEntry(options) @@ -181,8 +177,7 @@ func TestSelectEntry_MinSize(t *testing.T) { } func TestSelectEntry_SetOptions(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) e := NewSelectEntry([]string{"A", "B", "C"}) w := test.NewWindow(e) @@ -203,8 +198,7 @@ func TestSelectEntry_SetOptions(t *testing.T) { } func TestSelectEntry_SetOptions_Empty(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) e := NewSelectEntry([]string{}) w := test.NewWindow(e) diff --git a/widget/select_internal_test.go b/widget/select_internal_test.go index 218352b284..1a63fb687a 100644 --- a/widget/select_internal_test.go +++ b/widget/select_internal_test.go @@ -36,8 +36,7 @@ func TestSelect_SetOptions(t *testing.T) { } func TestSelectRenderer_TapAnimation(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, test.NewTheme()) sel := NewSelect([]string{"one"}, func(s string) {}) diff --git a/widget/select_test.go b/widget/select_test.go index 3bf972628f..2410cc717a 100644 --- a/widget/select_test.go +++ b/widget/select_test.go @@ -26,8 +26,7 @@ func TestNewSelect(t *testing.T) { } func TestSelect_Align(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) sel := widget.NewSelect([]string{"Hi"}, func(string) {}) sel.Alignment = fyne.TextAlignCenter @@ -45,8 +44,7 @@ func TestSelect_Align(t *testing.T) { } func TestSelect_ChangeTheme(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) combo := widget.NewSelect([]string{"1", "2"}, func(s string) {}) w := test.NewWindow(combo) @@ -106,8 +104,7 @@ func TestSelect_ClipValue(t *testing.T) { } func TestSelect_Disable(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) sel := widget.NewSelect([]string{"Hi"}, func(string) {}) w := test.NewWindow(&fyne.Container{Layout: layout.NewCenterLayout(), Objects: []fyne.CanvasObject{sel}}) @@ -150,8 +147,7 @@ func TestSelect_Enable(t *testing.T) { } func TestSelect_FocusRendering(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) t.Run("gain/lose focus", func(t *testing.T) { sel := widget.NewSelect([]string{"Option A", "Option B", "Option C"}, nil) @@ -191,8 +187,7 @@ func TestSelect_FocusRendering(t *testing.T) { } func TestSelect_KeyboardControl(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) t.Run("activate pop-up", func(t *testing.T) { sel := widget.NewSelect([]string{"Option A", "Option B"}, nil) @@ -284,8 +279,7 @@ func TestSelect_KeyboardControl(t *testing.T) { } func TestSelect_Move(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) combo := widget.NewSelect([]string{"1", "2"}, nil) w := test.NewWindow(combo) @@ -324,8 +318,7 @@ func TestSelect_SelectedIndex(t *testing.T) { } func TestSelect_SetSelected(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) var triggered bool var triggeredValue string @@ -417,8 +410,7 @@ func TestSelect_SetSelectedIndex_Invalid(t *testing.T) { } func TestSelect_Tapped(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) combo := widget.NewSelect([]string{"1", "2"}, func(s string) {}) w := test.NewWindow(combo) @@ -433,8 +425,7 @@ func TestSelect_Tapped(t *testing.T) { } func TestSelect_Tapped_Constrained(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) combo := widget.NewSelect([]string{"1", "2"}, func(s string) {}) w := test.NewWindow(combo) @@ -450,8 +441,7 @@ func TestSelect_Tapped_Constrained(t *testing.T) { } func TestSelect_Layout(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) for name, tt := range map[string]struct { placeholder string diff --git a/widget/slider_test.go b/widget/slider_test.go index 8521ebed30..9f504d577f 100644 --- a/widget/slider_test.go +++ b/widget/slider_test.go @@ -68,8 +68,7 @@ func TestSlider_Clamp(t *testing.T) { } func TestSlider_HorizontalLayout(t *testing.T) { - app := test.NewApp() - defer test.NewApp() + app := test.NewTempApp(t) app.Settings().SetTheme(internalTest.LightTheme(theme.DefaultTheme())) slider := NewSlider(0, 1) @@ -110,8 +109,7 @@ func TestSlider_OutOfRange(t *testing.T) { } func TestSlider_VerticalLayout(t *testing.T) { - app := test.NewApp() - defer test.NewApp() + app := test.NewTempApp(t) app.Settings().SetTheme(internalTest.LightTheme(theme.DefaultTheme())) slider := NewSlider(0, 1) diff --git a/widget/table_desktop_test.go b/widget/table_desktop_test.go index e06990b227..77ca292c61 100644 --- a/widget/table_desktop_test.go +++ b/widget/table_desktop_test.go @@ -13,8 +13,7 @@ import ( ) func TestTable_Hovered(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) table := NewTable( func() (int, int) { return 2, 2 }, diff --git a/widget/table_test.go b/widget/table_test.go index b634f532a8..07066067e5 100644 --- a/widget/table_test.go +++ b/widget/table_test.go @@ -54,8 +54,7 @@ func TestTable_Cache(t *testing.T) { } func TestTable_ChangeTheme(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) table := NewTable( func() (int, int) { return 3, 5 }, @@ -85,8 +84,7 @@ func TestTable_ChangeTheme(t *testing.T) { } func TestTable_Filled(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) table := NewTable( @@ -107,7 +105,7 @@ func TestTable_Filled(t *testing.T) { } func TestTable_Focus(t *testing.T) { - defer test.NewApp() + test.NewTempApp(t) table := NewTable( func() (int, int) { return 5, 5 }, @@ -168,8 +166,7 @@ func TestTable_Headers(t *testing.T) { func TestTable_JustHeaders(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) table := NewTableWithHeaders( func() (int, int) { return 0, 9 }, @@ -321,8 +318,7 @@ func TestTable_Resize(t *testing.T) { } func TestTable_Unselect(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) table := NewTable( func() (int, int) { return 3, 5 }, @@ -385,8 +381,7 @@ func TestTable_Refresh(t *testing.T) { } func TestTable_ScrollTo(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) // for this test the separator thickness is 0 test.ApplyTheme(t, &paddingZeroTheme{test.Theme()}) @@ -482,8 +477,7 @@ func TestTable_ScrollTo(t *testing.T) { } func TestTable_ScrollToBottom(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, test.NewTheme()) const ( @@ -517,8 +511,7 @@ func TestTable_ScrollToBottom(t *testing.T) { } func TestTable_ScrollToLeading(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) table := NewTable( func() (int, int) { return 3, 5 }, @@ -543,8 +536,7 @@ func TestTable_ScrollToLeading(t *testing.T) { } func TestTable_ScrollToTop(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) const ( maxRows int = 6 @@ -575,8 +567,7 @@ func TestTable_ScrollToTop(t *testing.T) { } func TestTable_ScrollToTrailing(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) table := NewTable( func() (int, int) { return 24, 24 }, @@ -604,8 +595,7 @@ func TestTable_ScrollToTrailing(t *testing.T) { } func TestTable_Selection(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) table := NewTable( func() (int, int) { return 5, 5 }, @@ -648,8 +638,7 @@ func TestTable_Selection(t *testing.T) { } func TestTable_Selection_OnHeader(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) table := NewTableWithHeaders( func() (int, int) { return 5, 5 }, @@ -678,8 +667,7 @@ func TestTable_Selection_OnHeader(t *testing.T) { } func TestTable_Select(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) table := NewTable( func() (int, int) { return 5, 5 }, @@ -716,8 +704,7 @@ func TestTable_Select(t *testing.T) { } func TestTable_SetColumnWidth(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) table := NewTable( @@ -796,8 +783,7 @@ func TestTable_SetColumnWidth_Dragged(t *testing.T) { } func TestTable_SetRowHeight(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) table := NewTable( @@ -890,8 +876,7 @@ func TestTable_ShowVisible(t *testing.T) { } func TestTable_SeparatorThicknessZero_NotPanics(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, &paddingZeroTheme{test.Theme()}) diff --git a/widget/tree_internal_test.go b/widget/tree_internal_test.go index 2107b4c982..5d7124b216 100644 --- a/widget/tree_internal_test.go +++ b/widget/tree_internal_test.go @@ -558,8 +558,7 @@ func TestTree_Select_Unselects(t *testing.T) { } func TestTree_ScrollTo(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, test.NewTheme()) data := make(map[string][]string) @@ -593,8 +592,7 @@ func TestTree_ScrollTo(t *testing.T) { } func TestTree_ScrollToBottom(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, test.NewTheme()) data := make(map[string][]string) @@ -663,8 +661,7 @@ func TestTree_ScrollToSelection(t *testing.T) { } func TestTree_ScrollToTop(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, test.NewTheme()) data := make(map[string][]string) diff --git a/widget/tree_test.go b/widget/tree_test.go index d53b3fc5cf..cf9260adf6 100644 --- a/widget/tree_test.go +++ b/widget/tree_test.go @@ -287,8 +287,7 @@ func TestTree_Layout(t *testing.T) { } func TestTree_ChangeTheme(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) tree := widget.NewTreeWithStrings(treeData) tree.OpenBranch("foo") @@ -309,8 +308,7 @@ func TestTree_ChangeTheme(t *testing.T) { } func TestTree_Move(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) tree := widget.NewTreeWithStrings(treeData) tree.OpenBranch("foo") @@ -328,8 +326,7 @@ func TestTree_Move(t *testing.T) { } func TestTree_Refresh(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) value := "Foo Leaf" diff --git a/widget/widget_test.go b/widget/widget_test.go index 780ff2ec8e..8a34b7cfe1 100644 --- a/widget/widget_test.go +++ b/widget/widget_test.go @@ -66,8 +66,7 @@ func TestApplyThemeCalledChild(t *testing.T) { } func TestSimpleRenderer(t *testing.T) { - test.NewApp() - defer test.NewApp() + test.NewTempApp(t) c := &fyne.Container{Layout: layout.NewStackLayout(), Objects: []fyne.CanvasObject{ newTestWidget(canvas.NewRectangle(color.Gray{Y: 0x79})), From 73ede978a2471fd6305f3b8e41b26c9b9b719050 Mon Sep 17 00:00:00 2001 From: Jacob Date: Sat, 18 May 2024 23:08:43 +0200 Subject: [PATCH 04/78] Fix a few more unclosed windows --- internal/app/theme_test.go | 3 ++- widget/entry_internal_test.go | 2 ++ widget/entry_password_extend_test.go | 1 + widget/list_test.go | 2 ++ widget/menu_desktop_test.go | 1 + 5 files changed, 8 insertions(+), 1 deletion(-) diff --git a/internal/app/theme_test.go b/internal/app/theme_test.go index a628fbe3a9..4109be02de 100644 --- a/internal/app/theme_test.go +++ b/internal/app/theme_test.go @@ -9,7 +9,8 @@ import ( func TestApplySettings_BeforeContentSet(t *testing.T) { a := test.NewApp() - _ = a.NewWindow("NoContent") + w := a.NewWindow("NoContent") + defer w.Close() app.ApplySettings(a.Settings(), a) } diff --git a/widget/entry_internal_test.go b/widget/entry_internal_test.go index b770924197..8af9f2f617 100644 --- a/widget/entry_internal_test.go +++ b/widget/entry_internal_test.go @@ -346,6 +346,7 @@ func TestEntry_PasteFromClipboard(t *testing.T) { entry := NewEntry() w := test.NewApp().NewWindow("") + defer w.Close() w.SetContent(entry) testContent := "test" @@ -363,6 +364,7 @@ func TestEntry_PasteFromClipboard_MultilineWrapping(t *testing.T) { entry.Wrapping = fyne.TextWrapWord w := test.NewApp().NewWindow("") + defer w.Close() w.SetContent(entry) w.Resize(fyne.NewSize(108, 64)) diff --git a/widget/entry_password_extend_test.go b/widget/entry_password_extend_test.go index 71f4011413..6fe43b7251 100644 --- a/widget/entry_password_extend_test.go +++ b/widget/entry_password_extend_test.go @@ -18,6 +18,7 @@ func TestEntry_Password_Extended_CreateRenderer(t *testing.T) { a := test.NewApp() defer test.NewApp() w := a.NewWindow("") + defer w.Close() entry := &extendEntry{} entry.ExtendBaseWidget(entry) entry.Password = true diff --git a/widget/list_test.go b/widget/list_test.go index 4d0c11c9ff..9fc237375c 100644 --- a/widget/list_test.go +++ b/widget/list_test.go @@ -629,6 +629,7 @@ func setupList(t *testing.T) (*List, fyne.Window) { func TestList_LimitUpdateItem(t *testing.T) { app := test.NewApp() w := app.NewWindow("") + defer w.Close() printOut := "" list := NewList( func() int { @@ -653,6 +654,7 @@ func TestList_LimitUpdateItem(t *testing.T) { func TestList_RefreshUpdatesAllItems(t *testing.T) { app := test.NewApp() w := app.NewWindow("") + defer w.Close() printOut := "" list := NewList( func() int { diff --git a/widget/menu_desktop_test.go b/widget/menu_desktop_test.go index 4d4f5743a2..068678370d 100644 --- a/widget/menu_desktop_test.go +++ b/widget/menu_desktop_test.go @@ -338,6 +338,7 @@ func TestMenu_TriggerTraversedMenu(t *testing.T) { )) m.OnDismiss = func() { dismissed = true } w := fyne.CurrentApp().NewWindow("") + t.Cleanup(w.Close) w.SetContent(internalWidget.NewOverlayContainer(m, w.Canvas(), nil)) return m } From 7c207d7ccbeba61b11aea93d6d0124ea5a4daf42 Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Wed, 22 May 2024 19:01:29 -0700 Subject: [PATCH 05/78] add AppendMarkdown function to RichText --- widget/markdown.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/widget/markdown.go b/widget/markdown.go index 8bbf8e41d2..157fa0ac41 100644 --- a/widget/markdown.go +++ b/widget/markdown.go @@ -27,6 +27,13 @@ func (t *RichText) ParseMarkdown(content string) { t.Refresh() } +// AppendMarkdown parses the given markdown string and appends the +// content to the widget, with the appropriate formatting. +func (t *RichText) AppendMarkdown(content string) { + t.Segments = append(t.Segments, parseMarkdown(content)...) + t.Refresh() +} + type markdownRenderer []RichTextSegment func (m *markdownRenderer) AddOptions(...renderer.Option) {} From 7cf308374a4e3c7e59dabe4c091cfa4713e4a6aa Mon Sep 17 00:00:00 2001 From: Jacob Date: Thu, 23 May 2024 11:03:33 +0200 Subject: [PATCH 06/78] Avoid some code duplication --- test/testwindow.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/testwindow.go b/test/testwindow.go index 9092c5f5d0..5e3fc113eb 100644 --- a/test/testwindow.go +++ b/test/testwindow.go @@ -25,8 +25,7 @@ type testWindow struct { // // Since: 2.5 func NewTempWindow(t testing.TB, content fyne.CanvasObject) fyne.Window { - window := fyne.CurrentApp().NewWindow("") - window.SetContent(content) + window := NewWindow(content) t.Cleanup(window.Close) return window } From 089f20b7637fbeb4470ef8984a12df7436c9f29f Mon Sep 17 00:00:00 2001 From: Jacob Date: Thu, 23 May 2024 12:37:18 +0200 Subject: [PATCH 07/78] Introduce test.TempWidgetRenderer to destroy the renderer once the test completes This allows us to fix many cases where the tests created and looked up widget renderers that would stay alive until a new window was created and the old was destroyed. --- container/apptabs_extend_test.go | 16 ++++++++-------- container/apptabs_test.go | 4 ++-- container/doctabs_extend_test.go | 16 ++++++++-------- container/doctabs_test.go | 2 +- container/multiplewindows_test.go | 2 +- container/split_test.go | 8 ++++---- dialog/file_test.go | 18 +++++++++--------- dialog/fileitem_test.go | 8 ++++---- dialog/folder_test.go | 4 ++-- test/test.go | 8 ++++++++ widget/accordion_internal_test.go | 20 ++++++++++---------- widget/activity_internal_test.go | 2 +- widget/button_internal_test.go | 28 ++++++++++++++-------------- widget/card_test.go | 4 ++-- widget/check_internal_test.go | 12 ++++++------ widget/entry_password_extend_test.go | 10 +++++----- widget/entry_password_test.go | 6 +++--- widget/entry_test.go | 2 +- widget/form_extend_test.go | 2 +- widget/form_test.go | 6 +++--- widget/icon_internal_test.go | 6 +++--- widget/label_test.go | 8 ++++---- widget/list_test.go | 8 ++++---- widget/progressbar_extend_test.go | 2 +- widget/progressbar_test.go | 6 +++--- widget/progressbarinfinite_test.go | 2 +- widget/radio_group_extended_test.go | 8 ++++---- widget/radio_group_internal_test.go | 22 +++++++++++----------- widget/radio_item_test.go | 2 +- widget/richtext_objects_test.go | 12 ++++++------ widget/richtext_test.go | 6 +++--- widget/select_internal_test.go | 4 ++-- widget/slider_test.go | 4 ++-- widget/table_test.go | 20 ++++++++++---------- widget/textgrid_test.go | 18 +++++++++--------- widget/toolbar_test.go | 2 +- widget/tree_internal_test.go | 10 +++++----- 37 files changed, 163 insertions(+), 155 deletions(-) diff --git a/container/apptabs_extend_test.go b/container/apptabs_extend_test.go index f9fd6b6fff..1f53648823 100644 --- a/container/apptabs_extend_test.go +++ b/container/apptabs_extend_test.go @@ -30,31 +30,31 @@ func TestAppTabs_Extended_Tapped(t *testing.T) { NewTabItem("Test2", widget.NewLabel("Test2")), ) tabs.Resize(fyne.NewSize(150, 150)) // Ensure AppTabs is big enough to show both tab buttons - r := test.WidgetRenderer(tabs).(*appTabsRenderer) + r := test.TempWidgetRenderer(t, tabs).(*appTabsRenderer) tab1 := r.bar.Objects[0].(*fyne.Container).Objects[0].(*tabButton) tab2 := r.bar.Objects[0].(*fyne.Container).Objects[1].(*tabButton) require.Equal(t, 0, tabs.SelectedIndex()) - require.Equal(t, theme.PrimaryColor(), test.WidgetRenderer(tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) tab2.Tapped(&fyne.PointEvent{}) assert.Equal(t, 1, tabs.SelectedIndex()) - require.Equal(t, theme.ForegroundColor(), test.WidgetRenderer(tab1).(*tabButtonRenderer).label.Color) - require.Equal(t, theme.PrimaryColor(), test.WidgetRenderer(tab2).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.ForegroundColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) assert.False(t, tabs.Items[0].Content.Visible()) assert.True(t, tabs.Items[1].Content.Visible()) tab2.Tapped(&fyne.PointEvent{}) assert.Equal(t, 1, tabs.SelectedIndex()) - require.Equal(t, theme.ForegroundColor(), test.WidgetRenderer(tab1).(*tabButtonRenderer).label.Color) - require.Equal(t, theme.PrimaryColor(), test.WidgetRenderer(tab2).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.ForegroundColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) assert.False(t, tabs.Items[0].Content.Visible()) assert.True(t, tabs.Items[1].Content.Visible()) tab1.Tapped(&fyne.PointEvent{}) assert.Equal(t, 0, tabs.SelectedIndex()) - require.Equal(t, theme.PrimaryColor(), test.WidgetRenderer(tab1).(*tabButtonRenderer).label.Color) - require.Equal(t, theme.ForegroundColor(), test.WidgetRenderer(tab2).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.ForegroundColor(), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) assert.True(t, tabs.Items[0].Content.Visible()) assert.False(t, tabs.Items[1].Content.Visible()) } diff --git a/container/apptabs_test.go b/container/apptabs_test.go index 5a18252f1c..7958e48412 100644 --- a/container/apptabs_test.go +++ b/container/apptabs_test.go @@ -39,7 +39,7 @@ func TestAppTabs_Empty(t *testing.T) { tabs = &AppTabs{} assert.Equal(t, 0, len(tabs.Items)) assert.Nil(t, tabs.Selected()) - assert.NotNil(t, test.WidgetRenderer(tabs)) // doesn't crash + assert.NotNil(t, test.TempWidgetRenderer(t, tabs)) // doesn't crash } func TestAppTabs_Hidden_AsChild(t *testing.T) { @@ -183,7 +183,7 @@ func TestAppTabs_DisableIndex(t *testing.T) { func TestAppTabs_ShowAfterAdd(t *testing.T) { tabs := NewAppTabs() - renderer := test.WidgetRenderer(tabs).(*appTabsRenderer) + renderer := test.TempWidgetRenderer(t, tabs).(*appTabsRenderer) assert.True(t, renderer.indicator.Hidden) diff --git a/container/doctabs_extend_test.go b/container/doctabs_extend_test.go index bd331730dd..00eb83d9e0 100644 --- a/container/doctabs_extend_test.go +++ b/container/doctabs_extend_test.go @@ -30,32 +30,32 @@ func TestDocTabs_Extended_Tapped(t *testing.T) { NewTabItem("Test2", widget.NewLabel("Test2")), ) tabs.Resize(fyne.NewSize(150, 150)) // Ensure DocTabs is big enough to show both tab buttons - r := test.WidgetRenderer(tabs).(*docTabsRenderer) + r := test.TempWidgetRenderer(t, tabs).(*docTabsRenderer) buttons := r.bar.Objects[0].(*Scroll).Content.(*fyne.Container).Objects tab1 := buttons[0].(*tabButton) tab2 := buttons[1].(*tabButton) require.Equal(t, 0, tabs.SelectedIndex()) - require.Equal(t, theme.PrimaryColor(), test.WidgetRenderer(tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) tab2.Tapped(&fyne.PointEvent{}) assert.Equal(t, 1, tabs.SelectedIndex()) - require.Equal(t, theme.ForegroundColor(), test.WidgetRenderer(tab1).(*tabButtonRenderer).label.Color) - require.Equal(t, theme.PrimaryColor(), test.WidgetRenderer(tab2).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.ForegroundColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) assert.False(t, tabs.Items[0].Content.Visible()) assert.True(t, tabs.Items[1].Content.Visible()) tab2.Tapped(&fyne.PointEvent{}) assert.Equal(t, 1, tabs.SelectedIndex()) - require.Equal(t, theme.ForegroundColor(), test.WidgetRenderer(tab1).(*tabButtonRenderer).label.Color) - require.Equal(t, theme.PrimaryColor(), test.WidgetRenderer(tab2).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.ForegroundColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) assert.False(t, tabs.Items[0].Content.Visible()) assert.True(t, tabs.Items[1].Content.Visible()) tab1.Tapped(&fyne.PointEvent{}) assert.Equal(t, 0, tabs.SelectedIndex()) - require.Equal(t, theme.PrimaryColor(), test.WidgetRenderer(tab1).(*tabButtonRenderer).label.Color) - require.Equal(t, theme.ForegroundColor(), test.WidgetRenderer(tab2).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.ForegroundColor(), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) assert.True(t, tabs.Items[0].Content.Visible()) assert.False(t, tabs.Items[1].Content.Visible()) } diff --git a/container/doctabs_test.go b/container/doctabs_test.go index a6cb924393..e0c24dff14 100644 --- a/container/doctabs_test.go +++ b/container/doctabs_test.go @@ -40,7 +40,7 @@ func TestDocTabs_Empty(t *testing.T) { tabs = &container.DocTabs{} assert.Equal(t, 0, len(tabs.Items)) assert.Nil(t, tabs.Selected()) - assert.NotNil(t, test.WidgetRenderer(tabs)) // doesn't crash + assert.NotNil(t, test.TempWidgetRenderer(t, tabs)) // doesn't crash } func TestDocTabs_Hidden_AsChild(t *testing.T) { diff --git a/container/multiplewindows_test.go b/container/multiplewindows_test.go index ea895bdfdb..c8901abb3a 100644 --- a/container/multiplewindows_test.go +++ b/container/multiplewindows_test.go @@ -20,7 +20,7 @@ func TestMultipleWindows_Add(t *testing.T) { func TestMultipleWindows_Drag(t *testing.T) { w := NewInnerWindow("1", widget.NewLabel("Inside")) m := NewMultipleWindows(w) - _ = test.WidgetRenderer(m) // initialise display + _ = test.TempWidgetRenderer(t, m) // initialise display assert.Equal(t, 1, len(m.Windows)) assert.True(t, w.Position().IsZero()) diff --git a/container/split_test.go b/container/split_test.go index 1f7d5c6c15..a7c1ee52d1 100644 --- a/container/split_test.go +++ b/container/split_test.go @@ -290,7 +290,7 @@ func TestSplitContainer_divider_drag(t *testing.T) { t.Run("Horizontal", func(t *testing.T) { split := NewHSplit(objA, objB) split.Resize(fyne.NewSize(108, 108)) - divider := test.WidgetRenderer(split).(*splitContainerRenderer).divider + divider := test.TempWidgetRenderer(t, split).(*splitContainerRenderer).divider assert.Equal(t, 0.5, split.Offset) divider.Dragged(&fyne.DragEvent{ @@ -324,7 +324,7 @@ func TestSplitContainer_divider_drag(t *testing.T) { t.Run("Vertical", func(t *testing.T) { split := NewVSplit(objA, objB) split.Resize(fyne.NewSize(108, 108)) - divider := test.WidgetRenderer(split).(*splitContainerRenderer).divider + divider := test.TempWidgetRenderer(t, split).(*splitContainerRenderer).divider assert.Equal(t, 0.5, split.Offset) divider.Dragged(&fyne.DragEvent{ @@ -366,7 +366,7 @@ func TestSplitContainer_divider_drag_StartOffsetLessThanMinSize(t *testing.T) { t.Run("Horizontal", func(t *testing.T) { split := NewHSplit(objA, objB) split.Resize(fyne.NewSize(108, 108)) - divider := test.WidgetRenderer(split).(*splitContainerRenderer).divider + divider := test.TempWidgetRenderer(t, split).(*splitContainerRenderer).divider t.Run("Leading", func(t *testing.T) { split.SetOffset(0.1) @@ -391,7 +391,7 @@ func TestSplitContainer_divider_drag_StartOffsetLessThanMinSize(t *testing.T) { t.Run("Vertical", func(t *testing.T) { split := NewVSplit(objA, objB) split.Resize(fyne.NewSize(108, 108)) - divider := test.WidgetRenderer(split).(*splitContainerRenderer).divider + divider := test.TempWidgetRenderer(t, split).(*splitContainerRenderer).divider t.Run("Leading", func(t *testing.T) { split.SetOffset(0.1) diff --git a/dialog/file_test.go b/dialog/file_test.go index 0c67fe767a..a81e329f39 100644 --- a/dialog/file_test.go +++ b/dialog/file_test.go @@ -214,17 +214,17 @@ func TestShowFileOpen(t *testing.T) { } files := ui.Objects[0].(*container.Split).Trailing.(*fyne.Container).Objects[1].(*container.Scroll).Content.(*fyne.Container).Objects[0].(*widget.GridWrap) - objects := test.WidgetRenderer(files).Objects()[0].(*container.Scroll).Content.(*fyne.Container).Objects + objects := test.TempWidgetRenderer(t, files).Objects()[0].(*container.Scroll).Content.(*fyne.Container).Objects assert.Greater(t, len(objects), 0) - fileName := test.WidgetRenderer(objects[0].(fyne.Widget)).Objects()[1].(*fileDialogItem).name + fileName := test.TempWidgetRenderer(t, objects[0].(fyne.Widget)).Objects()[1].(*fileDialogItem).name assert.Equal(t, "(Parent)", fileName) assert.True(t, open.Disabled()) var target *fileDialogItem id := 0 for i, icon := range objects { - item := test.WidgetRenderer(icon.(fyne.Widget)).Objects()[1].(*fileDialogItem) + item := test.TempWidgetRenderer(t, icon.(fyne.Widget)).Objects()[1].(*fileDialogItem) if item.dir == false { target = item id = i @@ -283,12 +283,12 @@ func TestHiddenFiles(t *testing.T) { assert.Equal(t, theme.SettingsIcon().Name(), optionsButton.Icon.Name()) files := ui.Objects[0].(*container.Split).Trailing.(*fyne.Container).Objects[1].(*container.Scroll).Content.(*fyne.Container).Objects[0].(*widget.GridWrap) - objects := test.WidgetRenderer(files).Objects()[0].(*container.Scroll).Content.(*fyne.Container).Objects + objects := test.TempWidgetRenderer(t, files).Objects()[0].(*container.Scroll).Content.(*fyne.Container).Objects assert.Greater(t, len(objects), 0) var target *fileDialogItem for _, icon := range objects { - item := test.WidgetRenderer(icon.(fyne.Widget)).Objects()[1].(*fileDialogItem) + item := test.TempWidgetRenderer(t, icon.(fyne.Widget)).Objects()[1].(*fileDialogItem) if item.name == ".hidden" { target = item } @@ -299,7 +299,7 @@ func TestHiddenFiles(t *testing.T) { d.dialog.refreshDir(d.dialog.dir) for _, icon := range objects { - item := test.WidgetRenderer(icon.(fyne.Widget)).Objects()[1].(*fileDialogItem) + item := test.TempWidgetRenderer(t, icon.(fyne.Widget)).Objects()[1].(*fileDialogItem) if item.name == ".hidden" { target = item } @@ -330,17 +330,17 @@ func TestShowFileSave(t *testing.T) { save := buttons.Objects[1].(*widget.Button) files := ui.Objects[0].(*container.Split).Trailing.(*fyne.Container).Objects[1].(*container.Scroll).Content.(*fyne.Container).Objects[0].(*widget.GridWrap) - objects := test.WidgetRenderer(files).Objects()[0].(*container.Scroll).Content.(*fyne.Container).Objects + objects := test.TempWidgetRenderer(t, files).Objects()[0].(*container.Scroll).Content.(*fyne.Container).Objects assert.Greater(t, len(objects), 0) - item := test.WidgetRenderer(objects[0].(fyne.Widget)).Objects()[1].(*fileDialogItem) + item := test.TempWidgetRenderer(t, objects[0].(fyne.Widget)).Objects()[1].(*fileDialogItem) assert.Equal(t, "(Parent)", item.name) assert.True(t, save.Disabled()) var target *fileDialogItem id := -1 for i, icon := range objects { - item := test.WidgetRenderer(icon.(fyne.Widget)).Objects()[1].(*fileDialogItem) + item := test.TempWidgetRenderer(t, icon.(fyne.Widget)).Objects()[1].(*fileDialogItem) if item.dir == false { target = item id = i diff --git a/dialog/fileitem_test.go b/dialog/fileitem_test.go index 1187847fd5..6882ec05b2 100644 --- a/dialog/fileitem_test.go +++ b/dialog/fileitem_test.go @@ -115,14 +115,14 @@ func TestFileItem_Wrap(t *testing.T) { _ = f.makeUI() item := f.newFileItem(storage.NewFileURI("/path/to/filename.txt"), false, false) item.Resize(item.MinSize()) - label := test.WidgetRenderer(item).(*fileItemRenderer).text + label := test.TempWidgetRenderer(t, item).(*fileItemRenderer).text assert.Equal(t, "filename", label.Text) - texts := test.WidgetRenderer(label).Objects() + texts := test.TempWidgetRenderer(t, label).Objects() assert.Equal(t, 1, len(texts)) item.setLocation(storage.NewFileURI("/path/to/averylongfilename.svg"), false, false) - rich := test.WidgetRenderer(label).Objects()[0].(*widget.RichText) - texts = test.WidgetRenderer(rich).Objects() + rich := test.TempWidgetRenderer(t, label).Objects()[0].(*widget.RichText) + texts = test.TempWidgetRenderer(t, rich).Objects() assert.Equal(t, 2, len(texts)) assert.Equal(t, "averylon", texts[0].(*canvas.Text).Text) } diff --git a/dialog/folder_test.go b/dialog/folder_test.go index 768caf9ac5..08c4a4b0a8 100644 --- a/dialog/folder_test.go +++ b/dialog/folder_test.go @@ -44,8 +44,8 @@ func TestShowFolderOpen(t *testing.T) { files := ui.Objects[0].(*container.Split).Trailing.(*fyne.Container).Objects[1].(*container.Scroll).Content.(*fyne.Container).Objects[0].(*widget.GridWrap) assert.Greater(t, len(d.dialog.data), 0) - item := test.WidgetRenderer(files).Objects()[0].(*container.Scroll).Content.(*fyne.Container).Objects[0] - fileName := test.WidgetRenderer(item.(fyne.Widget)).Objects()[1].(*fileDialogItem).name + item := test.TempWidgetRenderer(t, files).Objects()[0].(*container.Scroll).Content.(*fyne.Container).Objects[0] + fileName := test.TempWidgetRenderer(t, item.(fyne.Widget)).Objects()[1].(*fileDialogItem).name assert.Equal(t, "(Parent)", fileName) assert.False(t, open.Disabled()) diff --git a/test/test.go b/test/test.go index 6ca12fe8cd..3f38aab3ad 100644 --- a/test/test.go +++ b/test/test.go @@ -299,6 +299,14 @@ func ApplyTheme(t *testing.T, theme fyne.Theme) { } } +// TempWidgetRenderer allows test scripts to gain access to the current renderer for a widget. +// This can be used for verifying correctness of rendered components for a widget in unit tests. +// The widget renderer is automatically destroyed when the test ends. +func TempWidgetRenderer(t *testing.T, wid fyne.Widget) fyne.WidgetRenderer { + t.Cleanup(func() { cache.DestroyRenderer(wid) }) + return cache.Renderer(wid) +} + // WidgetRenderer allows test scripts to gain access to the current renderer for a widget. // This can be used for verifying correctness of rendered components for a widget in unit tests. func WidgetRenderer(wid fyne.Widget) fyne.WidgetRenderer { diff --git a/widget/accordion_internal_test.go b/widget/accordion_internal_test.go index 4633d9e984..db83052ad7 100644 --- a/widget/accordion_internal_test.go +++ b/widget/accordion_internal_test.go @@ -13,7 +13,7 @@ import ( func TestAccordion_Toggle(t *testing.T) { ai := NewAccordionItem("foo", NewLabel("foobar")) ac := NewAccordion(ai) - ar := test.WidgetRenderer(ac).(*accordionRenderer) + ar := test.TempWidgetRenderer(t, ac).(*accordionRenderer) aih := ar.headers[0] assert.False(t, ai.Open) @@ -35,7 +35,7 @@ func TestAccordionRenderer_Layout(t *testing.T) { ac.Append(ai1) ac.Append(ai2) - ar := test.WidgetRenderer(ac).(*accordionRenderer) + ar := test.TempWidgetRenderer(t, ac).(*accordionRenderer) aih0 := ar.headers[0] aih1 := ar.headers[1] aih2 := ar.headers[2] @@ -143,7 +143,7 @@ func TestAccordionRenderer_Layout(t *testing.T) { func TestAccordionRenderer_MinSize(t *testing.T) { t.Run("Empty", func(t *testing.T) { ac := NewAccordion() - ar := test.WidgetRenderer(ac).(*accordionRenderer) + ar := test.TempWidgetRenderer(t, ac).(*accordionRenderer) min := ar.MinSize() assert.Equal(t, float32(0), min.Width) assert.Equal(t, float32(0), min.Height) @@ -154,7 +154,7 @@ func TestAccordionRenderer_MinSize(t *testing.T) { ac := NewAccordion() ac.Append(ai) ac.Open(0) - ar := test.WidgetRenderer(ac).(*accordionRenderer) + ar := test.TempWidgetRenderer(t, ac).(*accordionRenderer) min := ar.MinSize() aih := ar.headers[0].MinSize() aid := ai.Detail.MinSize() @@ -165,7 +165,7 @@ func TestAccordionRenderer_MinSize(t *testing.T) { ac := NewAccordion() ac.Append(ai) ac.Close(0) - ar := test.WidgetRenderer(ac).(*accordionRenderer) + ar := test.TempWidgetRenderer(t, ac).(*accordionRenderer) min := ar.MinSize() aih := ar.headers[0].MinSize() assert.Equal(t, aih.Width, min.Width) @@ -184,7 +184,7 @@ func TestAccordionRenderer_MinSize(t *testing.T) { ac.Open(0) ac.Close(1) ac.Close(2) - ar := test.WidgetRenderer(ac).(*accordionRenderer) + ar := test.TempWidgetRenderer(t, ac).(*accordionRenderer) min := ar.MinSize() aih0 := ar.headers[0].MinSize() aih1 := ar.headers[1].MinSize() @@ -209,7 +209,7 @@ func TestAccordionRenderer_MinSize(t *testing.T) { ac.Append(ai1) ac.Append(ai2) ac.OpenAll() - ar := test.WidgetRenderer(ac).(*accordionRenderer) + ar := test.TempWidgetRenderer(t, ac).(*accordionRenderer) min := ar.MinSize() aih0 := ar.headers[0].MinSize() aih1 := ar.headers[1].MinSize() @@ -242,7 +242,7 @@ func TestAccordionRenderer_MinSize(t *testing.T) { ac.Open(0) ac.Open(1) ac.Close(2) - ar := test.WidgetRenderer(ac).(*accordionRenderer) + ar := test.TempWidgetRenderer(t, ac).(*accordionRenderer) min := ar.MinSize() aih0 := ar.headers[0].MinSize() aih1 := ar.headers[1].MinSize() @@ -268,7 +268,7 @@ func TestAccordionRenderer_MinSize(t *testing.T) { ac.Append(ai1) ac.Append(ai2) ac.CloseAll() - ar := test.WidgetRenderer(ac).(*accordionRenderer) + ar := test.TempWidgetRenderer(t, ac).(*accordionRenderer) min := ar.MinSize() aih0 := ar.headers[0].MinSize() aih1 := ar.headers[1].MinSize() @@ -287,7 +287,7 @@ func TestAccordionRenderer_MinSize(t *testing.T) { func TestAccordionRenderer_AddRemove(t *testing.T) { ac := NewAccordion() - ar := test.WidgetRenderer(ac).(*accordionRenderer) + ar := test.TempWidgetRenderer(t, ac).(*accordionRenderer) ac.Append(NewAccordionItem("foo0", NewLabel("foobar0"))) ac.Append(NewAccordionItem("foo1", NewLabel("foobar1"))) ac.Append(NewAccordionItem("foo2", NewLabel("foobar2"))) diff --git a/widget/activity_internal_test.go b/widget/activity_internal_test.go index 13372186da..9aa44526d4 100644 --- a/widget/activity_internal_test.go +++ b/widget/activity_internal_test.go @@ -17,7 +17,7 @@ func TestActivity_Animation(t *testing.T) { defer w.Close() w.Resize(a.MinSize()) - render := test.WidgetRenderer(a).(*activityRenderer) + render := test.TempWidgetRenderer(t, a).(*activityRenderer) render.anim.Tick(0) test.AssertImageMatches(t, "activity/animate_0.0.png", w.Canvas().Capture()) diff --git a/widget/button_internal_test.go b/widget/button_internal_test.go index 72c401aa81..9e2285a2f6 100644 --- a/widget/button_internal_test.go +++ b/widget/button_internal_test.go @@ -18,7 +18,7 @@ import ( func TestButton_Style(t *testing.T) { button := NewButton("Test", nil) - render := test.WidgetRenderer(button).(*buttonRenderer) + render := test.TempWidgetRenderer(t, button).(*buttonRenderer) render.applyTheme() bg := render.background.FillColor @@ -29,7 +29,7 @@ func TestButton_Style(t *testing.T) { func TestButton_DisabledColor(t *testing.T) { button := NewButton("Test", nil) - render := test.WidgetRenderer(button).(*buttonRenderer) + render := test.TempWidgetRenderer(t, button).(*buttonRenderer) render.applyTheme() bg := render.background.FillColor button.Importance = MediumImportance @@ -43,7 +43,7 @@ func TestButton_DisabledColor(t *testing.T) { func TestButton_Hover_Math(t *testing.T) { button := NewButtonWithIcon("Test", theme.HomeIcon(), func() {}) - render := test.WidgetRenderer(button).(*buttonRenderer) + render := test.TempWidgetRenderer(t, button).(*buttonRenderer) button.hovered = true // unpremultiplied over operator: // outA = srcA + dstA*(1-srcA) @@ -82,7 +82,7 @@ func TestButton_Hover_Math(t *testing.T) { func TestButton_DisabledIcon(t *testing.T) { button := NewButtonWithIcon("Test", theme.CancelIcon(), nil) - render := test.WidgetRenderer(button).(*buttonRenderer) + render := test.TempWidgetRenderer(t, button).(*buttonRenderer) assert.Equal(t, render.icon.Resource.Name(), theme.CancelIcon().Name()) button.Disable() @@ -94,7 +94,7 @@ func TestButton_DisabledIcon(t *testing.T) { func TestButton_DisabledIconChangeUsingSetIcon(t *testing.T) { button := NewButtonWithIcon("Test", theme.CancelIcon(), nil) - render := test.WidgetRenderer(button).(*buttonRenderer) + render := test.TempWidgetRenderer(t, button).(*buttonRenderer) assert.Equal(t, render.icon.Resource.Name(), theme.CancelIcon().Name()) // assert we are using the disabled original icon @@ -116,7 +116,7 @@ func TestButton_DisabledIconChangeUsingSetIcon(t *testing.T) { func TestButton_DisabledIconChangedDirectly(t *testing.T) { button := NewButtonWithIcon("Test", theme.CancelIcon(), nil) - render := test.WidgetRenderer(button).(*buttonRenderer) + render := test.TempWidgetRenderer(t, button).(*buttonRenderer) assert.Equal(t, render.icon.Resource.Name(), theme.CancelIcon().Name()) // assert we are using the disabled original icon @@ -142,7 +142,7 @@ func TestButton_Focus(t *testing.T) { button := NewButton("Test", func() { tapped = true }) - render := test.WidgetRenderer(button).(*buttonRenderer) + render := test.TempWidgetRenderer(t, button).(*buttonRenderer) render.applyTheme() assert.Equal(t, theme.ButtonColor(), render.background.FillColor) @@ -161,7 +161,7 @@ func TestButton_Focus(t *testing.T) { func TestButtonRenderer_Layout(t *testing.T) { button := NewButtonWithIcon("Test", theme.CancelIcon(), nil) - render := test.WidgetRenderer(button).(*buttonRenderer) + render := test.TempWidgetRenderer(t, button).(*buttonRenderer) render.Layout(render.MinSize()) assert.True(t, render.icon.Position().X < render.label.Position().X) @@ -172,7 +172,7 @@ func TestButtonRenderer_Layout(t *testing.T) { func TestButtonRenderer_Layout_Stretch(t *testing.T) { button := NewButtonWithIcon("Test", theme.CancelIcon(), nil) button.Resize(button.MinSize().Add(fyne.NewSize(100, 100))) - render := test.WidgetRenderer(button).(*buttonRenderer) + render := test.TempWidgetRenderer(t, button).(*buttonRenderer) textHeight := render.label.MinSize().Height minIconHeight := fyne.Max(theme.IconInlineSize(), textHeight) @@ -186,7 +186,7 @@ func TestButtonRenderer_Layout_Stretch(t *testing.T) { func TestButtonRenderer_Layout_NoText(t *testing.T) { button := NewButtonWithIcon("", theme.CancelIcon(), nil) - render := test.WidgetRenderer(button).(*buttonRenderer) + render := test.TempWidgetRenderer(t, button).(*buttonRenderer) button.Resize(fyne.NewSize(100, 100)) @@ -196,8 +196,8 @@ func TestButtonRenderer_Layout_NoText(t *testing.T) { func TestButtonRenderer_ApplyTheme(t *testing.T) { button := &Button{} - render := test.WidgetRenderer(button).(*buttonRenderer) - textRender := test.WidgetRenderer(render.label).(*textRenderer) + render := test.TempWidgetRenderer(t, button).(*buttonRenderer) + textRender := test.TempWidgetRenderer(t, render.label).(*textRenderer) textSize := textRender.Objects()[0].(*canvas.Text).TextSize customTextSize := textSize @@ -220,7 +220,7 @@ func TestButtonRenderer_TapAnimation(t *testing.T) { w.Resize(fyne.NewSize(50, 50).Add(fyne.NewSize(20, 20))) button.Resize(fyne.NewSize(50, 50)) - render1 := test.WidgetRenderer(button).(*buttonRenderer) + render1 := test.TempWidgetRenderer(t, button).(*buttonRenderer) test.Tap(button) button.tapAnim.Tick(0.5) test.AssertImageMatches(t, "button/tap_animation.png", w.Canvas().Capture()) @@ -228,7 +228,7 @@ func TestButtonRenderer_TapAnimation(t *testing.T) { cache.DestroyRenderer(button) button.Refresh() - render2 := test.WidgetRenderer(button).(*buttonRenderer) + render2 := test.TempWidgetRenderer(t, button).(*buttonRenderer) assert.NotEqual(t, render1, render2) diff --git a/widget/card_test.go b/widget/card_test.go index 1765040a63..2e914e165d 100644 --- a/widget/card_test.go +++ b/widget/card_test.go @@ -15,7 +15,7 @@ import ( func TestCard_SetImage(t *testing.T) { c := widget.NewCard("Title", "sub", widget.NewLabel("Content")) - r := test.WidgetRenderer(c) + r := test.TempWidgetRenderer(t, c) assert.Equal(t, 4, len(r.Objects())) // the 3 above plus shadow c.SetImage(canvas.NewImageFromResource(theme.ComputerIcon())) @@ -24,7 +24,7 @@ func TestCard_SetImage(t *testing.T) { func TestCard_SetContent(t *testing.T) { c := widget.NewCard("Title", "sub", widget.NewLabel("Content")) - r := test.WidgetRenderer(c) + r := test.TempWidgetRenderer(t, c) assert.Equal(t, 4, len(r.Objects())) // the 3 above plus shadow newContent := widget.NewLabel("New") diff --git a/widget/check_internal_test.go b/widget/check_internal_test.go index 9eec2a0984..49014b0fd7 100644 --- a/widget/check_internal_test.go +++ b/widget/check_internal_test.go @@ -45,7 +45,7 @@ func TestCheckUnChecked(t *testing.T) { func TestCheck_DisabledWhenChecked(t *testing.T) { check := NewCheck("Hi", nil) check.SetChecked(true) - render := test.WidgetRenderer(check).(*checkRenderer) + render := test.TempWidgetRenderer(t, check).(*checkRenderer) assert.True(t, strings.HasPrefix(render.icon.Resource.Name(), "primary_")) @@ -55,7 +55,7 @@ func TestCheck_DisabledWhenChecked(t *testing.T) { func TestCheck_DisabledWhenUnchecked(t *testing.T) { check := NewCheck("Hi", nil) - render := test.WidgetRenderer(check).(*checkRenderer) + render := test.TempWidgetRenderer(t, check).(*checkRenderer) assert.True(t, strings.HasPrefix(render.icon.Resource.Name(), "inputBorder_")) check.Disable() @@ -129,7 +129,7 @@ func TestCheck_Focused(t *testing.T) { check := NewCheck("Test", func(on bool) {}) w := test.NewWindow(check) defer w.Close() - render := test.WidgetRenderer(check).(*checkRenderer) + render := test.TempWidgetRenderer(t, check).(*checkRenderer) assert.False(t, check.focused) assert.Equal(t, color.Transparent, render.focusIndicator.FillColor) @@ -168,7 +168,7 @@ func TestCheck_Hovered(t *testing.T) { check := NewCheck("Test", func(on bool) {}) w := test.NewWindow(check) defer w.Close() - render := test.WidgetRenderer(check).(*checkRenderer) + render := test.TempWidgetRenderer(t, check).(*checkRenderer) check.SetChecked(true) assert.False(t, check.hovered) @@ -214,7 +214,7 @@ func TestCheck_HoveredOutsideActiveArea(t *testing.T) { check := NewCheck("Test", func(on bool) {}) w := test.NewWindow(check) defer w.Close() - render := test.WidgetRenderer(check).(*checkRenderer) + render := test.TempWidgetRenderer(t, check).(*checkRenderer) check.SetChecked(true) assert.False(t, check.hovered) @@ -274,7 +274,7 @@ func TestCheck_Disabled(t *testing.T) { func TestCheckRenderer_ApplyTheme(t *testing.T) { check := &Check{} v := fyne.CurrentApp().Settings().ThemeVariant() - render := test.WidgetRenderer(check).(*checkRenderer) + render := test.TempWidgetRenderer(t, check).(*checkRenderer) textSize := render.label.TextSize customTextSize := textSize diff --git a/widget/entry_password_extend_test.go b/widget/entry_password_extend_test.go index 71f4011413..aa083bcc2b 100644 --- a/widget/entry_password_extend_test.go +++ b/widget/entry_password_extend_test.go @@ -22,19 +22,19 @@ func TestEntry_Password_Extended_CreateRenderer(t *testing.T) { entry.ExtendBaseWidget(entry) entry.Password = true entry.Wrapping = fyne.TextWrap(fyne.TextTruncateClip) - assert.NotNil(t, test.WidgetRenderer(entry)) - r := test.WidgetRenderer(entry).(*entryRenderer).scroll.Content.(*entryContent) - p := test.WidgetRenderer(r).(*entryContentRenderer).provider + assert.NotNil(t, test.TempWidgetRenderer(t, entry)) + r := test.TempWidgetRenderer(t, entry).(*entryRenderer).scroll.Content.(*entryContent) + p := test.TempWidgetRenderer(t, r).(*entryContentRenderer).provider w.SetContent(entry) test.Type(entry, "Pass") - texts := test.WidgetRenderer(p).(*textRenderer).Objects() + texts := test.TempWidgetRenderer(t, p).(*textRenderer).Objects() assert.Equal(t, passwordChar+passwordChar+passwordChar+passwordChar, texts[0].(*canvas.Text).Text) assert.NotNil(t, entry.ActionItem) test.Tap(entry.ActionItem.(*passwordRevealer)) - texts = test.WidgetRenderer(p).(*textRenderer).Objects() + texts = test.TempWidgetRenderer(t, p).(*textRenderer).Objects() assert.Equal(t, "Pass", texts[0].(*canvas.Text).Text) assert.Equal(t, entry, w.Canvas().Focused()) } diff --git a/widget/entry_password_test.go b/widget/entry_password_test.go index 10742737fa..94a7b3659b 100644 --- a/widget/entry_password_test.go +++ b/widget/entry_password_test.go @@ -14,12 +14,12 @@ import ( func TestNewPasswordEntry(t *testing.T) { p := widget.NewPasswordEntry() p.Text = "visible" - r := test.WidgetRenderer(p) + r := test.TempWidgetRenderer(t, p) cont := r.Objects()[2].(*container.Scroll).Content.(fyne.Widget) - r = test.WidgetRenderer(cont) + r = test.TempWidgetRenderer(t, cont) rich := r.Objects()[1].(*widget.RichText) - r = test.WidgetRenderer(rich) + r = test.TempWidgetRenderer(t, rich) assert.Equal(t, "•••••••", r.Objects()[0].(*canvas.Text).Text) } diff --git a/widget/entry_test.go b/widget/entry_test.go index 28f9f69215..e68ccb8f84 100644 --- a/widget/entry_test.go +++ b/widget/entry_test.go @@ -1850,7 +1850,7 @@ func TestPasswordEntry_ActionItemSizeAndPlacement(t *testing.T) { b := widget.NewButton("", func() {}) b.Icon = theme.CancelIcon() e.ActionItem = b - test.WidgetRenderer(e).Layout(e.MinSize()) + test.TempWidgetRenderer(t, e).Layout(e.MinSize()) assert.Equal(t, fyne.NewSize(theme.IconInlineSize(), theme.IconInlineSize()), b.Size()) assert.Equal(t, fyne.NewPos(e.MinSize().Width-2*theme.Padding()-b.Size().Width, 2*theme.Padding()), b.Position()) } diff --git a/widget/form_extend_test.go b/widget/form_extend_test.go index b5bef19930..7cc8a53cdb 100644 --- a/widget/form_extend_test.go +++ b/widget/form_extend_test.go @@ -16,7 +16,7 @@ func TestForm_Extended_CreateRenderer(t *testing.T) { form := &extendedForm{} form.ExtendBaseWidget(form) form.Items = []*FormItem{{Text: "test1", Widget: NewEntry()}} - assert.NotNil(t, test.WidgetRenderer(form)) + assert.NotNil(t, test.TempWidgetRenderer(t, form)) assert.Equal(t, 2, len(form.itemGrid.Objects)) form.Append("test2", NewEntry()) diff --git a/widget/form_test.go b/widget/form_test.go index efa32a0e07..e217d7f594 100644 --- a/widget/form_test.go +++ b/widget/form_test.go @@ -25,7 +25,7 @@ func TestFormSize(t *testing.T) { func TestForm_CreateRenderer(t *testing.T) { form := &Form{Items: []*FormItem{{Text: "test1", Widget: NewEntry()}}} - assert.NotNil(t, test.WidgetRenderer(form)) + assert.NotNil(t, test.TempWidgetRenderer(t, form)) assert.Equal(t, 2, len(form.itemGrid.Objects)) form.Append("test2", NewEntry()) @@ -48,7 +48,7 @@ func TestForm_Append(t *testing.T) { func TestForm_Append_Items(t *testing.T) { form := &Form{Items: []*FormItem{{Text: "test1", Widget: NewEntry()}}} assert.Equal(t, 1, len(form.Items)) - renderer := test.WidgetRenderer(form) + renderer := test.TempWidgetRenderer(t, form) form.Items = append(form.Items, NewFormItem("test2", NewEntry())) assert.True(t, len(form.Items) == 2) @@ -117,7 +117,7 @@ func TestForm_ChangeText(t *testing.T) { item := NewFormItem("Test", NewEntry()) form := NewForm(item) - renderer := test.WidgetRenderer(form) + renderer := test.TempWidgetRenderer(t, form) c := renderer.Objects()[0].(*fyne.Container).Objects[0].(*fyne.Container) assert.Equal(t, "Test", c.Objects[0].(*canvas.Text).Text) diff --git a/widget/icon_internal_test.go b/widget/icon_internal_test.go index 4ce819b80f..2a7d71836d 100644 --- a/widget/icon_internal_test.go +++ b/widget/icon_internal_test.go @@ -12,7 +12,7 @@ import ( func TestNewIcon(t *testing.T) { icon := NewIcon(theme.ConfirmIcon()) - render := test.WidgetRenderer(icon) + render := test.TempWidgetRenderer(t, icon) assert.Equal(t, 1, len(render.Objects())) obj := render.Objects()[0] @@ -25,7 +25,7 @@ func TestNewIcon(t *testing.T) { func TestIcon_Nil(t *testing.T) { icon := NewIcon(nil) - render := test.WidgetRenderer(icon) + render := test.TempWidgetRenderer(t, icon) assert.Equal(t, 1, len(render.Objects())) assert.Nil(t, render.Objects()[0].(*canvas.Image).Resource) @@ -41,7 +41,7 @@ func TestIcon_MinSize(t *testing.T) { func TestIconRenderer_ApplyTheme(t *testing.T) { icon := NewIcon(theme.CancelIcon()) - render := test.WidgetRenderer(icon).(*iconRenderer) + render := test.TempWidgetRenderer(t, icon).(*iconRenderer) visible := render.Objects()[0].Visible() render.Refresh() diff --git a/widget/label_test.go b/widget/label_test.go index d359683d96..2927fa4540 100644 --- a/widget/label_test.go +++ b/widget/label_test.go @@ -128,14 +128,14 @@ func TestText_MinSize_MultiLine(t *testing.T) { textOneLine := NewLabel("Break") min := textOneLine.MinSize() textMultiLine := NewLabel("Bre\nak") - rich := test.WidgetRenderer(textMultiLine).Objects()[0].(*RichText) + rich := test.TempWidgetRenderer(t, textMultiLine).Objects()[0].(*RichText) min2 := textMultiLine.MinSize() assert.True(t, min2.Width < min.Width) assert.True(t, min2.Height > min.Height) yPos := float32(-1) - for _, text := range test.WidgetRenderer(rich).(*textRenderer).Objects() { + for _, text := range test.TempWidgetRenderer(t, rich).(*textRenderer).Objects() { assert.True(t, text.Size().Height < min2.Height) assert.True(t, text.Position().Y > yPos) yPos = text.Position().Y @@ -158,9 +158,9 @@ func TestText_MinSizeAdjustsWithContent(t *testing.T) { func TestLabel_ApplyTheme(t *testing.T) { text := NewLabel("Line 1") text.Hide() - rich := test.WidgetRenderer(text).Objects()[0].(*RichText) + rich := test.TempWidgetRenderer(t, text).Objects()[0].(*RichText) - render := test.WidgetRenderer(rich).(*textRenderer) + render := test.TempWidgetRenderer(t, rich).(*textRenderer) assert.Equal(t, theme.ForegroundColor(), render.Objects()[0].(*canvas.Text).Color) text.Show() assert.Equal(t, theme.ForegroundColor(), render.Objects()[0].(*canvas.Text).Color) diff --git a/widget/list_test.go b/widget/list_test.go index ddd7542948..74c927f5da 100644 --- a/widget/list_test.go +++ b/widget/list_test.go @@ -28,7 +28,7 @@ func TestNewList(t *testing.T) { assert.Equal(t, 1000, list.Length()) assert.GreaterOrEqual(t, list.MinSize().Width, template.MinSize().Width) - assert.Equal(t, list.MinSize(), template.MinSize().Max(test.WidgetRenderer(list).(*listRenderer).scroller.MinSize())) + assert.Equal(t, list.MinSize(), template.MinSize().Max(test.TempWidgetRenderer(t, list).(*listRenderer).scroller.MinSize())) assert.Equal(t, float32(0), list.offsetY) } @@ -51,7 +51,7 @@ func TestNewListWithData(t *testing.T) { assert.Equal(t, 1000, list.Length()) assert.GreaterOrEqual(t, list.MinSize().Width, template.MinSize().Width) - assert.Equal(t, list.MinSize(), template.MinSize().Max(test.WidgetRenderer(list).(*listRenderer).scroller.MinSize())) + assert.Equal(t, list.MinSize(), template.MinSize().Max(test.TempWidgetRenderer(t, list).(*listRenderer).scroller.MinSize())) assert.Equal(t, float32(0), list.offsetY) } @@ -118,7 +118,7 @@ func TestList_SetItemHeight(t *testing.T) { func(ListItemID, fyne.CanvasObject) { }) - lay := test.WidgetRenderer(list).(*listRenderer).layout + lay := test.TempWidgetRenderer(t, list).(*listRenderer).layout assert.Equal(t, fyne.NewSize(32, 32), list.MinSize()) assert.Equal(t, fyne.NewSize(10, 10*5+(4*theme.Padding())), lay.MinSize()) @@ -166,7 +166,7 @@ func TestList_OffsetChange(t *testing.T) { assert.Equal(t, float32(0), list.offsetY) - scroll := test.WidgetRenderer(list).(*listRenderer).scroller + scroll := test.TempWidgetRenderer(t, list).(*listRenderer).scroller scroll.Scrolled(&fyne.ScrollEvent{Scrolled: fyne.NewDelta(0, -280)}) assert.NotEqual(t, 0, list.offsetY) diff --git a/widget/progressbar_extend_test.go b/widget/progressbar_extend_test.go index d483ef01ac..01487b8c50 100644 --- a/widget/progressbar_extend_test.go +++ b/widget/progressbar_extend_test.go @@ -22,7 +22,7 @@ func newExtendedProgressBar() *extendedProgressBar { func TestProgressBarRenderer_Extended_Layout(t *testing.T) { bar := newExtendedProgressBar() bar.Resize(fyne.NewSize(100, 100)) - r := test.WidgetRenderer(bar).(*progressRenderer) + r := test.TempWidgetRenderer(t, bar).(*progressRenderer) assert.Equal(t, 0.0, bar.Value) assert.Equal(t, float32(0), r.bar.Size().Width) diff --git a/widget/progressbar_test.go b/widget/progressbar_test.go index 95cb3c9768..2095349815 100644 --- a/widget/progressbar_test.go +++ b/widget/progressbar_test.go @@ -97,7 +97,7 @@ func TestProgressRenderer_Layout(t *testing.T) { bar := NewProgressBar() bar.Resize(fyne.NewSize(100, 10)) - render := test.WidgetRenderer(bar).(*progressRenderer) + render := test.TempWidgetRenderer(t, bar).(*progressRenderer) assert.Equal(t, float32(0), render.bar.Size().Width) bar.SetValue(.5) @@ -111,7 +111,7 @@ func TestProgressRenderer_Layout_Overflow(t *testing.T) { bar := NewProgressBar() bar.Resize(fyne.NewSize(100, 10)) - render := test.WidgetRenderer(bar).(*progressRenderer) + render := test.TempWidgetRenderer(t, bar).(*progressRenderer) bar.SetValue(1) assert.Equal(t, bar.Size().Width, render.bar.Size().Width) @@ -121,7 +121,7 @@ func TestProgressRenderer_Layout_Overflow(t *testing.T) { func TestProgressRenderer_ApplyTheme(t *testing.T) { bar := NewProgressBar() - render := test.WidgetRenderer(bar).(*progressRenderer) + render := test.TempWidgetRenderer(t, bar).(*progressRenderer) oldLabelColor := render.label.Color render.Refresh() diff --git a/widget/progressbarinfinite_test.go b/widget/progressbarinfinite_test.go index 84ed5cfa43..42fbb1b75d 100644 --- a/widget/progressbarinfinite_test.go +++ b/widget/progressbarinfinite_test.go @@ -80,7 +80,7 @@ func TestInfiniteProgressRenderer_Layout(t *testing.T) { width := float32(100.0) bar.Resize(fyne.NewSize(width, 10)) - render := test.WidgetRenderer(bar).(*infProgressRenderer) + render := test.TempWidgetRenderer(t, bar).(*infProgressRenderer) render.updateBar(0.0) // start at the smallest size diff --git a/widget/radio_group_extended_test.go b/widget/radio_group_extended_test.go index 7e71898320..0e6a788597 100644 --- a/widget/radio_group_extended_test.go +++ b/widget/radio_group_extended_test.go @@ -130,9 +130,9 @@ func TestRadioGroup_Extended_Hovered(t *testing.T) { t.Run(tt.name, func(t *testing.T) { radio := newextendedRadioGroup(tt.options, nil) radio.Horizontal = tt.isHorizontal - item1 := test.WidgetRenderer(radio).Objects()[0].(*radioItem) + item1 := test.TempWidgetRenderer(t, radio).Objects()[0].(*radioItem) render1 := cache.Renderer(item1).(*radioItemRenderer) - render2 := cache.Renderer(test.WidgetRenderer(radio).Objects()[1].(*radioItem)).(*radioItemRenderer) + render2 := cache.Renderer(test.TempWidgetRenderer(t, radio).Objects()[1].(*radioItem)).(*radioItemRenderer) assert.False(t, item1.hovered) assert.Equal(t, color.Transparent, render1.focusIndicator.FillColor) @@ -165,7 +165,7 @@ func TestRadioGroup_Extended_Hovered(t *testing.T) { func TestRadioGroupRenderer_Extended_ApplyTheme(t *testing.T) { radio := newextendedRadioGroup([]string{"Test"}, func(string) {}) - render := cache.Renderer(test.WidgetRenderer(radio).Objects()[0].(*radioItem)).(*radioItemRenderer) + render := cache.Renderer(test.TempWidgetRenderer(t, radio).Objects()[0].(*radioItem)).(*radioItemRenderer) textSize := render.label.TextSize customTextSize := textSize @@ -179,7 +179,7 @@ func TestRadioGroupRenderer_Extended_ApplyTheme(t *testing.T) { func extendedRadioGroupTestTapItem(t *testing.T, radio *extendedRadioGroup, item int) { t.Helper() - renderer := test.WidgetRenderer(radio) + renderer := test.TempWidgetRenderer(t, radio) radioItem := renderer.Objects()[item].(*radioItem) radioItem.Tapped(&fyne.PointEvent{Position: fyne.NewPos(theme.Padding(), theme.Padding())}) } diff --git a/widget/radio_group_internal_test.go b/widget/radio_group_internal_test.go index 436d86ce89..940833a818 100644 --- a/widget/radio_group_internal_test.go +++ b/widget/radio_group_internal_test.go @@ -95,26 +95,26 @@ func TestRadioGroup_Append(t *testing.T) { radio := NewRadioGroup([]string{"Hi"}, nil) assert.Equal(t, 1, len(radio.Options)) - assert.Equal(t, 1, len(test.WidgetRenderer(radio).(*radioGroupRenderer).items)) + assert.Equal(t, 1, len(test.TempWidgetRenderer(t, radio).(*radioGroupRenderer).items)) radio.Options = append(radio.Options, "Another") radio.Refresh() assert.Equal(t, 2, len(radio.Options)) - assert.Equal(t, 2, len(test.WidgetRenderer(radio).(*radioGroupRenderer).items)) + assert.Equal(t, 2, len(test.TempWidgetRenderer(t, radio).(*radioGroupRenderer).items)) } func TestRadioGroup_Remove(t *testing.T) { radio := NewRadioGroup([]string{"Hi", "Another"}, nil) assert.Equal(t, 2, len(radio.Options)) - assert.Equal(t, 2, len(test.WidgetRenderer(radio).(*radioGroupRenderer).items)) + assert.Equal(t, 2, len(test.TempWidgetRenderer(t, radio).(*radioGroupRenderer).items)) radio.Options = radio.Options[:1] radio.Refresh() assert.Equal(t, 1, len(radio.Options)) - assert.Equal(t, 1, len(test.WidgetRenderer(radio).(*radioGroupRenderer).items)) + assert.Equal(t, 1, len(test.TempWidgetRenderer(t, radio).(*radioGroupRenderer).items)) } func TestRadioGroup_SetSelected(t *testing.T) { @@ -156,14 +156,14 @@ func TestRadioGroup_DuplicatedOptions(t *testing.T) { radio := NewRadioGroup([]string{"Hi", "Hi", "Hi", "Another", "Another"}, nil) assert.Equal(t, 5, len(radio.Options)) - assert.Equal(t, 5, len(test.WidgetRenderer(radio).(*radioGroupRenderer).items)) + assert.Equal(t, 5, len(test.TempWidgetRenderer(t, radio).(*radioGroupRenderer).items)) radioGroupTestTapItem(t, radio, 1) assert.Equal(t, "Hi", radio.Selected) assert.Equal(t, 1, radio.selectedIndex()) - item0 := test.WidgetRenderer(radio).Objects()[0].(*radioItem) + item0 := test.TempWidgetRenderer(t, radio).Objects()[0].(*radioItem) assert.Equal(t, false, item0.focused) - item1 := test.WidgetRenderer(radio).Objects()[0].(*radioItem) + item1 := test.TempWidgetRenderer(t, radio).Objects()[0].(*radioItem) assert.Equal(t, false, item1.focused) } @@ -173,7 +173,7 @@ func TestRadioGroup_AppendDuplicate(t *testing.T) { radio.Append("Hi") assert.Equal(t, 2, len(radio.Options)) - assert.Equal(t, 2, len(test.WidgetRenderer(radio).(*radioGroupRenderer).items)) + assert.Equal(t, 2, len(test.TempWidgetRenderer(t, radio).(*radioGroupRenderer).items)) } func TestRadioGroup_Disable(t *testing.T) { @@ -235,7 +235,7 @@ func TestRadioGroup_Hovered(t *testing.T) { t.Run(tt.name, func(t *testing.T) { radio := NewRadioGroup(tt.options, nil) radio.Horizontal = tt.isHorizontal - item1 := test.WidgetRenderer(radio).Objects()[0].(*radioItem) + item1 := test.TempWidgetRenderer(t, radio).Objects()[0].(*radioItem) render1 := radioGroupTestItemRenderer(t, radio, 0) render2 := radioGroupTestItemRenderer(t, radio, 1) @@ -311,12 +311,12 @@ func TestRadioGroupRenderer_ApplyTheme(t *testing.T) { func radioGroupTestTapItem(t *testing.T, radio *RadioGroup, item int) { t.Helper() - renderer := test.WidgetRenderer(radio) + renderer := test.TempWidgetRenderer(t, radio) radioItem := renderer.Objects()[item].(*radioItem) radioItem.Tapped(&fyne.PointEvent{Position: fyne.NewPos(theme.Padding(), theme.Padding())}) } func radioGroupTestItemRenderer(t *testing.T, radio *RadioGroup, item int) *radioItemRenderer { t.Cleanup(func() { cache.DestroyRenderer(radio) }) - return cache.Renderer(test.WidgetRenderer(radio).Objects()[item].(fyne.Widget)).(*radioItemRenderer) + return cache.Renderer(test.TempWidgetRenderer(t, radio).Objects()[item].(fyne.Widget)).(*radioItemRenderer) } diff --git a/widget/radio_item_test.go b/widget/radio_item_test.go index 0f63906e14..2331ce38a0 100644 --- a/widget/radio_item_test.go +++ b/widget/radio_item_test.go @@ -27,7 +27,7 @@ func BenchmarkRadioCreateRenderer(b *testing.B) { func TestRadioItem_FocusIndicator_Centered_Vertically(t *testing.T) { item := newRadioItem("Hello", nil) - render := test.WidgetRenderer(item).(*radioItemRenderer) + render := test.TempWidgetRenderer(t, item).(*radioItemRenderer) render.Layout(fyne.NewSize(200, 100)) focusIndicatorSize := theme.IconInlineSize() + 2*theme.Padding() diff --git a/widget/richtext_objects_test.go b/widget/richtext_objects_test.go index ff22b923b5..ff55c93699 100644 --- a/widget/richtext_objects_test.go +++ b/widget/richtext_objects_test.go @@ -15,7 +15,7 @@ import ( func TestRichText_Image(t *testing.T) { img := &ImageSegment{Title: "test", Source: storage.NewFileURI("./testdata/richtext/richtext_multiline.png")} text := NewRichText(img) - texts := test.WidgetRenderer(text).Objects() + texts := test.TempWidgetRenderer(t, text).Objects() drawn := texts[0].(*richImage).img text.Resize(fyne.NewSize(200, 200)) @@ -37,10 +37,10 @@ func TestRichText_HyperLink(t *testing.T) { &TextSegment{Text: "Text"}, &HyperlinkSegment{Text: "Link"}, }}) - texts := test.WidgetRenderer(text).Objects() + texts := test.TempWidgetRenderer(t, text).Objects() assert.Equal(t, "Text", texts[0].(*canvas.Text).Text) - richLink := test.WidgetRenderer(texts[1].(*fyne.Container).Objects[0].(*Hyperlink)).Objects()[0].(fyne.Widget) - linkText := test.WidgetRenderer(richLink).Objects()[0].(*canvas.Text) + richLink := test.TempWidgetRenderer(t, texts[1].(*fyne.Container).Objects[0].(*Hyperlink)).Objects()[0].(fyne.Widget) + linkText := test.TempWidgetRenderer(t, richLink).Objects()[0].(*canvas.Text) assert.Equal(t, "Link", linkText.Text) c := test.NewCanvas() @@ -54,7 +54,7 @@ func TestRichText_List(t *testing.T) { text := NewRichText(&ListSegment{Items: []RichTextSegment{ seg, }}) - texts := test.WidgetRenderer(text).Objects() + texts := test.TempWidgetRenderer(t, text).Objects() assert.Equal(t, "•", strings.TrimSpace(texts[0].(*canvas.Text).Text)) assert.Equal(t, "Test", texts[1].(*canvas.Text).Text) } @@ -64,7 +64,7 @@ func TestRichText_OrderedList(t *testing.T) { &TextSegment{Text: "One"}, &TextSegment{Text: "Two"}, }}) - texts := test.WidgetRenderer(text).Objects() + texts := test.TempWidgetRenderer(t, text).Objects() assert.Equal(t, "1.", strings.TrimSpace(texts[0].(*canvas.Text).Text)) assert.Equal(t, "One", texts[1].(*canvas.Text).Text) assert.Equal(t, "2.", strings.TrimSpace(texts[2].(*canvas.Text).Text)) diff --git a/widget/richtext_test.go b/widget/richtext_test.go index eaff83bd0b..11379a0a2b 100644 --- a/widget/richtext_test.go +++ b/widget/richtext_test.go @@ -49,7 +49,7 @@ func TestText_Alignment(t *testing.T) { seg := trailingBoldErrorSegment() seg.Text = "Test" text := NewRichText(seg) - assert.Equal(t, fyne.TextAlignTrailing, test.WidgetRenderer(text).Objects()[0].(*canvas.Text).Alignment) + assert.Equal(t, fyne.TextAlignTrailing, test.TempWidgetRenderer(t, text).Objects()[0].(*canvas.Text).Alignment) } func TestText_Row(t *testing.T) { @@ -136,8 +136,8 @@ func TestText_Scroll(t *testing.T) { assert.Less(t, text4.MinSize().Width, text3.MinSize().Width) assert.Equal(t, text4.MinSize().Height, text3.MinSize().Height) - content3 := test.WidgetRenderer(text3).Objects()[0].(*widget.Scroll).Content - content4 := test.WidgetRenderer(text4).Objects()[0].(*widget.Scroll).Content + content3 := test.TempWidgetRenderer(t, text3).Objects()[0].(*widget.Scroll).Content + content4 := test.TempWidgetRenderer(t, text4).Objects()[0].(*widget.Scroll).Content assert.Less(t, content4.MinSize().Width, content3.MinSize().Width) assert.Greater(t, content4.MinSize().Height, content3.MinSize().Height) } diff --git a/widget/select_internal_test.go b/widget/select_internal_test.go index 218352b284..9416f64a0e 100644 --- a/widget/select_internal_test.go +++ b/widget/select_internal_test.go @@ -52,7 +52,7 @@ func TestSelectRenderer_TapAnimation(t *testing.T) { path = "select/mobile/tap_animation.png" } - render1 := test.WidgetRenderer(sel).(*selectRenderer) + render1 := test.TempWidgetRenderer(t, sel).(*selectRenderer) test.Tap(sel) sel.popUp.Hide() sel.tapAnim.Tick(0.5) @@ -61,7 +61,7 @@ func TestSelectRenderer_TapAnimation(t *testing.T) { cache.DestroyRenderer(sel) sel.Refresh() - render2 := test.WidgetRenderer(sel).(*selectRenderer) + render2 := test.TempWidgetRenderer(t, sel).(*selectRenderer) assert.NotEqual(t, render1, render2) diff --git a/widget/slider_test.go b/widget/slider_test.go index 8521ebed30..d715c7da13 100644 --- a/widget/slider_test.go +++ b/widget/slider_test.go @@ -75,7 +75,7 @@ func TestSlider_HorizontalLayout(t *testing.T) { slider := NewSlider(0, 1) slider.Resize(fyne.NewSize(100, 10)) - render := test.WidgetRenderer(slider).(*sliderRenderer) + render := test.TempWidgetRenderer(t, slider).(*sliderRenderer) wSize := render.slider.Size() tSize := render.track.Size() aSize := render.active.Size() @@ -118,7 +118,7 @@ func TestSlider_VerticalLayout(t *testing.T) { slider.Orientation = Vertical slider.Resize(fyne.NewSize(10, 100)) - render := test.WidgetRenderer(slider).(*sliderRenderer) + render := test.TempWidgetRenderer(t, slider).(*sliderRenderer) wSize := render.slider.Size() tSize := render.track.Size() aSize := render.active.Size() diff --git a/widget/table_test.go b/widget/table_test.go index b634f532a8..33da580dd7 100644 --- a/widget/table_test.go +++ b/widget/table_test.go @@ -20,7 +20,7 @@ func TestTable_Empty(t *testing.T) { table.Resize(fyne.NewSize(120, 120)) table.CreateRenderer() - cellRenderer := test.WidgetRenderer(table.content.Content.(*tableCells)) + cellRenderer := test.TempWidgetRenderer(t, table.content.Content.(*tableCells)) cellRenderer.Refresh() // let's not crash :) } @@ -39,7 +39,7 @@ func TestTable_Cache(t *testing.T) { c.SetPadded(false) c.Resize(fyne.NewSize(120, 148)) - cellRenderer := test.WidgetRenderer(table.content.Content.(*tableCells)) + cellRenderer := test.TempWidgetRenderer(t, table.content.Content.(*tableCells)) cellRenderer.Refresh() assert.Equal(t, 6, len(cellRenderer.(*tableCellsRenderer).visible)) assert.Equal(t, "Cell 0, 0", cellRenderer.Objects()[0].(*Label).Text) @@ -69,7 +69,7 @@ func TestTable_ChangeTheme(t *testing.T) { table.CreateRenderer() table.Resize(fyne.NewSize(50, 30)) - content := test.WidgetRenderer(table.content.Content.(*tableCells)).(*tableCellsRenderer) + content := test.TempWidgetRenderer(t, table.content.Content.(*tableCells)).(*tableCellsRenderer) w := test.NewWindow(table) defer w.Close() w.Resize(fyne.NewSize(180, 180)) @@ -78,7 +78,7 @@ func TestTable_ChangeTheme(t *testing.T) { assert.Equal(t, NewLabel("placeholder").MinSize(), content.Objects()[0].(*Label).Size()) test.WithTestTheme(t, func() { - test.WidgetRenderer(table).Refresh() + test.TempWidgetRenderer(t, table).Refresh() test.AssertImageMatches(t, "table/theme_changed.png", w.Canvas().Capture()) }) assert.Equal(t, NewLabel("placeholder").MinSize(), content.Objects()[0].(*Label).Size()) @@ -157,7 +157,7 @@ func TestTable_Headers(t *testing.T) { }) table.Resize(fyne.NewSize(120, 120)) - cellRenderer := test.WidgetRenderer(table.content.Content.(*tableCells)) + cellRenderer := test.TempWidgetRenderer(t, table.content.Content.(*tableCells)) assert.Equal(t, "text", cellRenderer.(*tableCellsRenderer).Objects()[2].(*Label).Text) assert.Equal(t, "text", cellRenderer.(*tableCellsRenderer).Objects()[5].(*Label).Text) assert.True(t, areaContainsLabel(table.top.Content.(*fyne.Container).Objects, "A")) @@ -197,7 +197,7 @@ func TestTable_Sticky(t *testing.T) { }) table.Resize(fyne.NewSize(120, 120)) - cellRenderer := test.WidgetRenderer(table.content.Content.(*tableCells)).(*tableCellsRenderer) + cellRenderer := test.TempWidgetRenderer(t, table.content.Content.(*tableCells)).(*tableCellsRenderer) assert.True(t, areaContainsLabel(cellRenderer.Objects(), "text 0,0")) assert.True(t, areaContainsLabel(cellRenderer.Objects(), "text 1,0")) assert.True(t, areaContainsLabel(cellRenderer.Objects(), "text 2,1")) @@ -371,7 +371,7 @@ func TestTable_Refresh(t *testing.T) { }) table.Resize(fyne.NewSize(120, 120)) - cellRenderer := test.WidgetRenderer(table.content.Content.(*tableCells)) + cellRenderer := test.TempWidgetRenderer(t, table.content.Content.(*tableCells)) assert.Equal(t, "placeholder", cellRenderer.(*tableCellsRenderer).Objects()[7].(*Label).Text) displayText = "replaced" @@ -737,7 +737,7 @@ func TestTable_SetColumnWidth(t *testing.T) { table.Resize(fyne.NewSize(120, 120)) table.Select(TableCellID{1, 0}) - cellRenderer := test.WidgetRenderer(table.content.Content.(*tableCells)) + cellRenderer := test.TempWidgetRenderer(t, table.content.Content.(*tableCells)) cellRenderer.Refresh() assert.Equal(t, 8, len(cellRenderer.(*tableCellsRenderer).visible)) assert.Equal(t, float32(32), cellRenderer.(*tableCellsRenderer).Objects()[0].Size().Width) @@ -817,7 +817,7 @@ func TestTable_SetRowHeight(t *testing.T) { table.Resize(fyne.NewSize(120, 120)) table.Select(TableCellID{0, 1}) - cellRenderer := test.WidgetRenderer(table.content.Content.(*tableCells)) + cellRenderer := test.TempWidgetRenderer(t, table.content.Content.(*tableCells)) cellRenderer.Refresh() assert.Equal(t, 6, len(cellRenderer.(*tableCellsRenderer).visible)) assert.Equal(t, float32(48), cellRenderer.(*tableCellsRenderer).Objects()[0].Size().Height) @@ -884,7 +884,7 @@ func TestTable_ShowVisible(t *testing.T) { func(TableCellID, fyne.CanvasObject) {}) table.Resize(fyne.NewSize(120, 120)) - cellRenderer := test.WidgetRenderer(table.content.Content.(*tableCells)) + cellRenderer := test.TempWidgetRenderer(t, table.content.Content.(*tableCells)) cellRenderer.Refresh() assert.Equal(t, 8, len(cellRenderer.(*tableCellsRenderer).visible)) } diff --git a/widget/textgrid_test.go b/widget/textgrid_test.go index 0e4fa57fd1..be1fa38f7e 100644 --- a/widget/textgrid_test.go +++ b/widget/textgrid_test.go @@ -15,7 +15,7 @@ import ( func TestNewTextGrid(t *testing.T) { grid := NewTextGridFromString("A") - test.WidgetRenderer(grid).Refresh() + test.TempWidgetRenderer(t, grid).Refresh() assert.Equal(t, 1, len(grid.Rows)) assert.Equal(t, 1, len(grid.Rows[0].Cells)) @@ -24,7 +24,7 @@ func TestNewTextGrid(t *testing.T) { func TestTextGrid_CreateRendererRows(t *testing.T) { grid := NewTextGrid() grid.Resize(fyne.NewSize(52, 22)) - rend := test.WidgetRenderer(grid).(*textGridRenderer) + rend := test.TempWidgetRenderer(t, grid).(*textGridRenderer) rend.Refresh() assert.Equal(t, 12, len(rend.objects)) @@ -32,7 +32,7 @@ func TestTextGrid_CreateRendererRows(t *testing.T) { func TestTextGrid_Row(t *testing.T) { grid := NewTextGridFromString("Ab\nC") - test.WidgetRenderer(grid).Refresh() + test.TempWidgetRenderer(t, grid).Refresh() assert.NotNil(t, grid.Row(0)) assert.Equal(t, 2, len(grid.Row(0).Cells)) @@ -41,7 +41,7 @@ func TestTextGrid_Row(t *testing.T) { func TestTextGrid_Rows(t *testing.T) { grid := NewTextGridFromString("Ab\nC") - test.WidgetRenderer(grid).Refresh() + test.TempWidgetRenderer(t, grid).Refresh() assert.Equal(t, 2, len(grid.Rows)) assert.Equal(t, 2, len(grid.Rows[0].Cells)) @@ -49,7 +49,7 @@ func TestTextGrid_Rows(t *testing.T) { func TestTextGrid_RowText(t *testing.T) { grid := NewTextGridFromString("Ab\nC") - test.WidgetRenderer(grid).Refresh() + test.TempWidgetRenderer(t, grid).Refresh() assert.Equal(t, "Ab", grid.RowText(0)) assert.Equal(t, "C", grid.RowText(1)) @@ -140,7 +140,7 @@ func TestTextGridRenderer_Resize(t *testing.T) { grid := NewTextGridFromString("1\n2") grid.ShowLineNumbers = true - renderer := test.WidgetRenderer(grid) + renderer := test.TempWidgetRenderer(t, grid) min := renderer.MinSize() grid.Resize(fyne.NewSize(100, 250)) @@ -168,7 +168,7 @@ func TestTextGridRenderer_ShowLineNumbers(t *testing.T) { func TestTextGridRender_Size(t *testing.T) { grid := NewTextGrid() grid.Resize(fyne.NewSize(30, 42)) // causes refresh - rend := test.WidgetRenderer(grid).(*textGridRenderer) + rend := test.TempWidgetRenderer(t, grid).(*textGridRenderer) assert.Equal(t, 3, rend.cols) assert.Equal(t, 2, rend.rows) @@ -222,7 +222,7 @@ func TestTextGridRender_TextColor(t *testing.T) { func assertGridContent(t *testing.T, g *TextGrid, expected string) { lines := strings.Split(expected, "\n") - renderer := test.WidgetRenderer(g).(*textGridRenderer) + renderer := test.TempWidgetRenderer(t, g).(*textGridRenderer) for y, line := range lines { x := 0 // rune count - using index below would be offset into string bytes @@ -236,7 +236,7 @@ func assertGridContent(t *testing.T, g *TextGrid, expected string) { func assertGridStyle(t *testing.T, g *TextGrid, expected string, expectedStyles map[string]TextGridStyle) { lines := strings.Split(expected, "\n") - renderer := test.WidgetRenderer(g).(*textGridRenderer) + renderer := test.TempWidgetRenderer(t, g).(*textGridRenderer) for y, line := range lines { x := 0 // rune count - using index below would be offset into string bytes diff --git a/widget/toolbar_test.go b/widget/toolbar_test.go index f63fbe5cf0..5b33c60b71 100644 --- a/widget/toolbar_test.go +++ b/widget/toolbar_test.go @@ -45,7 +45,7 @@ func TestToolbar_Replace(t *testing.T) { icon := theme.ContentCutIcon() toolbar := NewToolbar(NewToolbarAction(icon, func() {})) assert.Equal(t, 1, len(toolbar.Items)) - render := test.WidgetRenderer(toolbar) + render := test.TempWidgetRenderer(t, toolbar) assert.Equal(t, icon.Name(), render.Objects()[0].(*Button).Icon.Name()) toolbar.Items[0] = NewToolbarAction(theme.HelpIcon(), func() {}) diff --git a/widget/tree_internal_test.go b/widget/tree_internal_test.go index 2107b4c982..300453c9ed 100644 --- a/widget/tree_internal_test.go +++ b/widget/tree_internal_test.go @@ -881,7 +881,7 @@ func TestTree_RefreshItem(t *testing.T) { c := test.NewWindow(tree) c.Resize(fyne.NewSize(100, 100)) - r := test.WidgetRenderer(tree.scroller.Content.(*treeContent)).(*treeContentRenderer) + r := test.TempWidgetRenderer(t, tree.scroller.Content.(*treeContent)).(*treeContentRenderer) assert.Equal(t, "Leaf", r.leaves["foobar1"].content.(*Label).Text) @@ -899,13 +899,13 @@ func TestTreeNodeRenderer_BackgroundColor(t *testing.T) { tree.OpenAllBranches() t.Run("Branch", func(t *testing.T) { a := getBranch(t, tree, "A") - ar := test.WidgetRenderer(a).(*treeNodeRenderer) + ar := test.TempWidgetRenderer(t, a).(*treeNodeRenderer) assert.Equal(t, theme.HoverColor(), ar.background.FillColor) assert.False(t, ar.background.Visible()) }) t.Run("Leaf", func(t *testing.T) { b := getLeaf(t, tree, "B") - br := test.WidgetRenderer(b).(*treeNodeRenderer) + br := test.TempWidgetRenderer(t, b).(*treeNodeRenderer) assert.Equal(t, theme.HoverColor(), br.background.FillColor) assert.False(t, br.background.Visible()) }) @@ -919,7 +919,7 @@ func TestTreeNodeRenderer_BackgroundColor_Hovered(t *testing.T) { tree.OpenAllBranches() t.Run("Branch", func(t *testing.T) { a := getBranch(t, tree, "A") - ar := test.WidgetRenderer(a).(*treeNodeRenderer) + ar := test.TempWidgetRenderer(t, a).(*treeNodeRenderer) a.MouseIn(&desktop.MouseEvent{}) assert.Equal(t, theme.HoverColor(), ar.background.FillColor) assert.True(t, ar.background.Visible()) @@ -929,7 +929,7 @@ func TestTreeNodeRenderer_BackgroundColor_Hovered(t *testing.T) { }) t.Run("Leaf", func(t *testing.T) { b := getLeaf(t, tree, "B") - br := test.WidgetRenderer(b).(*treeNodeRenderer) + br := test.TempWidgetRenderer(t, b).(*treeNodeRenderer) b.MouseIn(&desktop.MouseEvent{}) assert.Equal(t, theme.HoverColor(), br.background.FillColor) assert.True(t, br.background.Visible()) From 80489a249ad2e8864946979b3ed8617663d1295a Mon Sep 17 00:00:00 2001 From: Jacob Date: Thu, 23 May 2024 12:39:17 +0200 Subject: [PATCH 08/78] Add a Since: line --- test/test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/test.go b/test/test.go index 3f38aab3ad..2c0ee5b9ec 100644 --- a/test/test.go +++ b/test/test.go @@ -302,6 +302,8 @@ func ApplyTheme(t *testing.T, theme fyne.Theme) { // TempWidgetRenderer allows test scripts to gain access to the current renderer for a widget. // This can be used for verifying correctness of rendered components for a widget in unit tests. // The widget renderer is automatically destroyed when the test ends. +// +// Since: 2.5 func TempWidgetRenderer(t *testing.T, wid fyne.Widget) fyne.WidgetRenderer { t.Cleanup(func() { cache.DestroyRenderer(wid) }) return cache.Renderer(wid) From c118b65f821defad91d99656410bd9fa5d74bf5a Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Wed, 29 May 2024 08:50:16 -0700 Subject: [PATCH 09/78] Update AppendMarkdown documentation --- widget/markdown.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/widget/markdown.go b/widget/markdown.go index 157fa0ac41..a6e0b7f4a1 100644 --- a/widget/markdown.go +++ b/widget/markdown.go @@ -29,6 +29,11 @@ func (t *RichText) ParseMarkdown(content string) { // AppendMarkdown parses the given markdown string and appends the // content to the widget, with the appropriate formatting. +// This API is intended for appending complete markdown documents or +// standalone fragments, and should not be used to parse a single +// markdown document piecewise. Use ParseMarkdown for this case. +// +// Since: 2.5 func (t *RichText) AppendMarkdown(content string) { t.Segments = append(t.Segments, parseMarkdown(content)...) t.Refresh() From b171e2b994541b2409649cc087ea87441b146313 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Tue, 11 Jun 2024 14:03:51 +0100 Subject: [PATCH 10/78] Remove the need to hook resources in for overriding in theme override --- canvas/image.go | 15 ++++++++++++--- internal/cache/svg.go | 20 ++++++++++++++++---- internal/cache/theme.go | 42 +++-------------------------------------- test/markup_renderer.go | 7 ------- widget/button.go | 5 ++--- widget/icon.go | 14 +------------- 6 files changed, 34 insertions(+), 69 deletions(-) diff --git a/canvas/image.go b/canvas/image.go index fa2bb95113..4e02f788ee 100644 --- a/canvas/image.go +++ b/canvas/image.go @@ -270,7 +270,16 @@ func (i *Image) updateReader() (io.ReadCloser, error) { i.isSVG = false if i.Resource != nil { i.isSVG = svg.IsResourceSVG(i.Resource) - return io.NopCloser(bytes.NewReader(i.Resource.Content())), nil + content := i.Resource.Content() + if res, ok := i.Resource.(fyne.ThemedResource); i.isSVG && ok { + + th := cache.WidgetTheme(i) + if th != nil { + col := th.Color(res.ThemeColorName(), fyne.CurrentApp().Settings().ThemeVariant()) + content = svg.Colorize(content, col) + } + } + return io.NopCloser(bytes.NewReader(content)), nil } else if i.File != "" { var err error @@ -347,7 +356,7 @@ func (i *Image) renderSVG(width, height float32) (image.Image, error) { screenWidth, screenHeight = c.PixelCoordinateForPosition(fyne.Position{X: width, Y: height}) } - tex := cache.GetSvg(i.name(), screenWidth, screenHeight) + tex := cache.GetSvg(i.name(), i, screenWidth, screenHeight) if tex != nil { return tex, nil } @@ -357,6 +366,6 @@ func (i *Image) renderSVG(width, height float32) (image.Image, error) { if err != nil { return nil, err } - cache.SetSvg(i.name(), tex, screenWidth, screenHeight) + cache.SetSvg(i.name(), i, tex, screenWidth, screenHeight) return tex, nil } diff --git a/internal/cache/svg.go b/internal/cache/svg.go index 20b17038ff..94911acfca 100644 --- a/internal/cache/svg.go +++ b/internal/cache/svg.go @@ -4,13 +4,15 @@ import ( "image" "sync" "time" + + "fyne.io/fyne/v2" ) var svgs = &sync.Map{} // make(map[string]*svgInfo) // GetSvg gets svg image from cache if it exists. -func GetSvg(name string, w int, h int) *image.NRGBA { - sinfo, ok := svgs.Load(name) +func GetSvg(name string, o fyne.CanvasObject, w int, h int) *image.NRGBA { + sinfo, ok := svgs.Load(overriddenName(name, o)) if !ok || sinfo == nil { return nil } @@ -24,14 +26,14 @@ func GetSvg(name string, w int, h int) *image.NRGBA { } // SetSvg sets a svg into the cache map. -func SetSvg(name string, pix *image.NRGBA, w int, h int) { +func SetSvg(name string, o fyne.CanvasObject, pix *image.NRGBA, w int, h int) { sinfo := &svgInfo{ pix: pix, w: w, h: h, } sinfo.setAlive() - svgs.Store(name, sinfo) + svgs.Store(overriddenName(name, o), sinfo) } type svgInfo struct { @@ -57,3 +59,13 @@ func destroyExpiredSvgs(now time.Time) { svgs.Delete(exp) } } + +func overriddenName(name string, o fyne.CanvasObject) string { + if o != nil { // for overridden themes get the cache key right + if over, ok := overrides.Load(o); ok { + return over.(*overrideScope).cacheID + name + } + } + + return name +} diff --git a/internal/cache/theme.go b/internal/cache/theme.go index 0d1185647c..a4c5c6de8f 100644 --- a/internal/cache/theme.go +++ b/internal/cache/theme.go @@ -6,7 +6,6 @@ import ( "sync/atomic" "fyne.io/fyne/v2" - "fyne.io/fyne/v2/internal/svg" ) var ( @@ -30,7 +29,7 @@ func OverrideTheme(o fyne.CanvasObject, th fyne.Theme) { overrideTheme(o, s, id) } -func WidgetTheme(o fyne.Widget) fyne.Theme { +func WidgetTheme(o fyne.CanvasObject) fyne.Theme { data, ok := overrides.Load(o) if !ok { return nil @@ -39,43 +38,6 @@ func WidgetTheme(o fyne.Widget) fyne.Theme { return data.(*overrideScope).th } -func OverrideResourceTheme(res fyne.Resource, w fyne.Widget) fyne.Resource { - if th, ok := res.(fyne.ThemedResource); ok { - return &WidgetResource{ThemedResource: th, Owner: w} - } - - return res -} - -func themeForResource(res fyne.Resource) fyne.Theme { - if th, ok := res.(*WidgetResource); ok { - if over, ok := overrides.Load(th.Owner); ok { - return over.(*overrideScope).th - } - } - - return fyne.CurrentApp().Settings().Theme() -} - -type WidgetResource struct { - fyne.ThemedResource - Owner fyne.Widget -} - -// Content returns the underlying content of the resource adapted to the current text color. -func (res *WidgetResource) Content() []byte { - th := themeForResource(res) - return svg.Colorize(res.ThemedResource.Content(), th.Color(res.ThemeColorName(), fyne.CurrentApp().Settings().ThemeVariant())) -} - -func (res *WidgetResource) Name() string { - cacheID := "" - if over, ok := overrides.Load(res.Owner); ok { - cacheID = over.(*overrideScope).cacheID - } - return cacheID + res.ThemedResource.Name() -} - func overrideContainer(c *fyne.Container, s *overrideScope, id uint32) { for _, o := range c.Objects { overrideTheme(o, s, id) @@ -88,6 +50,8 @@ func overrideTheme(o fyne.CanvasObject, s *overrideScope, id uint32) { overrideWidget(c, s, id) case *fyne.Container: overrideContainer(c, s, id) + default: + overrides.Store(c, s) } } diff --git a/test/markup_renderer.go b/test/markup_renderer.go index ff37b46eee..acc91217ad 100644 --- a/test/markup_renderer.go +++ b/test/markup_renderer.go @@ -10,7 +10,6 @@ import ( "fyne.io/fyne/v2" fynecanvas "fyne.io/fyne/v2/canvas" - "fyne.io/fyne/v2/internal/cache" col "fyne.io/fyne/v2/internal/color" intdriver "fyne.io/fyne/v2/internal/driver" "fyne.io/fyne/v2/layout" @@ -152,12 +151,6 @@ func (r *markupRenderer) setResourceAttr(attrs map[string]*string, name string, if variant == "" { variant = "default" } - case *cache.WidgetResource: - if _, ok := t.ThemedResource.(*theme.InvertedThemedResource); ok { - variant = "inverted" - } else { - variant = string(t.ThemeColorName()) - } default: r.setStringAttr(attrs, name, rsc.Name()) return diff --git a/widget/button.go b/widget/button.go index b01b91e844..88601fabb8 100644 --- a/widget/button.go +++ b/widget/button.go @@ -6,7 +6,6 @@ import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/driver/desktop" - "fyne.io/fyne/v2/internal/cache" col "fyne.io/fyne/v2/internal/color" "fyne.io/fyne/v2/internal/widget" "fyne.io/fyne/v2/layout" @@ -344,7 +343,7 @@ func (r *buttonRenderer) applyTheme() { } } } - r.icon.Resource = cache.OverrideResourceTheme(icon, r.button) + r.icon.Resource = icon r.icon.Refresh() } } @@ -403,7 +402,7 @@ func (r *buttonRenderer) updateIconAndText() { if r.button.Disabled() { icon = theme.NewDisabledResource(icon) } - r.icon.Resource = cache.OverrideResourceTheme(icon, r.button) + r.icon.Resource = icon r.icon.Refresh() r.icon.Show() } else if r.icon != nil { diff --git a/widget/icon.go b/widget/icon.go index 695d42a2d5..bd30e413ab 100644 --- a/widget/icon.go +++ b/widget/icon.go @@ -3,7 +3,6 @@ package widget import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" - "fyne.io/fyne/v2/internal/cache" "fyne.io/fyne/v2/internal/widget" "fyne.io/fyne/v2/theme" ) @@ -32,12 +31,6 @@ func (i *iconRenderer) Refresh() { return } - r := i.image.Resource - if r != nil { - r = cache.OverrideResourceTheme(i.image.Resource, i.image) - i.image.Resource = r - } - i.image.propertyLock.RLock() i.raster.Resource = i.image.Resource i.image.cachedRes = i.image.Resource @@ -76,12 +69,7 @@ func (i *Icon) CreateRenderer() fyne.WidgetRenderer { i.propertyLock.RLock() defer i.propertyLock.RUnlock() - res := i.Resource - if res != nil { - res = cache.OverrideResourceTheme(i.Resource, i) - i.Resource = res - } - img := canvas.NewImageFromResource(res) + img := canvas.NewImageFromResource(i.Resource) img.FillMode = canvas.ImageFillContain r := &iconRenderer{image: i, raster: img} From 74bcc87c0f1eca91228a39a3b27bb2c5088948f9 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Tue, 11 Jun 2024 14:25:40 +0100 Subject: [PATCH 11/78] Add test of theme override and icon colourising --- container/theme_test.go | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 container/theme_test.go diff --git a/container/theme_test.go b/container/theme_test.go new file mode 100644 index 0000000000..1b189958a5 --- /dev/null +++ b/container/theme_test.go @@ -0,0 +1,37 @@ +package container + +import ( + "image" + "testing" + + "fyne.io/fyne/v2/test" + "fyne.io/fyne/v2/theme" + "fyne.io/fyne/v2/widget" + "github.com/stretchr/testify/assert" +) + +func TestThemeOverride_Icons(t *testing.T) { + b := widget.NewButtonWithIcon("", theme.HomeIcon(), func() {}) + o := NewThemeOverride(b, test.Theme()) + w := test.NewWindow(o) + plain := w.Canvas().Capture().(*image.NRGBA) + + o.Theme = test.NewTheme() + o.Refresh() + changed := w.Canvas().Capture().(*image.NRGBA) + + assert.NotEqual(t, plain.Pix, changed.Pix) +} + +func TestThemeOverride_Refresh(t *testing.T) { + b := widget.NewButton("Test", func() {}) + o := NewThemeOverride(b, test.Theme()) + w := test.NewWindow(o) + plain := w.Canvas().Capture().(*image.NRGBA) + + o.Theme = test.NewTheme() + o.Refresh() + changed := w.Canvas().Capture().(*image.NRGBA) + + assert.NotEqual(t, plain.Pix, changed.Pix) +} From 4a3c3bdd5601fead134b64351557e0ee036fa863 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Tue, 11 Jun 2024 14:38:22 +0100 Subject: [PATCH 12/78] Update tests and test files --- .../apptabs/desktop/hover_overflow.xml | 2 +- .../apptabs/desktop/tab_location_bottom.xml | 2 +- .../apptabs/desktop/tab_location_leading.xml | 2 +- .../apptabs/desktop/tab_location_top.xml | 2 +- .../apptabs/desktop/tab_location_trailing.xml | 2 +- .../apptabs/desktop/tapped_overflow_tabs.xml | 2 +- .../apptabs/mobile/tab_location_bottom.xml | 2 +- .../apptabs/mobile/tab_location_top.xml | 2 +- .../desktop/change_content_change_hidden.xml | 2 +- .../desktop/change_content_change_visible.xml | 2 +- .../desktop/change_content_initial.xml | 2 +- .../desktop/change_icon_change_selected.xml | 2 +- .../desktop/change_icon_change_unselected.xml | 2 +- .../doctabs/desktop/change_icon_initial.xml | 2 +- .../desktop/change_label_change_selected.xml | 2 +- .../change_label_change_unselected.xml | 2 +- .../doctabs/desktop/change_label_initial.xml | 2 +- .../change_label_to_longer_text_selected.xml | 2 +- .../doctabs/desktop/dynamic_appended.xml | 2 +- .../desktop/dynamic_appended_and_removed.xml | 2 +- .../dynamic_appended_another_three.xml | 2 +- .../doctabs/desktop/dynamic_initial.xml | 2 +- .../desktop/dynamic_replaced_completely.xml | 2 +- .../doctabs/desktop/hover_all_tabs.xml | 4 +-- .../doctabs/desktop/hover_create_tab.xml | 4 +-- .../testdata/doctabs/desktop/hover_first.xml | 4 +-- .../doctabs/desktop/hover_first_close.xml | 4 +-- .../testdata/doctabs/desktop/hover_none.xml | 4 +-- .../testdata/doctabs/desktop/hover_second.xml | 4 +-- .../doctabs/desktop/layout_bottom_icon.xml | 2 +- .../desktop/layout_bottom_icon_and_text.xml | 2 +- .../doctabs/desktop/layout_bottom_text.xml | 2 +- .../doctabs/desktop/layout_leading_icon.xml | 2 +- .../desktop/layout_leading_icon_and_text.xml | 2 +- .../doctabs/desktop/layout_leading_text.xml | 2 +- .../doctabs/desktop/layout_top_icon.xml | 2 +- .../desktop/layout_top_icon_and_text.xml | 2 +- .../doctabs/desktop/layout_top_text.xml | 2 +- .../doctabs/desktop/layout_trailing_icon.xml | 2 +- .../desktop/layout_trailing_icon_and_text.xml | 2 +- .../doctabs/desktop/layout_trailing_text.xml | 2 +- .../doctabs/desktop/tab_location_bottom.xml | 2 +- .../doctabs/desktop/tab_location_leading.xml | 2 +- .../doctabs/desktop/tab_location_top.xml | 2 +- .../doctabs/desktop/tab_location_trailing.xml | 2 +- .../doctabs/desktop/tapped_all_tabs.xml | 4 +-- .../doctabs/desktop/tapped_create_tab.xml | 4 +-- .../doctabs/desktop/tapped_first_selected.xml | 4 +-- .../desktop/tapped_second_selected.xml | 4 +-- .../doctabs/desktop/tapped_third_selected.xml | 4 +-- .../mobile/change_content_change_hidden.xml | 2 +- .../mobile/change_content_change_visible.xml | 2 +- .../doctabs/mobile/change_content_initial.xml | 2 +- .../mobile/change_icon_change_selected.xml | 2 +- .../mobile/change_icon_change_unselected.xml | 2 +- .../doctabs/mobile/change_icon_initial.xml | 2 +- .../mobile/change_label_change_selected.xml | 2 +- .../mobile/change_label_change_unselected.xml | 2 +- .../doctabs/mobile/change_label_initial.xml | 2 +- .../doctabs/mobile/dynamic_appended.xml | 2 +- .../mobile/dynamic_appended_and_removed.xml | 2 +- .../mobile/dynamic_appended_another_three.xml | 2 +- .../doctabs/mobile/dynamic_initial.xml | 2 +- .../mobile/dynamic_replaced_completely.xml | 2 +- .../testdata/doctabs/mobile/hover_none.xml | 2 +- .../doctabs/mobile/layout_bottom_ico.xml | 2 +- .../mobile/layout_bottom_icon_and_text.xml | 2 +- .../doctabs/mobile/layout_bottom_text.xml | 2 +- .../doctabs/mobile/layout_top_icon.xml | 2 +- .../mobile/layout_top_icon_and_text.xml | 2 +- .../doctabs/mobile/layout_top_text.xml | 2 +- .../doctabs/mobile/tab_location_bottom.xml | 2 +- .../doctabs/mobile/tab_location_top.xml | 2 +- .../doctabs/mobile/tapped_all_tabs.xml | 4 +-- .../doctabs/mobile/tapped_create_tab.xml | 4 +-- .../doctabs/mobile/tapped_first_selected.xml | 4 +-- .../doctabs/mobile/tapped_second_selected.xml | 4 +-- .../doctabs/mobile/tapped_third_selected.xml | 4 +-- internal/cache/base_test.go | 2 +- internal/cache/svg_test.go | 16 +++++----- widget/icon_extend_test.go | 2 +- widget/icon_internal_test.go | 3 +- ..._expanded_multiple_open_multiple_items.xml | 4 +-- ...ed_multiple_open_multiple_items_opened.xml | 4 +-- ...layout_expanded_multiple_open_one_item.xml | 2 +- ...expanded_multiple_open_one_item_opened.xml | 2 +- ...ut_expanded_single_open_multiple_items.xml | 4 +-- ...nded_single_open_multiple_items_opened.xml | 4 +-- .../layout_expanded_single_open_one_item.xml | 2 +- ...t_expanded_single_open_one_item_opened.xml | 2 +- .../layout_multiple_open_multiple_items.xml | 4 +-- ...ut_multiple_open_multiple_items_opened.xml | 4 +-- .../layout_multiple_open_one_item.xml | 2 +- .../layout_multiple_open_one_item_opened.xml | 2 +- .../layout_single_open_multiple_items.xml | 4 +-- ...yout_single_open_multiple_items_opened.xml | 4 +-- .../accordion/layout_single_open_one_item.xml | 2 +- .../layout_single_open_one_item_opened.xml | 2 +- .../layout_icon_only_center_leading.xml | 2 +- .../layout_icon_only_center_trailing.xml | 2 +- .../layout_icon_only_leading_leading.xml | 2 +- .../layout_icon_only_leading_trailing.xml | 2 +- .../layout_icon_only_trailing_leading.xml | 2 +- .../layout_icon_only_trailing_trailing.xml | 2 +- .../layout_text_icon_center_leading.xml | 2 +- .../layout_text_icon_center_trailing.xml | 2 +- .../layout_text_icon_leading_leading.xml | 2 +- .../layout_text_icon_leading_trailing.xml | 2 +- .../layout_text_icon_trailing_leading.xml | 2 +- .../layout_text_icon_trailing_trailing.xml | 2 +- widget/testdata/form/extended_entry.xml | 2 +- widget/testdata/form/layout.xml | 2 +- widget/testdata/icon/layout_resource.xml | 2 +- widget/testdata/list/initial.xml | 22 ++++++------- widget/testdata/list/item_removed.xml | 4 +-- widget/testdata/list/new_data.xml | 22 ++++++------- widget/testdata/list/offset_changed.xml | 22 ++++++------- widget/testdata/list/resized.xml | 32 +++++++++---------- widget/testdata/list/small.xml | 4 +-- widget/testdata/select/desktop/center.xml | 2 +- .../testdata/select/desktop/layout_empty.xml | 2 +- .../select/desktop/layout_empty_expanded.xml | 2 +- .../layout_empty_expanded_placeholder.xml | 2 +- .../desktop/layout_empty_placeholder.xml | 2 +- .../select/desktop/layout_multiple.xml | 2 +- .../desktop/layout_multiple_expanded.xml | 2 +- .../layout_multiple_expanded_placeholder.xml | 2 +- .../layout_multiple_expanded_selected.xml | 2 +- ...multiple_expanded_selected_placeholder.xml | 2 +- .../desktop/layout_multiple_placeholder.xml | 2 +- .../desktop/layout_multiple_selected.xml | 2 +- .../layout_multiple_selected_placeholder.xml | 2 +- .../testdata/select/desktop/layout_single.xml | 2 +- .../select/desktop/layout_single_expanded.xml | 2 +- .../layout_single_expanded_placeholder.xml | 2 +- .../layout_single_expanded_selected.xml | 2 +- ...t_single_expanded_selected_placeholder.xml | 2 +- .../desktop/layout_single_placeholder.xml | 2 +- .../select/desktop/layout_single_selected.xml | 2 +- .../layout_single_selected_placeholder.xml | 2 +- widget/testdata/select/desktop/move_moved.xml | 2 +- .../testdata/select/desktop/move_tapped.xml | 2 +- widget/testdata/select/desktop/tapped.xml | 2 +- .../select/desktop/tapped_constrained.xml | 2 +- widget/testdata/select/desktop/trailing.xml | 2 +- .../select/focus_focused_b_selected.xml | 2 +- .../select/focus_focused_none_selected.xml | 2 +- .../select/focus_unfocused_b_selected.xml | 2 +- .../select/focus_unfocused_none_selected.xml | 2 +- widget/testdata/select/kbdctrl_a_selected.xml | 2 +- widget/testdata/select/kbdctrl_b_selected.xml | 2 +- widget/testdata/select/kbdctrl_c_selected.xml | 2 +- .../testdata/select/kbdctrl_none_selected.xml | 2 +- .../select/kbdctrl_none_selected_popup.xml | 2 +- widget/testdata/select/mobile/center.xml | 2 +- .../testdata/select/mobile/layout_empty.xml | 2 +- .../select/mobile/layout_empty_expanded.xml | 2 +- .../layout_empty_expanded_placeholder.xml | 2 +- .../mobile/layout_empty_placeholder.xml | 2 +- .../select/mobile/layout_multiple.xml | 2 +- .../mobile/layout_multiple_expanded.xml | 2 +- .../layout_multiple_expanded_placeholder.xml | 2 +- .../layout_multiple_expanded_selected.xml | 2 +- ...multiple_expanded_selected_placeholder.xml | 2 +- .../mobile/layout_multiple_placeholder.xml | 2 +- .../mobile/layout_multiple_selected.xml | 2 +- .../layout_multiple_selected_placeholder.xml | 2 +- .../testdata/select/mobile/layout_single.xml | 2 +- .../select/mobile/layout_single_expanded.xml | 2 +- .../layout_single_expanded_placeholder.xml | 2 +- .../layout_single_expanded_selected.xml | 2 +- ...t_single_expanded_selected_placeholder.xml | 2 +- .../mobile/layout_single_placeholder.xml | 2 +- .../select/mobile/layout_single_selected.xml | 2 +- .../layout_single_selected_placeholder.xml | 2 +- widget/testdata/select/mobile/move_moved.xml | 2 +- widget/testdata/select/mobile/move_tapped.xml | 2 +- widget/testdata/select/mobile/tapped.xml | 2 +- .../select/mobile/tapped_constrained.xml | 2 +- widget/testdata/select/mobile/trailing.xml | 2 +- widget/testdata/select/move_initial.xml | 2 +- .../select/set_selected_2nd_selected.xml | 2 +- .../select/set_selected_none_selected.xml | 2 +- .../select_entry/disableable_enabled.xml | 2 +- .../disableable_enabled_opened.xml | 2 +- .../disableable_enabled_tapped.xml | 2 +- .../disableable_enabled_tapped_selected.xml | 2 +- .../select_entry/dropdown_B_opened.xml | 2 +- .../select_entry/dropdown_empty_opened.xml | 2 +- .../dropdown_empty_opened_shrunk.xml | 2 +- .../select_entry/dropdown_empty_setopts.xml | 2 +- .../select_entry/dropdown_initial.xml | 2 +- .../select_entry/dropdown_tapped_B.xml | 2 +- .../select_entry/dropdown_tapped_C.xml | 2 +- widget/testdata/tree/layout_multiple.xml | 4 +-- .../testdata/tree/layout_multiple_branch.xml | 4 +-- .../tree/layout_multiple_branch_opened.xml | 6 ++-- ...t_multiple_branch_opened_leaf_selected.xml | 6 ++-- ...layout_multiple_branch_opened_selected.xml | 6 ++-- .../tree/layout_multiple_branch_selected.xml | 4 +-- .../tree/layout_multiple_selected.xml | 4 +-- widget/testdata/tree/layout_single_branch.xml | 2 +- .../tree/layout_single_branch_opened.xml | 2 +- ...out_single_branch_opened_leaf_selected.xml | 2 +- .../layout_single_branch_opened_selected.xml | 2 +- .../tree/layout_single_branch_selected.xml | 2 +- widget/testdata/tree/move_initial.xml | 2 +- widget/testdata/tree/move_moved.xml | 2 +- 208 files changed, 296 insertions(+), 297 deletions(-) diff --git a/container/testdata/apptabs/desktop/hover_overflow.xml b/container/testdata/apptabs/desktop/hover_overflow.xml index 89865fcffc..c7624381c9 100644 --- a/container/testdata/apptabs/desktop/hover_overflow.xml +++ b/container/testdata/apptabs/desktop/hover_overflow.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/apptabs/desktop/tab_location_bottom.xml b/container/testdata/apptabs/desktop/tab_location_bottom.xml index 28ef841355..395ba77385 100644 --- a/container/testdata/apptabs/desktop/tab_location_bottom.xml +++ b/container/testdata/apptabs/desktop/tab_location_bottom.xml @@ -10,7 +10,7 @@ - + diff --git a/container/testdata/apptabs/desktop/tab_location_leading.xml b/container/testdata/apptabs/desktop/tab_location_leading.xml index 3929f7e8a7..f9d4411cd9 100644 --- a/container/testdata/apptabs/desktop/tab_location_leading.xml +++ b/container/testdata/apptabs/desktop/tab_location_leading.xml @@ -10,7 +10,7 @@ - + diff --git a/container/testdata/apptabs/desktop/tab_location_top.xml b/container/testdata/apptabs/desktop/tab_location_top.xml index 0770b32445..a8e51a7f0f 100644 --- a/container/testdata/apptabs/desktop/tab_location_top.xml +++ b/container/testdata/apptabs/desktop/tab_location_top.xml @@ -10,7 +10,7 @@ - + diff --git a/container/testdata/apptabs/desktop/tab_location_trailing.xml b/container/testdata/apptabs/desktop/tab_location_trailing.xml index 21bca15141..6d43df830b 100644 --- a/container/testdata/apptabs/desktop/tab_location_trailing.xml +++ b/container/testdata/apptabs/desktop/tab_location_trailing.xml @@ -10,7 +10,7 @@ - + diff --git a/container/testdata/apptabs/desktop/tapped_overflow_tabs.xml b/container/testdata/apptabs/desktop/tapped_overflow_tabs.xml index 72ad2b4349..25df2f2fda 100644 --- a/container/testdata/apptabs/desktop/tapped_overflow_tabs.xml +++ b/container/testdata/apptabs/desktop/tapped_overflow_tabs.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/apptabs/mobile/tab_location_bottom.xml b/container/testdata/apptabs/mobile/tab_location_bottom.xml index f498c34598..3ba0242c6a 100644 --- a/container/testdata/apptabs/mobile/tab_location_bottom.xml +++ b/container/testdata/apptabs/mobile/tab_location_bottom.xml @@ -10,7 +10,7 @@ - + diff --git a/container/testdata/apptabs/mobile/tab_location_top.xml b/container/testdata/apptabs/mobile/tab_location_top.xml index 06fd981143..5bf14d9e27 100644 --- a/container/testdata/apptabs/mobile/tab_location_top.xml +++ b/container/testdata/apptabs/mobile/tab_location_top.xml @@ -10,7 +10,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_content_change_hidden.xml b/container/testdata/doctabs/desktop/change_content_change_hidden.xml index 1e849c52d6..28f8cbc0a7 100644 --- a/container/testdata/doctabs/desktop/change_content_change_hidden.xml +++ b/container/testdata/doctabs/desktop/change_content_change_hidden.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_content_change_visible.xml b/container/testdata/doctabs/desktop/change_content_change_visible.xml index 1e849c52d6..28f8cbc0a7 100644 --- a/container/testdata/doctabs/desktop/change_content_change_visible.xml +++ b/container/testdata/doctabs/desktop/change_content_change_visible.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_content_initial.xml b/container/testdata/doctabs/desktop/change_content_initial.xml index 41a5080b17..ffe3d57aec 100644 --- a/container/testdata/doctabs/desktop/change_content_initial.xml +++ b/container/testdata/doctabs/desktop/change_content_initial.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_icon_change_selected.xml b/container/testdata/doctabs/desktop/change_icon_change_selected.xml index 3ec2846a82..0d2c439233 100644 --- a/container/testdata/doctabs/desktop/change_icon_change_selected.xml +++ b/container/testdata/doctabs/desktop/change_icon_change_selected.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_icon_change_unselected.xml b/container/testdata/doctabs/desktop/change_icon_change_unselected.xml index 85a5e92da4..ad6f34d462 100644 --- a/container/testdata/doctabs/desktop/change_icon_change_unselected.xml +++ b/container/testdata/doctabs/desktop/change_icon_change_unselected.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_icon_initial.xml b/container/testdata/doctabs/desktop/change_icon_initial.xml index 0053a49fc9..75aa3abff5 100644 --- a/container/testdata/doctabs/desktop/change_icon_initial.xml +++ b/container/testdata/doctabs/desktop/change_icon_initial.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_label_change_selected.xml b/container/testdata/doctabs/desktop/change_label_change_selected.xml index b6dad30414..ec83020480 100644 --- a/container/testdata/doctabs/desktop/change_label_change_selected.xml +++ b/container/testdata/doctabs/desktop/change_label_change_selected.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_label_change_unselected.xml b/container/testdata/doctabs/desktop/change_label_change_unselected.xml index 4e02a2dc1b..54d7b38348 100644 --- a/container/testdata/doctabs/desktop/change_label_change_unselected.xml +++ b/container/testdata/doctabs/desktop/change_label_change_unselected.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_label_initial.xml b/container/testdata/doctabs/desktop/change_label_initial.xml index 41a5080b17..ffe3d57aec 100644 --- a/container/testdata/doctabs/desktop/change_label_initial.xml +++ b/container/testdata/doctabs/desktop/change_label_initial.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_label_to_longer_text_selected.xml b/container/testdata/doctabs/desktop/change_label_to_longer_text_selected.xml index 8c7d991fb7..ce5c7405ea 100644 --- a/container/testdata/doctabs/desktop/change_label_to_longer_text_selected.xml +++ b/container/testdata/doctabs/desktop/change_label_to_longer_text_selected.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/desktop/dynamic_appended.xml b/container/testdata/doctabs/desktop/dynamic_appended.xml index cc2356a973..7c7004c811 100644 --- a/container/testdata/doctabs/desktop/dynamic_appended.xml +++ b/container/testdata/doctabs/desktop/dynamic_appended.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/desktop/dynamic_appended_and_removed.xml b/container/testdata/doctabs/desktop/dynamic_appended_and_removed.xml index 78840555f3..36a45a3fe0 100644 --- a/container/testdata/doctabs/desktop/dynamic_appended_and_removed.xml +++ b/container/testdata/doctabs/desktop/dynamic_appended_and_removed.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/dynamic_appended_another_three.xml b/container/testdata/doctabs/desktop/dynamic_appended_another_three.xml index ada2da3ad9..50a8a6ac6e 100644 --- a/container/testdata/doctabs/desktop/dynamic_appended_another_three.xml +++ b/container/testdata/doctabs/desktop/dynamic_appended_another_three.xml @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/desktop/dynamic_initial.xml b/container/testdata/doctabs/desktop/dynamic_initial.xml index 0a4e4d8293..b780bb6baa 100644 --- a/container/testdata/doctabs/desktop/dynamic_initial.xml +++ b/container/testdata/doctabs/desktop/dynamic_initial.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/dynamic_replaced_completely.xml b/container/testdata/doctabs/desktop/dynamic_replaced_completely.xml index b67be65511..5256e51ab6 100644 --- a/container/testdata/doctabs/desktop/dynamic_replaced_completely.xml +++ b/container/testdata/doctabs/desktop/dynamic_replaced_completely.xml @@ -19,7 +19,7 @@ - + diff --git a/container/testdata/doctabs/desktop/hover_all_tabs.xml b/container/testdata/doctabs/desktop/hover_all_tabs.xml index 2001342dbb..08fb43b54c 100644 --- a/container/testdata/doctabs/desktop/hover_all_tabs.xml +++ b/container/testdata/doctabs/desktop/hover_all_tabs.xml @@ -24,12 +24,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/hover_create_tab.xml b/container/testdata/doctabs/desktop/hover_create_tab.xml index a1519dad3b..704ac28e4f 100644 --- a/container/testdata/doctabs/desktop/hover_create_tab.xml +++ b/container/testdata/doctabs/desktop/hover_create_tab.xml @@ -24,12 +24,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/hover_first.xml b/container/testdata/doctabs/desktop/hover_first.xml index c667b672bf..7293106df9 100644 --- a/container/testdata/doctabs/desktop/hover_first.xml +++ b/container/testdata/doctabs/desktop/hover_first.xml @@ -28,12 +28,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/hover_first_close.xml b/container/testdata/doctabs/desktop/hover_first_close.xml index a1519dad3b..704ac28e4f 100644 --- a/container/testdata/doctabs/desktop/hover_first_close.xml +++ b/container/testdata/doctabs/desktop/hover_first_close.xml @@ -24,12 +24,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/hover_none.xml b/container/testdata/doctabs/desktop/hover_none.xml index dac234c75b..cfe88da7fd 100644 --- a/container/testdata/doctabs/desktop/hover_none.xml +++ b/container/testdata/doctabs/desktop/hover_none.xml @@ -24,12 +24,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/hover_second.xml b/container/testdata/doctabs/desktop/hover_second.xml index a1519dad3b..704ac28e4f 100644 --- a/container/testdata/doctabs/desktop/hover_second.xml +++ b/container/testdata/doctabs/desktop/hover_second.xml @@ -24,12 +24,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/layout_bottom_icon.xml b/container/testdata/doctabs/desktop/layout_bottom_icon.xml index 50959caa51..df477efb78 100644 --- a/container/testdata/doctabs/desktop/layout_bottom_icon.xml +++ b/container/testdata/doctabs/desktop/layout_bottom_icon.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_bottom_icon_and_text.xml b/container/testdata/doctabs/desktop/layout_bottom_icon_and_text.xml index 134e9dd86b..b7582a83b4 100644 --- a/container/testdata/doctabs/desktop/layout_bottom_icon_and_text.xml +++ b/container/testdata/doctabs/desktop/layout_bottom_icon_and_text.xml @@ -14,7 +14,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_bottom_text.xml b/container/testdata/doctabs/desktop/layout_bottom_text.xml index 1f56ee7df1..0d5725dfed 100644 --- a/container/testdata/doctabs/desktop/layout_bottom_text.xml +++ b/container/testdata/doctabs/desktop/layout_bottom_text.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_leading_icon.xml b/container/testdata/doctabs/desktop/layout_leading_icon.xml index bd3cf5382c..9ed4062f8b 100644 --- a/container/testdata/doctabs/desktop/layout_leading_icon.xml +++ b/container/testdata/doctabs/desktop/layout_leading_icon.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_leading_icon_and_text.xml b/container/testdata/doctabs/desktop/layout_leading_icon_and_text.xml index 02f8209357..3ad2dda74d 100644 --- a/container/testdata/doctabs/desktop/layout_leading_icon_and_text.xml +++ b/container/testdata/doctabs/desktop/layout_leading_icon_and_text.xml @@ -14,7 +14,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_leading_text.xml b/container/testdata/doctabs/desktop/layout_leading_text.xml index 6ea774962f..ed08c0184c 100644 --- a/container/testdata/doctabs/desktop/layout_leading_text.xml +++ b/container/testdata/doctabs/desktop/layout_leading_text.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_top_icon.xml b/container/testdata/doctabs/desktop/layout_top_icon.xml index 0b9c48639b..f2faf7b3cf 100644 --- a/container/testdata/doctabs/desktop/layout_top_icon.xml +++ b/container/testdata/doctabs/desktop/layout_top_icon.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_top_icon_and_text.xml b/container/testdata/doctabs/desktop/layout_top_icon_and_text.xml index 5184c5279b..ab7bf8f0b4 100644 --- a/container/testdata/doctabs/desktop/layout_top_icon_and_text.xml +++ b/container/testdata/doctabs/desktop/layout_top_icon_and_text.xml @@ -14,7 +14,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_top_text.xml b/container/testdata/doctabs/desktop/layout_top_text.xml index 7285d2906c..2cbd507db2 100644 --- a/container/testdata/doctabs/desktop/layout_top_text.xml +++ b/container/testdata/doctabs/desktop/layout_top_text.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_trailing_icon.xml b/container/testdata/doctabs/desktop/layout_trailing_icon.xml index c1712fb144..9a3c5bfd1f 100644 --- a/container/testdata/doctabs/desktop/layout_trailing_icon.xml +++ b/container/testdata/doctabs/desktop/layout_trailing_icon.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_trailing_icon_and_text.xml b/container/testdata/doctabs/desktop/layout_trailing_icon_and_text.xml index e061456519..9eb08deb0c 100644 --- a/container/testdata/doctabs/desktop/layout_trailing_icon_and_text.xml +++ b/container/testdata/doctabs/desktop/layout_trailing_icon_and_text.xml @@ -14,7 +14,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_trailing_text.xml b/container/testdata/doctabs/desktop/layout_trailing_text.xml index d11a178f28..f4f90e9056 100644 --- a/container/testdata/doctabs/desktop/layout_trailing_text.xml +++ b/container/testdata/doctabs/desktop/layout_trailing_text.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/tab_location_bottom.xml b/container/testdata/doctabs/desktop/tab_location_bottom.xml index a5c1bfc7fc..9894df8b8d 100644 --- a/container/testdata/doctabs/desktop/tab_location_bottom.xml +++ b/container/testdata/doctabs/desktop/tab_location_bottom.xml @@ -27,7 +27,7 @@ - + diff --git a/container/testdata/doctabs/desktop/tab_location_leading.xml b/container/testdata/doctabs/desktop/tab_location_leading.xml index facdf561b9..1bf2a414de 100644 --- a/container/testdata/doctabs/desktop/tab_location_leading.xml +++ b/container/testdata/doctabs/desktop/tab_location_leading.xml @@ -27,7 +27,7 @@ - + diff --git a/container/testdata/doctabs/desktop/tab_location_top.xml b/container/testdata/doctabs/desktop/tab_location_top.xml index e22784173b..76f3f18d25 100644 --- a/container/testdata/doctabs/desktop/tab_location_top.xml +++ b/container/testdata/doctabs/desktop/tab_location_top.xml @@ -27,7 +27,7 @@ - + diff --git a/container/testdata/doctabs/desktop/tab_location_trailing.xml b/container/testdata/doctabs/desktop/tab_location_trailing.xml index 4de6176739..a6696b684a 100644 --- a/container/testdata/doctabs/desktop/tab_location_trailing.xml +++ b/container/testdata/doctabs/desktop/tab_location_trailing.xml @@ -27,7 +27,7 @@ - + diff --git a/container/testdata/doctabs/desktop/tapped_all_tabs.xml b/container/testdata/doctabs/desktop/tapped_all_tabs.xml index 91007156b8..d61863b81a 100644 --- a/container/testdata/doctabs/desktop/tapped_all_tabs.xml +++ b/container/testdata/doctabs/desktop/tapped_all_tabs.xml @@ -30,12 +30,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/tapped_create_tab.xml b/container/testdata/doctabs/desktop/tapped_create_tab.xml index 4f5fbdb459..a06b5f7150 100644 --- a/container/testdata/doctabs/desktop/tapped_create_tab.xml +++ b/container/testdata/doctabs/desktop/tapped_create_tab.xml @@ -30,12 +30,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/tapped_first_selected.xml b/container/testdata/doctabs/desktop/tapped_first_selected.xml index 504d522758..11ed06c08d 100644 --- a/container/testdata/doctabs/desktop/tapped_first_selected.xml +++ b/container/testdata/doctabs/desktop/tapped_first_selected.xml @@ -27,12 +27,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/tapped_second_selected.xml b/container/testdata/doctabs/desktop/tapped_second_selected.xml index 5af061e0c4..795b8afea9 100644 --- a/container/testdata/doctabs/desktop/tapped_second_selected.xml +++ b/container/testdata/doctabs/desktop/tapped_second_selected.xml @@ -27,12 +27,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/tapped_third_selected.xml b/container/testdata/doctabs/desktop/tapped_third_selected.xml index 08b3531ae4..5907df0557 100644 --- a/container/testdata/doctabs/desktop/tapped_third_selected.xml +++ b/container/testdata/doctabs/desktop/tapped_third_selected.xml @@ -27,12 +27,12 @@ - + - + diff --git a/container/testdata/doctabs/mobile/change_content_change_hidden.xml b/container/testdata/doctabs/mobile/change_content_change_hidden.xml index f41fbd6321..60e378b2af 100644 --- a/container/testdata/doctabs/mobile/change_content_change_hidden.xml +++ b/container/testdata/doctabs/mobile/change_content_change_hidden.xml @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_content_change_visible.xml b/container/testdata/doctabs/mobile/change_content_change_visible.xml index f41fbd6321..60e378b2af 100644 --- a/container/testdata/doctabs/mobile/change_content_change_visible.xml +++ b/container/testdata/doctabs/mobile/change_content_change_visible.xml @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_content_initial.xml b/container/testdata/doctabs/mobile/change_content_initial.xml index 7ad4ba15e8..da6f48ba02 100644 --- a/container/testdata/doctabs/mobile/change_content_initial.xml +++ b/container/testdata/doctabs/mobile/change_content_initial.xml @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_icon_change_selected.xml b/container/testdata/doctabs/mobile/change_icon_change_selected.xml index 2b941ffa5d..7cfc200cea 100644 --- a/container/testdata/doctabs/mobile/change_icon_change_selected.xml +++ b/container/testdata/doctabs/mobile/change_icon_change_selected.xml @@ -22,7 +22,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_icon_change_unselected.xml b/container/testdata/doctabs/mobile/change_icon_change_unselected.xml index 118e08973a..c9121c34e6 100644 --- a/container/testdata/doctabs/mobile/change_icon_change_unselected.xml +++ b/container/testdata/doctabs/mobile/change_icon_change_unselected.xml @@ -22,7 +22,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_icon_initial.xml b/container/testdata/doctabs/mobile/change_icon_initial.xml index 7805daf3a1..a3577b95e9 100644 --- a/container/testdata/doctabs/mobile/change_icon_initial.xml +++ b/container/testdata/doctabs/mobile/change_icon_initial.xml @@ -22,7 +22,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_label_change_selected.xml b/container/testdata/doctabs/mobile/change_label_change_selected.xml index 698e5cd164..e629e32ba9 100644 --- a/container/testdata/doctabs/mobile/change_label_change_selected.xml +++ b/container/testdata/doctabs/mobile/change_label_change_selected.xml @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_label_change_unselected.xml b/container/testdata/doctabs/mobile/change_label_change_unselected.xml index 794dfee63a..c14ab0d2dc 100644 --- a/container/testdata/doctabs/mobile/change_label_change_unselected.xml +++ b/container/testdata/doctabs/mobile/change_label_change_unselected.xml @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_label_initial.xml b/container/testdata/doctabs/mobile/change_label_initial.xml index 7ad4ba15e8..da6f48ba02 100644 --- a/container/testdata/doctabs/mobile/change_label_initial.xml +++ b/container/testdata/doctabs/mobile/change_label_initial.xml @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/mobile/dynamic_appended.xml b/container/testdata/doctabs/mobile/dynamic_appended.xml index 182d0bd0b8..9bafebb114 100644 --- a/container/testdata/doctabs/mobile/dynamic_appended.xml +++ b/container/testdata/doctabs/mobile/dynamic_appended.xml @@ -22,7 +22,7 @@ - + diff --git a/container/testdata/doctabs/mobile/dynamic_appended_and_removed.xml b/container/testdata/doctabs/mobile/dynamic_appended_and_removed.xml index db7dc50539..4f35d61028 100644 --- a/container/testdata/doctabs/mobile/dynamic_appended_and_removed.xml +++ b/container/testdata/doctabs/mobile/dynamic_appended_and_removed.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/mobile/dynamic_appended_another_three.xml b/container/testdata/doctabs/mobile/dynamic_appended_another_three.xml index 78a0fda310..4b11853461 100644 --- a/container/testdata/doctabs/mobile/dynamic_appended_another_three.xml +++ b/container/testdata/doctabs/mobile/dynamic_appended_another_three.xml @@ -42,7 +42,7 @@ - + diff --git a/container/testdata/doctabs/mobile/dynamic_initial.xml b/container/testdata/doctabs/mobile/dynamic_initial.xml index 3ac0160fb0..affd36968d 100644 --- a/container/testdata/doctabs/mobile/dynamic_initial.xml +++ b/container/testdata/doctabs/mobile/dynamic_initial.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/mobile/dynamic_replaced_completely.xml b/container/testdata/doctabs/mobile/dynamic_replaced_completely.xml index b99fddaca1..ef7eb3deff 100644 --- a/container/testdata/doctabs/mobile/dynamic_replaced_completely.xml +++ b/container/testdata/doctabs/mobile/dynamic_replaced_completely.xml @@ -28,7 +28,7 @@ - + diff --git a/container/testdata/doctabs/mobile/hover_none.xml b/container/testdata/doctabs/mobile/hover_none.xml index f5da04b3bd..86e4a3d402 100644 --- a/container/testdata/doctabs/mobile/hover_none.xml +++ b/container/testdata/doctabs/mobile/hover_none.xml @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/mobile/layout_bottom_ico.xml b/container/testdata/doctabs/mobile/layout_bottom_ico.xml index 9f40d8cfc2..1df0bd559d 100644 --- a/container/testdata/doctabs/mobile/layout_bottom_ico.xml +++ b/container/testdata/doctabs/mobile/layout_bottom_ico.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/mobile/layout_bottom_icon_and_text.xml b/container/testdata/doctabs/mobile/layout_bottom_icon_and_text.xml index 97c3dbf02c..a7a8acf5e5 100644 --- a/container/testdata/doctabs/mobile/layout_bottom_icon_and_text.xml +++ b/container/testdata/doctabs/mobile/layout_bottom_icon_and_text.xml @@ -17,7 +17,7 @@ - + diff --git a/container/testdata/doctabs/mobile/layout_bottom_text.xml b/container/testdata/doctabs/mobile/layout_bottom_text.xml index 001c39c61e..6b149f6c06 100644 --- a/container/testdata/doctabs/mobile/layout_bottom_text.xml +++ b/container/testdata/doctabs/mobile/layout_bottom_text.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/mobile/layout_top_icon.xml b/container/testdata/doctabs/mobile/layout_top_icon.xml index 202ee560cf..087896f2b4 100644 --- a/container/testdata/doctabs/mobile/layout_top_icon.xml +++ b/container/testdata/doctabs/mobile/layout_top_icon.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/mobile/layout_top_icon_and_text.xml b/container/testdata/doctabs/mobile/layout_top_icon_and_text.xml index a21794d559..f326c67766 100644 --- a/container/testdata/doctabs/mobile/layout_top_icon_and_text.xml +++ b/container/testdata/doctabs/mobile/layout_top_icon_and_text.xml @@ -17,7 +17,7 @@ - + diff --git a/container/testdata/doctabs/mobile/layout_top_text.xml b/container/testdata/doctabs/mobile/layout_top_text.xml index 434ab1817f..a5398f6ea0 100644 --- a/container/testdata/doctabs/mobile/layout_top_text.xml +++ b/container/testdata/doctabs/mobile/layout_top_text.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/mobile/tab_location_bottom.xml b/container/testdata/doctabs/mobile/tab_location_bottom.xml index b86c07409c..96e8233d24 100644 --- a/container/testdata/doctabs/mobile/tab_location_bottom.xml +++ b/container/testdata/doctabs/mobile/tab_location_bottom.xml @@ -36,7 +36,7 @@ - + diff --git a/container/testdata/doctabs/mobile/tab_location_top.xml b/container/testdata/doctabs/mobile/tab_location_top.xml index ab8439e007..ea9e7dd63b 100644 --- a/container/testdata/doctabs/mobile/tab_location_top.xml +++ b/container/testdata/doctabs/mobile/tab_location_top.xml @@ -36,7 +36,7 @@ - + diff --git a/container/testdata/doctabs/mobile/tapped_all_tabs.xml b/container/testdata/doctabs/mobile/tapped_all_tabs.xml index c24064eb93..d53210e253 100644 --- a/container/testdata/doctabs/mobile/tapped_all_tabs.xml +++ b/container/testdata/doctabs/mobile/tapped_all_tabs.xml @@ -42,12 +42,12 @@ - + - + diff --git a/container/testdata/doctabs/mobile/tapped_create_tab.xml b/container/testdata/doctabs/mobile/tapped_create_tab.xml index e1dec74b47..5d1e0839e5 100644 --- a/container/testdata/doctabs/mobile/tapped_create_tab.xml +++ b/container/testdata/doctabs/mobile/tapped_create_tab.xml @@ -42,12 +42,12 @@ - + - + diff --git a/container/testdata/doctabs/mobile/tapped_first_selected.xml b/container/testdata/doctabs/mobile/tapped_first_selected.xml index 68414668e9..d61f0a4656 100644 --- a/container/testdata/doctabs/mobile/tapped_first_selected.xml +++ b/container/testdata/doctabs/mobile/tapped_first_selected.xml @@ -28,12 +28,12 @@ - + - + diff --git a/container/testdata/doctabs/mobile/tapped_second_selected.xml b/container/testdata/doctabs/mobile/tapped_second_selected.xml index ecd37da9b5..d95b5392b1 100644 --- a/container/testdata/doctabs/mobile/tapped_second_selected.xml +++ b/container/testdata/doctabs/mobile/tapped_second_selected.xml @@ -28,12 +28,12 @@ - + - + diff --git a/container/testdata/doctabs/mobile/tapped_third_selected.xml b/container/testdata/doctabs/mobile/tapped_third_selected.xml index 364fa3eda3..38e2595e0a 100644 --- a/container/testdata/doctabs/mobile/tapped_third_selected.xml +++ b/container/testdata/doctabs/mobile/tapped_third_selected.xml @@ -28,12 +28,12 @@ - + - + diff --git a/internal/cache/base_test.go b/internal/cache/base_test.go index 72ae9c1892..adffe67209 100644 --- a/internal/cache/base_test.go +++ b/internal/cache/base_test.go @@ -25,7 +25,7 @@ func TestCacheClean(t *testing.T) { for k := 0; k < 2; k++ { tm.setTime(10, 10+k*10) for i := 0; i < 20; i++ { - SetSvg(fmt.Sprintf("%d%d", k, i), nil, i, i+1) + SetSvg(fmt.Sprintf("%d%d", k, i), nil, nil, i, i+1) Renderer(&dummyWidget{onDestroy: func() { destroyedRenderersCnt++ }}) diff --git a/internal/cache/svg_test.go b/internal/cache/svg_test.go index 3f0899e27b..5296ae0427 100644 --- a/internal/cache/svg_test.go +++ b/internal/cache/svg_test.go @@ -22,12 +22,12 @@ func TestSvgCacheGet(t *testing.T) { img := addToCache("empty.svg", "", 25, 25) assert.Equal(t, 1, syncMapLen(svgs)) - newImg := GetSvg("empty.svg", 25, 25) + newImg := GetSvg("empty.svg", nil, 25, 25) assert.Equal(t, img, newImg) - miss := GetSvg("missing.svg", 25, 25) + miss := GetSvg("missing.svg", nil, 25, 25) assert.Nil(t, miss) - miss = GetSvg("empty.svg", 30, 30) + miss = GetSvg("empty.svg", nil, 30, 30) assert.Nil(t, miss) } @@ -36,12 +36,12 @@ func TestSvgCacheGet_File(t *testing.T) { img := addFileToCache("testdata/stroke.svg", 25, 25) assert.Equal(t, 1, syncMapLen(svgs)) - newImg := GetSvg("testdata/stroke.svg", 25, 25) + newImg := GetSvg("testdata/stroke.svg", nil, 25, 25) assert.Equal(t, img, newImg) - miss := GetSvg("missing.svg", 25, 25) + miss := GetSvg("missing.svg", nil, 25, 25) assert.Nil(t, miss) - miss = GetSvg("testdata/stroke.svg", 30, 30) + miss = GetSvg("testdata/stroke.svg", nil, 30, 30) assert.Nil(t, miss) } @@ -56,13 +56,13 @@ func TestSvgCacheReset(t *testing.T) { func addFileToCache(path string, w, h int) image.Image { tex := image.NewNRGBA(image.Rect(0, 0, w, h)) - SetSvg(path, tex, w, h) + SetSvg(path, nil, tex, w, h) return tex } func addToCache(name, content string, w, h int) image.Image { resource := fyne.NewStaticResource(name, []byte(content)) tex := image.NewNRGBA(image.Rect(0, 0, w, h)) - SetSvg(resource.Name(), tex, w, h) + SetSvg(resource.Name(), nil, tex, w, h) return tex } diff --git a/widget/icon_extend_test.go b/widget/icon_extend_test.go index f404b4efdc..e4c86c51c6 100644 --- a/widget/icon_extend_test.go +++ b/widget/icon_extend_test.go @@ -25,5 +25,5 @@ func TestIcon_Extended_SetResource(t *testing.T) { objs := cache.Renderer(icon).Objects() assert.Equal(t, 1, len(objs)) - assert.Equal(t, theme.ComputerIcon(), objs[0].(*canvas.Image).Resource.(*cache.WidgetResource).ThemedResource) + assert.Equal(t, theme.ComputerIcon(), objs[0].(*canvas.Image).Resource) } diff --git a/widget/icon_internal_test.go b/widget/icon_internal_test.go index 4ce819b80f..07733d66fe 100644 --- a/widget/icon_internal_test.go +++ b/widget/icon_internal_test.go @@ -4,7 +4,6 @@ import ( "testing" "fyne.io/fyne/v2/canvas" - "fyne.io/fyne/v2/internal/cache" "fyne.io/fyne/v2/test" "fyne.io/fyne/v2/theme" "github.com/stretchr/testify/assert" @@ -20,7 +19,7 @@ func TestNewIcon(t *testing.T) { if !ok { t.Fail() } - assert.Equal(t, theme.ConfirmIcon(), img.Resource.(*cache.WidgetResource).ThemedResource) + assert.Equal(t, theme.ConfirmIcon(), img.Resource) } func TestIcon_Nil(t *testing.T) { diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items.xml b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items.xml index ec1db5a0ee..3ca18d1caa 100644 --- a/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items_opened.xml index 4e54e150fc..086e03b7f2 100644 --- a/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items_opened.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_one_item.xml b/widget/testdata/accordion/layout_expanded_multiple_open_one_item.xml index b6f844fb7a..ad0531f594 100644 --- a/widget/testdata/accordion/layout_expanded_multiple_open_one_item.xml +++ b/widget/testdata/accordion/layout_expanded_multiple_open_one_item.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_one_item_opened.xml b/widget/testdata/accordion/layout_expanded_multiple_open_one_item_opened.xml index b5dcff715e..5393d0bd7d 100644 --- a/widget/testdata/accordion/layout_expanded_multiple_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_expanded_multiple_open_one_item_opened.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_expanded_single_open_multiple_items.xml b/widget/testdata/accordion/layout_expanded_single_open_multiple_items.xml index ec1db5a0ee..3ca18d1caa 100644 --- a/widget/testdata/accordion/layout_expanded_single_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_expanded_single_open_multiple_items.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_expanded_single_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_expanded_single_open_multiple_items_opened.xml index 79c4d2346a..8ab4d7b294 100644 --- a/widget/testdata/accordion/layout_expanded_single_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_expanded_single_open_multiple_items_opened.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_expanded_single_open_one_item.xml b/widget/testdata/accordion/layout_expanded_single_open_one_item.xml index b6f844fb7a..ad0531f594 100644 --- a/widget/testdata/accordion/layout_expanded_single_open_one_item.xml +++ b/widget/testdata/accordion/layout_expanded_single_open_one_item.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_expanded_single_open_one_item_opened.xml b/widget/testdata/accordion/layout_expanded_single_open_one_item_opened.xml index b5dcff715e..5393d0bd7d 100644 --- a/widget/testdata/accordion/layout_expanded_single_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_expanded_single_open_one_item_opened.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_multiple_open_multiple_items.xml b/widget/testdata/accordion/layout_multiple_open_multiple_items.xml index 5a5ef468e7..cdf9bbc0e0 100644 --- a/widget/testdata/accordion/layout_multiple_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_multiple_open_multiple_items.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml index 31620c9cc8..876d41617d 100644 --- a/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_multiple_open_one_item.xml b/widget/testdata/accordion/layout_multiple_open_one_item.xml index da361560a0..8835a72d89 100644 --- a/widget/testdata/accordion/layout_multiple_open_one_item.xml +++ b/widget/testdata/accordion/layout_multiple_open_one_item.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml b/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml index 9c0430b67f..e2fcd4def4 100644 --- a/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_single_open_multiple_items.xml b/widget/testdata/accordion/layout_single_open_multiple_items.xml index 5a5ef468e7..cdf9bbc0e0 100644 --- a/widget/testdata/accordion/layout_single_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_single_open_multiple_items.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml index 4e80548430..a6d4f151d6 100644 --- a/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_single_open_one_item.xml b/widget/testdata/accordion/layout_single_open_one_item.xml index da361560a0..8835a72d89 100644 --- a/widget/testdata/accordion/layout_single_open_one_item.xml +++ b/widget/testdata/accordion/layout_single_open_one_item.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_single_open_one_item_opened.xml b/widget/testdata/accordion/layout_single_open_one_item_opened.xml index 9c0430b67f..e2fcd4def4 100644 --- a/widget/testdata/accordion/layout_single_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_single_open_one_item_opened.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/button/layout_icon_only_center_leading.xml b/widget/testdata/button/layout_icon_only_center_leading.xml index 86f3fc0468..21fb65892a 100644 --- a/widget/testdata/button/layout_icon_only_center_leading.xml +++ b/widget/testdata/button/layout_icon_only_center_leading.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_icon_only_center_trailing.xml b/widget/testdata/button/layout_icon_only_center_trailing.xml index 86f3fc0468..21fb65892a 100644 --- a/widget/testdata/button/layout_icon_only_center_trailing.xml +++ b/widget/testdata/button/layout_icon_only_center_trailing.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_icon_only_leading_leading.xml b/widget/testdata/button/layout_icon_only_leading_leading.xml index df8f7f1922..2a533961a1 100644 --- a/widget/testdata/button/layout_icon_only_leading_leading.xml +++ b/widget/testdata/button/layout_icon_only_leading_leading.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_icon_only_leading_trailing.xml b/widget/testdata/button/layout_icon_only_leading_trailing.xml index df8f7f1922..2a533961a1 100644 --- a/widget/testdata/button/layout_icon_only_leading_trailing.xml +++ b/widget/testdata/button/layout_icon_only_leading_trailing.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_icon_only_trailing_leading.xml b/widget/testdata/button/layout_icon_only_trailing_leading.xml index fac82c6b4d..c288a884fd 100644 --- a/widget/testdata/button/layout_icon_only_trailing_leading.xml +++ b/widget/testdata/button/layout_icon_only_trailing_leading.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_icon_only_trailing_trailing.xml b/widget/testdata/button/layout_icon_only_trailing_trailing.xml index fac82c6b4d..c288a884fd 100644 --- a/widget/testdata/button/layout_icon_only_trailing_trailing.xml +++ b/widget/testdata/button/layout_icon_only_trailing_trailing.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_text_icon_center_leading.xml b/widget/testdata/button/layout_text_icon_center_leading.xml index c9ae1a5dda..47fe2c5f23 100644 --- a/widget/testdata/button/layout_text_icon_center_leading.xml +++ b/widget/testdata/button/layout_text_icon_center_leading.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/button/layout_text_icon_center_trailing.xml b/widget/testdata/button/layout_text_icon_center_trailing.xml index 3d2357f8bc..14a97153c7 100644 --- a/widget/testdata/button/layout_text_icon_center_trailing.xml +++ b/widget/testdata/button/layout_text_icon_center_trailing.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/button/layout_text_icon_leading_leading.xml b/widget/testdata/button/layout_text_icon_leading_leading.xml index e24a147ebb..9c92ec23d0 100644 --- a/widget/testdata/button/layout_text_icon_leading_leading.xml +++ b/widget/testdata/button/layout_text_icon_leading_leading.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/button/layout_text_icon_leading_trailing.xml b/widget/testdata/button/layout_text_icon_leading_trailing.xml index bce0eaa453..1f6a482bcd 100644 --- a/widget/testdata/button/layout_text_icon_leading_trailing.xml +++ b/widget/testdata/button/layout_text_icon_leading_trailing.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/button/layout_text_icon_trailing_leading.xml b/widget/testdata/button/layout_text_icon_trailing_leading.xml index d5f5a0da3d..98004a5386 100644 --- a/widget/testdata/button/layout_text_icon_trailing_leading.xml +++ b/widget/testdata/button/layout_text_icon_trailing_leading.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/button/layout_text_icon_trailing_trailing.xml b/widget/testdata/button/layout_text_icon_trailing_trailing.xml index 3aa4030ba8..293aa6c307 100644 --- a/widget/testdata/button/layout_text_icon_trailing_trailing.xml +++ b/widget/testdata/button/layout_text_icon_trailing_trailing.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/form/extended_entry.xml b/widget/testdata/form/extended_entry.xml index cd6ebedbad..dbcf90463d 100644 --- a/widget/testdata/form/extended_entry.xml +++ b/widget/testdata/form/extended_entry.xml @@ -22,7 +22,7 @@ - + diff --git a/widget/testdata/form/layout.xml b/widget/testdata/form/layout.xml index de9444978a..d746027d98 100644 --- a/widget/testdata/form/layout.xml +++ b/widget/testdata/form/layout.xml @@ -46,7 +46,7 @@ Cancel - + diff --git a/widget/testdata/icon/layout_resource.xml b/widget/testdata/icon/layout_resource.xml index b56d6eef80..7b7009d9d3 100644 --- a/widget/testdata/icon/layout_resource.xml +++ b/widget/testdata/icon/layout_resource.xml @@ -2,7 +2,7 @@ - + diff --git a/widget/testdata/list/initial.xml b/widget/testdata/list/initial.xml index e43564c0fe..e63c4ce515 100644 --- a/widget/testdata/list/initial.xml +++ b/widget/testdata/list/initial.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -78,7 +78,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -126,7 +126,7 @@ - + diff --git a/widget/testdata/list/item_removed.xml b/widget/testdata/list/item_removed.xml index 68d265a365..24909e338c 100644 --- a/widget/testdata/list/item_removed.xml +++ b/widget/testdata/list/item_removed.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + diff --git a/widget/testdata/list/new_data.xml b/widget/testdata/list/new_data.xml index fcc8c3f97c..2148abdc1b 100644 --- a/widget/testdata/list/new_data.xml +++ b/widget/testdata/list/new_data.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -78,7 +78,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -126,7 +126,7 @@ - + diff --git a/widget/testdata/list/offset_changed.xml b/widget/testdata/list/offset_changed.xml index 73c8d7d507..aebe51c6e4 100644 --- a/widget/testdata/list/offset_changed.xml +++ b/widget/testdata/list/offset_changed.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -78,7 +78,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -126,7 +126,7 @@ - + diff --git a/widget/testdata/list/resized.xml b/widget/testdata/list/resized.xml index 9b018ca69e..21fe8a8915 100644 --- a/widget/testdata/list/resized.xml +++ b/widget/testdata/list/resized.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -78,7 +78,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -126,7 +126,7 @@ - + @@ -138,7 +138,7 @@ - + @@ -150,7 +150,7 @@ - + @@ -162,7 +162,7 @@ - + @@ -174,7 +174,7 @@ - + @@ -186,7 +186,7 @@ - + diff --git a/widget/testdata/list/small.xml b/widget/testdata/list/small.xml index 68d265a365..24909e338c 100644 --- a/widget/testdata/list/small.xml +++ b/widget/testdata/list/small.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + diff --git a/widget/testdata/select/desktop/center.xml b/widget/testdata/select/desktop/center.xml index 8554e32e4b..8f240e15f5 100644 --- a/widget/testdata/select/desktop/center.xml +++ b/widget/testdata/select/desktop/center.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_empty.xml b/widget/testdata/select/desktop/layout_empty.xml index a662d36d6a..61cc0b0858 100644 --- a/widget/testdata/select/desktop/layout_empty.xml +++ b/widget/testdata/select/desktop/layout_empty.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_empty_expanded.xml b/widget/testdata/select/desktop/layout_empty_expanded.xml index de49b4ecd9..78ae0b49f1 100644 --- a/widget/testdata/select/desktop/layout_empty_expanded.xml +++ b/widget/testdata/select/desktop/layout_empty_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_empty_expanded_placeholder.xml b/widget/testdata/select/desktop/layout_empty_expanded_placeholder.xml index e9cc67d69b..f0ca21f624 100644 --- a/widget/testdata/select/desktop/layout_empty_expanded_placeholder.xml +++ b/widget/testdata/select/desktop/layout_empty_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_empty_placeholder.xml b/widget/testdata/select/desktop/layout_empty_placeholder.xml index b6fb6c7b9c..2c5f3f1622 100644 --- a/widget/testdata/select/desktop/layout_empty_placeholder.xml +++ b/widget/testdata/select/desktop/layout_empty_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_multiple.xml b/widget/testdata/select/desktop/layout_multiple.xml index a662d36d6a..61cc0b0858 100644 --- a/widget/testdata/select/desktop/layout_multiple.xml +++ b/widget/testdata/select/desktop/layout_multiple.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_multiple_expanded.xml b/widget/testdata/select/desktop/layout_multiple_expanded.xml index 9dd2180408..6719351dd0 100644 --- a/widget/testdata/select/desktop/layout_multiple_expanded.xml +++ b/widget/testdata/select/desktop/layout_multiple_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_multiple_expanded_placeholder.xml b/widget/testdata/select/desktop/layout_multiple_expanded_placeholder.xml index 59ec939be5..45fb862e40 100644 --- a/widget/testdata/select/desktop/layout_multiple_expanded_placeholder.xml +++ b/widget/testdata/select/desktop/layout_multiple_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_multiple_expanded_selected.xml b/widget/testdata/select/desktop/layout_multiple_expanded_selected.xml index 18bfb361b1..d917846da7 100644 --- a/widget/testdata/select/desktop/layout_multiple_expanded_selected.xml +++ b/widget/testdata/select/desktop/layout_multiple_expanded_selected.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/desktop/layout_multiple_expanded_selected_placeholder.xml b/widget/testdata/select/desktop/layout_multiple_expanded_selected_placeholder.xml index 39139e3bdc..ec48beb37e 100644 --- a/widget/testdata/select/desktop/layout_multiple_expanded_selected_placeholder.xml +++ b/widget/testdata/select/desktop/layout_multiple_expanded_selected_placeholder.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/desktop/layout_multiple_placeholder.xml b/widget/testdata/select/desktop/layout_multiple_placeholder.xml index b6fb6c7b9c..2c5f3f1622 100644 --- a/widget/testdata/select/desktop/layout_multiple_placeholder.xml +++ b/widget/testdata/select/desktop/layout_multiple_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_multiple_selected.xml b/widget/testdata/select/desktop/layout_multiple_selected.xml index 28338edfca..7e96da26c2 100644 --- a/widget/testdata/select/desktop/layout_multiple_selected.xml +++ b/widget/testdata/select/desktop/layout_multiple_selected.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/desktop/layout_multiple_selected_placeholder.xml b/widget/testdata/select/desktop/layout_multiple_selected_placeholder.xml index ee8fe4e34e..32d95230fb 100644 --- a/widget/testdata/select/desktop/layout_multiple_selected_placeholder.xml +++ b/widget/testdata/select/desktop/layout_multiple_selected_placeholder.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/desktop/layout_single.xml b/widget/testdata/select/desktop/layout_single.xml index a662d36d6a..61cc0b0858 100644 --- a/widget/testdata/select/desktop/layout_single.xml +++ b/widget/testdata/select/desktop/layout_single.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_single_expanded.xml b/widget/testdata/select/desktop/layout_single_expanded.xml index 1505d9daa9..f4643de528 100644 --- a/widget/testdata/select/desktop/layout_single_expanded.xml +++ b/widget/testdata/select/desktop/layout_single_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_single_expanded_placeholder.xml b/widget/testdata/select/desktop/layout_single_expanded_placeholder.xml index c05838c4c5..0d831fa20a 100644 --- a/widget/testdata/select/desktop/layout_single_expanded_placeholder.xml +++ b/widget/testdata/select/desktop/layout_single_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_single_expanded_selected.xml b/widget/testdata/select/desktop/layout_single_expanded_selected.xml index ec634b8d11..9ed9012267 100644 --- a/widget/testdata/select/desktop/layout_single_expanded_selected.xml +++ b/widget/testdata/select/desktop/layout_single_expanded_selected.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/desktop/layout_single_expanded_selected_placeholder.xml b/widget/testdata/select/desktop/layout_single_expanded_selected_placeholder.xml index b4ea2e54a8..31ba1f8a95 100644 --- a/widget/testdata/select/desktop/layout_single_expanded_selected_placeholder.xml +++ b/widget/testdata/select/desktop/layout_single_expanded_selected_placeholder.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/desktop/layout_single_placeholder.xml b/widget/testdata/select/desktop/layout_single_placeholder.xml index b6fb6c7b9c..2c5f3f1622 100644 --- a/widget/testdata/select/desktop/layout_single_placeholder.xml +++ b/widget/testdata/select/desktop/layout_single_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_single_selected.xml b/widget/testdata/select/desktop/layout_single_selected.xml index 3a5759a084..f74568aa76 100644 --- a/widget/testdata/select/desktop/layout_single_selected.xml +++ b/widget/testdata/select/desktop/layout_single_selected.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/desktop/layout_single_selected_placeholder.xml b/widget/testdata/select/desktop/layout_single_selected_placeholder.xml index df72a2755d..3f6b60bb72 100644 --- a/widget/testdata/select/desktop/layout_single_selected_placeholder.xml +++ b/widget/testdata/select/desktop/layout_single_selected_placeholder.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/desktop/move_moved.xml b/widget/testdata/select/desktop/move_moved.xml index d8970d07ad..82e60f5161 100644 --- a/widget/testdata/select/desktop/move_moved.xml +++ b/widget/testdata/select/desktop/move_moved.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/move_tapped.xml b/widget/testdata/select/desktop/move_tapped.xml index 1bc0dc77e8..5a574401ec 100644 --- a/widget/testdata/select/desktop/move_tapped.xml +++ b/widget/testdata/select/desktop/move_tapped.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/tapped.xml b/widget/testdata/select/desktop/tapped.xml index e458b45278..3d4884346a 100644 --- a/widget/testdata/select/desktop/tapped.xml +++ b/widget/testdata/select/desktop/tapped.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/tapped_constrained.xml b/widget/testdata/select/desktop/tapped_constrained.xml index c8a4d4645f..b7d4d408e9 100644 --- a/widget/testdata/select/desktop/tapped_constrained.xml +++ b/widget/testdata/select/desktop/tapped_constrained.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/trailing.xml b/widget/testdata/select/desktop/trailing.xml index 4a508145ea..594ac116f4 100644 --- a/widget/testdata/select/desktop/trailing.xml +++ b/widget/testdata/select/desktop/trailing.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/focus_focused_b_selected.xml b/widget/testdata/select/focus_focused_b_selected.xml index 75d99fe3e0..b81b0526a5 100644 --- a/widget/testdata/select/focus_focused_b_selected.xml +++ b/widget/testdata/select/focus_focused_b_selected.xml @@ -8,7 +8,7 @@ Option B - + diff --git a/widget/testdata/select/focus_focused_none_selected.xml b/widget/testdata/select/focus_focused_none_selected.xml index b9b1256011..bdf5de0334 100644 --- a/widget/testdata/select/focus_focused_none_selected.xml +++ b/widget/testdata/select/focus_focused_none_selected.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/focus_unfocused_b_selected.xml b/widget/testdata/select/focus_unfocused_b_selected.xml index b0e6edb017..eb55268c86 100644 --- a/widget/testdata/select/focus_unfocused_b_selected.xml +++ b/widget/testdata/select/focus_unfocused_b_selected.xml @@ -8,7 +8,7 @@ Option B - + diff --git a/widget/testdata/select/focus_unfocused_none_selected.xml b/widget/testdata/select/focus_unfocused_none_selected.xml index f8023d66b4..002073afa9 100644 --- a/widget/testdata/select/focus_unfocused_none_selected.xml +++ b/widget/testdata/select/focus_unfocused_none_selected.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/kbdctrl_a_selected.xml b/widget/testdata/select/kbdctrl_a_selected.xml index e03b58b81d..5fd0a13c17 100644 --- a/widget/testdata/select/kbdctrl_a_selected.xml +++ b/widget/testdata/select/kbdctrl_a_selected.xml @@ -8,7 +8,7 @@ Option A - + diff --git a/widget/testdata/select/kbdctrl_b_selected.xml b/widget/testdata/select/kbdctrl_b_selected.xml index ce434abfcc..e84c081854 100644 --- a/widget/testdata/select/kbdctrl_b_selected.xml +++ b/widget/testdata/select/kbdctrl_b_selected.xml @@ -8,7 +8,7 @@ Option B - + diff --git a/widget/testdata/select/kbdctrl_c_selected.xml b/widget/testdata/select/kbdctrl_c_selected.xml index 471b3f8eaa..dc9a52d63f 100644 --- a/widget/testdata/select/kbdctrl_c_selected.xml +++ b/widget/testdata/select/kbdctrl_c_selected.xml @@ -8,7 +8,7 @@ Option C - + diff --git a/widget/testdata/select/kbdctrl_none_selected.xml b/widget/testdata/select/kbdctrl_none_selected.xml index 5ff13edaa1..c42c622be5 100644 --- a/widget/testdata/select/kbdctrl_none_selected.xml +++ b/widget/testdata/select/kbdctrl_none_selected.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/kbdctrl_none_selected_popup.xml b/widget/testdata/select/kbdctrl_none_selected_popup.xml index a7241c9c3e..bacff1a03e 100644 --- a/widget/testdata/select/kbdctrl_none_selected_popup.xml +++ b/widget/testdata/select/kbdctrl_none_selected_popup.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/center.xml b/widget/testdata/select/mobile/center.xml index 39ba7a7342..196f4f8415 100644 --- a/widget/testdata/select/mobile/center.xml +++ b/widget/testdata/select/mobile/center.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_empty.xml b/widget/testdata/select/mobile/layout_empty.xml index a662d36d6a..61cc0b0858 100644 --- a/widget/testdata/select/mobile/layout_empty.xml +++ b/widget/testdata/select/mobile/layout_empty.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_empty_expanded.xml b/widget/testdata/select/mobile/layout_empty_expanded.xml index 3eedb23ae8..065a94cedb 100644 --- a/widget/testdata/select/mobile/layout_empty_expanded.xml +++ b/widget/testdata/select/mobile/layout_empty_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_empty_expanded_placeholder.xml b/widget/testdata/select/mobile/layout_empty_expanded_placeholder.xml index a5a9bd5a60..32d0d64c84 100644 --- a/widget/testdata/select/mobile/layout_empty_expanded_placeholder.xml +++ b/widget/testdata/select/mobile/layout_empty_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_empty_placeholder.xml b/widget/testdata/select/mobile/layout_empty_placeholder.xml index b6fb6c7b9c..2c5f3f1622 100644 --- a/widget/testdata/select/mobile/layout_empty_placeholder.xml +++ b/widget/testdata/select/mobile/layout_empty_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_multiple.xml b/widget/testdata/select/mobile/layout_multiple.xml index a662d36d6a..61cc0b0858 100644 --- a/widget/testdata/select/mobile/layout_multiple.xml +++ b/widget/testdata/select/mobile/layout_multiple.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_multiple_expanded.xml b/widget/testdata/select/mobile/layout_multiple_expanded.xml index 80b0712c51..456bb275b5 100644 --- a/widget/testdata/select/mobile/layout_multiple_expanded.xml +++ b/widget/testdata/select/mobile/layout_multiple_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_multiple_expanded_placeholder.xml b/widget/testdata/select/mobile/layout_multiple_expanded_placeholder.xml index b4a6bf5465..9fa456cd84 100644 --- a/widget/testdata/select/mobile/layout_multiple_expanded_placeholder.xml +++ b/widget/testdata/select/mobile/layout_multiple_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_multiple_expanded_selected.xml b/widget/testdata/select/mobile/layout_multiple_expanded_selected.xml index 981c30de72..caac8bf19b 100644 --- a/widget/testdata/select/mobile/layout_multiple_expanded_selected.xml +++ b/widget/testdata/select/mobile/layout_multiple_expanded_selected.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/mobile/layout_multiple_expanded_selected_placeholder.xml b/widget/testdata/select/mobile/layout_multiple_expanded_selected_placeholder.xml index e9b6ea463a..27fc48b3ae 100644 --- a/widget/testdata/select/mobile/layout_multiple_expanded_selected_placeholder.xml +++ b/widget/testdata/select/mobile/layout_multiple_expanded_selected_placeholder.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/mobile/layout_multiple_placeholder.xml b/widget/testdata/select/mobile/layout_multiple_placeholder.xml index b6fb6c7b9c..2c5f3f1622 100644 --- a/widget/testdata/select/mobile/layout_multiple_placeholder.xml +++ b/widget/testdata/select/mobile/layout_multiple_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_multiple_selected.xml b/widget/testdata/select/mobile/layout_multiple_selected.xml index 28338edfca..7e96da26c2 100644 --- a/widget/testdata/select/mobile/layout_multiple_selected.xml +++ b/widget/testdata/select/mobile/layout_multiple_selected.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/mobile/layout_multiple_selected_placeholder.xml b/widget/testdata/select/mobile/layout_multiple_selected_placeholder.xml index ee8fe4e34e..32d95230fb 100644 --- a/widget/testdata/select/mobile/layout_multiple_selected_placeholder.xml +++ b/widget/testdata/select/mobile/layout_multiple_selected_placeholder.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/mobile/layout_single.xml b/widget/testdata/select/mobile/layout_single.xml index a662d36d6a..61cc0b0858 100644 --- a/widget/testdata/select/mobile/layout_single.xml +++ b/widget/testdata/select/mobile/layout_single.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_single_expanded.xml b/widget/testdata/select/mobile/layout_single_expanded.xml index 739c3d74ad..266b1e3d28 100644 --- a/widget/testdata/select/mobile/layout_single_expanded.xml +++ b/widget/testdata/select/mobile/layout_single_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_single_expanded_placeholder.xml b/widget/testdata/select/mobile/layout_single_expanded_placeholder.xml index 440cdfa7a3..3368621da8 100644 --- a/widget/testdata/select/mobile/layout_single_expanded_placeholder.xml +++ b/widget/testdata/select/mobile/layout_single_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_single_expanded_selected.xml b/widget/testdata/select/mobile/layout_single_expanded_selected.xml index f4657c05cf..1ca5e88552 100644 --- a/widget/testdata/select/mobile/layout_single_expanded_selected.xml +++ b/widget/testdata/select/mobile/layout_single_expanded_selected.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/mobile/layout_single_expanded_selected_placeholder.xml b/widget/testdata/select/mobile/layout_single_expanded_selected_placeholder.xml index c4237bd6f1..bd2e88177d 100644 --- a/widget/testdata/select/mobile/layout_single_expanded_selected_placeholder.xml +++ b/widget/testdata/select/mobile/layout_single_expanded_selected_placeholder.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/mobile/layout_single_placeholder.xml b/widget/testdata/select/mobile/layout_single_placeholder.xml index b6fb6c7b9c..2c5f3f1622 100644 --- a/widget/testdata/select/mobile/layout_single_placeholder.xml +++ b/widget/testdata/select/mobile/layout_single_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_single_selected.xml b/widget/testdata/select/mobile/layout_single_selected.xml index 3a5759a084..f74568aa76 100644 --- a/widget/testdata/select/mobile/layout_single_selected.xml +++ b/widget/testdata/select/mobile/layout_single_selected.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/mobile/layout_single_selected_placeholder.xml b/widget/testdata/select/mobile/layout_single_selected_placeholder.xml index df72a2755d..3f6b60bb72 100644 --- a/widget/testdata/select/mobile/layout_single_selected_placeholder.xml +++ b/widget/testdata/select/mobile/layout_single_selected_placeholder.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/mobile/move_moved.xml b/widget/testdata/select/mobile/move_moved.xml index dad9d1c541..0f020a8795 100644 --- a/widget/testdata/select/mobile/move_moved.xml +++ b/widget/testdata/select/mobile/move_moved.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/move_tapped.xml b/widget/testdata/select/mobile/move_tapped.xml index 18ec0f2581..55554c89b2 100644 --- a/widget/testdata/select/mobile/move_tapped.xml +++ b/widget/testdata/select/mobile/move_tapped.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/tapped.xml b/widget/testdata/select/mobile/tapped.xml index 530b92b216..ebe503aa11 100644 --- a/widget/testdata/select/mobile/tapped.xml +++ b/widget/testdata/select/mobile/tapped.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/tapped_constrained.xml b/widget/testdata/select/mobile/tapped_constrained.xml index 7d6ae39b11..b0119c5a25 100644 --- a/widget/testdata/select/mobile/tapped_constrained.xml +++ b/widget/testdata/select/mobile/tapped_constrained.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/trailing.xml b/widget/testdata/select/mobile/trailing.xml index 9f5f1c2cdf..12891bb23c 100644 --- a/widget/testdata/select/mobile/trailing.xml +++ b/widget/testdata/select/mobile/trailing.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/move_initial.xml b/widget/testdata/select/move_initial.xml index edef866828..523b517793 100644 --- a/widget/testdata/select/move_initial.xml +++ b/widget/testdata/select/move_initial.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/set_selected_2nd_selected.xml b/widget/testdata/select/set_selected_2nd_selected.xml index 64e5368163..e59ab43a7b 100644 --- a/widget/testdata/select/set_selected_2nd_selected.xml +++ b/widget/testdata/select/set_selected_2nd_selected.xml @@ -8,7 +8,7 @@ 2 - + diff --git a/widget/testdata/select/set_selected_none_selected.xml b/widget/testdata/select/set_selected_none_selected.xml index f8023d66b4..002073afa9 100644 --- a/widget/testdata/select/set_selected_none_selected.xml +++ b/widget/testdata/select/set_selected_none_selected.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select_entry/disableable_enabled.xml b/widget/testdata/select_entry/disableable_enabled.xml index 8c21e77a02..9957cf2710 100644 --- a/widget/testdata/select_entry/disableable_enabled.xml +++ b/widget/testdata/select_entry/disableable_enabled.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/disableable_enabled_opened.xml b/widget/testdata/select_entry/disableable_enabled_opened.xml index a406a38880..8789b3d70e 100644 --- a/widget/testdata/select_entry/disableable_enabled_opened.xml +++ b/widget/testdata/select_entry/disableable_enabled_opened.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/disableable_enabled_tapped.xml b/widget/testdata/select_entry/disableable_enabled_tapped.xml index 8c21e77a02..9957cf2710 100644 --- a/widget/testdata/select_entry/disableable_enabled_tapped.xml +++ b/widget/testdata/select_entry/disableable_enabled_tapped.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/disableable_enabled_tapped_selected.xml b/widget/testdata/select_entry/disableable_enabled_tapped_selected.xml index 8c21e77a02..9957cf2710 100644 --- a/widget/testdata/select_entry/disableable_enabled_tapped_selected.xml +++ b/widget/testdata/select_entry/disableable_enabled_tapped_selected.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_B_opened.xml b/widget/testdata/select_entry/dropdown_B_opened.xml index 598666d4ce..cde64de66e 100644 --- a/widget/testdata/select_entry/dropdown_B_opened.xml +++ b/widget/testdata/select_entry/dropdown_B_opened.xml @@ -13,7 +13,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_empty_opened.xml b/widget/testdata/select_entry/dropdown_empty_opened.xml index a406a38880..8789b3d70e 100644 --- a/widget/testdata/select_entry/dropdown_empty_opened.xml +++ b/widget/testdata/select_entry/dropdown_empty_opened.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_empty_opened_shrunk.xml b/widget/testdata/select_entry/dropdown_empty_opened_shrunk.xml index 3e730ba386..ee6e28f49b 100644 --- a/widget/testdata/select_entry/dropdown_empty_opened_shrunk.xml +++ b/widget/testdata/select_entry/dropdown_empty_opened_shrunk.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_empty_setopts.xml b/widget/testdata/select_entry/dropdown_empty_setopts.xml index 0dde8f3b42..8d1eddaa5c 100644 --- a/widget/testdata/select_entry/dropdown_empty_setopts.xml +++ b/widget/testdata/select_entry/dropdown_empty_setopts.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_initial.xml b/widget/testdata/select_entry/dropdown_initial.xml index 8c21e77a02..9957cf2710 100644 --- a/widget/testdata/select_entry/dropdown_initial.xml +++ b/widget/testdata/select_entry/dropdown_initial.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_tapped_B.xml b/widget/testdata/select_entry/dropdown_tapped_B.xml index bdc0de4c2a..1b80ad5998 100644 --- a/widget/testdata/select_entry/dropdown_tapped_B.xml +++ b/widget/testdata/select_entry/dropdown_tapped_B.xml @@ -13,7 +13,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_tapped_C.xml b/widget/testdata/select_entry/dropdown_tapped_C.xml index aa5687879d..7ac03caf30 100644 --- a/widget/testdata/select_entry/dropdown_tapped_C.xml +++ b/widget/testdata/select_entry/dropdown_tapped_C.xml @@ -13,7 +13,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple.xml b/widget/testdata/tree/layout_multiple.xml index ad4493266f..e639f687fb 100644 --- a/widget/testdata/tree/layout_multiple.xml +++ b/widget/testdata/tree/layout_multiple.xml @@ -10,7 +10,7 @@ - + @@ -23,7 +23,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_branch.xml b/widget/testdata/tree/layout_multiple_branch.xml index 951678ac09..7d3920b4c5 100644 --- a/widget/testdata/tree/layout_multiple_branch.xml +++ b/widget/testdata/tree/layout_multiple_branch.xml @@ -10,7 +10,7 @@ - + @@ -23,7 +23,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_branch_opened.xml b/widget/testdata/tree/layout_multiple_branch_opened.xml index 9670887590..451fafb552 100644 --- a/widget/testdata/tree/layout_multiple_branch_opened.xml +++ b/widget/testdata/tree/layout_multiple_branch_opened.xml @@ -10,7 +10,7 @@ - + @@ -33,7 +33,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_branch_opened_leaf_selected.xml b/widget/testdata/tree/layout_multiple_branch_opened_leaf_selected.xml index 26ce829e2b..2852ad1da6 100644 --- a/widget/testdata/tree/layout_multiple_branch_opened_leaf_selected.xml +++ b/widget/testdata/tree/layout_multiple_branch_opened_leaf_selected.xml @@ -10,7 +10,7 @@ - + @@ -33,7 +33,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_branch_opened_selected.xml b/widget/testdata/tree/layout_multiple_branch_opened_selected.xml index 9c429af46e..89239d41f2 100644 --- a/widget/testdata/tree/layout_multiple_branch_opened_selected.xml +++ b/widget/testdata/tree/layout_multiple_branch_opened_selected.xml @@ -10,7 +10,7 @@ - + @@ -34,7 +34,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_branch_selected.xml b/widget/testdata/tree/layout_multiple_branch_selected.xml index aab25776fc..9bb72563ea 100644 --- a/widget/testdata/tree/layout_multiple_branch_selected.xml +++ b/widget/testdata/tree/layout_multiple_branch_selected.xml @@ -10,7 +10,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_selected.xml b/widget/testdata/tree/layout_multiple_selected.xml index f56138d952..5688c3e59f 100644 --- a/widget/testdata/tree/layout_multiple_selected.xml +++ b/widget/testdata/tree/layout_multiple_selected.xml @@ -10,7 +10,7 @@ - + @@ -23,7 +23,7 @@ - + diff --git a/widget/testdata/tree/layout_single_branch.xml b/widget/testdata/tree/layout_single_branch.xml index 107f4ac9c5..6a1702f49b 100644 --- a/widget/testdata/tree/layout_single_branch.xml +++ b/widget/testdata/tree/layout_single_branch.xml @@ -10,7 +10,7 @@ - + diff --git a/widget/testdata/tree/layout_single_branch_opened.xml b/widget/testdata/tree/layout_single_branch_opened.xml index 41f13bb606..6abdf67611 100644 --- a/widget/testdata/tree/layout_single_branch_opened.xml +++ b/widget/testdata/tree/layout_single_branch_opened.xml @@ -10,7 +10,7 @@ - + diff --git a/widget/testdata/tree/layout_single_branch_opened_leaf_selected.xml b/widget/testdata/tree/layout_single_branch_opened_leaf_selected.xml index 4752068030..134f1f0cf1 100644 --- a/widget/testdata/tree/layout_single_branch_opened_leaf_selected.xml +++ b/widget/testdata/tree/layout_single_branch_opened_leaf_selected.xml @@ -10,7 +10,7 @@ - + diff --git a/widget/testdata/tree/layout_single_branch_opened_selected.xml b/widget/testdata/tree/layout_single_branch_opened_selected.xml index 79411a5beb..bf2c5812ad 100644 --- a/widget/testdata/tree/layout_single_branch_opened_selected.xml +++ b/widget/testdata/tree/layout_single_branch_opened_selected.xml @@ -11,7 +11,7 @@ - + diff --git a/widget/testdata/tree/layout_single_branch_selected.xml b/widget/testdata/tree/layout_single_branch_selected.xml index 5abbae4dc2..9b3aef8dc1 100644 --- a/widget/testdata/tree/layout_single_branch_selected.xml +++ b/widget/testdata/tree/layout_single_branch_selected.xml @@ -11,7 +11,7 @@ - + diff --git a/widget/testdata/tree/move_initial.xml b/widget/testdata/tree/move_initial.xml index 71ae4c57a0..4cc2079241 100644 --- a/widget/testdata/tree/move_initial.xml +++ b/widget/testdata/tree/move_initial.xml @@ -10,7 +10,7 @@ - + diff --git a/widget/testdata/tree/move_moved.xml b/widget/testdata/tree/move_moved.xml index 9ea4ab28cb..48a05b96f1 100644 --- a/widget/testdata/tree/move_moved.xml +++ b/widget/testdata/tree/move_moved.xml @@ -10,7 +10,7 @@ - + From 389162b7161f15119becd5dbd28616db4b4c9eee Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Tue, 11 Jun 2024 14:47:00 +0100 Subject: [PATCH 13/78] Updating to latest systray fixes --- go.mod | 2 +- go.sum | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 4caadc5f78..e0ddf2e2d3 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module fyne.io/fyne/v2 go 1.19 require ( - fyne.io/systray v1.10.1-0.20240608091126-03c78c0eeffd + fyne.io/systray v1.10.1-0.20240611130111-26449f257a02 github.com/BurntSushi/toml v1.4.0 github.com/fogleman/gg v1.3.0 github.com/fredbi/uri v1.1.0 diff --git a/go.sum b/go.sum index 37cbad3c7a..0cdd2d6848 100644 --- a/go.sum +++ b/go.sum @@ -37,10 +37,8 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -fyne.io/systray v1.10.1-0.20231230205326-d160fd363db9 h1:E/gHmMVyk8TuI6JIgNIv/Qu1JABMVFBIkQ8lYRa5gkQ= -fyne.io/systray v1.10.1-0.20231230205326-d160fd363db9/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs= -fyne.io/systray v1.10.1-0.20240608091126-03c78c0eeffd h1:e59/YQEzpKizMVMRgvIufXP8ub6sQ4uz3pbYhiGDOPM= -fyne.io/systray v1.10.1-0.20240608091126-03c78c0eeffd/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs= +fyne.io/systray v1.10.1-0.20240611130111-26449f257a02 h1:ukSAnDNGKtlve5Cj5cB0qU3UAPIf1tRi5dQ/BOtfAdQ= +fyne.io/systray v1.10.1-0.20240611130111-26449f257a02/go.mod h1:RVwqP9nYMo7h5zViCBHri2FgjXF7H2cub7MAq4NSoLs= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= From 7d4f400646f669590234ec2b84464a5379b157bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Tue, 4 Jun 2024 18:05:05 +0200 Subject: [PATCH 14/78] =?UTF-8?q?[theme]=20remove=20=E2=80=9Cforeground?= =?UTF-8?q?=E2=80=9D=20from=20color=20name=20description=20for=20error,=20?= =?UTF-8?q?warning=20and=20success?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit While the label uses this color for foreground, the button uses it for background. --- theme/color.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/theme/color.go b/theme/color.go index f192c161b0..b2811096f0 100644 --- a/theme/color.go +++ b/theme/color.go @@ -61,7 +61,7 @@ const ( // Since: 2.0 ColorNameDisabled fyne.ThemeColorName = "disabled" - // ColorNameError is the name of theme lookup for foreground error color. + // ColorNameError is the name of theme lookup for error color. // // Since: 2.0 ColorNameError fyne.ThemeColorName = "error" @@ -151,12 +151,12 @@ const ( // Since: 2.0 ColorNameShadow fyne.ThemeColorName = "shadow" - // ColorNameSuccess is the name of theme lookup for foreground success color. + // ColorNameSuccess is the name of theme lookup for success color. // // Since: 2.3 ColorNameSuccess fyne.ThemeColorName = "success" - // ColorNameWarning is the name of theme lookup for foreground warning color. + // ColorNameWarning is the name of theme lookup for warning color. // // Since: 2.3 ColorNameWarning fyne.ThemeColorName = "warning" From 078eedb420d8e65d37c37fecdeaf55b4761268b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Sat, 8 Jun 2024 20:07:40 +0200 Subject: [PATCH 15/78] [theme] add color definition completeness test for default theme --- theme/color.go | 2 +- theme/theme.go | 2 +- theme/theme_test.go | 45 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/theme/color.go b/theme/color.go index b2811096f0..a03bd0aebd 100644 --- a/theme/color.go +++ b/theme/color.go @@ -6,7 +6,7 @@ import ( "fyne.io/fyne/v2" ) -// Keep in mind to add new constants to the tests at test/theme_test.go. +// Keep in mind to add new constants to the tests at theme/theme_test.go as well as test/theme_test.go. const ( // ColorRed is the red primary color name. // diff --git a/theme/theme.go b/theme/theme.go index b325a5cb1f..944ff07b8a 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -10,7 +10,7 @@ import ( "fyne.io/fyne/v2/internal/cache" ) -// Keep in mind to add new constants to the tests at test/theme_test.go. +// Keep in mind to add new constants to the tests at theme/theme_test.go as well as test/theme_test.go. const ( // VariantDark is the version of a theme that satisfies a user preference for a dark look. // diff --git a/theme/theme_test.go b/theme/theme_test.go index bcb7d80d0d..740c289111 100644 --- a/theme/theme_test.go +++ b/theme/theme_test.go @@ -10,6 +10,51 @@ import ( "fyne.io/fyne/v2/theme" ) +// Try to keep these in sync with the existing color names at theme/color.go. +var knownColorNames = []fyne.ThemeColorName{ + theme.ColorNameBackground, + theme.ColorNameButton, + theme.ColorNameDisabledButton, + theme.ColorNameDisabled, + theme.ColorNameError, + theme.ColorNameFocus, + theme.ColorNameForeground, + theme.ColorNameHeaderBackground, + theme.ColorNameHover, + theme.ColorNameHyperlink, + theme.ColorNameInputBackground, + theme.ColorNameInputBorder, + theme.ColorNameMenuBackground, + theme.ColorNameOnPrimary, + theme.ColorNameOverlayBackground, + theme.ColorNamePlaceHolder, + theme.ColorNamePressed, + theme.ColorNamePrimary, + theme.ColorNameScrollBar, + theme.ColorNameSelection, + theme.ColorNameSeparator, + theme.ColorNameShadow, + theme.ColorNameSuccess, + theme.ColorNameWarning, +} + +// Try to keep this in sync with the existing variants at theme/theme.go +var knownVariants = []fyne.ThemeVariant{ + theme.VariantDark, + theme.VariantLight, +} + +func Test_DefaultTheme_AllColorsDefined(t *testing.T) { + th := theme.DefaultTheme() + for _, variant := range knownVariants { + for _, cn := range knownColorNames { + // Transparent is used as fallback for unknown color names. + // Built-in color names should have well-defined non-transparent values. + assert.NotEqual(t, color.Transparent, th.Color(cn, variant), "undefined color %s variant %d", cn, variant) + } + } +} + func Test_DefaultTheme_OnPrimaryColor(t *testing.T) { darkColor := color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} defaultTheme := theme.DefaultTheme() From 78cb40360c2113bcd6a0505343f7bc565afdc4e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Mon, 10 Jun 2024 08:02:17 +0200 Subject: [PATCH 16/78] [theme] rename internal color constants for better grouping --- theme/color.go | 28 +++++++++++++++------------- theme/theme.go | 18 +++++++++--------- theme/theme_hints.go | 2 +- 3 files changed, 25 insertions(+), 23 deletions(-) diff --git a/theme/color.go b/theme/color.go index a03bd0aebd..6a67113e07 100644 --- a/theme/color.go +++ b/theme/color.go @@ -163,11 +163,13 @@ const ( ) var ( - backgroundColorDark = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} - backgroundColorLight = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} - errorColor = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} - successColor = color.NRGBA{R: 0x43, G: 0xf4, B: 0x36, A: 0xff} - warningColor = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} + colorDarkBackground = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} + + colorLightBackground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + + colorError = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} + colorSuccess = color.NRGBA{R: 0x43, G: 0xf4, B: 0x36, A: 0xff} + colorWarning = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} ) // BackgroundColor returns the theme's background color. @@ -275,24 +277,24 @@ func MenuBackgroundColor() color.Color { func OnPrimaryColorNamed(name string) color.Color { switch name { case ColorRed: - return backgroundColorLight + return colorLightBackground case ColorOrange: - return backgroundColorDark + return colorDarkBackground case ColorYellow: - return backgroundColorDark + return colorDarkBackground case ColorGreen: - return backgroundColorDark + return colorDarkBackground case ColorPurple: - return backgroundColorLight + return colorLightBackground case ColorBrown: - return backgroundColorLight + return colorLightBackground case ColorGray: - return backgroundColorDark + return colorDarkBackground } // We return the “on” value for ColorBlue for every other value. // There is no need to have it in the switch above. - return backgroundColorLight + return colorLightBackground } // OverlayBackgroundColor returns the theme's background color for overlays like dialogs. diff --git a/theme/theme.go b/theme/theme.go index 944ff07b8a..aef5abe001 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -217,7 +217,7 @@ func currentVariant() fyne.ThemeVariant { func darkPaletColorNamed(name fyne.ThemeColorName) color.Color { switch name { case ColorNameBackground: - return backgroundColorDark + return colorDarkBackground case ColorNameButton: return color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} case ColorNameDisabled: @@ -225,7 +225,7 @@ func darkPaletColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameDisabledButton: return color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} case ColorNameError: - return errorColor + return colorError case ColorNameForeground: return color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff} case ColorNameHover: @@ -251,9 +251,9 @@ func darkPaletColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameShadow: return color.NRGBA{A: 0x66} case ColorNameSuccess: - return successColor + return colorSuccess case ColorNameWarning: - return warningColor + return colorWarning } return color.Transparent @@ -285,7 +285,7 @@ func focusColorNamed(name string) color.NRGBA { func lightPaletColorNamed(name fyne.ThemeColorName) color.Color { switch name { case ColorNameBackground: - return backgroundColorLight + return colorLightBackground case ColorNameButton: return color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} case ColorNameDisabled: @@ -293,7 +293,7 @@ func lightPaletColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameDisabledButton: return color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} case ColorNameError: - return errorColor + return colorError case ColorNameForeground: return color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff} case ColorNameHover: @@ -307,7 +307,7 @@ func lightPaletColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameMenuBackground: return color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} case ColorNameOverlayBackground: - return backgroundColorLight + return colorLightBackground case ColorNamePlaceHolder: return color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff} case ColorNamePressed: @@ -319,9 +319,9 @@ func lightPaletColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameShadow: return color.NRGBA{A: 0x33} case ColorNameSuccess: - return successColor + return colorSuccess case ColorNameWarning: - return warningColor + return colorWarning } return color.Transparent diff --git a/theme/theme_hints.go b/theme/theme_hints.go index 58d9d367f5..318e66bedf 100644 --- a/theme/theme_hints.go +++ b/theme/theme_hints.go @@ -3,6 +3,6 @@ package theme var ( - fallbackColor = errorColor + fallbackColor = colorError fallbackIcon = NewErrorThemedResource(errorIconRes) ) From 82c67071613cc63aa58bf887bbd71878895f5d40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Mon, 10 Jun 2024 09:01:03 +0200 Subject: [PATCH 17/78] =?UTF-8?q?[theme]=20extract=20color=20=E2=80=9Ccons?= =?UTF-8?q?tants=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This keeps the color values compactly grouped at a single place. It might also prevent useless allocations because the compiler probably cannot optimize here. --- theme/color.go | 35 +++++++++++++++++++++++++++--- theme/theme.go | 58 +++++++++++++++++++++++++------------------------- 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/theme/color.go b/theme/color.go index 6a67113e07..406869a01a 100644 --- a/theme/color.go +++ b/theme/color.go @@ -163,9 +163,38 @@ const ( ) var ( - colorDarkBackground = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} - - colorLightBackground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorDarkBackground = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} + colorDarkButton = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} + colorDarkDisabled = color.NRGBA{R: 0x39, G: 0x39, B: 0x3a, A: 0xff} + colorDarkDisabledButton = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} + colorDarkForeground = color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff} + colorDarkHeaderBackground = color.NRGBA{R: 0x1b, G: 0x1b, B: 0x1b, A: 0xff} + colorDarkHover = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x0f} + colorDarkInputBackground = color.NRGBA{R: 0x20, G: 0x20, B: 0x23, A: 0xff} + colorDarkInputBorder = color.NRGBA{R: 0x39, G: 0x39, B: 0x3a, A: 0xff} + colorDarkMenuBackground = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} + colorDarkOverlayBackground = color.NRGBA{R: 0x18, G: 0x1d, B: 0x25, A: 0xff} + colorDarkPlaceholder = color.NRGBA{R: 0xb2, G: 0xb2, B: 0xb2, A: 0xff} + colorDarkPressed = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x66} + colorDarkScrollBar = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x99} + colorDarkSeparator = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xff} + colorDarkShadow = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x66} + + colorLightBackground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorLightButton = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} + colorLightDisabled = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} + colorLightDisabledButton = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} + colorLightForeground = color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff} + colorLightHeaderBackground = color.NRGBA{R: 0xf9, G: 0xf9, B: 0xf9, A: 0xff} + colorLightHover = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x0f} + colorLightInputBackground = color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff} + colorLightInputBorder = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} + colorLightMenuBackground = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} + colorLightPlaceholder = color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff} + colorLightPressed = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x19} + colorLightScrollBar = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x99} + colorLightSeparator = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} + colorLightShadow = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x33} colorError = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} colorSuccess = color.NRGBA{R: 0x43, G: 0xf4, B: 0x36, A: 0xff} diff --git a/theme/theme.go b/theme/theme.go index aef5abe001..60aa652583 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -219,37 +219,37 @@ func darkPaletColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameBackground: return colorDarkBackground case ColorNameButton: - return color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} + return colorDarkButton case ColorNameDisabled: - return color.NRGBA{R: 0x39, G: 0x39, B: 0x3a, A: 0xff} + return colorDarkDisabled case ColorNameDisabledButton: - return color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} + return colorDarkDisabledButton case ColorNameError: return colorError case ColorNameForeground: - return color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff} + return colorDarkForeground case ColorNameHover: - return color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x0f} + return colorDarkHover case ColorNameHeaderBackground: - return color.NRGBA{R: 0x1b, G: 0x1b, B: 0x1b, A: 0xff} + return colorDarkHeaderBackground case ColorNameInputBackground: - return color.NRGBA{R: 0x20, G: 0x20, B: 0x23, A: 0xff} + return colorDarkInputBackground case ColorNameInputBorder: - return color.NRGBA{R: 0x39, G: 0x39, B: 0x3a, A: 0xff} + return colorDarkInputBorder case ColorNameMenuBackground: - return color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} + return colorDarkMenuBackground case ColorNameOverlayBackground: - return color.NRGBA{R: 0x18, G: 0x1d, B: 0x25, A: 0xff} + return colorDarkOverlayBackground case ColorNamePlaceHolder: - return color.NRGBA{R: 0xb2, G: 0xb2, B: 0xb2, A: 0xff} + return colorDarkPlaceholder case ColorNamePressed: - return color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x66} + return colorDarkPressed case ColorNameScrollBar: - return color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x99} + return colorDarkScrollBar case ColorNameSeparator: - return color.NRGBA{R: 0x0, G: 0x0, B: 0x0, A: 0xff} + return colorDarkSeparator case ColorNameShadow: - return color.NRGBA{A: 0x66} + return colorDarkShadow case ColorNameSuccess: return colorSuccess case ColorNameWarning: @@ -287,37 +287,37 @@ func lightPaletColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameBackground: return colorLightBackground case ColorNameButton: - return color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} + return colorLightButton case ColorNameDisabled: - return color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} + return colorLightDisabled case ColorNameDisabledButton: - return color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} + return colorLightDisabledButton case ColorNameError: return colorError case ColorNameForeground: - return color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff} + return colorLightForeground case ColorNameHover: - return color.NRGBA{A: 0x0f} + return colorLightHover case ColorNameHeaderBackground: - return color.NRGBA{R: 0xf9, G: 0xf9, B: 0xf9, A: 0xff} + return colorLightHeaderBackground case ColorNameInputBackground: - return color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff} + return colorLightInputBackground case ColorNameInputBorder: - return color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} + return colorLightInputBorder case ColorNameMenuBackground: - return color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} + return colorLightMenuBackground case ColorNameOverlayBackground: return colorLightBackground case ColorNamePlaceHolder: - return color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff} + return colorLightPlaceholder case ColorNamePressed: - return color.NRGBA{A: 0x19} + return colorLightPressed case ColorNameScrollBar: - return color.NRGBA{A: 0x99} + return colorLightScrollBar case ColorNameSeparator: - return color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} + return colorLightSeparator case ColorNameShadow: - return color.NRGBA{A: 0x33} + return colorLightShadow case ColorNameSuccess: return colorSuccess case ColorNameWarning: From 0c4482610b550e96f1ceb8d03c8ef5aa38d75c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Mon, 10 Jun 2024 09:05:53 +0200 Subject: [PATCH 18/78] =?UTF-8?q?[theme]=20split=20old=20color=20=E2=80=9C?= =?UTF-8?q?constants=E2=80=9D=20into=20dark=20and=20light=20variants?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit These might diverge to improve the contrast. --- theme/color.go | 10 ++++++---- theme/theme.go | 12 ++++++------ theme/theme_hints.go | 2 +- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/theme/color.go b/theme/color.go index 406869a01a..47fde3934e 100644 --- a/theme/color.go +++ b/theme/color.go @@ -167,6 +167,7 @@ var ( colorDarkButton = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} colorDarkDisabled = color.NRGBA{R: 0x39, G: 0x39, B: 0x3a, A: 0xff} colorDarkDisabledButton = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} + colorDarkError = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} colorDarkForeground = color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff} colorDarkHeaderBackground = color.NRGBA{R: 0x1b, G: 0x1b, B: 0x1b, A: 0xff} colorDarkHover = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x0f} @@ -179,11 +180,14 @@ var ( colorDarkScrollBar = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x99} colorDarkSeparator = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xff} colorDarkShadow = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x66} + colorDarkSuccess = color.NRGBA{R: 0x43, G: 0xf4, B: 0x36, A: 0xff} + colorDarkWarning = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} colorLightBackground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} colorLightButton = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} colorLightDisabled = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} colorLightDisabledButton = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} + colorLightError = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} colorLightForeground = color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff} colorLightHeaderBackground = color.NRGBA{R: 0xf9, G: 0xf9, B: 0xf9, A: 0xff} colorLightHover = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x0f} @@ -195,10 +199,8 @@ var ( colorLightScrollBar = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x99} colorLightSeparator = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} colorLightShadow = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x33} - - colorError = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} - colorSuccess = color.NRGBA{R: 0x43, G: 0xf4, B: 0x36, A: 0xff} - colorWarning = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} + colorLightSuccess = color.NRGBA{R: 0x43, G: 0xf4, B: 0x36, A: 0xff} + colorLightWarning = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} ) // BackgroundColor returns the theme's background color. diff --git a/theme/theme.go b/theme/theme.go index 60aa652583..a52598bf98 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -225,7 +225,7 @@ func darkPaletColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameDisabledButton: return colorDarkDisabledButton case ColorNameError: - return colorError + return colorDarkError case ColorNameForeground: return colorDarkForeground case ColorNameHover: @@ -251,9 +251,9 @@ func darkPaletColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameShadow: return colorDarkShadow case ColorNameSuccess: - return colorSuccess + return colorDarkSuccess case ColorNameWarning: - return colorWarning + return colorDarkWarning } return color.Transparent @@ -293,7 +293,7 @@ func lightPaletColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameDisabledButton: return colorLightDisabledButton case ColorNameError: - return colorError + return colorLightError case ColorNameForeground: return colorLightForeground case ColorNameHover: @@ -319,9 +319,9 @@ func lightPaletColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameShadow: return colorLightShadow case ColorNameSuccess: - return colorSuccess + return colorLightSuccess case ColorNameWarning: - return colorWarning + return colorLightWarning } return color.Transparent diff --git a/theme/theme_hints.go b/theme/theme_hints.go index 318e66bedf..2c279e3840 100644 --- a/theme/theme_hints.go +++ b/theme/theme_hints.go @@ -3,6 +3,6 @@ package theme var ( - fallbackColor = colorError + fallbackColor = colorLightError fallbackIcon = NewErrorThemedResource(errorIconRes) ) From a6016480b0856eba6d21319e0cef08a5089c8a1a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Mon, 10 Jun 2024 09:29:13 +0200 Subject: [PATCH 19/78] [theme] fix typo --- theme/theme.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/theme/theme.go b/theme/theme.go index a52598bf98..3f7315bf8c 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -115,10 +115,10 @@ func (t *builtinTheme) Color(n fyne.ThemeColorName, v fyne.ThemeVariant) color.C } if v == VariantLight { - return lightPaletColorNamed(n) + return lightPaletteColorNamed(n) } - return darkPaletColorNamed(n) + return darkPaletteColorNamed(n) } func (t *builtinTheme) Font(style fyne.TextStyle) fyne.Resource { @@ -214,7 +214,7 @@ func currentVariant() fyne.ThemeVariant { return fyne.CurrentApp().Settings().ThemeVariant() } -func darkPaletColorNamed(name fyne.ThemeColorName) color.Color { +func darkPaletteColorNamed(name fyne.ThemeColorName) color.Color { switch name { case ColorNameBackground: return colorDarkBackground @@ -282,7 +282,7 @@ func focusColorNamed(name string) color.NRGBA { return color.NRGBA{R: 0x00, G: 0x6C, B: 0xff, A: 0x2a} } -func lightPaletColorNamed(name fyne.ThemeColorName) color.Color { +func lightPaletteColorNamed(name fyne.ThemeColorName) color.Color { switch name { case ColorNameBackground: return colorLightBackground From 51149660cfc6b74a547d9a7e80a6ea0aacbdc86d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Mon, 10 Jun 2024 09:37:43 +0200 Subject: [PATCH 20/78] =?UTF-8?q?[theme]=20introduce=20(yet=20unused)=20?= =?UTF-8?q?=E2=80=9Con=E2=80=9D=20colors=20for=20error,=20success=20and=20?= =?UTF-8?q?warning?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Besides “primary” these are the colors used to express different importance levels. To achieve a reasonable contrast, the color to paint on these (or to paint these on) might be different to the default foreground (or background) color. The new “on” colors are introduced with the foreground value but probably change, soon. --- test/markup_renderer.go | 3 +++ test/theme.go | 6 ++++++ test/theme_test.go | 3 +++ theme/color.go | 15 +++++++++++++++ theme/theme.go | 12 ++++++++++++ theme/theme_test.go | 3 +++ 6 files changed, 42 insertions(+) diff --git a/test/markup_renderer.go b/test/markup_renderer.go index 81d1b42f40..7ce458c722 100644 --- a/test/markup_renderer.go +++ b/test/markup_renderer.go @@ -410,7 +410,10 @@ func knownColor(c color.Color) string { nrgbaColor(theme.InputBackgroundColor()): "inputBackground", nrgbaColor(theme.InputBorderColor()): "inputBorder", nrgbaColor(theme.MenuBackgroundColor()): "menuBackground", + nrgbaColor(theme.Color(theme.ColorNameOnError)): "onError", nrgbaColor(theme.Color(theme.ColorNameOnPrimary)): "onPrimary", + nrgbaColor(theme.Color(theme.ColorNameOnSuccess)): "onSuccess", + nrgbaColor(theme.Color(theme.ColorNameOnWarning)): "onWarning", nrgbaColor(theme.OverlayBackgroundColor()): "overlayBackground", nrgbaColor(theme.PlaceHolderColor()): "placeholder", nrgbaColor(theme.Color(theme.ColorNamePressed)): "pressed", diff --git a/test/theme.go b/test/theme.go index d02a7158c0..1949e2ffe3 100644 --- a/test/theme.go +++ b/test/theme.go @@ -40,7 +40,10 @@ func NewTheme() fyne.Theme { theme.ColorNameInputBackground: red(30), theme.ColorNameInputBorder: gray(10), theme.ColorNameMenuBackground: red(50), + theme.ColorNameOnError: red(210), theme.ColorNameOnPrimary: red(200), + theme.ColorNameOnSuccess: blue(201), + theme.ColorNameOnWarning: blue(202), theme.ColorNameOverlayBackground: red(44), theme.ColorNamePlaceHolder: blue(200), theme.ColorNamePressed: blue(250), @@ -98,7 +101,10 @@ func Theme() fyne.Theme { theme.ColorNameInputBackground: color.NRGBA{R: 0x66, G: 0x66, B: 0x66, A: 0xff}, theme.ColorNameInputBorder: color.NRGBA{R: 0x86, G: 0x86, B: 0x86, A: 0xff}, theme.ColorNameMenuBackground: color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff}, + theme.ColorNameOnError: color.NRGBA{R: 0x08, G: 0x0a, B: 0x0f, A: 0xff}, theme.ColorNameOnPrimary: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0f, A: 0xff}, + theme.ColorNameOnSuccess: color.NRGBA{R: 0x0a, G: 0x0c, B: 0x0f, A: 0xff}, + theme.ColorNameOnWarning: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0a, A: 0xff}, theme.ColorNameOverlayBackground: color.NRGBA{R: 0x28, G: 0x28, B: 0x28, A: 0xff}, theme.ColorNamePlaceHolder: color.NRGBA{R: 0xaa, G: 0xaa, B: 0xaa, A: 0xff}, theme.ColorNamePressed: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x33}, diff --git a/test/theme_test.go b/test/theme_test.go index 603eece7ce..93641012d0 100644 --- a/test/theme_test.go +++ b/test/theme_test.go @@ -26,7 +26,10 @@ var knownColorNames = []fyne.ThemeColorName{ theme.ColorNameInputBackground, theme.ColorNameInputBorder, theme.ColorNameMenuBackground, + theme.ColorNameOnError, theme.ColorNameOnPrimary, + theme.ColorNameOnSuccess, + theme.ColorNameOnWarning, theme.ColorNameOverlayBackground, theme.ColorNamePlaceHolder, theme.ColorNamePressed, diff --git a/theme/color.go b/theme/color.go index 47fde3934e..c7a46a71ac 100644 --- a/theme/color.go +++ b/theme/color.go @@ -106,11 +106,26 @@ const ( // Since: 2.3 ColorNameMenuBackground fyne.ThemeColorName = "menuBackground" + // ColorNameOnError is the name of theme lookup for a contrast color to the error color. + // + // Since: 2.5 + ColorNameOnError fyne.ThemeColorName = "onError" + // ColorNameOnPrimary is the name of theme lookup for a contrast color to the primary color. // // Since: 2.5 ColorNameOnPrimary fyne.ThemeColorName = "onPrimary" + // ColorNameOnSuccess is the name of theme lookup for a contrast color to the success color. + // + // Since: 2.5 + ColorNameOnSuccess fyne.ThemeColorName = "onSuccess" + + // ColorNameOnWarning is the name of theme lookup for a contrast color to the warning color. + // + // Since: 2.5 + ColorNameOnWarning fyne.ThemeColorName = "onWarning" + // ColorNameOverlayBackground is the name of theme lookup for background color of overlays like dialogs. // // Since: 2.3 diff --git a/theme/theme.go b/theme/theme.go index 3f7315bf8c..34715ddb2f 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -238,6 +238,12 @@ func darkPaletteColorNamed(name fyne.ThemeColorName) color.Color { return colorDarkInputBorder case ColorNameMenuBackground: return colorDarkMenuBackground + case ColorNameOnError: + return colorDarkForeground + case ColorNameOnSuccess: + return colorDarkForeground + case ColorNameOnWarning: + return colorDarkForeground case ColorNameOverlayBackground: return colorDarkOverlayBackground case ColorNamePlaceHolder: @@ -306,6 +312,12 @@ func lightPaletteColorNamed(name fyne.ThemeColorName) color.Color { return colorLightInputBorder case ColorNameMenuBackground: return colorLightMenuBackground + case ColorNameOnError: + return colorLightForeground + case ColorNameOnSuccess: + return colorLightForeground + case ColorNameOnWarning: + return colorLightForeground case ColorNameOverlayBackground: return colorLightBackground case ColorNamePlaceHolder: diff --git a/theme/theme_test.go b/theme/theme_test.go index 740c289111..031d8d07f7 100644 --- a/theme/theme_test.go +++ b/theme/theme_test.go @@ -25,7 +25,10 @@ var knownColorNames = []fyne.ThemeColorName{ theme.ColorNameInputBackground, theme.ColorNameInputBorder, theme.ColorNameMenuBackground, + theme.ColorNameOnError, theme.ColorNameOnPrimary, + theme.ColorNameOnSuccess, + theme.ColorNameOnWarning, theme.ColorNameOverlayBackground, theme.ColorNamePlaceHolder, theme.ColorNamePressed, From 0eb96bc8dcf26acd8e46af758138bca3b863041f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Mon, 10 Jun 2024 10:31:52 +0200 Subject: [PATCH 21/78] [widget] adjust slider test to use test theme The production theme is not guaranteed to use unique color values and therefore is not reliable to create correct markup renderings. --- widget/slider_test.go | 4 ++-- widget/testdata/slider/horizontal.xml | 4 ++-- widget/testdata/slider/vertical.xml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/widget/slider_test.go b/widget/slider_test.go index 8521ebed30..79536eb722 100644 --- a/widget/slider_test.go +++ b/widget/slider_test.go @@ -70,7 +70,7 @@ func TestSlider_Clamp(t *testing.T) { func TestSlider_HorizontalLayout(t *testing.T) { app := test.NewApp() defer test.NewApp() - app.Settings().SetTheme(internalTest.LightTheme(theme.DefaultTheme())) + app.Settings().SetTheme(internalTest.LightTheme(test.Theme())) slider := NewSlider(0, 1) slider.Resize(fyne.NewSize(100, 10)) @@ -112,7 +112,7 @@ func TestSlider_OutOfRange(t *testing.T) { func TestSlider_VerticalLayout(t *testing.T) { app := test.NewApp() defer test.NewApp() - app.Settings().SetTheme(internalTest.LightTheme(theme.DefaultTheme())) + app.Settings().SetTheme(internalTest.LightTheme(test.Theme())) slider := NewSlider(0, 1) slider.Orientation = Vertical diff --git a/widget/testdata/slider/horizontal.xml b/widget/testdata/slider/horizontal.xml index 65d1773e1d..d6261497f5 100644 --- a/widget/testdata/slider/horizontal.xml +++ b/widget/testdata/slider/horizontal.xml @@ -1,8 +1,8 @@ - - + + diff --git a/widget/testdata/slider/vertical.xml b/widget/testdata/slider/vertical.xml index 1896e37629..06666c11c9 100644 --- a/widget/testdata/slider/vertical.xml +++ b/widget/testdata/slider/vertical.xml @@ -1,8 +1,8 @@ - - + + From 68a8a7b774e3c42e89c10183a2f19ad721d08081 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Mon, 10 Jun 2024 10:35:52 +0200 Subject: [PATCH 22/78] =?UTF-8?q?[widget]=20buttons=20use=20=E2=80=9ConErr?= =?UTF-8?q?or=E2=80=9D=20color=20on=20=E2=80=9Cerror=E2=80=9D=20background?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Formerly, the theme’s background color was used and therefore the “onError” color was changed to the background color value to make this a seamless change. --- dialog/testdata/dialog-confirm-importance.png | Bin 9018 -> 9103 bytes .../dialog-custom-confirm-importance.png | Bin 7107 -> 7256 bytes theme/color.go | 2 ++ theme/theme.go | 4 ++-- widget/button.go | 2 +- 5 files changed, 5 insertions(+), 3 deletions(-) diff --git a/dialog/testdata/dialog-confirm-importance.png b/dialog/testdata/dialog-confirm-importance.png index 2319b61f01bf8762e44a710711caf3494c9dfcf1..a2cf97efd22b48f9ee89fdd39af216e7057350a3 100644 GIT binary patch literal 9103 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 D3gl*v diff --git a/dialog/testdata/dialog-custom-confirm-importance.png b/dialog/testdata/dialog-custom-confirm-importance.png index 35b941edaeec6c98c7b5c171ed41ff7ddac49291..9b150292c7c8a93734de7da3d0c080c09ff274ff 100644 GIT binary patch literal 7256 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 Q!#U{1b7gq3jOn}o0OaAf00000 diff --git a/theme/color.go b/theme/color.go index c7a46a71ac..136e126649 100644 --- a/theme/color.go +++ b/theme/color.go @@ -189,6 +189,7 @@ var ( colorDarkInputBackground = color.NRGBA{R: 0x20, G: 0x20, B: 0x23, A: 0xff} colorDarkInputBorder = color.NRGBA{R: 0x39, G: 0x39, B: 0x3a, A: 0xff} colorDarkMenuBackground = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} + colorDarkOnError = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} colorDarkOverlayBackground = color.NRGBA{R: 0x18, G: 0x1d, B: 0x25, A: 0xff} colorDarkPlaceholder = color.NRGBA{R: 0xb2, G: 0xb2, B: 0xb2, A: 0xff} colorDarkPressed = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x66} @@ -209,6 +210,7 @@ var ( colorLightInputBackground = color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff} colorLightInputBorder = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} colorLightMenuBackground = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} + colorLightOnError = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} colorLightPlaceholder = color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff} colorLightPressed = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x19} colorLightScrollBar = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x99} diff --git a/theme/theme.go b/theme/theme.go index 34715ddb2f..0fbc86e2f4 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -239,7 +239,7 @@ func darkPaletteColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameMenuBackground: return colorDarkMenuBackground case ColorNameOnError: - return colorDarkForeground + return colorDarkOnError case ColorNameOnSuccess: return colorDarkForeground case ColorNameOnWarning: @@ -313,7 +313,7 @@ func lightPaletteColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameMenuBackground: return colorLightMenuBackground case ColorNameOnError: - return colorLightForeground + return colorLightOnError case ColorNameOnSuccess: return colorLightForeground case ColorNameOnWarning: diff --git a/widget/button.go b/widget/button.go index b01b91e844..a99e57c55f 100644 --- a/widget/button.go +++ b/widget/button.go @@ -365,7 +365,7 @@ func (r *buttonRenderer) buttonColorNames() (foreground, background, backgroundB if background == "" { switch b.Importance { case DangerImportance: - foreground = theme.ColorNameBackground + foreground = theme.ColorNameOnError background = theme.ColorNameError case HighImportance: foreground = theme.ColorNameOnPrimary From 24c8074346b3c547c1857d8a0f4153ff8eba23f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Wed, 12 Jun 2024 11:22:43 +0200 Subject: [PATCH 23/78] =?UTF-8?q?[widget]=20buttons=20use=20=E2=80=9ConSuc?= =?UTF-8?q?cess=E2=80=9D=20color=20on=20=E2=80=9Csuccess=E2=80=9D=20backgr?= =?UTF-8?q?ound?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Formerly, the theme’s background color was used and therefore the “onSuccess” color was changed to the background color value to make this a seamless change. This includes a “success button” in the Fyne demo app. --- cmd/fyne_demo/tutorials/widget.go | 5 +++++ theme/color.go | 2 ++ theme/theme.go | 4 ++-- widget/button.go | 2 +- 4 files changed, 10 insertions(+), 3 deletions(-) diff --git a/cmd/fyne_demo/tutorials/widget.go b/cmd/fyne_demo/tutorials/widget.go index 1654340c60..f0c6a005bd 100644 --- a/cmd/fyne_demo/tutorials/widget.go +++ b/cmd/fyne_demo/tutorials/widget.go @@ -140,6 +140,11 @@ func makeButtonTab(_ fyne.Window) fyne.CanvasObject { Importance: widget.HighImportance, OnTapped: func() { fmt.Println("high importance button") }, }, + &widget.Button{ + Text: "Success button", + Importance: widget.SuccessImportance, + OnTapped: func() { fmt.Println("success importance button") }, + }, &widget.Button{ Text: "Danger button", Importance: widget.DangerImportance, diff --git a/theme/color.go b/theme/color.go index 136e126649..b3b3d4372b 100644 --- a/theme/color.go +++ b/theme/color.go @@ -190,6 +190,7 @@ var ( colorDarkInputBorder = color.NRGBA{R: 0x39, G: 0x39, B: 0x3a, A: 0xff} colorDarkMenuBackground = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} colorDarkOnError = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} + colorDarkOnSuccess = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} colorDarkOverlayBackground = color.NRGBA{R: 0x18, G: 0x1d, B: 0x25, A: 0xff} colorDarkPlaceholder = color.NRGBA{R: 0xb2, G: 0xb2, B: 0xb2, A: 0xff} colorDarkPressed = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x66} @@ -211,6 +212,7 @@ var ( colorLightInputBorder = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} colorLightMenuBackground = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} colorLightOnError = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorLightOnSuccess = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} colorLightPlaceholder = color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff} colorLightPressed = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x19} colorLightScrollBar = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x99} diff --git a/theme/theme.go b/theme/theme.go index 0fbc86e2f4..820f71ad13 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -241,7 +241,7 @@ func darkPaletteColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameOnError: return colorDarkOnError case ColorNameOnSuccess: - return colorDarkForeground + return colorDarkOnSuccess case ColorNameOnWarning: return colorDarkForeground case ColorNameOverlayBackground: @@ -315,7 +315,7 @@ func lightPaletteColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameOnError: return colorLightOnError case ColorNameOnSuccess: - return colorLightForeground + return colorLightOnSuccess case ColorNameOnWarning: return colorLightForeground case ColorNameOverlayBackground: diff --git a/widget/button.go b/widget/button.go index a99e57c55f..e35cca629c 100644 --- a/widget/button.go +++ b/widget/button.go @@ -375,7 +375,7 @@ func (r *buttonRenderer) buttonColorNames() (foreground, background, backgroundB background = theme.ColorNameButton } case SuccessImportance: - foreground = theme.ColorNameBackground + foreground = theme.ColorNameOnSuccess background = theme.ColorNameSuccess case WarningImportance: foreground = theme.ColorNameBackground From 019a4cb4d717bdbf92dc4e28d9b9cb7d80c25b44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Wed, 12 Jun 2024 11:21:05 +0200 Subject: [PATCH 24/78] =?UTF-8?q?[widget]=20buttons=20use=20=E2=80=9ConWar?= =?UTF-8?q?ning=E2=80=9D=20color=20on=20=E2=80=9Cwarning=E2=80=9D=20backgr?= =?UTF-8?q?ound?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Formerly, the theme’s background color was used and therefore the “onWarning” color was changed to the background color value to make this a seamless change. --- theme/color.go | 2 ++ theme/theme.go | 4 ++-- widget/button.go | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/theme/color.go b/theme/color.go index b3b3d4372b..06d26adc87 100644 --- a/theme/color.go +++ b/theme/color.go @@ -191,6 +191,7 @@ var ( colorDarkMenuBackground = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} colorDarkOnError = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} colorDarkOnSuccess = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} + colorDarkOnWarning = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} colorDarkOverlayBackground = color.NRGBA{R: 0x18, G: 0x1d, B: 0x25, A: 0xff} colorDarkPlaceholder = color.NRGBA{R: 0xb2, G: 0xb2, B: 0xb2, A: 0xff} colorDarkPressed = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x66} @@ -213,6 +214,7 @@ var ( colorLightMenuBackground = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} colorLightOnError = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} colorLightOnSuccess = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorLightOnWarning = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} colorLightPlaceholder = color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff} colorLightPressed = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x19} colorLightScrollBar = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x99} diff --git a/theme/theme.go b/theme/theme.go index 820f71ad13..1d1199d3a7 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -243,7 +243,7 @@ func darkPaletteColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameOnSuccess: return colorDarkOnSuccess case ColorNameOnWarning: - return colorDarkForeground + return colorDarkOnWarning case ColorNameOverlayBackground: return colorDarkOverlayBackground case ColorNamePlaceHolder: @@ -317,7 +317,7 @@ func lightPaletteColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameOnSuccess: return colorLightOnSuccess case ColorNameOnWarning: - return colorLightForeground + return colorLightOnWarning case ColorNameOverlayBackground: return colorLightBackground case ColorNamePlaceHolder: diff --git a/widget/button.go b/widget/button.go index e35cca629c..2f02c6d5ee 100644 --- a/widget/button.go +++ b/widget/button.go @@ -378,7 +378,7 @@ func (r *buttonRenderer) buttonColorNames() (foreground, background, backgroundB foreground = theme.ColorNameOnSuccess background = theme.ColorNameSuccess case WarningImportance: - foreground = theme.ColorNameBackground + foreground = theme.ColorNameOnWarning background = theme.ColorNameWarning default: background = theme.ColorNameButton From 6672d89c9b1b801d1c45f3286593dda024e7c325 Mon Sep 17 00:00:00 2001 From: Drew Weymouth Date: Wed, 12 Jun 2024 07:39:55 -0700 Subject: [PATCH 25/78] remove ParseMarkdown suggestion for piecewise parsing --- widget/markdown.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/widget/markdown.go b/widget/markdown.go index a6e0b7f4a1..c32a4c7f23 100644 --- a/widget/markdown.go +++ b/widget/markdown.go @@ -31,7 +31,7 @@ func (t *RichText) ParseMarkdown(content string) { // content to the widget, with the appropriate formatting. // This API is intended for appending complete markdown documents or // standalone fragments, and should not be used to parse a single -// markdown document piecewise. Use ParseMarkdown for this case. +// markdown document piecewise. // // Since: 2.5 func (t *RichText) AppendMarkdown(content string) { From d6170d2045fcd3425d84cbc113650d1b51bb398e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Wed, 12 Jun 2024 16:41:29 +0200 Subject: [PATCH 26/78] {app.d => internalapp.D}efaultVariant With exporting this internally, the settings app can access it and provide a more accurate preview. --- app/app_desktop_darwin.go | 27 +++++--------- app/app_desktop_darwin.m | 5 --- app/app_mobile.go | 5 ++- app/app_mobile_and.go | 4 --- app/app_mobile_ios.go | 6 ---- app/app_other.go | 5 --- app/app_theme_web.go | 12 ------- app/app_windows.go | 25 ------------- app/app_xdg.go | 11 ++---- app/settings.go | 3 +- app/settings_test.go | 7 ++-- internal/app/theme_darwin.go | 27 ++++++++++++++ internal/app/theme_darwin.m | 8 +++++ internal/app/theme_mobile.go | 18 ++++++++++ internal/app/theme_other.go | 15 ++++++++ .../app/theme_wasm.go | 5 ++- internal/app/theme_web.go | 15 ++++++++ internal/app/theme_windows.go | 35 +++++++++++++++++++ internal/app/theme_xdg.go | 20 +++++++++++ 19 files changed, 162 insertions(+), 91 deletions(-) delete mode 100644 app/app_theme_web.go create mode 100644 internal/app/theme_darwin.go create mode 100644 internal/app/theme_darwin.m create mode 100644 internal/app/theme_mobile.go create mode 100644 internal/app/theme_other.go rename app/app_theme_wasm.go => internal/app/theme_wasm.go (59%) create mode 100644 internal/app/theme_web.go create mode 100644 internal/app/theme_windows.go create mode 100644 internal/app/theme_xdg.go diff --git a/app/app_desktop_darwin.go b/app/app_desktop_darwin.go index 2142503299..1390a14dd0 100644 --- a/app/app_desktop_darwin.go +++ b/app/app_desktop_darwin.go @@ -9,7 +9,6 @@ package app #include bool isBundled(); -bool isDarkMode(); void watchTheme(); */ import "C" @@ -20,15 +19,12 @@ import ( "path/filepath" "fyne.io/fyne/v2" - "fyne.io/fyne/v2/theme" ) -// SetSystemTrayMenu creates a system tray item and attaches the specified menu. -// By default this will use the application icon. -func (a *fyneApp) SetSystemTrayMenu(menu *fyne.Menu) { - if desk, ok := a.Driver().(systrayDriver); ok { - desk.SetSystemTrayMenu(menu) - } +func (a *fyneApp) OpenURL(url *url.URL) error { + cmd := exec.Command("open", url.String()) + cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr + return cmd.Run() } // SetSystemTrayIcon sets a custom image for the system tray icon. @@ -37,11 +33,12 @@ func (a *fyneApp) SetSystemTrayIcon(icon fyne.Resource) { a.Driver().(systrayDriver).SetSystemTrayIcon(icon) } -func defaultVariant() fyne.ThemeVariant { - if C.isDarkMode() { - return theme.VariantDark +// SetSystemTrayMenu creates a system tray item and attaches the specified menu. +// By default this will use the application icon. +func (a *fyneApp) SetSystemTrayMenu(menu *fyne.Menu) { + if desk, ok := a.Driver().(systrayDriver); ok { + desk.SetSystemTrayMenu(menu) } - return theme.VariantLight } func rootConfigDir() string { @@ -51,12 +48,6 @@ func rootConfigDir() string { return filepath.Join(desktopConfig, "fyne") } -func (a *fyneApp) OpenURL(url *url.URL) error { - cmd := exec.Command("open", url.String()) - cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr - return cmd.Run() -} - //export themeChanged func themeChanged() { fyne.CurrentApp().Settings().(*settings).setupTheme() diff --git a/app/app_desktop_darwin.m b/app/app_desktop_darwin.m index a571f6642a..3aa12910a6 100644 --- a/app/app_desktop_darwin.m +++ b/app/app_desktop_darwin.m @@ -4,11 +4,6 @@ #import -bool isDarkMode() { - NSString *style = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"]; - return [@"Dark" isEqualToString:style]; -} - void watchTheme() { [[NSDistributedNotificationCenter defaultCenter] addObserverForName:@"AppleInterfaceThemeChangedNotification" object:nil queue:nil usingBlock:^(NSNotification *note) { diff --git a/app/app_mobile.go b/app/app_mobile.go index 9976bb0d88..0303c202a2 100644 --- a/app/app_mobile.go +++ b/app/app_mobile.go @@ -4,18 +4,17 @@ package app import ( "fyne.io/fyne/v2" + internalapp "fyne.io/fyne/v2/internal/app" "fyne.io/fyne/v2/internal/driver/mobile" ) -var systemTheme fyne.ThemeVariant - // NewWithID returns a new app instance using the appropriate runtime driver. // The ID string should be globally unique to this app. func NewWithID(id string) fyne.App { d := mobile.NewGoMobileDriver() a := newAppWithDriver(d, id) d.(mobile.ConfiguredDriver).SetOnConfigurationChanged(func(c *mobile.Configuration) { - systemTheme = c.SystemTheme + internalapp.SystemTheme = c.SystemTheme a.Settings().(*settings).setupTheme() }) diff --git a/app/app_mobile_and.go b/app/app_mobile_and.go index 35baf26e14..9abf04745c 100644 --- a/app/app_mobile_and.go +++ b/app/app_mobile_and.go @@ -45,10 +45,6 @@ func (a *fyneApp) SendNotification(n *fyne.Notification) { }) } -func defaultVariant() fyne.ThemeVariant { - return systemTheme -} - func rootConfigDir() string { filesDir := os.Getenv("FILESDIR") if filesDir == "" { diff --git a/app/app_mobile_ios.go b/app/app_mobile_ios.go index fb79323d91..991e4b6ea7 100644 --- a/app/app_mobile_ios.go +++ b/app/app_mobile_ios.go @@ -17,8 +17,6 @@ import ( "net/url" "path/filepath" "unsafe" - - "fyne.io/fyne/v2" ) func rootConfigDir() string { @@ -33,7 +31,3 @@ func (a *fyneApp) OpenURL(url *url.URL) error { return nil } - -func defaultVariant() fyne.ThemeVariant { - return systemTheme -} diff --git a/app/app_other.go b/app/app_other.go index d20799ba7f..6842be5e64 100644 --- a/app/app_other.go +++ b/app/app_other.go @@ -9,13 +9,8 @@ import ( "path/filepath" "fyne.io/fyne/v2" - "fyne.io/fyne/v2/theme" ) -func defaultVariant() fyne.ThemeVariant { - return theme.VariantDark -} - func rootConfigDir() string { return filepath.Join(os.TempDir(), "fyne-test") } diff --git a/app/app_theme_web.go b/app/app_theme_web.go deleted file mode 100644 index df16339216..0000000000 --- a/app/app_theme_web.go +++ /dev/null @@ -1,12 +0,0 @@ -//go:build !ci && !wasm && test_web_driver - -package app - -import ( - "fyne.io/fyne/v2" - "fyne.io/fyne/v2/theme" -) - -func defaultVariant() fyne.ThemeVariant { - return theme.VariantDark -} diff --git a/app/app_windows.go b/app/app_windows.go index e2a8f713ed..bc648d9cfe 100644 --- a/app/app_windows.go +++ b/app/app_windows.go @@ -11,10 +11,7 @@ import ( "strings" "syscall" - "golang.org/x/sys/windows/registry" - "fyne.io/fyne/v2" - "fyne.io/fyne/v2/theme" ) const notificationTemplate = `$title = "%s" @@ -31,28 +28,6 @@ $xml.LoadXml($toastXml.OuterXml) $toast = [Windows.UI.Notifications.ToastNotification]::new($xml) [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier("%s").Show($toast);` -func isDark() bool { - k, err := registry.OpenKey(registry.CURRENT_USER, `SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize`, registry.QUERY_VALUE) - if err != nil { // older version of Windows will not have this key - return false - } - defer k.Close() - - useLight, _, err := k.GetIntegerValue("AppsUseLightTheme") - if err != nil { // older version of Windows will not have this value - return false - } - - return useLight == 0 -} - -func defaultVariant() fyne.ThemeVariant { - if isDark() { - return theme.VariantDark - } - return theme.VariantLight -} - func rootConfigDir() string { homeDir, _ := os.UserHomeDir() diff --git a/app/app_xdg.go b/app/app_xdg.go index 88ff6ad7ee..93b9a75d7b 100644 --- a/app/app_xdg.go +++ b/app/app_xdg.go @@ -16,16 +16,11 @@ import ( "github.com/rymdport/portal/settings/appearance" "fyne.io/fyne/v2" + internalapp "fyne.io/fyne/v2/internal/app" "fyne.io/fyne/v2/internal/build" "fyne.io/fyne/v2/theme" ) -var currentVariant atomic.Uint64 - -func defaultVariant() fyne.ThemeVariant { - return fyne.ThemeVariant(currentVariant.Load()) -} - func (a *fyneApp) OpenURL(url *url.URL) error { if build.IsFlatpak { err := openuri.OpenURI("", url.String(), nil) @@ -123,11 +118,11 @@ func rootConfigDir() string { func watchTheme() { go func() { // with portal this may not be immediate, so we update a cache instead - currentVariant.Store(uint64(findFreedesktopColorScheme())) + internalapp.CurrentVariant.Store(uint64(findFreedesktopColorScheme())) portalSettings.OnSignalSettingChanged(func(changed portalSettings.Changed) { if changed.Namespace == "org.freedesktop.appearance" && changed.Key == "color-scheme" { - currentVariant.Store(uint64(findFreedesktopColorScheme())) + internalapp.CurrentVariant.Store(uint64(findFreedesktopColorScheme())) fyne.CurrentApp().Settings().(*settings).setupTheme() } }) diff --git a/app/settings.go b/app/settings.go index 2b6fddd62c..ca83c84e6d 100644 --- a/app/settings.go +++ b/app/settings.go @@ -7,6 +7,7 @@ import ( "sync" "fyne.io/fyne/v2" + internalapp "fyne.io/fyne/v2/internal/app" "fyne.io/fyne/v2/internal/build" "fyne.io/fyne/v2/theme" ) @@ -152,7 +153,7 @@ func (s *settings) setupTheme() { name = env } - variant := defaultVariant() + variant := internalapp.DefaultVariant() effectiveTheme := s.theme if !s.themeSpecified { effectiveTheme = s.loadSystemTheme() diff --git a/app/settings_test.go b/app/settings_test.go index 65745df0f6..ade718653e 100644 --- a/app/settings_test.go +++ b/app/settings_test.go @@ -6,6 +6,7 @@ import ( "testing" "fyne.io/fyne/v2" + internalapp "fyne.io/fyne/v2/internal/app" "fyne.io/fyne/v2/internal/build" internalTest "fyne.io/fyne/v2/internal/test" "fyne.io/fyne/v2/test" @@ -43,7 +44,7 @@ func TestSettingsLoad(t *testing.T) { func TestOverrideTheme(t *testing.T) { set := &settings{} set.setupTheme() - assert.Equal(t, defaultVariant(), set.ThemeVariant()) + assert.Equal(t, internalapp.DefaultVariant(), set.ThemeVariant()) set.schema.ThemeName = "light" set.setupTheme() @@ -57,7 +58,7 @@ func TestOverrideTheme(t *testing.T) { set = &settings{} set.setupTheme() - assert.Equal(t, defaultVariant(), set.ThemeVariant()) + assert.Equal(t, internalapp.DefaultVariant(), set.ThemeVariant()) err := os.Setenv("FYNE_THEME", "light") if err != nil { @@ -106,7 +107,7 @@ func TestCustomTheme(t *testing.T) { set.setupTheme() assert.True(t, set.Theme() == ctheme) - assert.Equal(t, defaultVariant(), set.ThemeVariant()) + assert.Equal(t, internalapp.DefaultVariant(), set.ThemeVariant()) err := set.loadFromFile(filepath.Join("testdata", "light-theme.json")) if err != nil { diff --git a/internal/app/theme_darwin.go b/internal/app/theme_darwin.go new file mode 100644 index 0000000000..0d3004451e --- /dev/null +++ b/internal/app/theme_darwin.go @@ -0,0 +1,27 @@ +//go:build !ci && !ios && !wasm && !test_web_driver + +package app + +/* +#cgo CFLAGS: -x objective-c +#cgo LDFLAGS: -framework Foundation + +#include + +bool isDarkMode(); +*/ +import "C" +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/theme" +) + +// DefaultVariant returns the systems default fyne.ThemeVariant. +// Normally, you should not need this. It is extracted out of the root app package to give the +// settings app access to it. +func DefaultVariant() fyne.ThemeVariant { + if C.isDarkMode() { + return theme.VariantDark + } + return theme.VariantLight +} diff --git a/internal/app/theme_darwin.m b/internal/app/theme_darwin.m new file mode 100644 index 0000000000..b830ba1358 --- /dev/null +++ b/internal/app/theme_darwin.m @@ -0,0 +1,8 @@ +//go:build !ci && !ios + +#import + +bool isDarkMode() { + NSString *style = [[NSUserDefaults standardUserDefaults] stringForKey:@"AppleInterfaceStyle"]; + return [@"Dark" isEqualToString:style]; +} diff --git a/internal/app/theme_mobile.go b/internal/app/theme_mobile.go new file mode 100644 index 0000000000..231a005db7 --- /dev/null +++ b/internal/app/theme_mobile.go @@ -0,0 +1,18 @@ +//go:build !ci && (android || ios || mobile) + +package app + +import ( + "fyne.io/fyne/v2" +) + +// SystemTheme contains the system’s theme variant. +// It is intended for internal use, only! +var SystemTheme fyne.ThemeVariant + +// DefaultVariant returns the systems default fyne.ThemeVariant. +// Normally, you should not need this. It is extracted out of the root app package to give the +// settings app access to it. +func DefaultVariant() fyne.ThemeVariant { + return SystemTheme +} diff --git a/internal/app/theme_other.go b/internal/app/theme_other.go new file mode 100644 index 0000000000..4328beedb6 --- /dev/null +++ b/internal/app/theme_other.go @@ -0,0 +1,15 @@ +//go:build ci || (!linux && !darwin && !windows && !freebsd && !openbsd && !netbsd && !wasm && !test_web_driver) + +package app + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/theme" +) + +// DefaultVariant returns the systems default fyne.ThemeVariant. +// Normally, you should not need this. It is extracted out of the root app package to give the +// settings app access to it. +func DefaultVariant() fyne.ThemeVariant { + return theme.VariantDark +} diff --git a/app/app_theme_wasm.go b/internal/app/theme_wasm.go similarity index 59% rename from app/app_theme_wasm.go rename to internal/app/theme_wasm.go index 59c7045ce3..81c9433f0b 100644 --- a/app/app_theme_wasm.go +++ b/internal/app/theme_wasm.go @@ -9,7 +9,10 @@ import ( "fyne.io/fyne/v2/theme" ) -func defaultVariant() fyne.ThemeVariant { +// DefaultVariant returns the systems default fyne.ThemeVariant. +// Normally, you should not need this. It is extracted out of the root app package to give the +// settings app access to it. +func DefaultVariant() fyne.ThemeVariant { matches := js.Global().Call("matchMedia", "(prefers-color-scheme: dark)") if matches.Truthy() { if matches.Get("matches").Bool() { diff --git a/internal/app/theme_web.go b/internal/app/theme_web.go new file mode 100644 index 0000000000..926c131392 --- /dev/null +++ b/internal/app/theme_web.go @@ -0,0 +1,15 @@ +//go:build !ci && !wasm && test_web_driver + +package app + +import ( + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/theme" +) + +// DefaultVariant returns the systems default fyne.ThemeVariant. +// Normally, you should not need this. It is extracted out of the root app package to give the +// settings app access to it. +func DefaultVariant() fyne.ThemeVariant { + return theme.VariantDark +} diff --git a/internal/app/theme_windows.go b/internal/app/theme_windows.go new file mode 100644 index 0000000000..768e83de3e --- /dev/null +++ b/internal/app/theme_windows.go @@ -0,0 +1,35 @@ +//go:build !ci && !android && !ios && !wasm && !test_web_driver + +package app + +import ( + "golang.org/x/sys/windows/registry" + + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/theme" +) + +// DefaultVariant returns the systems default fyne.ThemeVariant. +// Normally, you should not need this. It is extracted out of the root app package to give the +// settings app access to it. +func DefaultVariant() fyne.ThemeVariant { + if isDark() { + return theme.VariantDark + } + return theme.VariantLight +} + +func isDark() bool { + k, err := registry.OpenKey(registry.CURRENT_USER, `SOFTWARE\Microsoft\Windows\CurrentVersion\Themes\Personalize`, registry.QUERY_VALUE) + if err != nil { // older version of Windows will not have this key + return false + } + defer k.Close() + + useLight, _, err := k.GetIntegerValue("AppsUseLightTheme") + if err != nil { // older version of Windows will not have this value + return false + } + + return useLight == 0 +} diff --git a/internal/app/theme_xdg.go b/internal/app/theme_xdg.go new file mode 100644 index 0000000000..2f81e45829 --- /dev/null +++ b/internal/app/theme_xdg.go @@ -0,0 +1,20 @@ +//go:build !ci && !wasm && !test_web_driver && (linux || openbsd || freebsd || netbsd) && !android + +package app + +import ( + "sync/atomic" + + "fyne.io/fyne/v2" +) + +// CurrentVariant contains the system’s theme variant. +// It is intended for internal use, only! +var CurrentVariant atomic.Uint64 + +// DefaultVariant returns the systems default fyne.ThemeVariant. +// Normally, you should not need this. It is extracted out of the root app package to give the +// settings app access to it. +func DefaultVariant() fyne.ThemeVariant { + return fyne.ThemeVariant(CurrentVariant.Load()) +} From 81ecd125aff9f79144134ea6097e824e3ea8484b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Thu, 13 Jun 2024 18:05:37 +0200 Subject: [PATCH 27/78] =?UTF-8?q?[settings]=20preview=20uses=20actual=20sy?= =?UTF-8?q?stem=20default=20variant=20when=20=E2=80=9Csystem=20default?= =?UTF-8?q?=E2=80=9D=20is=20selected?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/fyne_settings/settings/appearance.go | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/cmd/fyne_settings/settings/appearance.go b/cmd/fyne_settings/settings/appearance.go index 3f3b024ac7..5b13ad7244 100644 --- a/cmd/fyne_settings/settings/appearance.go +++ b/cmd/fyne_settings/settings/appearance.go @@ -11,6 +11,7 @@ import ( "fyne.io/fyne/v2/app" "fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/container" + internalapp "fyne.io/fyne/v2/internal/app" intWidget "fyne.io/fyne/v2/internal/widget" "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/theme" @@ -18,7 +19,9 @@ import ( ) const ( - systemThemeName = "system default" + themeNameDark = "dark" + themeNameLight = "light" + themeNameSystem = "system default" ) // Settings gives access to user interfaces to control Fyne settings @@ -56,11 +59,11 @@ func (s *Settings) LoadAppearanceScreen(w fyne.Window) fyne.CanvasObject { s.preview = s.createPreview() def := s.fyneSettings.ThemeName - themeNames := []string{"dark", "light"} + themeNames := []string{themeNameDark, themeNameLight} if runtime.GOOS == "darwin" || runtime.GOOS == "windows" { - themeNames = append(themeNames, systemThemeName) + themeNames = append(themeNames, themeNameSystem) if s.fyneSettings.ThemeName == "" { - def = systemThemeName + def = themeNameSystem } } themes := widget.NewSelect(themeNames, s.chooseTheme) @@ -102,7 +105,7 @@ func (s *Settings) LoadAppearanceScreen(w fyne.Window) fyne.CanvasObject { } func (s *Settings) chooseTheme(name string) { - if name == systemThemeName { + if name == themeNameSystem { name = "" } s.fyneSettings.ThemeName = name @@ -242,8 +245,11 @@ type previewTheme struct { func (p *previewTheme) Color(n fyne.ThemeColorName, _ fyne.ThemeVariant) color.Color { variant := theme.VariantDark - if p.s.fyneSettings.ThemeName == "light" { + switch p.s.fyneSettings.ThemeName { + case themeNameLight: variant = theme.VariantLight + case themeNameSystem: + variant = internalapp.DefaultVariant() } switch n { From afc2e5865a9a6ca91f00bd79ba55c71e1c287f45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Wed, 12 Jun 2024 13:52:14 +0200 Subject: [PATCH 28/78] =?UTF-8?q?[dialog]=20color=20picker=E2=80=99s=20bas?= =?UTF-8?q?ic=20colors=20should=20not=20depend=20on=20theme?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- dialog/color_picker.go | 45 ++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/dialog/color_picker.go b/dialog/color_picker.go index 410aa7715a..7040e8652d 100644 --- a/dialog/color_picker.go +++ b/dialog/color_picker.go @@ -12,29 +12,36 @@ import ( // newColorBasicPicker returns a component for selecting basic colors. func newColorBasicPicker(callback func(color.Color)) fyne.CanvasObject { - return newColorButtonBox([]color.Color{ - theme.PrimaryColorNamed(theme.ColorRed), - theme.PrimaryColorNamed(theme.ColorOrange), - theme.PrimaryColorNamed(theme.ColorYellow), - theme.PrimaryColorNamed(theme.ColorGreen), - theme.PrimaryColorNamed(theme.ColorBlue), - theme.PrimaryColorNamed(theme.ColorPurple), - theme.PrimaryColorNamed(theme.ColorBrown), - // theme.PrimaryColorNamed(theme.ColorGray), - }, theme.ColorChromaticIcon(), callback) + return newColorButtonBox( + stringsToColors( + "#f44336", // red + "#ff9800", // orange + "#ffeb3b", // yellow + "#8bc34a", // green + "#296ff6", // blue + "#9c27b0", // purple + "#795548", // brown + ), + theme.ColorChromaticIcon(), + callback, + ) } // newColorGreyscalePicker returns a component for selecting greyscale colors. func newColorGreyscalePicker(callback func(color.Color)) fyne.CanvasObject { - return newColorButtonBox(stringsToColors([]string{ - "#ffffff", - "#cccccc", - "#aaaaaa", - "#808080", - "#555555", - "#333333", - "#000000", - }...), theme.ColorAchromaticIcon(), callback) + return newColorButtonBox( + stringsToColors( + "#ffffff", + "#cccccc", + "#aaaaaa", + "#808080", + "#555555", + "#333333", + "#000000", + ), + theme.ColorAchromaticIcon(), + callback, + ) } // newColorRecentPicker returns a component for selecting recent colors. From 72d388694615b7d2c1e2e3941f92a98c6abd0d81 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Wed, 12 Jun 2024 13:54:34 +0200 Subject: [PATCH 29/78] [fyne_demo] color animation should not depend on theme colors --- cmd/fyne_demo/tutorials/animation.go | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/cmd/fyne_demo/tutorials/animation.go b/cmd/fyne_demo/tutorials/animation.go index 6e2c71a102..532c9bad2a 100644 --- a/cmd/fyne_demo/tutorials/animation.go +++ b/cmd/fyne_demo/tutorials/animation.go @@ -21,11 +21,14 @@ func makeAnimationCanvas() fyne.CanvasObject { rect := canvas.NewRectangle(color.Black) rect.Resize(fyne.NewSize(410, 140)) - a := canvas.NewColorRGBAAnimation(theme.PrimaryColorNamed(theme.ColorBlue), theme.PrimaryColorNamed(theme.ColorGreen), + a := canvas.NewColorRGBAAnimation( + color.NRGBA{R: 0x29, G: 0x6f, B: 0xf6, A: 0xaa}, + color.NRGBA{R: 0x8b, G: 0xc3, B: 0x4a, A: 0xaa}, time.Second*3, func(c color.Color) { rect.FillColor = c canvas.Refresh(rect) - }) + }, + ) a.RepeatCount = fyne.AnimationRepeatForever a.AutoReverse = true a.Start() From e2b49f87b41647d2f0440af9cb2c9c8d5cb70b9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Thu, 13 Jun 2024 18:54:21 +0200 Subject: [PATCH 30/78] [fyne_settings] remove color from color button and name it properly The color depends on the theme and therefore subject to change. --- cmd/fyne_settings/settings/appearance.go | 35 ++++++++++++------------ 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/cmd/fyne_settings/settings/appearance.go b/cmd/fyne_settings/settings/appearance.go index 3f3b024ac7..ae03918c2c 100644 --- a/cmd/fyne_settings/settings/appearance.go +++ b/cmd/fyne_settings/settings/appearance.go @@ -74,7 +74,7 @@ func (s *Settings) LoadAppearanceScreen(w fyne.Window) fyne.CanvasObject { }) animations.Checked = !s.fyneSettings.DisableAnimations for _, c := range theme.PrimaryColorNames() { - b := newColorButton(c, theme.PrimaryColorNamed(c), s) + b := newPrimaryColorButton(c, s) s.colors = append(s.colors, b) } swatch := container.NewGridWithColumns(len(s.colors), s.colors...) @@ -167,22 +167,21 @@ func (s *Settings) saveToFile(path string) error { return os.WriteFile(path, data, 0644) } -type colorButton struct { +type primaryColorButton struct { widget.BaseWidget - name string - color color.Color + name string s *Settings } -func newColorButton(n string, c color.Color, s *Settings) *colorButton { - b := &colorButton{name: n, color: c, s: s} +func newPrimaryColorButton(name string, s *Settings) *primaryColorButton { + b := &primaryColorButton{name: name, s: s} b.ExtendBaseWidget(b) return b } -func (c *colorButton) CreateRenderer() fyne.WidgetRenderer { - r := canvas.NewRectangle(c.color) +func (c *primaryColorButton) CreateRenderer() fyne.WidgetRenderer { + r := canvas.NewRectangle(theme.PrimaryColorNamed(c.name)) r.CornerRadius = theme.SelectionRadiusSize() r.StrokeWidth = 5 @@ -190,10 +189,10 @@ func (c *colorButton) CreateRenderer() fyne.WidgetRenderer { r.StrokeColor = theme.PrimaryColor() } - return &colorRenderer{c: c, rect: r, objs: []fyne.CanvasObject{r}} + return &primaryColorButtonRenderer{c: c, rect: r, objs: []fyne.CanvasObject{r}} } -func (c *colorButton) Tapped(_ *fyne.PointEvent) { +func (c *primaryColorButton) Tapped(_ *fyne.PointEvent) { c.s.fyneSettings.PrimaryColor = c.name for _, child := range c.s.colors { child.Refresh() @@ -202,37 +201,37 @@ func (c *colorButton) Tapped(_ *fyne.PointEvent) { c.s.refreshPreview() } -type colorRenderer struct { - c *colorButton +type primaryColorButtonRenderer struct { + c *primaryColorButton rect *canvas.Rectangle objs []fyne.CanvasObject } -func (c *colorRenderer) Layout(s fyne.Size) { +func (c *primaryColorButtonRenderer) Layout(s fyne.Size) { c.rect.Resize(s) } -func (c *colorRenderer) MinSize() fyne.Size { +func (c *primaryColorButtonRenderer) MinSize() fyne.Size { return fyne.NewSize(20, 32) } -func (c *colorRenderer) Refresh() { +func (c *primaryColorButtonRenderer) Refresh() { if c.c.name == c.c.s.fyneSettings.PrimaryColor { c.rect.StrokeColor = theme.PrimaryColor() } else { c.rect.StrokeColor = color.Transparent } - c.rect.FillColor = c.c.color + c.rect.FillColor = theme.PrimaryColorNamed(c.c.name) c.rect.CornerRadius = theme.SelectionRadiusSize() c.rect.Refresh() } -func (c *colorRenderer) Objects() []fyne.CanvasObject { +func (c *primaryColorButtonRenderer) Objects() []fyne.CanvasObject { return c.objs } -func (c *colorRenderer) Destroy() { +func (c *primaryColorButtonRenderer) Destroy() { } type previewTheme struct { From a524443a0be8b4c6f715c854ea0583519283edcb Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Thu, 13 Jun 2024 19:43:48 +0100 Subject: [PATCH 31/78] Allow an About menu item in File to be used as special to replace the macOS about in the app menu --- cmd/fyne_demo/main.go | 7 +++++++ internal/driver/glfw/menu_darwin.go | 29 ++++++++++++++++++++++++++--- internal/driver/glfw/menu_darwin.m | 14 +++++++++++--- 3 files changed, 44 insertions(+), 6 deletions(-) diff --git a/cmd/fyne_demo/main.go b/cmd/fyne_demo/main.go index 81deb5fcbb..f5c93b3567 100644 --- a/cmd/fyne_demo/main.go +++ b/cmd/fyne_demo/main.go @@ -120,6 +120,12 @@ func makeMenu(a fyne.App, w fyne.Window) *fyne.MainMenu { w.Resize(fyne.NewSize(440, 520)) w.Show() } + showAbout := func() { + w := a.NewWindow("About") + w.SetContent(widget.NewLabel("About Fyne Demo app...")) + w.Show() + } + aboutItem := fyne.NewMenuItem("About", showAbout) settingsItem := fyne.NewMenuItem("Settings", openSettings) settingsShortcut := &desktop.CustomShortcut{KeyName: fyne.KeyComma, Modifier: fyne.KeyModifierShortcutDefault} settingsItem.Shortcut = settingsShortcut @@ -170,6 +176,7 @@ func makeMenu(a fyne.App, w fyne.Window) *fyne.MainMenu { if !device.IsMobile() && !device.IsBrowser() { file.Items = append(file.Items, fyne.NewMenuItemSeparator(), settingsItem) } + file.Items = append(file.Items, aboutItem) main := fyne.NewMainMenu( file, fyne.NewMenu("Edit", cutItem, copyItem, pasteItem, fyne.NewMenuItemSeparator(), findItem), diff --git a/internal/driver/glfw/menu_darwin.go b/internal/driver/glfw/menu_darwin.go index 7b2629edbb..addce2adf0 100644 --- a/internal/driver/glfw/menu_darwin.go +++ b/internal/driver/glfw/menu_darwin.go @@ -139,11 +139,35 @@ func exceptionCallback(e *C.char) { func handleSpecialItems(w *window, menu *fyne.Menu, nextItemID int, addSeparator bool) (*fyne.Menu, int) { for i, item := range menu.Items { - if item.Label == "Settings" || item.Label == "Settings…" || item.Label == "Preferences" || item.Label == "Preferences…" { + switch item.Label { + case "Settings", "Settings…", "Preferences", "Preferences…": items := make([]*fyne.MenuItem, 0, len(menu.Items)-1) items = append(items, menu.Items[:i]...) items = append(items, menu.Items[i+1:]...) - menu, nextItemID = handleSpecialItems(w, fyne.NewMenu(menu.Label, items...), nextItemID, false) + menu.Items = items + + insertNativeMenuItem(C.darwinAppMenu(), item, nextItemID, 1) + if addSeparator { + C.insertDarwinMenuItem( + C.darwinAppMenu(), + C.CString(""), + C.CString(""), + C.uint(0), + C.int(nextItemID), + C.int(1), + C.bool(true), + unsafe.Pointer(nil), + C.uint(0), + ) + } + nextItemID = registerCallback(w, item, nextItemID) + case "About": + items := make([]*fyne.MenuItem, 0, len(menu.Items)-1) + items = append(items, menu.Items[:i]...) + if i < len(menu.Items)-1 { + items = append(items, menu.Items[i+1:]...) + } + menu.Items = items insertNativeMenuItem(C.darwinAppMenu(), item, nextItemID, 1) if addSeparator { @@ -160,7 +184,6 @@ func handleSpecialItems(w *window, menu *fyne.Menu, nextItemID int, addSeparator ) } nextItemID = registerCallback(w, item, nextItemID) - break } } return menu, nextItemID diff --git a/internal/driver/glfw/menu_darwin.m b/internal/driver/glfw/menu_darwin.m index 458c5ab269..58e71e3d01 100644 --- a/internal/driver/glfw/menu_darwin.m +++ b/internal/driver/glfw/menu_darwin.m @@ -109,10 +109,18 @@ void handleException(const char* m, id e) { } } - if (index > -1) { - [menu insertItem:item atIndex:index]; + if (strcmp(label, "About") == 0) { + item = [menu itemArray][0]; + [item setAction:@selector(tapped:)]; + [item setTarget:[FyneMenuHandler class]]; + [item setTag:id+menuTagMin]; + return item; } else { - [menu addItem:item]; + if (index > -1) { + [menu insertItem:item atIndex:index]; + } else { + [menu addItem:item]; + } } [item release]; // retained by the menu return item; From 8f79bd0326a827d05cc009810b4a05ffcc910159 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Fri, 14 Jun 2024 11:12:54 +0200 Subject: [PATCH 32/78] =?UTF-8?q?[internal/app]=20don=E2=80=99t=20ignore?= =?UTF-8?q?=20anything=20in=20CI?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/app/theme_darwin.go | 2 +- internal/app/theme_mobile.go | 2 +- internal/app/theme_other.go | 2 +- internal/app/theme_wasm.go | 2 +- internal/app/theme_web.go | 2 +- internal/app/theme_windows.go | 2 +- internal/app/theme_xdg.go | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/internal/app/theme_darwin.go b/internal/app/theme_darwin.go index 0d3004451e..84f5828981 100644 --- a/internal/app/theme_darwin.go +++ b/internal/app/theme_darwin.go @@ -1,4 +1,4 @@ -//go:build !ci && !ios && !wasm && !test_web_driver +//go:build !ios && !wasm && !test_web_driver package app diff --git a/internal/app/theme_mobile.go b/internal/app/theme_mobile.go index 231a005db7..fc10428074 100644 --- a/internal/app/theme_mobile.go +++ b/internal/app/theme_mobile.go @@ -1,4 +1,4 @@ -//go:build !ci && (android || ios || mobile) +//go:build android || ios || mobile package app diff --git a/internal/app/theme_other.go b/internal/app/theme_other.go index 4328beedb6..f2d69da073 100644 --- a/internal/app/theme_other.go +++ b/internal/app/theme_other.go @@ -1,4 +1,4 @@ -//go:build ci || (!linux && !darwin && !windows && !freebsd && !openbsd && !netbsd && !wasm && !test_web_driver) +//go:build !linux && !darwin && !windows && !freebsd && !openbsd && !netbsd && !wasm && !test_web_driver package app diff --git a/internal/app/theme_wasm.go b/internal/app/theme_wasm.go index 81c9433f0b..427ae3fec6 100644 --- a/internal/app/theme_wasm.go +++ b/internal/app/theme_wasm.go @@ -1,4 +1,4 @@ -//go:build !ci && wasm +//go:build wasm package app diff --git a/internal/app/theme_web.go b/internal/app/theme_web.go index 926c131392..310317c0c6 100644 --- a/internal/app/theme_web.go +++ b/internal/app/theme_web.go @@ -1,4 +1,4 @@ -//go:build !ci && !wasm && test_web_driver +//go:build !wasm && test_web_driver package app diff --git a/internal/app/theme_windows.go b/internal/app/theme_windows.go index 768e83de3e..f347bc5178 100644 --- a/internal/app/theme_windows.go +++ b/internal/app/theme_windows.go @@ -1,4 +1,4 @@ -//go:build !ci && !android && !ios && !wasm && !test_web_driver +//go:build !android && !ios && !wasm && !test_web_driver package app diff --git a/internal/app/theme_xdg.go b/internal/app/theme_xdg.go index 2f81e45829..0ed53d77ee 100644 --- a/internal/app/theme_xdg.go +++ b/internal/app/theme_xdg.go @@ -1,4 +1,4 @@ -//go:build !ci && !wasm && !test_web_driver && (linux || openbsd || freebsd || netbsd) && !android +//go:build !wasm && !test_web_driver && !android && (linux || openbsd || freebsd || netbsd) package app From f91c6ad424ffd0f0fb6df95517b84b9e5377ab93 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 14 Jun 2024 10:19:33 +0100 Subject: [PATCH 33/78] Ensure we log theme info for known resources --- .../desktop/change_icon_change_selected.xml | 2 +- .../desktop/change_icon_change_unselected.xml | 2 +- .../apptabs/desktop/change_icon_initial.xml | 2 +- .../mobile/change_icon_change_selected.xml | 2 +- .../mobile/change_icon_change_unselected.xml | 2 +- .../apptabs/mobile/change_icon_initial.xml | 2 +- .../desktop/change_icon_change_selected.xml | 2 +- .../desktop/change_icon_change_unselected.xml | 2 +- .../doctabs/desktop/change_icon_initial.xml | 2 +- .../doctabs/desktop/hover_all_tabs.xml | 2 +- .../doctabs/desktop/hover_create_tab.xml | 2 +- .../testdata/doctabs/desktop/hover_first.xml | 2 +- .../doctabs/desktop/hover_first_close.xml | 2 +- .../testdata/doctabs/desktop/hover_none.xml | 2 +- .../testdata/doctabs/desktop/hover_second.xml | 2 +- .../doctabs/desktop/tapped_all_tabs.xml | 4 +- .../doctabs/desktop/tapped_create_tab.xml | 2 +- .../doctabs/desktop/tapped_first_selected.xml | 2 +- .../desktop/tapped_second_selected.xml | 2 +- .../doctabs/desktop/tapped_third_selected.xml | 2 +- .../mobile/change_content_change_hidden.xml | 2 +- .../mobile/change_content_change_visible.xml | 2 +- .../doctabs/mobile/change_content_initial.xml | 2 +- .../mobile/change_icon_change_selected.xml | 4 +- .../mobile/change_icon_change_unselected.xml | 4 +- .../doctabs/mobile/change_icon_initial.xml | 4 +- .../mobile/change_label_change_selected.xml | 2 +- .../mobile/change_label_change_unselected.xml | 2 +- .../doctabs/mobile/change_label_initial.xml | 2 +- .../doctabs/mobile/dynamic_appended.xml | 2 +- .../mobile/dynamic_appended_another_three.xml | 6 +- .../mobile/dynamic_replaced_completely.xml | 4 +- .../testdata/doctabs/mobile/hover_none.xml | 2 +- .../doctabs/mobile/tab_location_bottom.xml | 4 +- .../doctabs/mobile/tab_location_top.xml | 4 +- .../doctabs/mobile/tapped_all_tabs.xml | 10 +-- .../doctabs/mobile/tapped_create_tab.xml | 8 +- .../doctabs/mobile/tapped_first_selected.xml | 6 +- .../doctabs/mobile/tapped_second_selected.xml | 6 +- .../doctabs/mobile/tapped_third_selected.xml | 6 +- .../menu_bar_kbdctrl_close_submenu_1.xml | 4 +- .../menu_bar_kbdctrl_close_submenu_2.xml | 2 +- .../menu_bar_kbdctrl_open_submenu_1.xml | 4 +- .../menu_bar_kbdctrl_open_submenu_2.xml | 4 +- ...kbdctrl_traverse_menu_bar_items_left_3.xml | 2 +- ...bdctrl_traverse_menu_bar_items_right_3.xml | 2 +- .../menu_bar_kbdctrl_traverse_menu_down_1.xml | 2 +- .../menu_bar_kbdctrl_traverse_menu_down_2.xml | 2 +- .../menu_bar_kbdctrl_traverse_menu_down_3.xml | 2 +- .../menu_bar_kbdctrl_traverse_menu_up_1.xml | 2 +- .../menu_bar_kbdctrl_traverse_menu_up_2.xml | 2 +- test/markup_renderer.go | 15 ++-- ..._expanded_multiple_open_multiple_items.xml | 4 +- ...ed_multiple_open_multiple_items_opened.xml | 4 +- ...layout_expanded_multiple_open_one_item.xml | 2 +- ...expanded_multiple_open_one_item_opened.xml | 2 +- ...ut_expanded_single_open_multiple_items.xml | 4 +- ...nded_single_open_multiple_items_opened.xml | 4 +- .../layout_expanded_single_open_one_item.xml | 2 +- ...t_expanded_single_open_one_item_opened.xml | 2 +- .../layout_multiple_open_multiple_items.xml | 4 +- ...ut_multiple_open_multiple_items_opened.xml | 4 +- .../layout_multiple_open_one_item.xml | 2 +- .../layout_multiple_open_one_item_opened.xml | 2 +- .../layout_single_open_multiple_items.xml | 4 +- ...yout_single_open_multiple_items_opened.xml | 4 +- .../accordion/layout_single_open_one_item.xml | 2 +- .../layout_single_open_one_item_opened.xml | 2 +- .../layout_icon_only_center_leading.xml | 2 +- .../layout_icon_only_center_trailing.xml | 2 +- .../layout_icon_only_leading_leading.xml | 2 +- .../layout_icon_only_leading_trailing.xml | 2 +- .../layout_icon_only_trailing_leading.xml | 2 +- .../layout_icon_only_trailing_trailing.xml | 2 +- .../layout_text_icon_center_leading.xml | 2 +- .../layout_text_icon_center_trailing.xml | 2 +- .../layout_text_icon_leading_leading.xml | 2 +- .../layout_text_icon_leading_trailing.xml | 2 +- .../layout_text_icon_trailing_leading.xml | 2 +- .../layout_text_icon_trailing_trailing.xml | 2 +- widget/testdata/card/layout_all_items.xml | 2 +- widget/testdata/card/layout_image_content.xml | 2 +- widget/testdata/card/layout_just_image.xml | 2 +- widget/testdata/card/layout_titles_image.xml | 2 +- widget/testdata/entry/validate_valid.xml | 2 +- widget/testdata/form/extended_entry.xml | 2 +- widget/testdata/form/layout.xml | 2 +- widget/testdata/icon/layout_resource.xml | 2 +- widget/testdata/list/initial.xml | 22 ++--- widget/testdata/list/item_removed.xml | 4 +- widget/testdata/list/new_data.xml | 22 ++--- widget/testdata/list/offset_changed.xml | 22 ++--- widget/testdata/list/resized.xml | 32 +++---- widget/testdata/list/small.xml | 4 +- .../menu/desktop/layout_background_reset.xml | 4 +- .../desktop/layout_no_space_on_both_sides.xml | 14 +-- .../menu/desktop/layout_no_space_on_right.xml | 14 +-- .../testdata/menu/desktop/layout_normal.xml | 4 +- .../desktop/layout_normal_with_submenus.xml | 14 +-- .../menu/desktop/layout_theme_changed.xml | 4 +- .../menu/desktop/layout_window_too_short.xml | 4 +- .../layout_window_too_short_for_submenu.xml | 16 ++-- .../menu/desktop/traverse_first_active.xml | 2 +- .../menu/desktop/traverse_initial.xml | 2 +- .../menu/desktop/traverse_second_active.xml | 2 +- .../desktop/traverse_submenu_first_active.xml | 2 +- .../traverse_submenu_second_active.xml | 2 +- .../menu/desktop/traverse_third_active.xml | 2 +- .../menu/mobile/layout_background_reset.xml | 2 +- .../mobile/layout_no_space_on_both_sides.xml | 12 +-- .../menu/mobile/layout_no_space_on_right.xml | 12 +-- widget/testdata/menu/mobile/layout_normal.xml | 2 +- .../mobile/layout_normal_with_submenus.xml | 12 +-- .../menu/mobile/layout_theme_changed.xml | 2 +- .../menu/mobile/layout_window_too_short.xml | 2 +- .../layout_window_too_short_for_submenu.xml | 14 +-- .../testdata/menu/refresh_2nd_checkmark.xml | 2 +- widget/testdata/menu/refresh_checkmark.xml | 2 +- widget/testdata/menu/refresh_initial.xml | 2 +- widget/testdata/password_entry/concealed.xml | 2 +- widget/testdata/password_entry/initial.xml | 2 +- .../password_entry/obfuscation_typed.xml | 2 +- .../password_entry/placeholder_initial.xml | 2 +- .../password_entry/placeholder_typed.xml | 2 +- widget/testdata/password_entry/revealed.xml | 2 +- .../popup_menu/kbd_ctrl_first_active.xml | 36 ++++++++ .../popup_menu/kbd_ctrl_first_sub_active.xml | 63 +++++++++++++ .../kbd_ctrl_first_sub_sub_active.xml | 89 +++++++++++++++++++ .../popup_menu/kbd_ctrl_second_active.xml | 36 ++++++++ .../popup_menu/kbd_ctrl_second_sub_active.xml | 63 +++++++++++++ .../kbd_ctrl_second_sub_sub_active.xml | 89 +++++++++++++++++++ widget/testdata/popup_menu/kbd_ctrl_shown.xml | 35 ++++++++ widget/testdata/select/desktop/center.xml | 2 +- .../testdata/select/desktop/layout_empty.xml | 2 +- .../select/desktop/layout_empty_expanded.xml | 2 +- .../layout_empty_expanded_placeholder.xml | 2 +- .../desktop/layout_empty_placeholder.xml | 2 +- .../select/desktop/layout_multiple.xml | 2 +- .../desktop/layout_multiple_expanded.xml | 2 +- .../layout_multiple_expanded_placeholder.xml | 2 +- .../layout_multiple_expanded_selected.xml | 2 +- ...multiple_expanded_selected_placeholder.xml | 2 +- .../desktop/layout_multiple_placeholder.xml | 2 +- .../desktop/layout_multiple_selected.xml | 2 +- .../layout_multiple_selected_placeholder.xml | 2 +- .../testdata/select/desktop/layout_single.xml | 2 +- .../select/desktop/layout_single_expanded.xml | 2 +- .../layout_single_expanded_placeholder.xml | 2 +- .../layout_single_expanded_selected.xml | 2 +- ...t_single_expanded_selected_placeholder.xml | 2 +- .../desktop/layout_single_placeholder.xml | 2 +- .../select/desktop/layout_single_selected.xml | 2 +- .../layout_single_selected_placeholder.xml | 2 +- widget/testdata/select/desktop/move_moved.xml | 2 +- .../testdata/select/desktop/move_tapped.xml | 2 +- widget/testdata/select/desktop/tapped.xml | 2 +- .../select/desktop/tapped_constrained.xml | 2 +- widget/testdata/select/desktop/trailing.xml | 2 +- .../select/focus_focused_b_selected.xml | 2 +- .../select/focus_focused_none_selected.xml | 2 +- .../select/focus_unfocused_b_selected.xml | 2 +- .../select/focus_unfocused_none_selected.xml | 2 +- widget/testdata/select/kbdctrl_a_selected.xml | 2 +- widget/testdata/select/kbdctrl_b_selected.xml | 2 +- widget/testdata/select/kbdctrl_c_selected.xml | 2 +- .../testdata/select/kbdctrl_none_selected.xml | 2 +- .../select/kbdctrl_none_selected_popup.xml | 2 +- widget/testdata/select/mobile/center.xml | 2 +- .../testdata/select/mobile/layout_empty.xml | 2 +- .../select/mobile/layout_empty_expanded.xml | 2 +- .../layout_empty_expanded_placeholder.xml | 2 +- .../mobile/layout_empty_placeholder.xml | 2 +- .../select/mobile/layout_multiple.xml | 2 +- .../mobile/layout_multiple_expanded.xml | 2 +- .../layout_multiple_expanded_placeholder.xml | 2 +- .../layout_multiple_expanded_selected.xml | 2 +- ...multiple_expanded_selected_placeholder.xml | 2 +- .../mobile/layout_multiple_placeholder.xml | 2 +- .../mobile/layout_multiple_selected.xml | 2 +- .../layout_multiple_selected_placeholder.xml | 2 +- .../testdata/select/mobile/layout_single.xml | 2 +- .../select/mobile/layout_single_expanded.xml | 2 +- .../layout_single_expanded_placeholder.xml | 2 +- .../layout_single_expanded_selected.xml | 2 +- ...t_single_expanded_selected_placeholder.xml | 2 +- .../mobile/layout_single_placeholder.xml | 2 +- .../select/mobile/layout_single_selected.xml | 2 +- .../layout_single_selected_placeholder.xml | 2 +- widget/testdata/select/mobile/move_moved.xml | 2 +- widget/testdata/select/mobile/move_tapped.xml | 2 +- widget/testdata/select/mobile/tapped.xml | 2 +- .../select/mobile/tapped_constrained.xml | 2 +- widget/testdata/select/mobile/trailing.xml | 2 +- widget/testdata/select/move_initial.xml | 2 +- .../select/set_selected_2nd_selected.xml | 2 +- .../select/set_selected_none_selected.xml | 2 +- .../select_entry/disableable_enabled.xml | 2 +- .../disableable_enabled_opened.xml | 2 +- .../disableable_enabled_tapped.xml | 2 +- .../disableable_enabled_tapped_selected.xml | 2 +- .../select_entry/dropdown_B_opened.xml | 2 +- .../select_entry/dropdown_empty_opened.xml | 2 +- .../dropdown_empty_opened_shrunk.xml | 2 +- .../select_entry/dropdown_empty_setopts.xml | 2 +- .../select_entry/dropdown_initial.xml | 2 +- .../select_entry/dropdown_tapped_B.xml | 2 +- .../select_entry/dropdown_tapped_C.xml | 2 +- widget/testdata/tree/layout_multiple.xml | 4 +- .../testdata/tree/layout_multiple_branch.xml | 4 +- .../tree/layout_multiple_branch_opened.xml | 6 +- ...t_multiple_branch_opened_leaf_selected.xml | 6 +- ...layout_multiple_branch_opened_selected.xml | 6 +- .../tree/layout_multiple_branch_selected.xml | 4 +- .../tree/layout_multiple_selected.xml | 4 +- widget/testdata/tree/layout_single_branch.xml | 2 +- .../tree/layout_single_branch_opened.xml | 2 +- ...out_single_branch_opened_leaf_selected.xml | 2 +- .../layout_single_branch_opened_selected.xml | 2 +- .../tree/layout_single_branch_selected.xml | 2 +- widget/testdata/tree/move_initial.xml | 2 +- widget/testdata/tree/move_moved.xml | 2 +- 221 files changed, 774 insertions(+), 358 deletions(-) create mode 100644 widget/testdata/popup_menu/kbd_ctrl_first_active.xml create mode 100644 widget/testdata/popup_menu/kbd_ctrl_first_sub_active.xml create mode 100644 widget/testdata/popup_menu/kbd_ctrl_first_sub_sub_active.xml create mode 100644 widget/testdata/popup_menu/kbd_ctrl_second_active.xml create mode 100644 widget/testdata/popup_menu/kbd_ctrl_second_sub_active.xml create mode 100644 widget/testdata/popup_menu/kbd_ctrl_second_sub_sub_active.xml create mode 100644 widget/testdata/popup_menu/kbd_ctrl_shown.xml diff --git a/container/testdata/apptabs/desktop/change_icon_change_selected.xml b/container/testdata/apptabs/desktop/change_icon_change_selected.xml index bce4d41e1f..244d3e7682 100644 --- a/container/testdata/apptabs/desktop/change_icon_change_selected.xml +++ b/container/testdata/apptabs/desktop/change_icon_change_selected.xml @@ -7,7 +7,7 @@ - + diff --git a/container/testdata/apptabs/desktop/change_icon_change_unselected.xml b/container/testdata/apptabs/desktop/change_icon_change_unselected.xml index 508d5b0ce2..fe745fdaf9 100644 --- a/container/testdata/apptabs/desktop/change_icon_change_unselected.xml +++ b/container/testdata/apptabs/desktop/change_icon_change_unselected.xml @@ -7,7 +7,7 @@ - + diff --git a/container/testdata/apptabs/desktop/change_icon_initial.xml b/container/testdata/apptabs/desktop/change_icon_initial.xml index dac9b30f2d..d6bf827a5f 100644 --- a/container/testdata/apptabs/desktop/change_icon_initial.xml +++ b/container/testdata/apptabs/desktop/change_icon_initial.xml @@ -7,7 +7,7 @@ - + diff --git a/container/testdata/apptabs/mobile/change_icon_change_selected.xml b/container/testdata/apptabs/mobile/change_icon_change_selected.xml index 22bf6138bb..7debe0288c 100644 --- a/container/testdata/apptabs/mobile/change_icon_change_selected.xml +++ b/container/testdata/apptabs/mobile/change_icon_change_selected.xml @@ -7,7 +7,7 @@ - + diff --git a/container/testdata/apptabs/mobile/change_icon_change_unselected.xml b/container/testdata/apptabs/mobile/change_icon_change_unselected.xml index c0f4d26cff..ddab283930 100644 --- a/container/testdata/apptabs/mobile/change_icon_change_unselected.xml +++ b/container/testdata/apptabs/mobile/change_icon_change_unselected.xml @@ -7,7 +7,7 @@ - + diff --git a/container/testdata/apptabs/mobile/change_icon_initial.xml b/container/testdata/apptabs/mobile/change_icon_initial.xml index d5c86c237f..e0eef1fd38 100644 --- a/container/testdata/apptabs/mobile/change_icon_initial.xml +++ b/container/testdata/apptabs/mobile/change_icon_initial.xml @@ -7,7 +7,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_icon_change_selected.xml b/container/testdata/doctabs/desktop/change_icon_change_selected.xml index 0d2c439233..954b37469f 100644 --- a/container/testdata/doctabs/desktop/change_icon_change_selected.xml +++ b/container/testdata/doctabs/desktop/change_icon_change_selected.xml @@ -8,7 +8,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_icon_change_unselected.xml b/container/testdata/doctabs/desktop/change_icon_change_unselected.xml index ad6f34d462..260a6167b5 100644 --- a/container/testdata/doctabs/desktop/change_icon_change_unselected.xml +++ b/container/testdata/doctabs/desktop/change_icon_change_unselected.xml @@ -8,7 +8,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_icon_initial.xml b/container/testdata/doctabs/desktop/change_icon_initial.xml index 75aa3abff5..7f21febb00 100644 --- a/container/testdata/doctabs/desktop/change_icon_initial.xml +++ b/container/testdata/doctabs/desktop/change_icon_initial.xml @@ -8,7 +8,7 @@ - + diff --git a/container/testdata/doctabs/desktop/hover_all_tabs.xml b/container/testdata/doctabs/desktop/hover_all_tabs.xml index 08fb43b54c..09d03ab7cb 100644 --- a/container/testdata/doctabs/desktop/hover_all_tabs.xml +++ b/container/testdata/doctabs/desktop/hover_all_tabs.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/hover_create_tab.xml b/container/testdata/doctabs/desktop/hover_create_tab.xml index 704ac28e4f..5d0aa1a20b 100644 --- a/container/testdata/doctabs/desktop/hover_create_tab.xml +++ b/container/testdata/doctabs/desktop/hover_create_tab.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/hover_first.xml b/container/testdata/doctabs/desktop/hover_first.xml index 7293106df9..d46710c0a1 100644 --- a/container/testdata/doctabs/desktop/hover_first.xml +++ b/container/testdata/doctabs/desktop/hover_first.xml @@ -28,7 +28,7 @@ - + diff --git a/container/testdata/doctabs/desktop/hover_first_close.xml b/container/testdata/doctabs/desktop/hover_first_close.xml index 704ac28e4f..5d0aa1a20b 100644 --- a/container/testdata/doctabs/desktop/hover_first_close.xml +++ b/container/testdata/doctabs/desktop/hover_first_close.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/hover_none.xml b/container/testdata/doctabs/desktop/hover_none.xml index cfe88da7fd..c42721d0dd 100644 --- a/container/testdata/doctabs/desktop/hover_none.xml +++ b/container/testdata/doctabs/desktop/hover_none.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/hover_second.xml b/container/testdata/doctabs/desktop/hover_second.xml index 704ac28e4f..5d0aa1a20b 100644 --- a/container/testdata/doctabs/desktop/hover_second.xml +++ b/container/testdata/doctabs/desktop/hover_second.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/tapped_all_tabs.xml b/container/testdata/doctabs/desktop/tapped_all_tabs.xml index d61863b81a..2fdcb73f26 100644 --- a/container/testdata/doctabs/desktop/tapped_all_tabs.xml +++ b/container/testdata/doctabs/desktop/tapped_all_tabs.xml @@ -30,7 +30,7 @@ - + @@ -76,7 +76,7 @@ Another - + diff --git a/container/testdata/doctabs/desktop/tapped_create_tab.xml b/container/testdata/doctabs/desktop/tapped_create_tab.xml index a06b5f7150..6a06a36b28 100644 --- a/container/testdata/doctabs/desktop/tapped_create_tab.xml +++ b/container/testdata/doctabs/desktop/tapped_create_tab.xml @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/desktop/tapped_first_selected.xml b/container/testdata/doctabs/desktop/tapped_first_selected.xml index 11ed06c08d..e0cbc3f1cb 100644 --- a/container/testdata/doctabs/desktop/tapped_first_selected.xml +++ b/container/testdata/doctabs/desktop/tapped_first_selected.xml @@ -27,7 +27,7 @@ - + diff --git a/container/testdata/doctabs/desktop/tapped_second_selected.xml b/container/testdata/doctabs/desktop/tapped_second_selected.xml index 795b8afea9..853d541d38 100644 --- a/container/testdata/doctabs/desktop/tapped_second_selected.xml +++ b/container/testdata/doctabs/desktop/tapped_second_selected.xml @@ -27,7 +27,7 @@ - + diff --git a/container/testdata/doctabs/desktop/tapped_third_selected.xml b/container/testdata/doctabs/desktop/tapped_third_selected.xml index 5907df0557..77de845142 100644 --- a/container/testdata/doctabs/desktop/tapped_third_selected.xml +++ b/container/testdata/doctabs/desktop/tapped_third_selected.xml @@ -27,7 +27,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_content_change_hidden.xml b/container/testdata/doctabs/mobile/change_content_change_hidden.xml index 60e378b2af..8a3af77aeb 100644 --- a/container/testdata/doctabs/mobile/change_content_change_hidden.xml +++ b/container/testdata/doctabs/mobile/change_content_change_hidden.xml @@ -13,7 +13,7 @@ Test2 - + diff --git a/container/testdata/doctabs/mobile/change_content_change_visible.xml b/container/testdata/doctabs/mobile/change_content_change_visible.xml index 60e378b2af..8a3af77aeb 100644 --- a/container/testdata/doctabs/mobile/change_content_change_visible.xml +++ b/container/testdata/doctabs/mobile/change_content_change_visible.xml @@ -13,7 +13,7 @@ Test2 - + diff --git a/container/testdata/doctabs/mobile/change_content_initial.xml b/container/testdata/doctabs/mobile/change_content_initial.xml index da6f48ba02..97fb993876 100644 --- a/container/testdata/doctabs/mobile/change_content_initial.xml +++ b/container/testdata/doctabs/mobile/change_content_initial.xml @@ -13,7 +13,7 @@ Test2 - + diff --git a/container/testdata/doctabs/mobile/change_icon_change_selected.xml b/container/testdata/doctabs/mobile/change_icon_change_selected.xml index 7cfc200cea..963229609a 100644 --- a/container/testdata/doctabs/mobile/change_icon_change_selected.xml +++ b/container/testdata/doctabs/mobile/change_icon_change_selected.xml @@ -12,9 +12,9 @@ - + - + diff --git a/container/testdata/doctabs/mobile/change_icon_change_unselected.xml b/container/testdata/doctabs/mobile/change_icon_change_unselected.xml index c9121c34e6..ba0ba9a260 100644 --- a/container/testdata/doctabs/mobile/change_icon_change_unselected.xml +++ b/container/testdata/doctabs/mobile/change_icon_change_unselected.xml @@ -12,9 +12,9 @@ - + - + diff --git a/container/testdata/doctabs/mobile/change_icon_initial.xml b/container/testdata/doctabs/mobile/change_icon_initial.xml index a3577b95e9..3a795a01f9 100644 --- a/container/testdata/doctabs/mobile/change_icon_initial.xml +++ b/container/testdata/doctabs/mobile/change_icon_initial.xml @@ -12,9 +12,9 @@ - + - + diff --git a/container/testdata/doctabs/mobile/change_label_change_selected.xml b/container/testdata/doctabs/mobile/change_label_change_selected.xml index e629e32ba9..30795cbd94 100644 --- a/container/testdata/doctabs/mobile/change_label_change_selected.xml +++ b/container/testdata/doctabs/mobile/change_label_change_selected.xml @@ -13,7 +13,7 @@ Test2 - + diff --git a/container/testdata/doctabs/mobile/change_label_change_unselected.xml b/container/testdata/doctabs/mobile/change_label_change_unselected.xml index c14ab0d2dc..666f0cdff5 100644 --- a/container/testdata/doctabs/mobile/change_label_change_unselected.xml +++ b/container/testdata/doctabs/mobile/change_label_change_unselected.xml @@ -13,7 +13,7 @@ New 2 - + diff --git a/container/testdata/doctabs/mobile/change_label_initial.xml b/container/testdata/doctabs/mobile/change_label_initial.xml index da6f48ba02..97fb993876 100644 --- a/container/testdata/doctabs/mobile/change_label_initial.xml +++ b/container/testdata/doctabs/mobile/change_label_initial.xml @@ -13,7 +13,7 @@ Test2 - + diff --git a/container/testdata/doctabs/mobile/dynamic_appended.xml b/container/testdata/doctabs/mobile/dynamic_appended.xml index 9bafebb114..159a9a4970 100644 --- a/container/testdata/doctabs/mobile/dynamic_appended.xml +++ b/container/testdata/doctabs/mobile/dynamic_appended.xml @@ -13,7 +13,7 @@ Test2 - + diff --git a/container/testdata/doctabs/mobile/dynamic_appended_another_three.xml b/container/testdata/doctabs/mobile/dynamic_appended_another_three.xml index 4b11853461..27a7fc17c4 100644 --- a/container/testdata/doctabs/mobile/dynamic_appended_another_three.xml +++ b/container/testdata/doctabs/mobile/dynamic_appended_another_three.xml @@ -13,19 +13,19 @@ Test3 - + Test4 - + Test5 - + diff --git a/container/testdata/doctabs/mobile/dynamic_replaced_completely.xml b/container/testdata/doctabs/mobile/dynamic_replaced_completely.xml index ef7eb3deff..08c2f8c8e1 100644 --- a/container/testdata/doctabs/mobile/dynamic_replaced_completely.xml +++ b/container/testdata/doctabs/mobile/dynamic_replaced_completely.xml @@ -13,13 +13,13 @@ Test7 - + Test8 - + diff --git a/container/testdata/doctabs/mobile/hover_none.xml b/container/testdata/doctabs/mobile/hover_none.xml index 86e4a3d402..3505dce33f 100644 --- a/container/testdata/doctabs/mobile/hover_none.xml +++ b/container/testdata/doctabs/mobile/hover_none.xml @@ -13,7 +13,7 @@ Test2 - + diff --git a/container/testdata/doctabs/mobile/tab_location_bottom.xml b/container/testdata/doctabs/mobile/tab_location_bottom.xml index 96e8233d24..0735a9fff5 100644 --- a/container/testdata/doctabs/mobile/tab_location_bottom.xml +++ b/container/testdata/doctabs/mobile/tab_location_bottom.xml @@ -13,13 +13,13 @@ Test2 - + Test3 - + diff --git a/container/testdata/doctabs/mobile/tab_location_top.xml b/container/testdata/doctabs/mobile/tab_location_top.xml index ea9e7dd63b..2b992c0383 100644 --- a/container/testdata/doctabs/mobile/tab_location_top.xml +++ b/container/testdata/doctabs/mobile/tab_location_top.xml @@ -13,13 +13,13 @@ Test2 - + Test3 - + diff --git a/container/testdata/doctabs/mobile/tapped_all_tabs.xml b/container/testdata/doctabs/mobile/tapped_all_tabs.xml index d53210e253..0664b01725 100644 --- a/container/testdata/doctabs/mobile/tapped_all_tabs.xml +++ b/container/testdata/doctabs/mobile/tapped_all_tabs.xml @@ -7,19 +7,19 @@ Test1 - + Test2 - + Test3 - + @@ -42,7 +42,7 @@ - + @@ -88,7 +88,7 @@ Another - + diff --git a/container/testdata/doctabs/mobile/tapped_create_tab.xml b/container/testdata/doctabs/mobile/tapped_create_tab.xml index 5d1e0839e5..fdb115b156 100644 --- a/container/testdata/doctabs/mobile/tapped_create_tab.xml +++ b/container/testdata/doctabs/mobile/tapped_create_tab.xml @@ -7,19 +7,19 @@ Test1 - + Test2 - + Test3 - + @@ -42,7 +42,7 @@ - + diff --git a/container/testdata/doctabs/mobile/tapped_first_selected.xml b/container/testdata/doctabs/mobile/tapped_first_selected.xml index d61f0a4656..af92adf08f 100644 --- a/container/testdata/doctabs/mobile/tapped_first_selected.xml +++ b/container/testdata/doctabs/mobile/tapped_first_selected.xml @@ -13,13 +13,13 @@ Test2 - + Test3 - + @@ -28,7 +28,7 @@ - + diff --git a/container/testdata/doctabs/mobile/tapped_second_selected.xml b/container/testdata/doctabs/mobile/tapped_second_selected.xml index d95b5392b1..058cfcc109 100644 --- a/container/testdata/doctabs/mobile/tapped_second_selected.xml +++ b/container/testdata/doctabs/mobile/tapped_second_selected.xml @@ -7,7 +7,7 @@ Test1 - + @@ -19,7 +19,7 @@ Test3 - + @@ -28,7 +28,7 @@ - + diff --git a/container/testdata/doctabs/mobile/tapped_third_selected.xml b/container/testdata/doctabs/mobile/tapped_third_selected.xml index 38e2595e0a..06a0956c9b 100644 --- a/container/testdata/doctabs/mobile/tapped_third_selected.xml +++ b/container/testdata/doctabs/mobile/tapped_third_selected.xml @@ -7,13 +7,13 @@ Test1 - + Test2 - + @@ -28,7 +28,7 @@ - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_1.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_1.xml index ddc6ebd10c..181e5a3e5e 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_1.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_1.xml @@ -56,7 +56,7 @@ Recent - + @@ -85,7 +85,7 @@ Older - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_2.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_2.xml index e531e7009a..260ea09072 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_2.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_2.xml @@ -56,7 +56,7 @@ Recent - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_1.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_1.xml index aa72779b20..223f6d3a2a 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_1.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_1.xml @@ -56,7 +56,7 @@ Recent - + @@ -85,7 +85,7 @@ Older - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_2.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_2.xml index 049ee467b8..a9ade0aa7a 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_2.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_2.xml @@ -56,7 +56,7 @@ Recent - + @@ -85,7 +85,7 @@ Older - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_left_3.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_left_3.xml index 187b9aee26..a048609e8b 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_left_3.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_left_3.xml @@ -55,7 +55,7 @@ Recent - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_right_3.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_right_3.xml index 187b9aee26..a048609e8b 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_right_3.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_right_3.xml @@ -55,7 +55,7 @@ Recent - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_1.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_1.xml index 06219b15c8..5b63c8eea9 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_1.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_1.xml @@ -56,7 +56,7 @@ Recent - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_2.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_2.xml index 6c637652f3..dc14299b84 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_2.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_2.xml @@ -56,7 +56,7 @@ Recent - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_3.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_3.xml index e531e7009a..260ea09072 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_3.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_3.xml @@ -56,7 +56,7 @@ Recent - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_1.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_1.xml index 6c637652f3..dc14299b84 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_1.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_1.xml @@ -56,7 +56,7 @@ Recent - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_2.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_2.xml index 06219b15c8..5b63c8eea9 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_2.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_2.xml @@ -56,7 +56,7 @@ Recent - + diff --git a/test/markup_renderer.go b/test/markup_renderer.go index acc91217ad..a93397dfff 100644 --- a/test/markup_renderer.go +++ b/test/markup_renderer.go @@ -3,6 +3,7 @@ package test import ( "fmt" "image/color" + "log" "reflect" "sort" "strings" @@ -131,9 +132,10 @@ func (r *markupRenderer) setResourceAttr(attrs map[string]*string, name string, return } + named := false if value := knownResource(rsc); value != "" { r.setStringAttr(attrs, name, value) - return + named = true } var variant string @@ -152,14 +154,17 @@ func (r *markupRenderer) setResourceAttr(attrs map[string]*string, name string, variant = "default" } default: + log.Println("TYPE WAS", t) r.setStringAttr(attrs, name, rsc.Name()) return } - // That’s some magic to access the private `source` field of the themed resource. - v := reflect.ValueOf(rsc).Elem().Field(0) - src := reflect.NewAt(v.Type(), unsafe.Pointer(v.UnsafeAddr())).Elem().Interface().(fyne.Resource) - r.setResourceAttr(attrs, name, src) + if !named { + // That’s some magic to access the private `source` field of the themed resource. + v := reflect.ValueOf(rsc).Elem().Field(0) + src := reflect.NewAt(v.Type(), unsafe.Pointer(v.UnsafeAddr())).Elem().Interface().(fyne.Resource) + r.setResourceAttr(attrs, name, src) + } r.setStringAttr(attrs, "themed", variant) } diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items.xml b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items.xml index 3ca18d1caa..5e4abf7d30 100644 --- a/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items_opened.xml index 086e03b7f2..9ba2616a4e 100644 --- a/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items_opened.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_one_item.xml b/widget/testdata/accordion/layout_expanded_multiple_open_one_item.xml index ad0531f594..1df3bf9d1b 100644 --- a/widget/testdata/accordion/layout_expanded_multiple_open_one_item.xml +++ b/widget/testdata/accordion/layout_expanded_multiple_open_one_item.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_one_item_opened.xml b/widget/testdata/accordion/layout_expanded_multiple_open_one_item_opened.xml index 5393d0bd7d..772a332db2 100644 --- a/widget/testdata/accordion/layout_expanded_multiple_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_expanded_multiple_open_one_item_opened.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_expanded_single_open_multiple_items.xml b/widget/testdata/accordion/layout_expanded_single_open_multiple_items.xml index 3ca18d1caa..5e4abf7d30 100644 --- a/widget/testdata/accordion/layout_expanded_single_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_expanded_single_open_multiple_items.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_expanded_single_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_expanded_single_open_multiple_items_opened.xml index 8ab4d7b294..aa999752e6 100644 --- a/widget/testdata/accordion/layout_expanded_single_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_expanded_single_open_multiple_items_opened.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_expanded_single_open_one_item.xml b/widget/testdata/accordion/layout_expanded_single_open_one_item.xml index ad0531f594..1df3bf9d1b 100644 --- a/widget/testdata/accordion/layout_expanded_single_open_one_item.xml +++ b/widget/testdata/accordion/layout_expanded_single_open_one_item.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_expanded_single_open_one_item_opened.xml b/widget/testdata/accordion/layout_expanded_single_open_one_item_opened.xml index 5393d0bd7d..772a332db2 100644 --- a/widget/testdata/accordion/layout_expanded_single_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_expanded_single_open_one_item_opened.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_multiple_open_multiple_items.xml b/widget/testdata/accordion/layout_multiple_open_multiple_items.xml index cdf9bbc0e0..ca4d8f7261 100644 --- a/widget/testdata/accordion/layout_multiple_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_multiple_open_multiple_items.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml index 876d41617d..54948cd1de 100644 --- a/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_multiple_open_one_item.xml b/widget/testdata/accordion/layout_multiple_open_one_item.xml index 8835a72d89..20ca10df55 100644 --- a/widget/testdata/accordion/layout_multiple_open_one_item.xml +++ b/widget/testdata/accordion/layout_multiple_open_one_item.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml b/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml index e2fcd4def4..e0ed3ffe4a 100644 --- a/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_single_open_multiple_items.xml b/widget/testdata/accordion/layout_single_open_multiple_items.xml index cdf9bbc0e0..ca4d8f7261 100644 --- a/widget/testdata/accordion/layout_single_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_single_open_multiple_items.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml index a6d4f151d6..68e06003cd 100644 --- a/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_single_open_one_item.xml b/widget/testdata/accordion/layout_single_open_one_item.xml index 8835a72d89..20ca10df55 100644 --- a/widget/testdata/accordion/layout_single_open_one_item.xml +++ b/widget/testdata/accordion/layout_single_open_one_item.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_single_open_one_item_opened.xml b/widget/testdata/accordion/layout_single_open_one_item_opened.xml index e2fcd4def4..e0ed3ffe4a 100644 --- a/widget/testdata/accordion/layout_single_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_single_open_one_item_opened.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/button/layout_icon_only_center_leading.xml b/widget/testdata/button/layout_icon_only_center_leading.xml index 21fb65892a..45a99778e5 100644 --- a/widget/testdata/button/layout_icon_only_center_leading.xml +++ b/widget/testdata/button/layout_icon_only_center_leading.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_icon_only_center_trailing.xml b/widget/testdata/button/layout_icon_only_center_trailing.xml index 21fb65892a..45a99778e5 100644 --- a/widget/testdata/button/layout_icon_only_center_trailing.xml +++ b/widget/testdata/button/layout_icon_only_center_trailing.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_icon_only_leading_leading.xml b/widget/testdata/button/layout_icon_only_leading_leading.xml index 2a533961a1..75f9417b42 100644 --- a/widget/testdata/button/layout_icon_only_leading_leading.xml +++ b/widget/testdata/button/layout_icon_only_leading_leading.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_icon_only_leading_trailing.xml b/widget/testdata/button/layout_icon_only_leading_trailing.xml index 2a533961a1..75f9417b42 100644 --- a/widget/testdata/button/layout_icon_only_leading_trailing.xml +++ b/widget/testdata/button/layout_icon_only_leading_trailing.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_icon_only_trailing_leading.xml b/widget/testdata/button/layout_icon_only_trailing_leading.xml index c288a884fd..6e33e34ef1 100644 --- a/widget/testdata/button/layout_icon_only_trailing_leading.xml +++ b/widget/testdata/button/layout_icon_only_trailing_leading.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_icon_only_trailing_trailing.xml b/widget/testdata/button/layout_icon_only_trailing_trailing.xml index c288a884fd..6e33e34ef1 100644 --- a/widget/testdata/button/layout_icon_only_trailing_trailing.xml +++ b/widget/testdata/button/layout_icon_only_trailing_trailing.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_text_icon_center_leading.xml b/widget/testdata/button/layout_text_icon_center_leading.xml index 47fe2c5f23..54764c84e2 100644 --- a/widget/testdata/button/layout_text_icon_center_leading.xml +++ b/widget/testdata/button/layout_text_icon_center_leading.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/button/layout_text_icon_center_trailing.xml b/widget/testdata/button/layout_text_icon_center_trailing.xml index 14a97153c7..427cda6803 100644 --- a/widget/testdata/button/layout_text_icon_center_trailing.xml +++ b/widget/testdata/button/layout_text_icon_center_trailing.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/button/layout_text_icon_leading_leading.xml b/widget/testdata/button/layout_text_icon_leading_leading.xml index 9c92ec23d0..50dfad6674 100644 --- a/widget/testdata/button/layout_text_icon_leading_leading.xml +++ b/widget/testdata/button/layout_text_icon_leading_leading.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/button/layout_text_icon_leading_trailing.xml b/widget/testdata/button/layout_text_icon_leading_trailing.xml index 1f6a482bcd..5955c9a9f3 100644 --- a/widget/testdata/button/layout_text_icon_leading_trailing.xml +++ b/widget/testdata/button/layout_text_icon_leading_trailing.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/button/layout_text_icon_trailing_leading.xml b/widget/testdata/button/layout_text_icon_trailing_leading.xml index 98004a5386..6e9994edc3 100644 --- a/widget/testdata/button/layout_text_icon_trailing_leading.xml +++ b/widget/testdata/button/layout_text_icon_trailing_leading.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/button/layout_text_icon_trailing_trailing.xml b/widget/testdata/button/layout_text_icon_trailing_trailing.xml index 293aa6c307..446168e728 100644 --- a/widget/testdata/button/layout_text_icon_trailing_trailing.xml +++ b/widget/testdata/button/layout_text_icon_trailing_trailing.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/card/layout_all_items.xml b/widget/testdata/card/layout_all_items.xml index d0c97f4543..213daa7195 100644 --- a/widget/testdata/card/layout_all_items.xml +++ b/widget/testdata/card/layout_all_items.xml @@ -13,7 +13,7 @@ Longer title subtitle with length - + diff --git a/widget/testdata/card/layout_image_content.xml b/widget/testdata/card/layout_image_content.xml index cb0efb0047..b01c834bb7 100644 --- a/widget/testdata/card/layout_image_content.xml +++ b/widget/testdata/card/layout_image_content.xml @@ -13,7 +13,7 @@ - + diff --git a/widget/testdata/card/layout_just_image.xml b/widget/testdata/card/layout_just_image.xml index 3e77789526..00bb92aeb8 100644 --- a/widget/testdata/card/layout_just_image.xml +++ b/widget/testdata/card/layout_just_image.xml @@ -13,7 +13,7 @@ - + diff --git a/widget/testdata/card/layout_titles_image.xml b/widget/testdata/card/layout_titles_image.xml index 89271f4d99..79adff3709 100644 --- a/widget/testdata/card/layout_titles_image.xml +++ b/widget/testdata/card/layout_titles_image.xml @@ -13,7 +13,7 @@ Title Subtitle - + diff --git a/widget/testdata/entry/validate_valid.xml b/widget/testdata/entry/validate_valid.xml index 8e89fa5a33..6c465354d0 100644 --- a/widget/testdata/entry/validate_valid.xml +++ b/widget/testdata/entry/validate_valid.xml @@ -10,7 +10,7 @@ - + diff --git a/widget/testdata/form/extended_entry.xml b/widget/testdata/form/extended_entry.xml index dbcf90463d..b62c28eab7 100644 --- a/widget/testdata/form/extended_entry.xml +++ b/widget/testdata/form/extended_entry.xml @@ -22,7 +22,7 @@ - + diff --git a/widget/testdata/form/layout.xml b/widget/testdata/form/layout.xml index d746027d98..85a43ce363 100644 --- a/widget/testdata/form/layout.xml +++ b/widget/testdata/form/layout.xml @@ -46,7 +46,7 @@ Cancel - + diff --git a/widget/testdata/icon/layout_resource.xml b/widget/testdata/icon/layout_resource.xml index 7b7009d9d3..161dcb833a 100644 --- a/widget/testdata/icon/layout_resource.xml +++ b/widget/testdata/icon/layout_resource.xml @@ -2,7 +2,7 @@ - + diff --git a/widget/testdata/list/initial.xml b/widget/testdata/list/initial.xml index e63c4ce515..497a5c777f 100644 --- a/widget/testdata/list/initial.xml +++ b/widget/testdata/list/initial.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -78,7 +78,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -126,7 +126,7 @@ - + diff --git a/widget/testdata/list/item_removed.xml b/widget/testdata/list/item_removed.xml index 24909e338c..19ea41c30d 100644 --- a/widget/testdata/list/item_removed.xml +++ b/widget/testdata/list/item_removed.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + diff --git a/widget/testdata/list/new_data.xml b/widget/testdata/list/new_data.xml index 2148abdc1b..dfdab99d38 100644 --- a/widget/testdata/list/new_data.xml +++ b/widget/testdata/list/new_data.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -78,7 +78,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -126,7 +126,7 @@ - + diff --git a/widget/testdata/list/offset_changed.xml b/widget/testdata/list/offset_changed.xml index aebe51c6e4..1d2f039f3a 100644 --- a/widget/testdata/list/offset_changed.xml +++ b/widget/testdata/list/offset_changed.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -78,7 +78,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -126,7 +126,7 @@ - + diff --git a/widget/testdata/list/resized.xml b/widget/testdata/list/resized.xml index 21fe8a8915..4ed8d8ec52 100644 --- a/widget/testdata/list/resized.xml +++ b/widget/testdata/list/resized.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -78,7 +78,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -126,7 +126,7 @@ - + @@ -138,7 +138,7 @@ - + @@ -150,7 +150,7 @@ - + @@ -162,7 +162,7 @@ - + @@ -174,7 +174,7 @@ - + @@ -186,7 +186,7 @@ - + diff --git a/widget/testdata/list/small.xml b/widget/testdata/list/small.xml index 24909e338c..19ea41c30d 100644 --- a/widget/testdata/list/small.xml +++ b/widget/testdata/list/small.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + diff --git a/widget/testdata/menu/desktop/layout_background_reset.xml b/widget/testdata/menu/desktop/layout_background_reset.xml index 5e4ec37666..fc0bf05e16 100644 --- a/widget/testdata/menu/desktop/layout_background_reset.xml +++ b/widget/testdata/menu/desktop/layout_background_reset.xml @@ -31,14 +31,14 @@ C - + D - + diff --git a/widget/testdata/menu/desktop/layout_no_space_on_both_sides.xml b/widget/testdata/menu/desktop/layout_no_space_on_both_sides.xml index b6e280a9e6..8fb4dad6b2 100644 --- a/widget/testdata/menu/desktop/layout_no_space_on_both_sides.xml +++ b/widget/testdata/menu/desktop/layout_no_space_on_both_sides.xml @@ -31,14 +31,14 @@ C - + D - + @@ -60,17 +60,17 @@ subitem A - + subitem B - - + + subitem C (long) - - + + diff --git a/widget/testdata/menu/desktop/layout_no_space_on_right.xml b/widget/testdata/menu/desktop/layout_no_space_on_right.xml index aecf229094..c9ed93bb8e 100644 --- a/widget/testdata/menu/desktop/layout_no_space_on_right.xml +++ b/widget/testdata/menu/desktop/layout_no_space_on_right.xml @@ -31,14 +31,14 @@ C - + D - + @@ -60,17 +60,17 @@ subitem A - + subitem B - - + + subitem C (long) - - + + diff --git a/widget/testdata/menu/desktop/layout_normal.xml b/widget/testdata/menu/desktop/layout_normal.xml index b90e21c00c..85ce7dbbce 100644 --- a/widget/testdata/menu/desktop/layout_normal.xml +++ b/widget/testdata/menu/desktop/layout_normal.xml @@ -30,14 +30,14 @@ C - + D - + diff --git a/widget/testdata/menu/desktop/layout_normal_with_submenus.xml b/widget/testdata/menu/desktop/layout_normal_with_submenus.xml index 4dc10a5e2a..e95ba62de1 100644 --- a/widget/testdata/menu/desktop/layout_normal_with_submenus.xml +++ b/widget/testdata/menu/desktop/layout_normal_with_submenus.xml @@ -31,14 +31,14 @@ C - + D - + @@ -60,17 +60,17 @@ subitem A - + subitem B - - + + subitem C (long) - - + + diff --git a/widget/testdata/menu/desktop/layout_theme_changed.xml b/widget/testdata/menu/desktop/layout_theme_changed.xml index b90e21c00c..85ce7dbbce 100644 --- a/widget/testdata/menu/desktop/layout_theme_changed.xml +++ b/widget/testdata/menu/desktop/layout_theme_changed.xml @@ -30,14 +30,14 @@ C - + D - + diff --git a/widget/testdata/menu/desktop/layout_window_too_short.xml b/widget/testdata/menu/desktop/layout_window_too_short.xml index 720e59d739..f36d68833c 100644 --- a/widget/testdata/menu/desktop/layout_window_too_short.xml +++ b/widget/testdata/menu/desktop/layout_window_too_short.xml @@ -30,14 +30,14 @@ C - + D - + diff --git a/widget/testdata/menu/desktop/layout_window_too_short_for_submenu.xml b/widget/testdata/menu/desktop/layout_window_too_short_for_submenu.xml index cea53b5227..0811d598bb 100644 --- a/widget/testdata/menu/desktop/layout_window_too_short_for_submenu.xml +++ b/widget/testdata/menu/desktop/layout_window_too_short_for_submenu.xml @@ -31,14 +31,14 @@ C - + D - + @@ -68,18 +68,18 @@ subitem A - + subitem B - - + + subitem C (long) - - + + @@ -101,7 +101,7 @@ subsubitem A (long) - + subsubitem B diff --git a/widget/testdata/menu/desktop/traverse_first_active.xml b/widget/testdata/menu/desktop/traverse_first_active.xml index c01913f44d..352d187013 100644 --- a/widget/testdata/menu/desktop/traverse_first_active.xml +++ b/widget/testdata/menu/desktop/traverse_first_active.xml @@ -25,7 +25,7 @@ Bar - + diff --git a/widget/testdata/menu/desktop/traverse_initial.xml b/widget/testdata/menu/desktop/traverse_initial.xml index 84d67eb2d5..2012f9d00c 100644 --- a/widget/testdata/menu/desktop/traverse_initial.xml +++ b/widget/testdata/menu/desktop/traverse_initial.xml @@ -24,7 +24,7 @@ Bar - + diff --git a/widget/testdata/menu/desktop/traverse_second_active.xml b/widget/testdata/menu/desktop/traverse_second_active.xml index 1a84731395..753c22ce73 100644 --- a/widget/testdata/menu/desktop/traverse_second_active.xml +++ b/widget/testdata/menu/desktop/traverse_second_active.xml @@ -25,7 +25,7 @@ Bar - + diff --git a/widget/testdata/menu/desktop/traverse_submenu_first_active.xml b/widget/testdata/menu/desktop/traverse_submenu_first_active.xml index 453f56bf49..5117b256e4 100644 --- a/widget/testdata/menu/desktop/traverse_submenu_first_active.xml +++ b/widget/testdata/menu/desktop/traverse_submenu_first_active.xml @@ -25,7 +25,7 @@ Bar - + diff --git a/widget/testdata/menu/desktop/traverse_submenu_second_active.xml b/widget/testdata/menu/desktop/traverse_submenu_second_active.xml index 28700cb6d9..613145ae57 100644 --- a/widget/testdata/menu/desktop/traverse_submenu_second_active.xml +++ b/widget/testdata/menu/desktop/traverse_submenu_second_active.xml @@ -25,7 +25,7 @@ Bar - + diff --git a/widget/testdata/menu/desktop/traverse_third_active.xml b/widget/testdata/menu/desktop/traverse_third_active.xml index 6541bdc3a7..b4566dfdcb 100644 --- a/widget/testdata/menu/desktop/traverse_third_active.xml +++ b/widget/testdata/menu/desktop/traverse_third_active.xml @@ -24,7 +24,7 @@ Bar - + diff --git a/widget/testdata/menu/mobile/layout_background_reset.xml b/widget/testdata/menu/mobile/layout_background_reset.xml index 06841c0058..047e545ef7 100644 --- a/widget/testdata/menu/mobile/layout_background_reset.xml +++ b/widget/testdata/menu/mobile/layout_background_reset.xml @@ -30,7 +30,7 @@ C - + diff --git a/widget/testdata/menu/mobile/layout_no_space_on_both_sides.xml b/widget/testdata/menu/mobile/layout_no_space_on_both_sides.xml index c2409d803d..3237155b22 100644 --- a/widget/testdata/menu/mobile/layout_no_space_on_both_sides.xml +++ b/widget/testdata/menu/mobile/layout_no_space_on_both_sides.xml @@ -30,7 +30,7 @@ C - + @@ -52,17 +52,17 @@ subitem A - + subitem B - - + + subitem C (long) - - + + diff --git a/widget/testdata/menu/mobile/layout_no_space_on_right.xml b/widget/testdata/menu/mobile/layout_no_space_on_right.xml index 4551dbfcbe..afe1eadd8d 100644 --- a/widget/testdata/menu/mobile/layout_no_space_on_right.xml +++ b/widget/testdata/menu/mobile/layout_no_space_on_right.xml @@ -30,7 +30,7 @@ C - + @@ -52,17 +52,17 @@ subitem A - + subitem B - - + + subitem C (long) - - + + diff --git a/widget/testdata/menu/mobile/layout_normal.xml b/widget/testdata/menu/mobile/layout_normal.xml index 06841c0058..047e545ef7 100644 --- a/widget/testdata/menu/mobile/layout_normal.xml +++ b/widget/testdata/menu/mobile/layout_normal.xml @@ -30,7 +30,7 @@ C - + diff --git a/widget/testdata/menu/mobile/layout_normal_with_submenus.xml b/widget/testdata/menu/mobile/layout_normal_with_submenus.xml index 63885e78ce..43dc299d2b 100644 --- a/widget/testdata/menu/mobile/layout_normal_with_submenus.xml +++ b/widget/testdata/menu/mobile/layout_normal_with_submenus.xml @@ -30,7 +30,7 @@ C - + @@ -52,17 +52,17 @@ subitem A - + subitem B - - + + subitem C (long) - - + + diff --git a/widget/testdata/menu/mobile/layout_theme_changed.xml b/widget/testdata/menu/mobile/layout_theme_changed.xml index 06841c0058..047e545ef7 100644 --- a/widget/testdata/menu/mobile/layout_theme_changed.xml +++ b/widget/testdata/menu/mobile/layout_theme_changed.xml @@ -30,7 +30,7 @@ C - + diff --git a/widget/testdata/menu/mobile/layout_window_too_short.xml b/widget/testdata/menu/mobile/layout_window_too_short.xml index 3be7223b90..f9eb349893 100644 --- a/widget/testdata/menu/mobile/layout_window_too_short.xml +++ b/widget/testdata/menu/mobile/layout_window_too_short.xml @@ -30,7 +30,7 @@ C - + diff --git a/widget/testdata/menu/mobile/layout_window_too_short_for_submenu.xml b/widget/testdata/menu/mobile/layout_window_too_short_for_submenu.xml index beed243bf1..b5ede8f8cb 100644 --- a/widget/testdata/menu/mobile/layout_window_too_short_for_submenu.xml +++ b/widget/testdata/menu/mobile/layout_window_too_short_for_submenu.xml @@ -30,7 +30,7 @@ C - + @@ -52,17 +52,17 @@ subitem A - + subitem B - - + + subitem C (long) - - + + @@ -84,7 +84,7 @@ subsubitem A (long) - + subsubitem B diff --git a/widget/testdata/menu/refresh_2nd_checkmark.xml b/widget/testdata/menu/refresh_2nd_checkmark.xml index a15aca6785..cf28a9be51 100644 --- a/widget/testdata/menu/refresh_2nd_checkmark.xml +++ b/widget/testdata/menu/refresh_2nd_checkmark.xml @@ -33,7 +33,7 @@ Baz - + diff --git a/widget/testdata/menu/refresh_checkmark.xml b/widget/testdata/menu/refresh_checkmark.xml index f1630e6b31..ac980b3fee 100644 --- a/widget/testdata/menu/refresh_checkmark.xml +++ b/widget/testdata/menu/refresh_checkmark.xml @@ -32,7 +32,7 @@ Baz - + diff --git a/widget/testdata/menu/refresh_initial.xml b/widget/testdata/menu/refresh_initial.xml index 099d852916..70b117af61 100644 --- a/widget/testdata/menu/refresh_initial.xml +++ b/widget/testdata/menu/refresh_initial.xml @@ -24,7 +24,7 @@ Bar - + diff --git a/widget/testdata/password_entry/concealed.xml b/widget/testdata/password_entry/concealed.xml index 7a338af718..cbad822380 100644 --- a/widget/testdata/password_entry/concealed.xml +++ b/widget/testdata/password_entry/concealed.xml @@ -12,7 +12,7 @@ - + diff --git a/widget/testdata/password_entry/initial.xml b/widget/testdata/password_entry/initial.xml index 91a53becaf..acabeb5427 100644 --- a/widget/testdata/password_entry/initial.xml +++ b/widget/testdata/password_entry/initial.xml @@ -14,7 +14,7 @@ - + diff --git a/widget/testdata/password_entry/obfuscation_typed.xml b/widget/testdata/password_entry/obfuscation_typed.xml index 4aeb653138..d110a01380 100644 --- a/widget/testdata/password_entry/obfuscation_typed.xml +++ b/widget/testdata/password_entry/obfuscation_typed.xml @@ -12,7 +12,7 @@ - + diff --git a/widget/testdata/password_entry/placeholder_initial.xml b/widget/testdata/password_entry/placeholder_initial.xml index e053dd68db..a6b495acb8 100644 --- a/widget/testdata/password_entry/placeholder_initial.xml +++ b/widget/testdata/password_entry/placeholder_initial.xml @@ -14,7 +14,7 @@ - + diff --git a/widget/testdata/password_entry/placeholder_typed.xml b/widget/testdata/password_entry/placeholder_typed.xml index 4aeb653138..d110a01380 100644 --- a/widget/testdata/password_entry/placeholder_typed.xml +++ b/widget/testdata/password_entry/placeholder_typed.xml @@ -12,7 +12,7 @@ - + diff --git a/widget/testdata/password_entry/revealed.xml b/widget/testdata/password_entry/revealed.xml index 84c64d07b9..41388da4e0 100644 --- a/widget/testdata/password_entry/revealed.xml +++ b/widget/testdata/password_entry/revealed.xml @@ -12,7 +12,7 @@ - + diff --git a/widget/testdata/popup_menu/kbd_ctrl_first_active.xml b/widget/testdata/popup_menu/kbd_ctrl_first_active.xml new file mode 100644 index 0000000000..a0cbddd831 --- /dev/null +++ b/widget/testdata/popup_menu/kbd_ctrl_first_active.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + + Option A + + + Option B + + + + + + + + + diff --git a/widget/testdata/popup_menu/kbd_ctrl_first_sub_active.xml b/widget/testdata/popup_menu/kbd_ctrl_first_sub_active.xml new file mode 100644 index 0000000000..d088429229 --- /dev/null +++ b/widget/testdata/popup_menu/kbd_ctrl_first_sub_active.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + Option A + + + + Option B + + + + + + + + + + + + + + + + + + + + + + + Sub Option A + + + Sub Option B + + + + + + + + + + diff --git a/widget/testdata/popup_menu/kbd_ctrl_first_sub_sub_active.xml b/widget/testdata/popup_menu/kbd_ctrl_first_sub_sub_active.xml new file mode 100644 index 0000000000..f11dd5e16f --- /dev/null +++ b/widget/testdata/popup_menu/kbd_ctrl_first_sub_sub_active.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + Option A + + + + Option B + + + + + + + + + + + + + + + + + + + + + + Sub Option A + + + + Sub Option B + + + + + + + + + + + + + + + + + + + + + + + Sub Sub Option A + + + Sub Sub Option B + + + + + + + + + + diff --git a/widget/testdata/popup_menu/kbd_ctrl_second_active.xml b/widget/testdata/popup_menu/kbd_ctrl_second_active.xml new file mode 100644 index 0000000000..ef81b77812 --- /dev/null +++ b/widget/testdata/popup_menu/kbd_ctrl_second_active.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + + + + + Option A + + + + Option B + + + + + + + + + diff --git a/widget/testdata/popup_menu/kbd_ctrl_second_sub_active.xml b/widget/testdata/popup_menu/kbd_ctrl_second_sub_active.xml new file mode 100644 index 0000000000..fe0b26f5ad --- /dev/null +++ b/widget/testdata/popup_menu/kbd_ctrl_second_sub_active.xml @@ -0,0 +1,63 @@ + + + + + + + + + + + + + + + + + + + + + + + Option A + + + + Option B + + + + + + + + + + + + + + + + + + + + + + Sub Option A + + + + Sub Option B + + + + + + + + + + diff --git a/widget/testdata/popup_menu/kbd_ctrl_second_sub_sub_active.xml b/widget/testdata/popup_menu/kbd_ctrl_second_sub_sub_active.xml new file mode 100644 index 0000000000..bb543306ca --- /dev/null +++ b/widget/testdata/popup_menu/kbd_ctrl_second_sub_sub_active.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + Option A + + + + Option B + + + + + + + + + + + + + + + + + + + + + + Sub Option A + + + + Sub Option B + + + + + + + + + + + + + + + + + + + + + + Sub Sub Option A + + + + Sub Sub Option B + + + + + + + + + + diff --git a/widget/testdata/popup_menu/kbd_ctrl_shown.xml b/widget/testdata/popup_menu/kbd_ctrl_shown.xml new file mode 100644 index 0000000000..1bdbcc9234 --- /dev/null +++ b/widget/testdata/popup_menu/kbd_ctrl_shown.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + Option A + + + Option B + + + + + + + + + diff --git a/widget/testdata/select/desktop/center.xml b/widget/testdata/select/desktop/center.xml index 8f240e15f5..854b59e44f 100644 --- a/widget/testdata/select/desktop/center.xml +++ b/widget/testdata/select/desktop/center.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_empty.xml b/widget/testdata/select/desktop/layout_empty.xml index 61cc0b0858..09ab9428f0 100644 --- a/widget/testdata/select/desktop/layout_empty.xml +++ b/widget/testdata/select/desktop/layout_empty.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_empty_expanded.xml b/widget/testdata/select/desktop/layout_empty_expanded.xml index 78ae0b49f1..4dbfaedc0b 100644 --- a/widget/testdata/select/desktop/layout_empty_expanded.xml +++ b/widget/testdata/select/desktop/layout_empty_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_empty_expanded_placeholder.xml b/widget/testdata/select/desktop/layout_empty_expanded_placeholder.xml index f0ca21f624..fd2d579b1e 100644 --- a/widget/testdata/select/desktop/layout_empty_expanded_placeholder.xml +++ b/widget/testdata/select/desktop/layout_empty_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_empty_placeholder.xml b/widget/testdata/select/desktop/layout_empty_placeholder.xml index 2c5f3f1622..745ddfd9b3 100644 --- a/widget/testdata/select/desktop/layout_empty_placeholder.xml +++ b/widget/testdata/select/desktop/layout_empty_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_multiple.xml b/widget/testdata/select/desktop/layout_multiple.xml index 61cc0b0858..09ab9428f0 100644 --- a/widget/testdata/select/desktop/layout_multiple.xml +++ b/widget/testdata/select/desktop/layout_multiple.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_multiple_expanded.xml b/widget/testdata/select/desktop/layout_multiple_expanded.xml index 6719351dd0..9c1634f119 100644 --- a/widget/testdata/select/desktop/layout_multiple_expanded.xml +++ b/widget/testdata/select/desktop/layout_multiple_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_multiple_expanded_placeholder.xml b/widget/testdata/select/desktop/layout_multiple_expanded_placeholder.xml index 45fb862e40..2d1de6ded4 100644 --- a/widget/testdata/select/desktop/layout_multiple_expanded_placeholder.xml +++ b/widget/testdata/select/desktop/layout_multiple_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_multiple_expanded_selected.xml b/widget/testdata/select/desktop/layout_multiple_expanded_selected.xml index d917846da7..3e4dadea48 100644 --- a/widget/testdata/select/desktop/layout_multiple_expanded_selected.xml +++ b/widget/testdata/select/desktop/layout_multiple_expanded_selected.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/desktop/layout_multiple_expanded_selected_placeholder.xml b/widget/testdata/select/desktop/layout_multiple_expanded_selected_placeholder.xml index ec48beb37e..8da21f0e70 100644 --- a/widget/testdata/select/desktop/layout_multiple_expanded_selected_placeholder.xml +++ b/widget/testdata/select/desktop/layout_multiple_expanded_selected_placeholder.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/desktop/layout_multiple_placeholder.xml b/widget/testdata/select/desktop/layout_multiple_placeholder.xml index 2c5f3f1622..745ddfd9b3 100644 --- a/widget/testdata/select/desktop/layout_multiple_placeholder.xml +++ b/widget/testdata/select/desktop/layout_multiple_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_multiple_selected.xml b/widget/testdata/select/desktop/layout_multiple_selected.xml index 7e96da26c2..0f7c615b58 100644 --- a/widget/testdata/select/desktop/layout_multiple_selected.xml +++ b/widget/testdata/select/desktop/layout_multiple_selected.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/desktop/layout_multiple_selected_placeholder.xml b/widget/testdata/select/desktop/layout_multiple_selected_placeholder.xml index 32d95230fb..6a8b41271c 100644 --- a/widget/testdata/select/desktop/layout_multiple_selected_placeholder.xml +++ b/widget/testdata/select/desktop/layout_multiple_selected_placeholder.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/desktop/layout_single.xml b/widget/testdata/select/desktop/layout_single.xml index 61cc0b0858..09ab9428f0 100644 --- a/widget/testdata/select/desktop/layout_single.xml +++ b/widget/testdata/select/desktop/layout_single.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_single_expanded.xml b/widget/testdata/select/desktop/layout_single_expanded.xml index f4643de528..7cec2ae56a 100644 --- a/widget/testdata/select/desktop/layout_single_expanded.xml +++ b/widget/testdata/select/desktop/layout_single_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_single_expanded_placeholder.xml b/widget/testdata/select/desktop/layout_single_expanded_placeholder.xml index 0d831fa20a..d4557bf0c0 100644 --- a/widget/testdata/select/desktop/layout_single_expanded_placeholder.xml +++ b/widget/testdata/select/desktop/layout_single_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_single_expanded_selected.xml b/widget/testdata/select/desktop/layout_single_expanded_selected.xml index 9ed9012267..411e22c4e6 100644 --- a/widget/testdata/select/desktop/layout_single_expanded_selected.xml +++ b/widget/testdata/select/desktop/layout_single_expanded_selected.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/desktop/layout_single_expanded_selected_placeholder.xml b/widget/testdata/select/desktop/layout_single_expanded_selected_placeholder.xml index 31ba1f8a95..59b355e43c 100644 --- a/widget/testdata/select/desktop/layout_single_expanded_selected_placeholder.xml +++ b/widget/testdata/select/desktop/layout_single_expanded_selected_placeholder.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/desktop/layout_single_placeholder.xml b/widget/testdata/select/desktop/layout_single_placeholder.xml index 2c5f3f1622..745ddfd9b3 100644 --- a/widget/testdata/select/desktop/layout_single_placeholder.xml +++ b/widget/testdata/select/desktop/layout_single_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_single_selected.xml b/widget/testdata/select/desktop/layout_single_selected.xml index f74568aa76..4401d5f13a 100644 --- a/widget/testdata/select/desktop/layout_single_selected.xml +++ b/widget/testdata/select/desktop/layout_single_selected.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/desktop/layout_single_selected_placeholder.xml b/widget/testdata/select/desktop/layout_single_selected_placeholder.xml index 3f6b60bb72..d3c22a298f 100644 --- a/widget/testdata/select/desktop/layout_single_selected_placeholder.xml +++ b/widget/testdata/select/desktop/layout_single_selected_placeholder.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/desktop/move_moved.xml b/widget/testdata/select/desktop/move_moved.xml index 82e60f5161..fe7a703d38 100644 --- a/widget/testdata/select/desktop/move_moved.xml +++ b/widget/testdata/select/desktop/move_moved.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/move_tapped.xml b/widget/testdata/select/desktop/move_tapped.xml index 5a574401ec..a33c8f91f1 100644 --- a/widget/testdata/select/desktop/move_tapped.xml +++ b/widget/testdata/select/desktop/move_tapped.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/tapped.xml b/widget/testdata/select/desktop/tapped.xml index 3d4884346a..8e777f040b 100644 --- a/widget/testdata/select/desktop/tapped.xml +++ b/widget/testdata/select/desktop/tapped.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/tapped_constrained.xml b/widget/testdata/select/desktop/tapped_constrained.xml index b7d4d408e9..154b3d420e 100644 --- a/widget/testdata/select/desktop/tapped_constrained.xml +++ b/widget/testdata/select/desktop/tapped_constrained.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/trailing.xml b/widget/testdata/select/desktop/trailing.xml index 594ac116f4..24e23eff65 100644 --- a/widget/testdata/select/desktop/trailing.xml +++ b/widget/testdata/select/desktop/trailing.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/focus_focused_b_selected.xml b/widget/testdata/select/focus_focused_b_selected.xml index b81b0526a5..7ddc9baf40 100644 --- a/widget/testdata/select/focus_focused_b_selected.xml +++ b/widget/testdata/select/focus_focused_b_selected.xml @@ -8,7 +8,7 @@ Option B - + diff --git a/widget/testdata/select/focus_focused_none_selected.xml b/widget/testdata/select/focus_focused_none_selected.xml index bdf5de0334..8f69eb8504 100644 --- a/widget/testdata/select/focus_focused_none_selected.xml +++ b/widget/testdata/select/focus_focused_none_selected.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/focus_unfocused_b_selected.xml b/widget/testdata/select/focus_unfocused_b_selected.xml index eb55268c86..a2036bd447 100644 --- a/widget/testdata/select/focus_unfocused_b_selected.xml +++ b/widget/testdata/select/focus_unfocused_b_selected.xml @@ -8,7 +8,7 @@ Option B - + diff --git a/widget/testdata/select/focus_unfocused_none_selected.xml b/widget/testdata/select/focus_unfocused_none_selected.xml index 002073afa9..78314b39ff 100644 --- a/widget/testdata/select/focus_unfocused_none_selected.xml +++ b/widget/testdata/select/focus_unfocused_none_selected.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/kbdctrl_a_selected.xml b/widget/testdata/select/kbdctrl_a_selected.xml index 5fd0a13c17..a2970ec1ae 100644 --- a/widget/testdata/select/kbdctrl_a_selected.xml +++ b/widget/testdata/select/kbdctrl_a_selected.xml @@ -8,7 +8,7 @@ Option A - + diff --git a/widget/testdata/select/kbdctrl_b_selected.xml b/widget/testdata/select/kbdctrl_b_selected.xml index e84c081854..28387be042 100644 --- a/widget/testdata/select/kbdctrl_b_selected.xml +++ b/widget/testdata/select/kbdctrl_b_selected.xml @@ -8,7 +8,7 @@ Option B - + diff --git a/widget/testdata/select/kbdctrl_c_selected.xml b/widget/testdata/select/kbdctrl_c_selected.xml index dc9a52d63f..f12cadb8f8 100644 --- a/widget/testdata/select/kbdctrl_c_selected.xml +++ b/widget/testdata/select/kbdctrl_c_selected.xml @@ -8,7 +8,7 @@ Option C - + diff --git a/widget/testdata/select/kbdctrl_none_selected.xml b/widget/testdata/select/kbdctrl_none_selected.xml index c42c622be5..1d8234bcef 100644 --- a/widget/testdata/select/kbdctrl_none_selected.xml +++ b/widget/testdata/select/kbdctrl_none_selected.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/kbdctrl_none_selected_popup.xml b/widget/testdata/select/kbdctrl_none_selected_popup.xml index bacff1a03e..f660211654 100644 --- a/widget/testdata/select/kbdctrl_none_selected_popup.xml +++ b/widget/testdata/select/kbdctrl_none_selected_popup.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/center.xml b/widget/testdata/select/mobile/center.xml index 196f4f8415..4f608bc9ee 100644 --- a/widget/testdata/select/mobile/center.xml +++ b/widget/testdata/select/mobile/center.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_empty.xml b/widget/testdata/select/mobile/layout_empty.xml index 61cc0b0858..09ab9428f0 100644 --- a/widget/testdata/select/mobile/layout_empty.xml +++ b/widget/testdata/select/mobile/layout_empty.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_empty_expanded.xml b/widget/testdata/select/mobile/layout_empty_expanded.xml index 065a94cedb..207009f5ef 100644 --- a/widget/testdata/select/mobile/layout_empty_expanded.xml +++ b/widget/testdata/select/mobile/layout_empty_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_empty_expanded_placeholder.xml b/widget/testdata/select/mobile/layout_empty_expanded_placeholder.xml index 32d0d64c84..62e8fbca89 100644 --- a/widget/testdata/select/mobile/layout_empty_expanded_placeholder.xml +++ b/widget/testdata/select/mobile/layout_empty_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_empty_placeholder.xml b/widget/testdata/select/mobile/layout_empty_placeholder.xml index 2c5f3f1622..745ddfd9b3 100644 --- a/widget/testdata/select/mobile/layout_empty_placeholder.xml +++ b/widget/testdata/select/mobile/layout_empty_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_multiple.xml b/widget/testdata/select/mobile/layout_multiple.xml index 61cc0b0858..09ab9428f0 100644 --- a/widget/testdata/select/mobile/layout_multiple.xml +++ b/widget/testdata/select/mobile/layout_multiple.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_multiple_expanded.xml b/widget/testdata/select/mobile/layout_multiple_expanded.xml index 456bb275b5..9f1b2c7ca0 100644 --- a/widget/testdata/select/mobile/layout_multiple_expanded.xml +++ b/widget/testdata/select/mobile/layout_multiple_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_multiple_expanded_placeholder.xml b/widget/testdata/select/mobile/layout_multiple_expanded_placeholder.xml index 9fa456cd84..4956c25b6d 100644 --- a/widget/testdata/select/mobile/layout_multiple_expanded_placeholder.xml +++ b/widget/testdata/select/mobile/layout_multiple_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_multiple_expanded_selected.xml b/widget/testdata/select/mobile/layout_multiple_expanded_selected.xml index caac8bf19b..5b7b9d64f5 100644 --- a/widget/testdata/select/mobile/layout_multiple_expanded_selected.xml +++ b/widget/testdata/select/mobile/layout_multiple_expanded_selected.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/mobile/layout_multiple_expanded_selected_placeholder.xml b/widget/testdata/select/mobile/layout_multiple_expanded_selected_placeholder.xml index 27fc48b3ae..ff4f546967 100644 --- a/widget/testdata/select/mobile/layout_multiple_expanded_selected_placeholder.xml +++ b/widget/testdata/select/mobile/layout_multiple_expanded_selected_placeholder.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/mobile/layout_multiple_placeholder.xml b/widget/testdata/select/mobile/layout_multiple_placeholder.xml index 2c5f3f1622..745ddfd9b3 100644 --- a/widget/testdata/select/mobile/layout_multiple_placeholder.xml +++ b/widget/testdata/select/mobile/layout_multiple_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_multiple_selected.xml b/widget/testdata/select/mobile/layout_multiple_selected.xml index 7e96da26c2..0f7c615b58 100644 --- a/widget/testdata/select/mobile/layout_multiple_selected.xml +++ b/widget/testdata/select/mobile/layout_multiple_selected.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/mobile/layout_multiple_selected_placeholder.xml b/widget/testdata/select/mobile/layout_multiple_selected_placeholder.xml index 32d95230fb..6a8b41271c 100644 --- a/widget/testdata/select/mobile/layout_multiple_selected_placeholder.xml +++ b/widget/testdata/select/mobile/layout_multiple_selected_placeholder.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/mobile/layout_single.xml b/widget/testdata/select/mobile/layout_single.xml index 61cc0b0858..09ab9428f0 100644 --- a/widget/testdata/select/mobile/layout_single.xml +++ b/widget/testdata/select/mobile/layout_single.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_single_expanded.xml b/widget/testdata/select/mobile/layout_single_expanded.xml index 266b1e3d28..c3e1a45341 100644 --- a/widget/testdata/select/mobile/layout_single_expanded.xml +++ b/widget/testdata/select/mobile/layout_single_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_single_expanded_placeholder.xml b/widget/testdata/select/mobile/layout_single_expanded_placeholder.xml index 3368621da8..f22c7c5823 100644 --- a/widget/testdata/select/mobile/layout_single_expanded_placeholder.xml +++ b/widget/testdata/select/mobile/layout_single_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_single_expanded_selected.xml b/widget/testdata/select/mobile/layout_single_expanded_selected.xml index 1ca5e88552..b022d4bfaa 100644 --- a/widget/testdata/select/mobile/layout_single_expanded_selected.xml +++ b/widget/testdata/select/mobile/layout_single_expanded_selected.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/mobile/layout_single_expanded_selected_placeholder.xml b/widget/testdata/select/mobile/layout_single_expanded_selected_placeholder.xml index bd2e88177d..cf239729ba 100644 --- a/widget/testdata/select/mobile/layout_single_expanded_selected_placeholder.xml +++ b/widget/testdata/select/mobile/layout_single_expanded_selected_placeholder.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/mobile/layout_single_placeholder.xml b/widget/testdata/select/mobile/layout_single_placeholder.xml index 2c5f3f1622..745ddfd9b3 100644 --- a/widget/testdata/select/mobile/layout_single_placeholder.xml +++ b/widget/testdata/select/mobile/layout_single_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_single_selected.xml b/widget/testdata/select/mobile/layout_single_selected.xml index f74568aa76..4401d5f13a 100644 --- a/widget/testdata/select/mobile/layout_single_selected.xml +++ b/widget/testdata/select/mobile/layout_single_selected.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/mobile/layout_single_selected_placeholder.xml b/widget/testdata/select/mobile/layout_single_selected_placeholder.xml index 3f6b60bb72..d3c22a298f 100644 --- a/widget/testdata/select/mobile/layout_single_selected_placeholder.xml +++ b/widget/testdata/select/mobile/layout_single_selected_placeholder.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/mobile/move_moved.xml b/widget/testdata/select/mobile/move_moved.xml index 0f020a8795..9fa98c83cf 100644 --- a/widget/testdata/select/mobile/move_moved.xml +++ b/widget/testdata/select/mobile/move_moved.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/move_tapped.xml b/widget/testdata/select/mobile/move_tapped.xml index 55554c89b2..ac9ea9aaba 100644 --- a/widget/testdata/select/mobile/move_tapped.xml +++ b/widget/testdata/select/mobile/move_tapped.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/tapped.xml b/widget/testdata/select/mobile/tapped.xml index ebe503aa11..09fa240c6e 100644 --- a/widget/testdata/select/mobile/tapped.xml +++ b/widget/testdata/select/mobile/tapped.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/tapped_constrained.xml b/widget/testdata/select/mobile/tapped_constrained.xml index b0119c5a25..7984f79f28 100644 --- a/widget/testdata/select/mobile/tapped_constrained.xml +++ b/widget/testdata/select/mobile/tapped_constrained.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/trailing.xml b/widget/testdata/select/mobile/trailing.xml index 12891bb23c..6837834ccc 100644 --- a/widget/testdata/select/mobile/trailing.xml +++ b/widget/testdata/select/mobile/trailing.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/move_initial.xml b/widget/testdata/select/move_initial.xml index 523b517793..b95d5e26ed 100644 --- a/widget/testdata/select/move_initial.xml +++ b/widget/testdata/select/move_initial.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/set_selected_2nd_selected.xml b/widget/testdata/select/set_selected_2nd_selected.xml index e59ab43a7b..1c6df774b7 100644 --- a/widget/testdata/select/set_selected_2nd_selected.xml +++ b/widget/testdata/select/set_selected_2nd_selected.xml @@ -8,7 +8,7 @@ 2 - + diff --git a/widget/testdata/select/set_selected_none_selected.xml b/widget/testdata/select/set_selected_none_selected.xml index 002073afa9..78314b39ff 100644 --- a/widget/testdata/select/set_selected_none_selected.xml +++ b/widget/testdata/select/set_selected_none_selected.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select_entry/disableable_enabled.xml b/widget/testdata/select_entry/disableable_enabled.xml index 9957cf2710..f2278867fb 100644 --- a/widget/testdata/select_entry/disableable_enabled.xml +++ b/widget/testdata/select_entry/disableable_enabled.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/disableable_enabled_opened.xml b/widget/testdata/select_entry/disableable_enabled_opened.xml index 8789b3d70e..24531a6eec 100644 --- a/widget/testdata/select_entry/disableable_enabled_opened.xml +++ b/widget/testdata/select_entry/disableable_enabled_opened.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/disableable_enabled_tapped.xml b/widget/testdata/select_entry/disableable_enabled_tapped.xml index 9957cf2710..f2278867fb 100644 --- a/widget/testdata/select_entry/disableable_enabled_tapped.xml +++ b/widget/testdata/select_entry/disableable_enabled_tapped.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/disableable_enabled_tapped_selected.xml b/widget/testdata/select_entry/disableable_enabled_tapped_selected.xml index 9957cf2710..f2278867fb 100644 --- a/widget/testdata/select_entry/disableable_enabled_tapped_selected.xml +++ b/widget/testdata/select_entry/disableable_enabled_tapped_selected.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_B_opened.xml b/widget/testdata/select_entry/dropdown_B_opened.xml index cde64de66e..26b63ea136 100644 --- a/widget/testdata/select_entry/dropdown_B_opened.xml +++ b/widget/testdata/select_entry/dropdown_B_opened.xml @@ -13,7 +13,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_empty_opened.xml b/widget/testdata/select_entry/dropdown_empty_opened.xml index 8789b3d70e..24531a6eec 100644 --- a/widget/testdata/select_entry/dropdown_empty_opened.xml +++ b/widget/testdata/select_entry/dropdown_empty_opened.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_empty_opened_shrunk.xml b/widget/testdata/select_entry/dropdown_empty_opened_shrunk.xml index ee6e28f49b..e4f22952d8 100644 --- a/widget/testdata/select_entry/dropdown_empty_opened_shrunk.xml +++ b/widget/testdata/select_entry/dropdown_empty_opened_shrunk.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_empty_setopts.xml b/widget/testdata/select_entry/dropdown_empty_setopts.xml index 8d1eddaa5c..435c36c9fc 100644 --- a/widget/testdata/select_entry/dropdown_empty_setopts.xml +++ b/widget/testdata/select_entry/dropdown_empty_setopts.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_initial.xml b/widget/testdata/select_entry/dropdown_initial.xml index 9957cf2710..f2278867fb 100644 --- a/widget/testdata/select_entry/dropdown_initial.xml +++ b/widget/testdata/select_entry/dropdown_initial.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_tapped_B.xml b/widget/testdata/select_entry/dropdown_tapped_B.xml index 1b80ad5998..ee8b585236 100644 --- a/widget/testdata/select_entry/dropdown_tapped_B.xml +++ b/widget/testdata/select_entry/dropdown_tapped_B.xml @@ -13,7 +13,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_tapped_C.xml b/widget/testdata/select_entry/dropdown_tapped_C.xml index 7ac03caf30..8b8191d13d 100644 --- a/widget/testdata/select_entry/dropdown_tapped_C.xml +++ b/widget/testdata/select_entry/dropdown_tapped_C.xml @@ -13,7 +13,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple.xml b/widget/testdata/tree/layout_multiple.xml index e639f687fb..2b135e4417 100644 --- a/widget/testdata/tree/layout_multiple.xml +++ b/widget/testdata/tree/layout_multiple.xml @@ -10,7 +10,7 @@ - + @@ -23,7 +23,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_branch.xml b/widget/testdata/tree/layout_multiple_branch.xml index 7d3920b4c5..3a0084acf2 100644 --- a/widget/testdata/tree/layout_multiple_branch.xml +++ b/widget/testdata/tree/layout_multiple_branch.xml @@ -10,7 +10,7 @@ - + @@ -23,7 +23,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_branch_opened.xml b/widget/testdata/tree/layout_multiple_branch_opened.xml index 451fafb552..ad10c20a85 100644 --- a/widget/testdata/tree/layout_multiple_branch_opened.xml +++ b/widget/testdata/tree/layout_multiple_branch_opened.xml @@ -10,7 +10,7 @@ - + @@ -33,7 +33,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_branch_opened_leaf_selected.xml b/widget/testdata/tree/layout_multiple_branch_opened_leaf_selected.xml index 2852ad1da6..761f7488e4 100644 --- a/widget/testdata/tree/layout_multiple_branch_opened_leaf_selected.xml +++ b/widget/testdata/tree/layout_multiple_branch_opened_leaf_selected.xml @@ -10,7 +10,7 @@ - + @@ -33,7 +33,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_branch_opened_selected.xml b/widget/testdata/tree/layout_multiple_branch_opened_selected.xml index 89239d41f2..dc990ce239 100644 --- a/widget/testdata/tree/layout_multiple_branch_opened_selected.xml +++ b/widget/testdata/tree/layout_multiple_branch_opened_selected.xml @@ -10,7 +10,7 @@ - + @@ -34,7 +34,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_branch_selected.xml b/widget/testdata/tree/layout_multiple_branch_selected.xml index 9bb72563ea..9b89f93a80 100644 --- a/widget/testdata/tree/layout_multiple_branch_selected.xml +++ b/widget/testdata/tree/layout_multiple_branch_selected.xml @@ -10,7 +10,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_selected.xml b/widget/testdata/tree/layout_multiple_selected.xml index 5688c3e59f..eb0e889e39 100644 --- a/widget/testdata/tree/layout_multiple_selected.xml +++ b/widget/testdata/tree/layout_multiple_selected.xml @@ -10,7 +10,7 @@ - + @@ -23,7 +23,7 @@ - + diff --git a/widget/testdata/tree/layout_single_branch.xml b/widget/testdata/tree/layout_single_branch.xml index 6a1702f49b..e66c7c1048 100644 --- a/widget/testdata/tree/layout_single_branch.xml +++ b/widget/testdata/tree/layout_single_branch.xml @@ -10,7 +10,7 @@ - + diff --git a/widget/testdata/tree/layout_single_branch_opened.xml b/widget/testdata/tree/layout_single_branch_opened.xml index 6abdf67611..9e756f4a7d 100644 --- a/widget/testdata/tree/layout_single_branch_opened.xml +++ b/widget/testdata/tree/layout_single_branch_opened.xml @@ -10,7 +10,7 @@ - + diff --git a/widget/testdata/tree/layout_single_branch_opened_leaf_selected.xml b/widget/testdata/tree/layout_single_branch_opened_leaf_selected.xml index 134f1f0cf1..cdb0787eac 100644 --- a/widget/testdata/tree/layout_single_branch_opened_leaf_selected.xml +++ b/widget/testdata/tree/layout_single_branch_opened_leaf_selected.xml @@ -10,7 +10,7 @@ - + diff --git a/widget/testdata/tree/layout_single_branch_opened_selected.xml b/widget/testdata/tree/layout_single_branch_opened_selected.xml index bf2c5812ad..e8722d6db0 100644 --- a/widget/testdata/tree/layout_single_branch_opened_selected.xml +++ b/widget/testdata/tree/layout_single_branch_opened_selected.xml @@ -11,7 +11,7 @@ - + diff --git a/widget/testdata/tree/layout_single_branch_selected.xml b/widget/testdata/tree/layout_single_branch_selected.xml index 9b3aef8dc1..4c44e41b93 100644 --- a/widget/testdata/tree/layout_single_branch_selected.xml +++ b/widget/testdata/tree/layout_single_branch_selected.xml @@ -11,7 +11,7 @@ - + diff --git a/widget/testdata/tree/move_initial.xml b/widget/testdata/tree/move_initial.xml index 4cc2079241..8757fba251 100644 --- a/widget/testdata/tree/move_initial.xml +++ b/widget/testdata/tree/move_initial.xml @@ -10,7 +10,7 @@ - + diff --git a/widget/testdata/tree/move_moved.xml b/widget/testdata/tree/move_moved.xml index 48a05b96f1..cd8f7ec686 100644 --- a/widget/testdata/tree/move_moved.xml +++ b/widget/testdata/tree/move_moved.xml @@ -10,7 +10,7 @@ - + From 7a46b4baed2aaece4e91af0b169c4a8034b22a18 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 14 Jun 2024 10:19:44 +0100 Subject: [PATCH 34/78] Remove stray space --- canvas/image.go | 1 - 1 file changed, 1 deletion(-) diff --git a/canvas/image.go b/canvas/image.go index 4e02f788ee..f4d512c849 100644 --- a/canvas/image.go +++ b/canvas/image.go @@ -272,7 +272,6 @@ func (i *Image) updateReader() (io.ReadCloser, error) { i.isSVG = svg.IsResourceSVG(i.Resource) content := i.Resource.Content() if res, ok := i.Resource.(fyne.ThemedResource); i.isSVG && ok { - th := cache.WidgetTheme(i) if th != nil { col := th.Color(res.ThemeColorName(), fyne.CurrentApp().Settings().ThemeVariant()) From 1039bfd9472344ee1481cc2a9bbb2c60173bc127 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 14 Jun 2024 10:28:21 +0100 Subject: [PATCH 35/78] use foreground not default as fallback --- .../desktop/change_icon_change_selected.xml | 2 +- .../desktop/change_icon_change_unselected.xml | 2 +- .../apptabs/desktop/change_icon_initial.xml | 2 +- .../apptabs/desktop/hover_overflow.xml | 2 +- .../apptabs/desktop/tab_location_bottom.xml | 2 +- .../apptabs/desktop/tab_location_leading.xml | 2 +- .../apptabs/desktop/tab_location_top.xml | 2 +- .../apptabs/desktop/tab_location_trailing.xml | 2 +- .../apptabs/desktop/tapped_overflow_tabs.xml | 2 +- .../mobile/change_icon_change_selected.xml | 2 +- .../mobile/change_icon_change_unselected.xml | 2 +- .../apptabs/mobile/change_icon_initial.xml | 2 +- .../apptabs/mobile/tab_location_bottom.xml | 2 +- .../apptabs/mobile/tab_location_top.xml | 2 +- .../desktop/change_content_change_hidden.xml | 2 +- .../desktop/change_content_change_visible.xml | 2 +- .../desktop/change_content_initial.xml | 2 +- .../desktop/change_icon_change_selected.xml | 4 +-- .../desktop/change_icon_change_unselected.xml | 4 +-- .../doctabs/desktop/change_icon_initial.xml | 4 +-- .../desktop/change_label_change_selected.xml | 2 +- .../change_label_change_unselected.xml | 2 +- .../doctabs/desktop/change_label_initial.xml | 2 +- .../change_label_to_longer_text_selected.xml | 2 +- .../doctabs/desktop/dynamic_appended.xml | 2 +- .../desktop/dynamic_appended_and_removed.xml | 2 +- .../dynamic_appended_another_three.xml | 2 +- .../doctabs/desktop/dynamic_initial.xml | 2 +- .../desktop/dynamic_replaced_completely.xml | 2 +- .../doctabs/desktop/hover_all_tabs.xml | 4 +-- .../doctabs/desktop/hover_create_tab.xml | 4 +-- .../testdata/doctabs/desktop/hover_first.xml | 4 +-- .../doctabs/desktop/hover_first_close.xml | 4 +-- .../testdata/doctabs/desktop/hover_none.xml | 4 +-- .../testdata/doctabs/desktop/hover_second.xml | 4 +-- .../doctabs/desktop/layout_bottom_icon.xml | 2 +- .../desktop/layout_bottom_icon_and_text.xml | 2 +- .../doctabs/desktop/layout_bottom_text.xml | 2 +- .../doctabs/desktop/layout_leading_icon.xml | 2 +- .../desktop/layout_leading_icon_and_text.xml | 2 +- .../doctabs/desktop/layout_leading_text.xml | 2 +- .../doctabs/desktop/layout_top_icon.xml | 2 +- .../desktop/layout_top_icon_and_text.xml | 2 +- .../doctabs/desktop/layout_top_text.xml | 2 +- .../doctabs/desktop/layout_trailing_icon.xml | 2 +- .../desktop/layout_trailing_icon_and_text.xml | 2 +- .../doctabs/desktop/layout_trailing_text.xml | 2 +- .../doctabs/desktop/tab_location_bottom.xml | 2 +- .../doctabs/desktop/tab_location_leading.xml | 2 +- .../doctabs/desktop/tab_location_top.xml | 2 +- .../doctabs/desktop/tab_location_trailing.xml | 2 +- .../doctabs/desktop/tapped_all_tabs.xml | 6 ++-- .../doctabs/desktop/tapped_create_tab.xml | 4 +-- .../doctabs/desktop/tapped_first_selected.xml | 4 +-- .../desktop/tapped_second_selected.xml | 4 +-- .../doctabs/desktop/tapped_third_selected.xml | 4 +-- .../mobile/change_content_change_hidden.xml | 4 +-- .../mobile/change_content_change_visible.xml | 4 +-- .../doctabs/mobile/change_content_initial.xml | 4 +-- .../mobile/change_icon_change_selected.xml | 6 ++-- .../mobile/change_icon_change_unselected.xml | 6 ++-- .../doctabs/mobile/change_icon_initial.xml | 6 ++-- .../mobile/change_label_change_selected.xml | 4 +-- .../mobile/change_label_change_unselected.xml | 4 +-- .../doctabs/mobile/change_label_initial.xml | 4 +-- .../doctabs/mobile/dynamic_appended.xml | 4 +-- .../mobile/dynamic_appended_and_removed.xml | 2 +- .../mobile/dynamic_appended_another_three.xml | 8 ++--- .../doctabs/mobile/dynamic_initial.xml | 2 +- .../mobile/dynamic_replaced_completely.xml | 6 ++-- .../testdata/doctabs/mobile/hover_none.xml | 4 +-- .../doctabs/mobile/layout_bottom_ico.xml | 2 +- .../mobile/layout_bottom_icon_and_text.xml | 2 +- .../doctabs/mobile/layout_bottom_text.xml | 2 +- .../doctabs/mobile/layout_top_icon.xml | 2 +- .../mobile/layout_top_icon_and_text.xml | 2 +- .../doctabs/mobile/layout_top_text.xml | 2 +- .../doctabs/mobile/tab_location_bottom.xml | 6 ++-- .../doctabs/mobile/tab_location_top.xml | 6 ++-- .../doctabs/mobile/tapped_all_tabs.xml | 12 +++---- .../doctabs/mobile/tapped_create_tab.xml | 10 +++--- .../doctabs/mobile/tapped_first_selected.xml | 8 ++--- .../doctabs/mobile/tapped_second_selected.xml | 8 ++--- .../doctabs/mobile/tapped_third_selected.xml | 8 ++--- .../menu_bar_kbdctrl_close_submenu_1.xml | 4 +-- .../menu_bar_kbdctrl_close_submenu_2.xml | 2 +- .../menu_bar_kbdctrl_open_submenu_1.xml | 4 +-- .../menu_bar_kbdctrl_open_submenu_2.xml | 4 +-- ...kbdctrl_traverse_menu_bar_items_left_3.xml | 2 +- ...bdctrl_traverse_menu_bar_items_right_3.xml | 2 +- .../menu_bar_kbdctrl_traverse_menu_down_1.xml | 2 +- .../menu_bar_kbdctrl_traverse_menu_down_2.xml | 2 +- .../menu_bar_kbdctrl_traverse_menu_down_3.xml | 2 +- .../menu_bar_kbdctrl_traverse_menu_up_1.xml | 2 +- .../menu_bar_kbdctrl_traverse_menu_up_2.xml | 2 +- test/markup_renderer.go | 4 +-- ..._expanded_multiple_open_multiple_items.xml | 4 +-- ...ed_multiple_open_multiple_items_opened.xml | 4 +-- ...layout_expanded_multiple_open_one_item.xml | 2 +- ...expanded_multiple_open_one_item_opened.xml | 2 +- ...ut_expanded_single_open_multiple_items.xml | 4 +-- ...nded_single_open_multiple_items_opened.xml | 4 +-- .../layout_expanded_single_open_one_item.xml | 2 +- ...t_expanded_single_open_one_item_opened.xml | 2 +- .../layout_multiple_open_multiple_items.xml | 4 +-- ...ut_multiple_open_multiple_items_opened.xml | 4 +-- .../layout_multiple_open_one_item.xml | 2 +- .../layout_multiple_open_one_item_opened.xml | 2 +- .../layout_single_open_multiple_items.xml | 4 +-- ...yout_single_open_multiple_items_opened.xml | 4 +-- .../accordion/layout_single_open_one_item.xml | 2 +- .../layout_single_open_one_item_opened.xml | 2 +- .../layout_icon_only_center_leading.xml | 2 +- .../layout_icon_only_center_trailing.xml | 2 +- .../layout_icon_only_leading_leading.xml | 2 +- .../layout_icon_only_leading_trailing.xml | 2 +- .../layout_icon_only_trailing_leading.xml | 2 +- .../layout_icon_only_trailing_trailing.xml | 2 +- .../layout_text_icon_center_leading.xml | 2 +- .../layout_text_icon_center_trailing.xml | 2 +- .../layout_text_icon_leading_leading.xml | 2 +- .../layout_text_icon_leading_trailing.xml | 2 +- .../layout_text_icon_trailing_leading.xml | 2 +- .../layout_text_icon_trailing_trailing.xml | 2 +- widget/testdata/card/layout_all_items.xml | 2 +- widget/testdata/card/layout_image_content.xml | 2 +- widget/testdata/card/layout_just_image.xml | 2 +- widget/testdata/card/layout_titles_image.xml | 2 +- widget/testdata/entry/validate_valid.xml | 2 +- widget/testdata/form/extended_entry.xml | 2 +- widget/testdata/form/layout.xml | 2 +- widget/testdata/icon/layout_resource.xml | 2 +- widget/testdata/list/initial.xml | 22 ++++++------- widget/testdata/list/item_removed.xml | 4 +-- widget/testdata/list/new_data.xml | 22 ++++++------- widget/testdata/list/offset_changed.xml | 22 ++++++------- widget/testdata/list/resized.xml | 32 +++++++++---------- widget/testdata/list/small.xml | 4 +-- .../menu/desktop/layout_background_reset.xml | 4 +-- .../desktop/layout_no_space_on_both_sides.xml | 14 ++++---- .../menu/desktop/layout_no_space_on_right.xml | 14 ++++---- .../testdata/menu/desktop/layout_normal.xml | 4 +-- .../desktop/layout_normal_with_submenus.xml | 14 ++++---- .../menu/desktop/layout_theme_changed.xml | 4 +-- .../menu/desktop/layout_window_too_short.xml | 4 +-- .../layout_window_too_short_for_submenu.xml | 16 +++++----- .../menu/desktop/traverse_first_active.xml | 2 +- .../menu/desktop/traverse_initial.xml | 2 +- .../menu/desktop/traverse_second_active.xml | 2 +- .../desktop/traverse_submenu_first_active.xml | 2 +- .../traverse_submenu_second_active.xml | 2 +- .../menu/desktop/traverse_third_active.xml | 2 +- .../menu/mobile/layout_background_reset.xml | 2 +- .../mobile/layout_no_space_on_both_sides.xml | 12 +++---- .../menu/mobile/layout_no_space_on_right.xml | 12 +++---- widget/testdata/menu/mobile/layout_normal.xml | 2 +- .../mobile/layout_normal_with_submenus.xml | 12 +++---- .../menu/mobile/layout_theme_changed.xml | 2 +- .../menu/mobile/layout_window_too_short.xml | 2 +- .../layout_window_too_short_for_submenu.xml | 14 ++++---- .../testdata/menu/refresh_2nd_checkmark.xml | 2 +- widget/testdata/menu/refresh_checkmark.xml | 2 +- widget/testdata/menu/refresh_initial.xml | 4 +-- widget/testdata/password_entry/concealed.xml | 2 +- widget/testdata/password_entry/initial.xml | 2 +- .../password_entry/obfuscation_typed.xml | 2 +- .../password_entry/placeholder_initial.xml | 2 +- .../password_entry/placeholder_typed.xml | 2 +- widget/testdata/password_entry/revealed.xml | 2 +- .../desktop/kbd_ctrl_first_active.xml | 2 +- .../desktop/kbd_ctrl_first_sub_active.xml | 4 +-- .../desktop/kbd_ctrl_first_sub_sub_active.xml | 4 +-- .../desktop/kbd_ctrl_second_active.xml | 2 +- .../desktop/kbd_ctrl_second_sub_active.xml | 4 +-- .../kbd_ctrl_second_sub_sub_active.xml | 4 +-- .../popup_menu/desktop/kbd_ctrl_shown.xml | 2 +- widget/testdata/select/desktop/center.xml | 2 +- .../testdata/select/desktop/layout_empty.xml | 2 +- .../select/desktop/layout_empty_expanded.xml | 2 +- .../layout_empty_expanded_placeholder.xml | 2 +- .../desktop/layout_empty_placeholder.xml | 2 +- .../select/desktop/layout_multiple.xml | 2 +- .../desktop/layout_multiple_expanded.xml | 2 +- .../layout_multiple_expanded_placeholder.xml | 2 +- .../layout_multiple_expanded_selected.xml | 2 +- ...multiple_expanded_selected_placeholder.xml | 2 +- .../desktop/layout_multiple_placeholder.xml | 2 +- .../desktop/layout_multiple_selected.xml | 2 +- .../layout_multiple_selected_placeholder.xml | 2 +- .../testdata/select/desktop/layout_single.xml | 2 +- .../select/desktop/layout_single_expanded.xml | 2 +- .../layout_single_expanded_placeholder.xml | 2 +- .../layout_single_expanded_selected.xml | 2 +- ...t_single_expanded_selected_placeholder.xml | 2 +- .../desktop/layout_single_placeholder.xml | 2 +- .../select/desktop/layout_single_selected.xml | 2 +- .../layout_single_selected_placeholder.xml | 2 +- widget/testdata/select/desktop/move_moved.xml | 2 +- .../testdata/select/desktop/move_tapped.xml | 2 +- widget/testdata/select/desktop/tapped.xml | 2 +- .../select/desktop/tapped_constrained.xml | 2 +- widget/testdata/select/desktop/trailing.xml | 2 +- .../select/focus_focused_b_selected.xml | 2 +- .../select/focus_focused_none_selected.xml | 2 +- .../select/focus_unfocused_b_selected.xml | 2 +- .../select/focus_unfocused_none_selected.xml | 2 +- widget/testdata/select/kbdctrl_a_selected.xml | 2 +- widget/testdata/select/kbdctrl_b_selected.xml | 2 +- widget/testdata/select/kbdctrl_c_selected.xml | 2 +- .../testdata/select/kbdctrl_none_selected.xml | 2 +- .../select/kbdctrl_none_selected_popup.xml | 2 +- widget/testdata/select/mobile/center.xml | 2 +- .../testdata/select/mobile/layout_empty.xml | 2 +- .../select/mobile/layout_empty_expanded.xml | 2 +- .../layout_empty_expanded_placeholder.xml | 2 +- .../mobile/layout_empty_placeholder.xml | 2 +- .../select/mobile/layout_multiple.xml | 2 +- .../mobile/layout_multiple_expanded.xml | 2 +- .../layout_multiple_expanded_placeholder.xml | 2 +- .../layout_multiple_expanded_selected.xml | 2 +- ...multiple_expanded_selected_placeholder.xml | 2 +- .../mobile/layout_multiple_placeholder.xml | 2 +- .../mobile/layout_multiple_selected.xml | 2 +- .../layout_multiple_selected_placeholder.xml | 2 +- .../testdata/select/mobile/layout_single.xml | 2 +- .../select/mobile/layout_single_expanded.xml | 2 +- .../layout_single_expanded_placeholder.xml | 2 +- .../layout_single_expanded_selected.xml | 2 +- ...t_single_expanded_selected_placeholder.xml | 2 +- .../mobile/layout_single_placeholder.xml | 2 +- .../select/mobile/layout_single_selected.xml | 2 +- .../layout_single_selected_placeholder.xml | 2 +- widget/testdata/select/mobile/move_moved.xml | 2 +- widget/testdata/select/mobile/move_tapped.xml | 2 +- widget/testdata/select/mobile/tapped.xml | 2 +- .../select/mobile/tapped_constrained.xml | 2 +- widget/testdata/select/mobile/trailing.xml | 2 +- widget/testdata/select/move_initial.xml | 2 +- .../select/set_selected_2nd_selected.xml | 2 +- .../select/set_selected_none_selected.xml | 2 +- .../select_entry/disableable_enabled.xml | 2 +- .../disableable_enabled_opened.xml | 2 +- .../disableable_enabled_tapped.xml | 2 +- .../disableable_enabled_tapped_selected.xml | 2 +- .../select_entry/dropdown_B_opened.xml | 2 +- .../select_entry/dropdown_empty_opened.xml | 2 +- .../dropdown_empty_opened_shrunk.xml | 2 +- .../select_entry/dropdown_empty_setopts.xml | 2 +- .../select_entry/dropdown_initial.xml | 2 +- .../select_entry/dropdown_tapped_B.xml | 2 +- .../select_entry/dropdown_tapped_C.xml | 2 +- widget/testdata/tree/layout_multiple.xml | 4 +-- .../testdata/tree/layout_multiple_branch.xml | 4 +-- .../tree/layout_multiple_branch_opened.xml | 6 ++-- ...t_multiple_branch_opened_leaf_selected.xml | 6 ++-- ...layout_multiple_branch_opened_selected.xml | 6 ++-- .../tree/layout_multiple_branch_selected.xml | 4 +-- .../tree/layout_multiple_selected.xml | 4 +-- widget/testdata/tree/layout_single_branch.xml | 2 +- .../tree/layout_single_branch_opened.xml | 2 +- ...out_single_branch_opened_leaf_selected.xml | 2 +- .../layout_single_branch_opened_selected.xml | 2 +- .../tree/layout_single_branch_selected.xml | 2 +- widget/testdata/tree/move_initial.xml | 2 +- widget/testdata/tree/move_moved.xml | 2 +- 265 files changed, 444 insertions(+), 446 deletions(-) diff --git a/container/testdata/apptabs/desktop/change_icon_change_selected.xml b/container/testdata/apptabs/desktop/change_icon_change_selected.xml index 244d3e7682..809f31f8b2 100644 --- a/container/testdata/apptabs/desktop/change_icon_change_selected.xml +++ b/container/testdata/apptabs/desktop/change_icon_change_selected.xml @@ -7,7 +7,7 @@ - + diff --git a/container/testdata/apptabs/desktop/change_icon_change_unselected.xml b/container/testdata/apptabs/desktop/change_icon_change_unselected.xml index fe745fdaf9..b3e2bf2b41 100644 --- a/container/testdata/apptabs/desktop/change_icon_change_unselected.xml +++ b/container/testdata/apptabs/desktop/change_icon_change_unselected.xml @@ -7,7 +7,7 @@ - + diff --git a/container/testdata/apptabs/desktop/change_icon_initial.xml b/container/testdata/apptabs/desktop/change_icon_initial.xml index d6bf827a5f..e2314b8cb7 100644 --- a/container/testdata/apptabs/desktop/change_icon_initial.xml +++ b/container/testdata/apptabs/desktop/change_icon_initial.xml @@ -7,7 +7,7 @@ - + diff --git a/container/testdata/apptabs/desktop/hover_overflow.xml b/container/testdata/apptabs/desktop/hover_overflow.xml index c7624381c9..89865fcffc 100644 --- a/container/testdata/apptabs/desktop/hover_overflow.xml +++ b/container/testdata/apptabs/desktop/hover_overflow.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/apptabs/desktop/tab_location_bottom.xml b/container/testdata/apptabs/desktop/tab_location_bottom.xml index 395ba77385..28ef841355 100644 --- a/container/testdata/apptabs/desktop/tab_location_bottom.xml +++ b/container/testdata/apptabs/desktop/tab_location_bottom.xml @@ -10,7 +10,7 @@ - + diff --git a/container/testdata/apptabs/desktop/tab_location_leading.xml b/container/testdata/apptabs/desktop/tab_location_leading.xml index f9d4411cd9..3929f7e8a7 100644 --- a/container/testdata/apptabs/desktop/tab_location_leading.xml +++ b/container/testdata/apptabs/desktop/tab_location_leading.xml @@ -10,7 +10,7 @@ - + diff --git a/container/testdata/apptabs/desktop/tab_location_top.xml b/container/testdata/apptabs/desktop/tab_location_top.xml index a8e51a7f0f..0770b32445 100644 --- a/container/testdata/apptabs/desktop/tab_location_top.xml +++ b/container/testdata/apptabs/desktop/tab_location_top.xml @@ -10,7 +10,7 @@ - + diff --git a/container/testdata/apptabs/desktop/tab_location_trailing.xml b/container/testdata/apptabs/desktop/tab_location_trailing.xml index 6d43df830b..21bca15141 100644 --- a/container/testdata/apptabs/desktop/tab_location_trailing.xml +++ b/container/testdata/apptabs/desktop/tab_location_trailing.xml @@ -10,7 +10,7 @@ - + diff --git a/container/testdata/apptabs/desktop/tapped_overflow_tabs.xml b/container/testdata/apptabs/desktop/tapped_overflow_tabs.xml index 25df2f2fda..72ad2b4349 100644 --- a/container/testdata/apptabs/desktop/tapped_overflow_tabs.xml +++ b/container/testdata/apptabs/desktop/tapped_overflow_tabs.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/apptabs/mobile/change_icon_change_selected.xml b/container/testdata/apptabs/mobile/change_icon_change_selected.xml index 7debe0288c..8d3c2d95f5 100644 --- a/container/testdata/apptabs/mobile/change_icon_change_selected.xml +++ b/container/testdata/apptabs/mobile/change_icon_change_selected.xml @@ -7,7 +7,7 @@ - + diff --git a/container/testdata/apptabs/mobile/change_icon_change_unselected.xml b/container/testdata/apptabs/mobile/change_icon_change_unselected.xml index ddab283930..fdb7fabb40 100644 --- a/container/testdata/apptabs/mobile/change_icon_change_unselected.xml +++ b/container/testdata/apptabs/mobile/change_icon_change_unselected.xml @@ -7,7 +7,7 @@ - + diff --git a/container/testdata/apptabs/mobile/change_icon_initial.xml b/container/testdata/apptabs/mobile/change_icon_initial.xml index e0eef1fd38..cdb284c656 100644 --- a/container/testdata/apptabs/mobile/change_icon_initial.xml +++ b/container/testdata/apptabs/mobile/change_icon_initial.xml @@ -7,7 +7,7 @@ - + diff --git a/container/testdata/apptabs/mobile/tab_location_bottom.xml b/container/testdata/apptabs/mobile/tab_location_bottom.xml index 3ba0242c6a..f498c34598 100644 --- a/container/testdata/apptabs/mobile/tab_location_bottom.xml +++ b/container/testdata/apptabs/mobile/tab_location_bottom.xml @@ -10,7 +10,7 @@ - + diff --git a/container/testdata/apptabs/mobile/tab_location_top.xml b/container/testdata/apptabs/mobile/tab_location_top.xml index 5bf14d9e27..06fd981143 100644 --- a/container/testdata/apptabs/mobile/tab_location_top.xml +++ b/container/testdata/apptabs/mobile/tab_location_top.xml @@ -10,7 +10,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_content_change_hidden.xml b/container/testdata/doctabs/desktop/change_content_change_hidden.xml index 28f8cbc0a7..1e849c52d6 100644 --- a/container/testdata/doctabs/desktop/change_content_change_hidden.xml +++ b/container/testdata/doctabs/desktop/change_content_change_hidden.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_content_change_visible.xml b/container/testdata/doctabs/desktop/change_content_change_visible.xml index 28f8cbc0a7..1e849c52d6 100644 --- a/container/testdata/doctabs/desktop/change_content_change_visible.xml +++ b/container/testdata/doctabs/desktop/change_content_change_visible.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_content_initial.xml b/container/testdata/doctabs/desktop/change_content_initial.xml index ffe3d57aec..41a5080b17 100644 --- a/container/testdata/doctabs/desktop/change_content_initial.xml +++ b/container/testdata/doctabs/desktop/change_content_initial.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_icon_change_selected.xml b/container/testdata/doctabs/desktop/change_icon_change_selected.xml index 954b37469f..1a06ef8d0f 100644 --- a/container/testdata/doctabs/desktop/change_icon_change_selected.xml +++ b/container/testdata/doctabs/desktop/change_icon_change_selected.xml @@ -8,7 +8,7 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_icon_change_unselected.xml b/container/testdata/doctabs/desktop/change_icon_change_unselected.xml index 260a6167b5..93302e3bc1 100644 --- a/container/testdata/doctabs/desktop/change_icon_change_unselected.xml +++ b/container/testdata/doctabs/desktop/change_icon_change_unselected.xml @@ -8,7 +8,7 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_icon_initial.xml b/container/testdata/doctabs/desktop/change_icon_initial.xml index 7f21febb00..d637f4bbdc 100644 --- a/container/testdata/doctabs/desktop/change_icon_initial.xml +++ b/container/testdata/doctabs/desktop/change_icon_initial.xml @@ -8,7 +8,7 @@ - + @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_label_change_selected.xml b/container/testdata/doctabs/desktop/change_label_change_selected.xml index ec83020480..b6dad30414 100644 --- a/container/testdata/doctabs/desktop/change_label_change_selected.xml +++ b/container/testdata/doctabs/desktop/change_label_change_selected.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_label_change_unselected.xml b/container/testdata/doctabs/desktop/change_label_change_unselected.xml index 54d7b38348..4e02a2dc1b 100644 --- a/container/testdata/doctabs/desktop/change_label_change_unselected.xml +++ b/container/testdata/doctabs/desktop/change_label_change_unselected.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_label_initial.xml b/container/testdata/doctabs/desktop/change_label_initial.xml index ffe3d57aec..41a5080b17 100644 --- a/container/testdata/doctabs/desktop/change_label_initial.xml +++ b/container/testdata/doctabs/desktop/change_label_initial.xml @@ -24,7 +24,7 @@ - + diff --git a/container/testdata/doctabs/desktop/change_label_to_longer_text_selected.xml b/container/testdata/doctabs/desktop/change_label_to_longer_text_selected.xml index ce5c7405ea..8c7d991fb7 100644 --- a/container/testdata/doctabs/desktop/change_label_to_longer_text_selected.xml +++ b/container/testdata/doctabs/desktop/change_label_to_longer_text_selected.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/desktop/dynamic_appended.xml b/container/testdata/doctabs/desktop/dynamic_appended.xml index 7c7004c811..cc2356a973 100644 --- a/container/testdata/doctabs/desktop/dynamic_appended.xml +++ b/container/testdata/doctabs/desktop/dynamic_appended.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/desktop/dynamic_appended_and_removed.xml b/container/testdata/doctabs/desktop/dynamic_appended_and_removed.xml index 36a45a3fe0..78840555f3 100644 --- a/container/testdata/doctabs/desktop/dynamic_appended_and_removed.xml +++ b/container/testdata/doctabs/desktop/dynamic_appended_and_removed.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/dynamic_appended_another_three.xml b/container/testdata/doctabs/desktop/dynamic_appended_another_three.xml index 50a8a6ac6e..ada2da3ad9 100644 --- a/container/testdata/doctabs/desktop/dynamic_appended_another_three.xml +++ b/container/testdata/doctabs/desktop/dynamic_appended_another_three.xml @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/desktop/dynamic_initial.xml b/container/testdata/doctabs/desktop/dynamic_initial.xml index b780bb6baa..0a4e4d8293 100644 --- a/container/testdata/doctabs/desktop/dynamic_initial.xml +++ b/container/testdata/doctabs/desktop/dynamic_initial.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/dynamic_replaced_completely.xml b/container/testdata/doctabs/desktop/dynamic_replaced_completely.xml index 5256e51ab6..b67be65511 100644 --- a/container/testdata/doctabs/desktop/dynamic_replaced_completely.xml +++ b/container/testdata/doctabs/desktop/dynamic_replaced_completely.xml @@ -19,7 +19,7 @@ - + diff --git a/container/testdata/doctabs/desktop/hover_all_tabs.xml b/container/testdata/doctabs/desktop/hover_all_tabs.xml index 09d03ab7cb..2001342dbb 100644 --- a/container/testdata/doctabs/desktop/hover_all_tabs.xml +++ b/container/testdata/doctabs/desktop/hover_all_tabs.xml @@ -24,12 +24,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/hover_create_tab.xml b/container/testdata/doctabs/desktop/hover_create_tab.xml index 5d0aa1a20b..a1519dad3b 100644 --- a/container/testdata/doctabs/desktop/hover_create_tab.xml +++ b/container/testdata/doctabs/desktop/hover_create_tab.xml @@ -24,12 +24,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/hover_first.xml b/container/testdata/doctabs/desktop/hover_first.xml index d46710c0a1..c667b672bf 100644 --- a/container/testdata/doctabs/desktop/hover_first.xml +++ b/container/testdata/doctabs/desktop/hover_first.xml @@ -28,12 +28,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/hover_first_close.xml b/container/testdata/doctabs/desktop/hover_first_close.xml index 5d0aa1a20b..a1519dad3b 100644 --- a/container/testdata/doctabs/desktop/hover_first_close.xml +++ b/container/testdata/doctabs/desktop/hover_first_close.xml @@ -24,12 +24,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/hover_none.xml b/container/testdata/doctabs/desktop/hover_none.xml index c42721d0dd..dac234c75b 100644 --- a/container/testdata/doctabs/desktop/hover_none.xml +++ b/container/testdata/doctabs/desktop/hover_none.xml @@ -24,12 +24,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/hover_second.xml b/container/testdata/doctabs/desktop/hover_second.xml index 5d0aa1a20b..a1519dad3b 100644 --- a/container/testdata/doctabs/desktop/hover_second.xml +++ b/container/testdata/doctabs/desktop/hover_second.xml @@ -24,12 +24,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/layout_bottom_icon.xml b/container/testdata/doctabs/desktop/layout_bottom_icon.xml index df477efb78..50959caa51 100644 --- a/container/testdata/doctabs/desktop/layout_bottom_icon.xml +++ b/container/testdata/doctabs/desktop/layout_bottom_icon.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_bottom_icon_and_text.xml b/container/testdata/doctabs/desktop/layout_bottom_icon_and_text.xml index b7582a83b4..134e9dd86b 100644 --- a/container/testdata/doctabs/desktop/layout_bottom_icon_and_text.xml +++ b/container/testdata/doctabs/desktop/layout_bottom_icon_and_text.xml @@ -14,7 +14,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_bottom_text.xml b/container/testdata/doctabs/desktop/layout_bottom_text.xml index 0d5725dfed..1f56ee7df1 100644 --- a/container/testdata/doctabs/desktop/layout_bottom_text.xml +++ b/container/testdata/doctabs/desktop/layout_bottom_text.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_leading_icon.xml b/container/testdata/doctabs/desktop/layout_leading_icon.xml index 9ed4062f8b..bd3cf5382c 100644 --- a/container/testdata/doctabs/desktop/layout_leading_icon.xml +++ b/container/testdata/doctabs/desktop/layout_leading_icon.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_leading_icon_and_text.xml b/container/testdata/doctabs/desktop/layout_leading_icon_and_text.xml index 3ad2dda74d..02f8209357 100644 --- a/container/testdata/doctabs/desktop/layout_leading_icon_and_text.xml +++ b/container/testdata/doctabs/desktop/layout_leading_icon_and_text.xml @@ -14,7 +14,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_leading_text.xml b/container/testdata/doctabs/desktop/layout_leading_text.xml index ed08c0184c..6ea774962f 100644 --- a/container/testdata/doctabs/desktop/layout_leading_text.xml +++ b/container/testdata/doctabs/desktop/layout_leading_text.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_top_icon.xml b/container/testdata/doctabs/desktop/layout_top_icon.xml index f2faf7b3cf..0b9c48639b 100644 --- a/container/testdata/doctabs/desktop/layout_top_icon.xml +++ b/container/testdata/doctabs/desktop/layout_top_icon.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_top_icon_and_text.xml b/container/testdata/doctabs/desktop/layout_top_icon_and_text.xml index ab7bf8f0b4..5184c5279b 100644 --- a/container/testdata/doctabs/desktop/layout_top_icon_and_text.xml +++ b/container/testdata/doctabs/desktop/layout_top_icon_and_text.xml @@ -14,7 +14,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_top_text.xml b/container/testdata/doctabs/desktop/layout_top_text.xml index 2cbd507db2..7285d2906c 100644 --- a/container/testdata/doctabs/desktop/layout_top_text.xml +++ b/container/testdata/doctabs/desktop/layout_top_text.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_trailing_icon.xml b/container/testdata/doctabs/desktop/layout_trailing_icon.xml index 9a3c5bfd1f..c1712fb144 100644 --- a/container/testdata/doctabs/desktop/layout_trailing_icon.xml +++ b/container/testdata/doctabs/desktop/layout_trailing_icon.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_trailing_icon_and_text.xml b/container/testdata/doctabs/desktop/layout_trailing_icon_and_text.xml index 9eb08deb0c..e061456519 100644 --- a/container/testdata/doctabs/desktop/layout_trailing_icon_and_text.xml +++ b/container/testdata/doctabs/desktop/layout_trailing_icon_and_text.xml @@ -14,7 +14,7 @@ - + diff --git a/container/testdata/doctabs/desktop/layout_trailing_text.xml b/container/testdata/doctabs/desktop/layout_trailing_text.xml index f4f90e9056..d11a178f28 100644 --- a/container/testdata/doctabs/desktop/layout_trailing_text.xml +++ b/container/testdata/doctabs/desktop/layout_trailing_text.xml @@ -13,7 +13,7 @@ - + diff --git a/container/testdata/doctabs/desktop/tab_location_bottom.xml b/container/testdata/doctabs/desktop/tab_location_bottom.xml index 9894df8b8d..a5c1bfc7fc 100644 --- a/container/testdata/doctabs/desktop/tab_location_bottom.xml +++ b/container/testdata/doctabs/desktop/tab_location_bottom.xml @@ -27,7 +27,7 @@ - + diff --git a/container/testdata/doctabs/desktop/tab_location_leading.xml b/container/testdata/doctabs/desktop/tab_location_leading.xml index 1bf2a414de..facdf561b9 100644 --- a/container/testdata/doctabs/desktop/tab_location_leading.xml +++ b/container/testdata/doctabs/desktop/tab_location_leading.xml @@ -27,7 +27,7 @@ - + diff --git a/container/testdata/doctabs/desktop/tab_location_top.xml b/container/testdata/doctabs/desktop/tab_location_top.xml index 76f3f18d25..e22784173b 100644 --- a/container/testdata/doctabs/desktop/tab_location_top.xml +++ b/container/testdata/doctabs/desktop/tab_location_top.xml @@ -27,7 +27,7 @@ - + diff --git a/container/testdata/doctabs/desktop/tab_location_trailing.xml b/container/testdata/doctabs/desktop/tab_location_trailing.xml index a6696b684a..4de6176739 100644 --- a/container/testdata/doctabs/desktop/tab_location_trailing.xml +++ b/container/testdata/doctabs/desktop/tab_location_trailing.xml @@ -27,7 +27,7 @@ - + diff --git a/container/testdata/doctabs/desktop/tapped_all_tabs.xml b/container/testdata/doctabs/desktop/tapped_all_tabs.xml index 2fdcb73f26..32f72d36d3 100644 --- a/container/testdata/doctabs/desktop/tapped_all_tabs.xml +++ b/container/testdata/doctabs/desktop/tapped_all_tabs.xml @@ -30,12 +30,12 @@ - + - + @@ -76,7 +76,7 @@ Another - + diff --git a/container/testdata/doctabs/desktop/tapped_create_tab.xml b/container/testdata/doctabs/desktop/tapped_create_tab.xml index 6a06a36b28..4f5fbdb459 100644 --- a/container/testdata/doctabs/desktop/tapped_create_tab.xml +++ b/container/testdata/doctabs/desktop/tapped_create_tab.xml @@ -30,12 +30,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/tapped_first_selected.xml b/container/testdata/doctabs/desktop/tapped_first_selected.xml index e0cbc3f1cb..504d522758 100644 --- a/container/testdata/doctabs/desktop/tapped_first_selected.xml +++ b/container/testdata/doctabs/desktop/tapped_first_selected.xml @@ -27,12 +27,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/tapped_second_selected.xml b/container/testdata/doctabs/desktop/tapped_second_selected.xml index 853d541d38..5af061e0c4 100644 --- a/container/testdata/doctabs/desktop/tapped_second_selected.xml +++ b/container/testdata/doctabs/desktop/tapped_second_selected.xml @@ -27,12 +27,12 @@ - + - + diff --git a/container/testdata/doctabs/desktop/tapped_third_selected.xml b/container/testdata/doctabs/desktop/tapped_third_selected.xml index 77de845142..08b3531ae4 100644 --- a/container/testdata/doctabs/desktop/tapped_third_selected.xml +++ b/container/testdata/doctabs/desktop/tapped_third_selected.xml @@ -27,12 +27,12 @@ - + - + diff --git a/container/testdata/doctabs/mobile/change_content_change_hidden.xml b/container/testdata/doctabs/mobile/change_content_change_hidden.xml index 8a3af77aeb..5964894592 100644 --- a/container/testdata/doctabs/mobile/change_content_change_hidden.xml +++ b/container/testdata/doctabs/mobile/change_content_change_hidden.xml @@ -13,7 +13,7 @@ Test2 - + @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_content_change_visible.xml b/container/testdata/doctabs/mobile/change_content_change_visible.xml index 8a3af77aeb..5964894592 100644 --- a/container/testdata/doctabs/mobile/change_content_change_visible.xml +++ b/container/testdata/doctabs/mobile/change_content_change_visible.xml @@ -13,7 +13,7 @@ Test2 - + @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_content_initial.xml b/container/testdata/doctabs/mobile/change_content_initial.xml index 97fb993876..1142de040c 100644 --- a/container/testdata/doctabs/mobile/change_content_initial.xml +++ b/container/testdata/doctabs/mobile/change_content_initial.xml @@ -13,7 +13,7 @@ Test2 - + @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_icon_change_selected.xml b/container/testdata/doctabs/mobile/change_icon_change_selected.xml index 963229609a..2c2b150796 100644 --- a/container/testdata/doctabs/mobile/change_icon_change_selected.xml +++ b/container/testdata/doctabs/mobile/change_icon_change_selected.xml @@ -12,9 +12,9 @@ - + - + @@ -22,7 +22,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_icon_change_unselected.xml b/container/testdata/doctabs/mobile/change_icon_change_unselected.xml index ba0ba9a260..918e54e500 100644 --- a/container/testdata/doctabs/mobile/change_icon_change_unselected.xml +++ b/container/testdata/doctabs/mobile/change_icon_change_unselected.xml @@ -12,9 +12,9 @@ - + - + @@ -22,7 +22,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_icon_initial.xml b/container/testdata/doctabs/mobile/change_icon_initial.xml index 3a795a01f9..bd033ee873 100644 --- a/container/testdata/doctabs/mobile/change_icon_initial.xml +++ b/container/testdata/doctabs/mobile/change_icon_initial.xml @@ -12,9 +12,9 @@ - + - + @@ -22,7 +22,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_label_change_selected.xml b/container/testdata/doctabs/mobile/change_label_change_selected.xml index 30795cbd94..d634ea9272 100644 --- a/container/testdata/doctabs/mobile/change_label_change_selected.xml +++ b/container/testdata/doctabs/mobile/change_label_change_selected.xml @@ -13,7 +13,7 @@ Test2 - + @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_label_change_unselected.xml b/container/testdata/doctabs/mobile/change_label_change_unselected.xml index 666f0cdff5..1b54f603f3 100644 --- a/container/testdata/doctabs/mobile/change_label_change_unselected.xml +++ b/container/testdata/doctabs/mobile/change_label_change_unselected.xml @@ -13,7 +13,7 @@ New 2 - + @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/mobile/change_label_initial.xml b/container/testdata/doctabs/mobile/change_label_initial.xml index 97fb993876..1142de040c 100644 --- a/container/testdata/doctabs/mobile/change_label_initial.xml +++ b/container/testdata/doctabs/mobile/change_label_initial.xml @@ -13,7 +13,7 @@ Test2 - + @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/mobile/dynamic_appended.xml b/container/testdata/doctabs/mobile/dynamic_appended.xml index 159a9a4970..630bb963ec 100644 --- a/container/testdata/doctabs/mobile/dynamic_appended.xml +++ b/container/testdata/doctabs/mobile/dynamic_appended.xml @@ -13,7 +13,7 @@ Test2 - + @@ -22,7 +22,7 @@ - + diff --git a/container/testdata/doctabs/mobile/dynamic_appended_and_removed.xml b/container/testdata/doctabs/mobile/dynamic_appended_and_removed.xml index 4f35d61028..db7dc50539 100644 --- a/container/testdata/doctabs/mobile/dynamic_appended_and_removed.xml +++ b/container/testdata/doctabs/mobile/dynamic_appended_and_removed.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/mobile/dynamic_appended_another_three.xml b/container/testdata/doctabs/mobile/dynamic_appended_another_three.xml index 27a7fc17c4..2687412d91 100644 --- a/container/testdata/doctabs/mobile/dynamic_appended_another_three.xml +++ b/container/testdata/doctabs/mobile/dynamic_appended_another_three.xml @@ -13,19 +13,19 @@ Test3 - + Test4 - + Test5 - + @@ -42,7 +42,7 @@ - + diff --git a/container/testdata/doctabs/mobile/dynamic_initial.xml b/container/testdata/doctabs/mobile/dynamic_initial.xml index affd36968d..3ac0160fb0 100644 --- a/container/testdata/doctabs/mobile/dynamic_initial.xml +++ b/container/testdata/doctabs/mobile/dynamic_initial.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/mobile/dynamic_replaced_completely.xml b/container/testdata/doctabs/mobile/dynamic_replaced_completely.xml index 08c2f8c8e1..47e239d34d 100644 --- a/container/testdata/doctabs/mobile/dynamic_replaced_completely.xml +++ b/container/testdata/doctabs/mobile/dynamic_replaced_completely.xml @@ -13,13 +13,13 @@ Test7 - + Test8 - + @@ -28,7 +28,7 @@ - + diff --git a/container/testdata/doctabs/mobile/hover_none.xml b/container/testdata/doctabs/mobile/hover_none.xml index 3505dce33f..aa57bfba17 100644 --- a/container/testdata/doctabs/mobile/hover_none.xml +++ b/container/testdata/doctabs/mobile/hover_none.xml @@ -13,7 +13,7 @@ Test2 - + @@ -30,7 +30,7 @@ - + diff --git a/container/testdata/doctabs/mobile/layout_bottom_ico.xml b/container/testdata/doctabs/mobile/layout_bottom_ico.xml index 1df0bd559d..9f40d8cfc2 100644 --- a/container/testdata/doctabs/mobile/layout_bottom_ico.xml +++ b/container/testdata/doctabs/mobile/layout_bottom_ico.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/mobile/layout_bottom_icon_and_text.xml b/container/testdata/doctabs/mobile/layout_bottom_icon_and_text.xml index a7a8acf5e5..97c3dbf02c 100644 --- a/container/testdata/doctabs/mobile/layout_bottom_icon_and_text.xml +++ b/container/testdata/doctabs/mobile/layout_bottom_icon_and_text.xml @@ -17,7 +17,7 @@ - + diff --git a/container/testdata/doctabs/mobile/layout_bottom_text.xml b/container/testdata/doctabs/mobile/layout_bottom_text.xml index 6b149f6c06..001c39c61e 100644 --- a/container/testdata/doctabs/mobile/layout_bottom_text.xml +++ b/container/testdata/doctabs/mobile/layout_bottom_text.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/mobile/layout_top_icon.xml b/container/testdata/doctabs/mobile/layout_top_icon.xml index 087896f2b4..202ee560cf 100644 --- a/container/testdata/doctabs/mobile/layout_top_icon.xml +++ b/container/testdata/doctabs/mobile/layout_top_icon.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/mobile/layout_top_icon_and_text.xml b/container/testdata/doctabs/mobile/layout_top_icon_and_text.xml index f326c67766..a21794d559 100644 --- a/container/testdata/doctabs/mobile/layout_top_icon_and_text.xml +++ b/container/testdata/doctabs/mobile/layout_top_icon_and_text.xml @@ -17,7 +17,7 @@ - + diff --git a/container/testdata/doctabs/mobile/layout_top_text.xml b/container/testdata/doctabs/mobile/layout_top_text.xml index a5398f6ea0..434ab1817f 100644 --- a/container/testdata/doctabs/mobile/layout_top_text.xml +++ b/container/testdata/doctabs/mobile/layout_top_text.xml @@ -16,7 +16,7 @@ - + diff --git a/container/testdata/doctabs/mobile/tab_location_bottom.xml b/container/testdata/doctabs/mobile/tab_location_bottom.xml index 0735a9fff5..874f391f33 100644 --- a/container/testdata/doctabs/mobile/tab_location_bottom.xml +++ b/container/testdata/doctabs/mobile/tab_location_bottom.xml @@ -13,13 +13,13 @@ Test2 - + Test3 - + @@ -36,7 +36,7 @@ - + diff --git a/container/testdata/doctabs/mobile/tab_location_top.xml b/container/testdata/doctabs/mobile/tab_location_top.xml index 2b992c0383..31724f57c1 100644 --- a/container/testdata/doctabs/mobile/tab_location_top.xml +++ b/container/testdata/doctabs/mobile/tab_location_top.xml @@ -13,13 +13,13 @@ Test2 - + Test3 - + @@ -36,7 +36,7 @@ - + diff --git a/container/testdata/doctabs/mobile/tapped_all_tabs.xml b/container/testdata/doctabs/mobile/tapped_all_tabs.xml index 0664b01725..6235bee898 100644 --- a/container/testdata/doctabs/mobile/tapped_all_tabs.xml +++ b/container/testdata/doctabs/mobile/tapped_all_tabs.xml @@ -7,19 +7,19 @@ Test1 - + Test2 - + Test3 - + @@ -42,12 +42,12 @@ - + - + @@ -88,7 +88,7 @@ Another - + diff --git a/container/testdata/doctabs/mobile/tapped_create_tab.xml b/container/testdata/doctabs/mobile/tapped_create_tab.xml index fdb115b156..2ef7396635 100644 --- a/container/testdata/doctabs/mobile/tapped_create_tab.xml +++ b/container/testdata/doctabs/mobile/tapped_create_tab.xml @@ -7,19 +7,19 @@ Test1 - + Test2 - + Test3 - + @@ -42,12 +42,12 @@ - + - + diff --git a/container/testdata/doctabs/mobile/tapped_first_selected.xml b/container/testdata/doctabs/mobile/tapped_first_selected.xml index af92adf08f..596f0de910 100644 --- a/container/testdata/doctabs/mobile/tapped_first_selected.xml +++ b/container/testdata/doctabs/mobile/tapped_first_selected.xml @@ -13,13 +13,13 @@ Test2 - + Test3 - + @@ -28,12 +28,12 @@ - + - + diff --git a/container/testdata/doctabs/mobile/tapped_second_selected.xml b/container/testdata/doctabs/mobile/tapped_second_selected.xml index 058cfcc109..6ec1d9d20e 100644 --- a/container/testdata/doctabs/mobile/tapped_second_selected.xml +++ b/container/testdata/doctabs/mobile/tapped_second_selected.xml @@ -7,7 +7,7 @@ Test1 - + @@ -19,7 +19,7 @@ Test3 - + @@ -28,12 +28,12 @@ - + - + diff --git a/container/testdata/doctabs/mobile/tapped_third_selected.xml b/container/testdata/doctabs/mobile/tapped_third_selected.xml index 06a0956c9b..02c7c6bf7d 100644 --- a/container/testdata/doctabs/mobile/tapped_third_selected.xml +++ b/container/testdata/doctabs/mobile/tapped_third_selected.xml @@ -7,13 +7,13 @@ Test1 - + Test2 - + @@ -28,12 +28,12 @@ - + - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_1.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_1.xml index 181e5a3e5e..785c2047d2 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_1.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_1.xml @@ -56,7 +56,7 @@ Recent - + @@ -85,7 +85,7 @@ Older - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_2.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_2.xml index 260ea09072..0a9fa42d92 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_2.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_close_submenu_2.xml @@ -56,7 +56,7 @@ Recent - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_1.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_1.xml index 223f6d3a2a..9323324874 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_1.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_1.xml @@ -56,7 +56,7 @@ Recent - + @@ -85,7 +85,7 @@ Older - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_2.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_2.xml index a9ade0aa7a..71dde7c00b 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_2.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_open_submenu_2.xml @@ -56,7 +56,7 @@ Recent - + @@ -85,7 +85,7 @@ Older - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_left_3.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_left_3.xml index a048609e8b..d5fbeec296 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_left_3.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_left_3.xml @@ -55,7 +55,7 @@ Recent - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_right_3.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_right_3.xml index a048609e8b..d5fbeec296 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_right_3.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_bar_items_right_3.xml @@ -55,7 +55,7 @@ Recent - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_1.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_1.xml index 5b63c8eea9..48ecc96cfe 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_1.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_1.xml @@ -56,7 +56,7 @@ Recent - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_2.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_2.xml index dc14299b84..03c6982d69 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_2.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_2.xml @@ -56,7 +56,7 @@ Recent - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_3.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_3.xml index 260ea09072..0a9fa42d92 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_3.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_down_3.xml @@ -56,7 +56,7 @@ Recent - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_1.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_1.xml index dc14299b84..03c6982d69 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_1.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_1.xml @@ -56,7 +56,7 @@ Recent - + diff --git a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_2.xml b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_2.xml index 5b63c8eea9..48ecc96cfe 100644 --- a/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_2.xml +++ b/internal/driver/glfw/testdata/menu_bar_kbdctrl_traverse_menu_up_2.xml @@ -56,7 +56,7 @@ Recent - + diff --git a/test/markup_renderer.go b/test/markup_renderer.go index a93397dfff..6016fcea47 100644 --- a/test/markup_renderer.go +++ b/test/markup_renderer.go @@ -3,7 +3,6 @@ package test import ( "fmt" "image/color" - "log" "reflect" "sort" "strings" @@ -151,10 +150,9 @@ func (r *markupRenderer) setResourceAttr(attrs map[string]*string, name string, case *theme.ThemedResource: variant = string(t.ColorName) if variant == "" { - variant = "default" + variant = "foreground" } default: - log.Println("TYPE WAS", t) r.setStringAttr(attrs, name, rsc.Name()) return } diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items.xml b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items.xml index 5e4abf7d30..ec1db5a0ee 100644 --- a/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items_opened.xml index 9ba2616a4e..4e54e150fc 100644 --- a/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_expanded_multiple_open_multiple_items_opened.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_one_item.xml b/widget/testdata/accordion/layout_expanded_multiple_open_one_item.xml index 1df3bf9d1b..b6f844fb7a 100644 --- a/widget/testdata/accordion/layout_expanded_multiple_open_one_item.xml +++ b/widget/testdata/accordion/layout_expanded_multiple_open_one_item.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_expanded_multiple_open_one_item_opened.xml b/widget/testdata/accordion/layout_expanded_multiple_open_one_item_opened.xml index 772a332db2..b5dcff715e 100644 --- a/widget/testdata/accordion/layout_expanded_multiple_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_expanded_multiple_open_one_item_opened.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_expanded_single_open_multiple_items.xml b/widget/testdata/accordion/layout_expanded_single_open_multiple_items.xml index 5e4abf7d30..ec1db5a0ee 100644 --- a/widget/testdata/accordion/layout_expanded_single_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_expanded_single_open_multiple_items.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_expanded_single_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_expanded_single_open_multiple_items_opened.xml index aa999752e6..79c4d2346a 100644 --- a/widget/testdata/accordion/layout_expanded_single_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_expanded_single_open_multiple_items_opened.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_expanded_single_open_one_item.xml b/widget/testdata/accordion/layout_expanded_single_open_one_item.xml index 1df3bf9d1b..b6f844fb7a 100644 --- a/widget/testdata/accordion/layout_expanded_single_open_one_item.xml +++ b/widget/testdata/accordion/layout_expanded_single_open_one_item.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_expanded_single_open_one_item_opened.xml b/widget/testdata/accordion/layout_expanded_single_open_one_item_opened.xml index 772a332db2..b5dcff715e 100644 --- a/widget/testdata/accordion/layout_expanded_single_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_expanded_single_open_one_item_opened.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_multiple_open_multiple_items.xml b/widget/testdata/accordion/layout_multiple_open_multiple_items.xml index ca4d8f7261..5a5ef468e7 100644 --- a/widget/testdata/accordion/layout_multiple_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_multiple_open_multiple_items.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml index 54948cd1de..31620c9cc8 100644 --- a/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_multiple_open_multiple_items_opened.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_multiple_open_one_item.xml b/widget/testdata/accordion/layout_multiple_open_one_item.xml index 20ca10df55..da361560a0 100644 --- a/widget/testdata/accordion/layout_multiple_open_one_item.xml +++ b/widget/testdata/accordion/layout_multiple_open_one_item.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml b/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml index e0ed3ffe4a..9c0430b67f 100644 --- a/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_multiple_open_one_item_opened.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_single_open_multiple_items.xml b/widget/testdata/accordion/layout_single_open_multiple_items.xml index ca4d8f7261..5a5ef468e7 100644 --- a/widget/testdata/accordion/layout_single_open_multiple_items.xml +++ b/widget/testdata/accordion/layout_single_open_multiple_items.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml b/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml index 68e06003cd..4e80548430 100644 --- a/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml +++ b/widget/testdata/accordion/layout_single_open_multiple_items_opened.xml @@ -8,7 +8,7 @@ A - + @@ -16,7 +16,7 @@ B - + diff --git a/widget/testdata/accordion/layout_single_open_one_item.xml b/widget/testdata/accordion/layout_single_open_one_item.xml index 20ca10df55..da361560a0 100644 --- a/widget/testdata/accordion/layout_single_open_one_item.xml +++ b/widget/testdata/accordion/layout_single_open_one_item.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/accordion/layout_single_open_one_item_opened.xml b/widget/testdata/accordion/layout_single_open_one_item_opened.xml index e0ed3ffe4a..9c0430b67f 100644 --- a/widget/testdata/accordion/layout_single_open_one_item_opened.xml +++ b/widget/testdata/accordion/layout_single_open_one_item_opened.xml @@ -8,7 +8,7 @@ A - + diff --git a/widget/testdata/button/layout_icon_only_center_leading.xml b/widget/testdata/button/layout_icon_only_center_leading.xml index 45a99778e5..86f3fc0468 100644 --- a/widget/testdata/button/layout_icon_only_center_leading.xml +++ b/widget/testdata/button/layout_icon_only_center_leading.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_icon_only_center_trailing.xml b/widget/testdata/button/layout_icon_only_center_trailing.xml index 45a99778e5..86f3fc0468 100644 --- a/widget/testdata/button/layout_icon_only_center_trailing.xml +++ b/widget/testdata/button/layout_icon_only_center_trailing.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_icon_only_leading_leading.xml b/widget/testdata/button/layout_icon_only_leading_leading.xml index 75f9417b42..df8f7f1922 100644 --- a/widget/testdata/button/layout_icon_only_leading_leading.xml +++ b/widget/testdata/button/layout_icon_only_leading_leading.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_icon_only_leading_trailing.xml b/widget/testdata/button/layout_icon_only_leading_trailing.xml index 75f9417b42..df8f7f1922 100644 --- a/widget/testdata/button/layout_icon_only_leading_trailing.xml +++ b/widget/testdata/button/layout_icon_only_leading_trailing.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_icon_only_trailing_leading.xml b/widget/testdata/button/layout_icon_only_trailing_leading.xml index 6e33e34ef1..fac82c6b4d 100644 --- a/widget/testdata/button/layout_icon_only_trailing_leading.xml +++ b/widget/testdata/button/layout_icon_only_trailing_leading.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_icon_only_trailing_trailing.xml b/widget/testdata/button/layout_icon_only_trailing_trailing.xml index 6e33e34ef1..fac82c6b4d 100644 --- a/widget/testdata/button/layout_icon_only_trailing_trailing.xml +++ b/widget/testdata/button/layout_icon_only_trailing_trailing.xml @@ -3,7 +3,7 @@ - + diff --git a/widget/testdata/button/layout_text_icon_center_leading.xml b/widget/testdata/button/layout_text_icon_center_leading.xml index 54764c84e2..c9ae1a5dda 100644 --- a/widget/testdata/button/layout_text_icon_center_leading.xml +++ b/widget/testdata/button/layout_text_icon_center_leading.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/button/layout_text_icon_center_trailing.xml b/widget/testdata/button/layout_text_icon_center_trailing.xml index 427cda6803..3d2357f8bc 100644 --- a/widget/testdata/button/layout_text_icon_center_trailing.xml +++ b/widget/testdata/button/layout_text_icon_center_trailing.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/button/layout_text_icon_leading_leading.xml b/widget/testdata/button/layout_text_icon_leading_leading.xml index 50dfad6674..e24a147ebb 100644 --- a/widget/testdata/button/layout_text_icon_leading_leading.xml +++ b/widget/testdata/button/layout_text_icon_leading_leading.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/button/layout_text_icon_leading_trailing.xml b/widget/testdata/button/layout_text_icon_leading_trailing.xml index 5955c9a9f3..bce0eaa453 100644 --- a/widget/testdata/button/layout_text_icon_leading_trailing.xml +++ b/widget/testdata/button/layout_text_icon_leading_trailing.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/button/layout_text_icon_trailing_leading.xml b/widget/testdata/button/layout_text_icon_trailing_leading.xml index 6e9994edc3..d5f5a0da3d 100644 --- a/widget/testdata/button/layout_text_icon_trailing_leading.xml +++ b/widget/testdata/button/layout_text_icon_trailing_leading.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/button/layout_text_icon_trailing_trailing.xml b/widget/testdata/button/layout_text_icon_trailing_trailing.xml index 446168e728..3aa4030ba8 100644 --- a/widget/testdata/button/layout_text_icon_trailing_trailing.xml +++ b/widget/testdata/button/layout_text_icon_trailing_trailing.xml @@ -6,7 +6,7 @@ Test - + diff --git a/widget/testdata/card/layout_all_items.xml b/widget/testdata/card/layout_all_items.xml index 213daa7195..3c6527ba5e 100644 --- a/widget/testdata/card/layout_all_items.xml +++ b/widget/testdata/card/layout_all_items.xml @@ -13,7 +13,7 @@ Longer title subtitle with length - + diff --git a/widget/testdata/card/layout_image_content.xml b/widget/testdata/card/layout_image_content.xml index b01c834bb7..947bb789d7 100644 --- a/widget/testdata/card/layout_image_content.xml +++ b/widget/testdata/card/layout_image_content.xml @@ -13,7 +13,7 @@ - + diff --git a/widget/testdata/card/layout_just_image.xml b/widget/testdata/card/layout_just_image.xml index 00bb92aeb8..3c27bc168e 100644 --- a/widget/testdata/card/layout_just_image.xml +++ b/widget/testdata/card/layout_just_image.xml @@ -13,7 +13,7 @@ - + diff --git a/widget/testdata/card/layout_titles_image.xml b/widget/testdata/card/layout_titles_image.xml index 79adff3709..96a7df5520 100644 --- a/widget/testdata/card/layout_titles_image.xml +++ b/widget/testdata/card/layout_titles_image.xml @@ -13,7 +13,7 @@ Title Subtitle - + diff --git a/widget/testdata/entry/validate_valid.xml b/widget/testdata/entry/validate_valid.xml index 6c465354d0..ecf591962d 100644 --- a/widget/testdata/entry/validate_valid.xml +++ b/widget/testdata/entry/validate_valid.xml @@ -10,7 +10,7 @@ - + diff --git a/widget/testdata/form/extended_entry.xml b/widget/testdata/form/extended_entry.xml index b62c28eab7..cd6ebedbad 100644 --- a/widget/testdata/form/extended_entry.xml +++ b/widget/testdata/form/extended_entry.xml @@ -22,7 +22,7 @@ - + diff --git a/widget/testdata/form/layout.xml b/widget/testdata/form/layout.xml index 85a43ce363..de9444978a 100644 --- a/widget/testdata/form/layout.xml +++ b/widget/testdata/form/layout.xml @@ -46,7 +46,7 @@ Cancel - + diff --git a/widget/testdata/icon/layout_resource.xml b/widget/testdata/icon/layout_resource.xml index 161dcb833a..b56d6eef80 100644 --- a/widget/testdata/icon/layout_resource.xml +++ b/widget/testdata/icon/layout_resource.xml @@ -2,7 +2,7 @@ - + diff --git a/widget/testdata/list/initial.xml b/widget/testdata/list/initial.xml index 497a5c777f..e43564c0fe 100644 --- a/widget/testdata/list/initial.xml +++ b/widget/testdata/list/initial.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -78,7 +78,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -126,7 +126,7 @@ - + diff --git a/widget/testdata/list/item_removed.xml b/widget/testdata/list/item_removed.xml index 19ea41c30d..68d265a365 100644 --- a/widget/testdata/list/item_removed.xml +++ b/widget/testdata/list/item_removed.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + diff --git a/widget/testdata/list/new_data.xml b/widget/testdata/list/new_data.xml index dfdab99d38..fcc8c3f97c 100644 --- a/widget/testdata/list/new_data.xml +++ b/widget/testdata/list/new_data.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -78,7 +78,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -126,7 +126,7 @@ - + diff --git a/widget/testdata/list/offset_changed.xml b/widget/testdata/list/offset_changed.xml index 1d2f039f3a..73c8d7d507 100644 --- a/widget/testdata/list/offset_changed.xml +++ b/widget/testdata/list/offset_changed.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -78,7 +78,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -126,7 +126,7 @@ - + diff --git a/widget/testdata/list/resized.xml b/widget/testdata/list/resized.xml index 4ed8d8ec52..9b018ca69e 100644 --- a/widget/testdata/list/resized.xml +++ b/widget/testdata/list/resized.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + @@ -30,7 +30,7 @@ - + @@ -42,7 +42,7 @@ - + @@ -54,7 +54,7 @@ - + @@ -66,7 +66,7 @@ - + @@ -78,7 +78,7 @@ - + @@ -90,7 +90,7 @@ - + @@ -102,7 +102,7 @@ - + @@ -114,7 +114,7 @@ - + @@ -126,7 +126,7 @@ - + @@ -138,7 +138,7 @@ - + @@ -150,7 +150,7 @@ - + @@ -162,7 +162,7 @@ - + @@ -174,7 +174,7 @@ - + @@ -186,7 +186,7 @@ - + diff --git a/widget/testdata/list/small.xml b/widget/testdata/list/small.xml index 19ea41c30d..68d265a365 100644 --- a/widget/testdata/list/small.xml +++ b/widget/testdata/list/small.xml @@ -6,7 +6,7 @@ - + @@ -18,7 +18,7 @@ - + diff --git a/widget/testdata/menu/desktop/layout_background_reset.xml b/widget/testdata/menu/desktop/layout_background_reset.xml index fc0bf05e16..6b8acac398 100644 --- a/widget/testdata/menu/desktop/layout_background_reset.xml +++ b/widget/testdata/menu/desktop/layout_background_reset.xml @@ -31,14 +31,14 @@ C - + D - + diff --git a/widget/testdata/menu/desktop/layout_no_space_on_both_sides.xml b/widget/testdata/menu/desktop/layout_no_space_on_both_sides.xml index 8fb4dad6b2..21abcd5a40 100644 --- a/widget/testdata/menu/desktop/layout_no_space_on_both_sides.xml +++ b/widget/testdata/menu/desktop/layout_no_space_on_both_sides.xml @@ -31,14 +31,14 @@ C - + D - + @@ -60,17 +60,17 @@ subitem A - + subitem B - - + + subitem C (long) - - + + diff --git a/widget/testdata/menu/desktop/layout_no_space_on_right.xml b/widget/testdata/menu/desktop/layout_no_space_on_right.xml index c9ed93bb8e..d1449ae378 100644 --- a/widget/testdata/menu/desktop/layout_no_space_on_right.xml +++ b/widget/testdata/menu/desktop/layout_no_space_on_right.xml @@ -31,14 +31,14 @@ C - + D - + @@ -60,17 +60,17 @@ subitem A - + subitem B - - + + subitem C (long) - - + + diff --git a/widget/testdata/menu/desktop/layout_normal.xml b/widget/testdata/menu/desktop/layout_normal.xml index 85ce7dbbce..8326518b26 100644 --- a/widget/testdata/menu/desktop/layout_normal.xml +++ b/widget/testdata/menu/desktop/layout_normal.xml @@ -30,14 +30,14 @@ C - + D - + diff --git a/widget/testdata/menu/desktop/layout_normal_with_submenus.xml b/widget/testdata/menu/desktop/layout_normal_with_submenus.xml index e95ba62de1..0317428029 100644 --- a/widget/testdata/menu/desktop/layout_normal_with_submenus.xml +++ b/widget/testdata/menu/desktop/layout_normal_with_submenus.xml @@ -31,14 +31,14 @@ C - + D - + @@ -60,17 +60,17 @@ subitem A - + subitem B - - + + subitem C (long) - - + + diff --git a/widget/testdata/menu/desktop/layout_theme_changed.xml b/widget/testdata/menu/desktop/layout_theme_changed.xml index 85ce7dbbce..8326518b26 100644 --- a/widget/testdata/menu/desktop/layout_theme_changed.xml +++ b/widget/testdata/menu/desktop/layout_theme_changed.xml @@ -30,14 +30,14 @@ C - + D - + diff --git a/widget/testdata/menu/desktop/layout_window_too_short.xml b/widget/testdata/menu/desktop/layout_window_too_short.xml index f36d68833c..5b2b28a72f 100644 --- a/widget/testdata/menu/desktop/layout_window_too_short.xml +++ b/widget/testdata/menu/desktop/layout_window_too_short.xml @@ -30,14 +30,14 @@ C - + D - + diff --git a/widget/testdata/menu/desktop/layout_window_too_short_for_submenu.xml b/widget/testdata/menu/desktop/layout_window_too_short_for_submenu.xml index 0811d598bb..d46f88f101 100644 --- a/widget/testdata/menu/desktop/layout_window_too_short_for_submenu.xml +++ b/widget/testdata/menu/desktop/layout_window_too_short_for_submenu.xml @@ -31,14 +31,14 @@ C - + D - + @@ -68,18 +68,18 @@ subitem A - + subitem B - - + + subitem C (long) - - + + @@ -101,7 +101,7 @@ subsubitem A (long) - + subsubitem B diff --git a/widget/testdata/menu/desktop/traverse_first_active.xml b/widget/testdata/menu/desktop/traverse_first_active.xml index 352d187013..dba03c69e2 100644 --- a/widget/testdata/menu/desktop/traverse_first_active.xml +++ b/widget/testdata/menu/desktop/traverse_first_active.xml @@ -25,7 +25,7 @@ Bar - + diff --git a/widget/testdata/menu/desktop/traverse_initial.xml b/widget/testdata/menu/desktop/traverse_initial.xml index 2012f9d00c..a228b0f6fb 100644 --- a/widget/testdata/menu/desktop/traverse_initial.xml +++ b/widget/testdata/menu/desktop/traverse_initial.xml @@ -24,7 +24,7 @@ Bar - + diff --git a/widget/testdata/menu/desktop/traverse_second_active.xml b/widget/testdata/menu/desktop/traverse_second_active.xml index 753c22ce73..dd181e4d10 100644 --- a/widget/testdata/menu/desktop/traverse_second_active.xml +++ b/widget/testdata/menu/desktop/traverse_second_active.xml @@ -25,7 +25,7 @@ Bar - + diff --git a/widget/testdata/menu/desktop/traverse_submenu_first_active.xml b/widget/testdata/menu/desktop/traverse_submenu_first_active.xml index 5117b256e4..5e90d80f6f 100644 --- a/widget/testdata/menu/desktop/traverse_submenu_first_active.xml +++ b/widget/testdata/menu/desktop/traverse_submenu_first_active.xml @@ -25,7 +25,7 @@ Bar - + diff --git a/widget/testdata/menu/desktop/traverse_submenu_second_active.xml b/widget/testdata/menu/desktop/traverse_submenu_second_active.xml index 613145ae57..ad4cd0bc9f 100644 --- a/widget/testdata/menu/desktop/traverse_submenu_second_active.xml +++ b/widget/testdata/menu/desktop/traverse_submenu_second_active.xml @@ -25,7 +25,7 @@ Bar - + diff --git a/widget/testdata/menu/desktop/traverse_third_active.xml b/widget/testdata/menu/desktop/traverse_third_active.xml index b4566dfdcb..78e80bafa2 100644 --- a/widget/testdata/menu/desktop/traverse_third_active.xml +++ b/widget/testdata/menu/desktop/traverse_third_active.xml @@ -24,7 +24,7 @@ Bar - + diff --git a/widget/testdata/menu/mobile/layout_background_reset.xml b/widget/testdata/menu/mobile/layout_background_reset.xml index 047e545ef7..1985e5cccf 100644 --- a/widget/testdata/menu/mobile/layout_background_reset.xml +++ b/widget/testdata/menu/mobile/layout_background_reset.xml @@ -30,7 +30,7 @@ C - + diff --git a/widget/testdata/menu/mobile/layout_no_space_on_both_sides.xml b/widget/testdata/menu/mobile/layout_no_space_on_both_sides.xml index 3237155b22..fb5b48eaf3 100644 --- a/widget/testdata/menu/mobile/layout_no_space_on_both_sides.xml +++ b/widget/testdata/menu/mobile/layout_no_space_on_both_sides.xml @@ -30,7 +30,7 @@ C - + @@ -52,17 +52,17 @@ subitem A - + subitem B - - + + subitem C (long) - - + + diff --git a/widget/testdata/menu/mobile/layout_no_space_on_right.xml b/widget/testdata/menu/mobile/layout_no_space_on_right.xml index afe1eadd8d..3511c8ad7f 100644 --- a/widget/testdata/menu/mobile/layout_no_space_on_right.xml +++ b/widget/testdata/menu/mobile/layout_no_space_on_right.xml @@ -30,7 +30,7 @@ C - + @@ -52,17 +52,17 @@ subitem A - + subitem B - - + + subitem C (long) - - + + diff --git a/widget/testdata/menu/mobile/layout_normal.xml b/widget/testdata/menu/mobile/layout_normal.xml index 047e545ef7..1985e5cccf 100644 --- a/widget/testdata/menu/mobile/layout_normal.xml +++ b/widget/testdata/menu/mobile/layout_normal.xml @@ -30,7 +30,7 @@ C - + diff --git a/widget/testdata/menu/mobile/layout_normal_with_submenus.xml b/widget/testdata/menu/mobile/layout_normal_with_submenus.xml index 43dc299d2b..aefdf5e83f 100644 --- a/widget/testdata/menu/mobile/layout_normal_with_submenus.xml +++ b/widget/testdata/menu/mobile/layout_normal_with_submenus.xml @@ -30,7 +30,7 @@ C - + @@ -52,17 +52,17 @@ subitem A - + subitem B - - + + subitem C (long) - - + + diff --git a/widget/testdata/menu/mobile/layout_theme_changed.xml b/widget/testdata/menu/mobile/layout_theme_changed.xml index 047e545ef7..1985e5cccf 100644 --- a/widget/testdata/menu/mobile/layout_theme_changed.xml +++ b/widget/testdata/menu/mobile/layout_theme_changed.xml @@ -30,7 +30,7 @@ C - + diff --git a/widget/testdata/menu/mobile/layout_window_too_short.xml b/widget/testdata/menu/mobile/layout_window_too_short.xml index f9eb349893..0ce0f8f971 100644 --- a/widget/testdata/menu/mobile/layout_window_too_short.xml +++ b/widget/testdata/menu/mobile/layout_window_too_short.xml @@ -30,7 +30,7 @@ C - + diff --git a/widget/testdata/menu/mobile/layout_window_too_short_for_submenu.xml b/widget/testdata/menu/mobile/layout_window_too_short_for_submenu.xml index b5ede8f8cb..e63f1db9e0 100644 --- a/widget/testdata/menu/mobile/layout_window_too_short_for_submenu.xml +++ b/widget/testdata/menu/mobile/layout_window_too_short_for_submenu.xml @@ -30,7 +30,7 @@ C - + @@ -52,17 +52,17 @@ subitem A - + subitem B - - + + subitem C (long) - - + + @@ -84,7 +84,7 @@ subsubitem A (long) - + subsubitem B diff --git a/widget/testdata/menu/refresh_2nd_checkmark.xml b/widget/testdata/menu/refresh_2nd_checkmark.xml index cf28a9be51..7e873d7a09 100644 --- a/widget/testdata/menu/refresh_2nd_checkmark.xml +++ b/widget/testdata/menu/refresh_2nd_checkmark.xml @@ -33,7 +33,7 @@ Baz - + diff --git a/widget/testdata/menu/refresh_checkmark.xml b/widget/testdata/menu/refresh_checkmark.xml index ac980b3fee..e6a962571d 100644 --- a/widget/testdata/menu/refresh_checkmark.xml +++ b/widget/testdata/menu/refresh_checkmark.xml @@ -32,7 +32,7 @@ Baz - + diff --git a/widget/testdata/menu/refresh_initial.xml b/widget/testdata/menu/refresh_initial.xml index 70b117af61..508301020e 100644 --- a/widget/testdata/menu/refresh_initial.xml +++ b/widget/testdata/menu/refresh_initial.xml @@ -24,8 +24,8 @@ Bar - - + + diff --git a/widget/testdata/password_entry/concealed.xml b/widget/testdata/password_entry/concealed.xml index cbad822380..d940f0ce1c 100644 --- a/widget/testdata/password_entry/concealed.xml +++ b/widget/testdata/password_entry/concealed.xml @@ -12,7 +12,7 @@ - + diff --git a/widget/testdata/password_entry/initial.xml b/widget/testdata/password_entry/initial.xml index acabeb5427..e90fea5221 100644 --- a/widget/testdata/password_entry/initial.xml +++ b/widget/testdata/password_entry/initial.xml @@ -14,7 +14,7 @@ - + diff --git a/widget/testdata/password_entry/obfuscation_typed.xml b/widget/testdata/password_entry/obfuscation_typed.xml index d110a01380..c50cf399d4 100644 --- a/widget/testdata/password_entry/obfuscation_typed.xml +++ b/widget/testdata/password_entry/obfuscation_typed.xml @@ -12,7 +12,7 @@ - + diff --git a/widget/testdata/password_entry/placeholder_initial.xml b/widget/testdata/password_entry/placeholder_initial.xml index a6b495acb8..788a91c1bd 100644 --- a/widget/testdata/password_entry/placeholder_initial.xml +++ b/widget/testdata/password_entry/placeholder_initial.xml @@ -14,7 +14,7 @@ - + diff --git a/widget/testdata/password_entry/placeholder_typed.xml b/widget/testdata/password_entry/placeholder_typed.xml index d110a01380..c50cf399d4 100644 --- a/widget/testdata/password_entry/placeholder_typed.xml +++ b/widget/testdata/password_entry/placeholder_typed.xml @@ -12,7 +12,7 @@ - + diff --git a/widget/testdata/password_entry/revealed.xml b/widget/testdata/password_entry/revealed.xml index 41388da4e0..e72e2674f7 100644 --- a/widget/testdata/password_entry/revealed.xml +++ b/widget/testdata/password_entry/revealed.xml @@ -12,7 +12,7 @@ - + diff --git a/widget/testdata/popup_menu/desktop/kbd_ctrl_first_active.xml b/widget/testdata/popup_menu/desktop/kbd_ctrl_first_active.xml index 2be7bbf3e8..1603dc0cb7 100644 --- a/widget/testdata/popup_menu/desktop/kbd_ctrl_first_active.xml +++ b/widget/testdata/popup_menu/desktop/kbd_ctrl_first_active.xml @@ -25,7 +25,7 @@ Option B - + diff --git a/widget/testdata/popup_menu/desktop/kbd_ctrl_first_sub_active.xml b/widget/testdata/popup_menu/desktop/kbd_ctrl_first_sub_active.xml index d69b26384e..56722b2794 100644 --- a/widget/testdata/popup_menu/desktop/kbd_ctrl_first_sub_active.xml +++ b/widget/testdata/popup_menu/desktop/kbd_ctrl_first_sub_active.xml @@ -25,7 +25,7 @@ Option B - + @@ -51,7 +51,7 @@ Sub Option B - + diff --git a/widget/testdata/popup_menu/desktop/kbd_ctrl_first_sub_sub_active.xml b/widget/testdata/popup_menu/desktop/kbd_ctrl_first_sub_sub_active.xml index f07c52d3fd..82af199de6 100644 --- a/widget/testdata/popup_menu/desktop/kbd_ctrl_first_sub_sub_active.xml +++ b/widget/testdata/popup_menu/desktop/kbd_ctrl_first_sub_sub_active.xml @@ -25,7 +25,7 @@ Option B - + @@ -51,7 +51,7 @@ Sub Option B - + diff --git a/widget/testdata/popup_menu/desktop/kbd_ctrl_second_active.xml b/widget/testdata/popup_menu/desktop/kbd_ctrl_second_active.xml index 511a18129f..a62d93ac42 100644 --- a/widget/testdata/popup_menu/desktop/kbd_ctrl_second_active.xml +++ b/widget/testdata/popup_menu/desktop/kbd_ctrl_second_active.xml @@ -25,7 +25,7 @@ Option B - + diff --git a/widget/testdata/popup_menu/desktop/kbd_ctrl_second_sub_active.xml b/widget/testdata/popup_menu/desktop/kbd_ctrl_second_sub_active.xml index 3e1872d393..b6408c8777 100644 --- a/widget/testdata/popup_menu/desktop/kbd_ctrl_second_sub_active.xml +++ b/widget/testdata/popup_menu/desktop/kbd_ctrl_second_sub_active.xml @@ -25,7 +25,7 @@ Option B - + @@ -51,7 +51,7 @@ Sub Option B - + diff --git a/widget/testdata/popup_menu/desktop/kbd_ctrl_second_sub_sub_active.xml b/widget/testdata/popup_menu/desktop/kbd_ctrl_second_sub_sub_active.xml index fd83ff9d84..ee7c22f2a1 100644 --- a/widget/testdata/popup_menu/desktop/kbd_ctrl_second_sub_sub_active.xml +++ b/widget/testdata/popup_menu/desktop/kbd_ctrl_second_sub_sub_active.xml @@ -25,7 +25,7 @@ Option B - + @@ -51,7 +51,7 @@ Sub Option B - + diff --git a/widget/testdata/popup_menu/desktop/kbd_ctrl_shown.xml b/widget/testdata/popup_menu/desktop/kbd_ctrl_shown.xml index 3e61b5dc08..5a12a7e8d9 100644 --- a/widget/testdata/popup_menu/desktop/kbd_ctrl_shown.xml +++ b/widget/testdata/popup_menu/desktop/kbd_ctrl_shown.xml @@ -24,7 +24,7 @@ Option B - + diff --git a/widget/testdata/select/desktop/center.xml b/widget/testdata/select/desktop/center.xml index 854b59e44f..8554e32e4b 100644 --- a/widget/testdata/select/desktop/center.xml +++ b/widget/testdata/select/desktop/center.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_empty.xml b/widget/testdata/select/desktop/layout_empty.xml index 09ab9428f0..a662d36d6a 100644 --- a/widget/testdata/select/desktop/layout_empty.xml +++ b/widget/testdata/select/desktop/layout_empty.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_empty_expanded.xml b/widget/testdata/select/desktop/layout_empty_expanded.xml index 4dbfaedc0b..de49b4ecd9 100644 --- a/widget/testdata/select/desktop/layout_empty_expanded.xml +++ b/widget/testdata/select/desktop/layout_empty_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_empty_expanded_placeholder.xml b/widget/testdata/select/desktop/layout_empty_expanded_placeholder.xml index fd2d579b1e..e9cc67d69b 100644 --- a/widget/testdata/select/desktop/layout_empty_expanded_placeholder.xml +++ b/widget/testdata/select/desktop/layout_empty_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_empty_placeholder.xml b/widget/testdata/select/desktop/layout_empty_placeholder.xml index 745ddfd9b3..b6fb6c7b9c 100644 --- a/widget/testdata/select/desktop/layout_empty_placeholder.xml +++ b/widget/testdata/select/desktop/layout_empty_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_multiple.xml b/widget/testdata/select/desktop/layout_multiple.xml index 09ab9428f0..a662d36d6a 100644 --- a/widget/testdata/select/desktop/layout_multiple.xml +++ b/widget/testdata/select/desktop/layout_multiple.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_multiple_expanded.xml b/widget/testdata/select/desktop/layout_multiple_expanded.xml index 9c1634f119..9dd2180408 100644 --- a/widget/testdata/select/desktop/layout_multiple_expanded.xml +++ b/widget/testdata/select/desktop/layout_multiple_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_multiple_expanded_placeholder.xml b/widget/testdata/select/desktop/layout_multiple_expanded_placeholder.xml index 2d1de6ded4..59ec939be5 100644 --- a/widget/testdata/select/desktop/layout_multiple_expanded_placeholder.xml +++ b/widget/testdata/select/desktop/layout_multiple_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_multiple_expanded_selected.xml b/widget/testdata/select/desktop/layout_multiple_expanded_selected.xml index 3e4dadea48..18bfb361b1 100644 --- a/widget/testdata/select/desktop/layout_multiple_expanded_selected.xml +++ b/widget/testdata/select/desktop/layout_multiple_expanded_selected.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/desktop/layout_multiple_expanded_selected_placeholder.xml b/widget/testdata/select/desktop/layout_multiple_expanded_selected_placeholder.xml index 8da21f0e70..39139e3bdc 100644 --- a/widget/testdata/select/desktop/layout_multiple_expanded_selected_placeholder.xml +++ b/widget/testdata/select/desktop/layout_multiple_expanded_selected_placeholder.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/desktop/layout_multiple_placeholder.xml b/widget/testdata/select/desktop/layout_multiple_placeholder.xml index 745ddfd9b3..b6fb6c7b9c 100644 --- a/widget/testdata/select/desktop/layout_multiple_placeholder.xml +++ b/widget/testdata/select/desktop/layout_multiple_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_multiple_selected.xml b/widget/testdata/select/desktop/layout_multiple_selected.xml index 0f7c615b58..28338edfca 100644 --- a/widget/testdata/select/desktop/layout_multiple_selected.xml +++ b/widget/testdata/select/desktop/layout_multiple_selected.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/desktop/layout_multiple_selected_placeholder.xml b/widget/testdata/select/desktop/layout_multiple_selected_placeholder.xml index 6a8b41271c..ee8fe4e34e 100644 --- a/widget/testdata/select/desktop/layout_multiple_selected_placeholder.xml +++ b/widget/testdata/select/desktop/layout_multiple_selected_placeholder.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/desktop/layout_single.xml b/widget/testdata/select/desktop/layout_single.xml index 09ab9428f0..a662d36d6a 100644 --- a/widget/testdata/select/desktop/layout_single.xml +++ b/widget/testdata/select/desktop/layout_single.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_single_expanded.xml b/widget/testdata/select/desktop/layout_single_expanded.xml index 7cec2ae56a..1505d9daa9 100644 --- a/widget/testdata/select/desktop/layout_single_expanded.xml +++ b/widget/testdata/select/desktop/layout_single_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/layout_single_expanded_placeholder.xml b/widget/testdata/select/desktop/layout_single_expanded_placeholder.xml index d4557bf0c0..c05838c4c5 100644 --- a/widget/testdata/select/desktop/layout_single_expanded_placeholder.xml +++ b/widget/testdata/select/desktop/layout_single_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_single_expanded_selected.xml b/widget/testdata/select/desktop/layout_single_expanded_selected.xml index 411e22c4e6..ec634b8d11 100644 --- a/widget/testdata/select/desktop/layout_single_expanded_selected.xml +++ b/widget/testdata/select/desktop/layout_single_expanded_selected.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/desktop/layout_single_expanded_selected_placeholder.xml b/widget/testdata/select/desktop/layout_single_expanded_selected_placeholder.xml index 59b355e43c..b4ea2e54a8 100644 --- a/widget/testdata/select/desktop/layout_single_expanded_selected_placeholder.xml +++ b/widget/testdata/select/desktop/layout_single_expanded_selected_placeholder.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/desktop/layout_single_placeholder.xml b/widget/testdata/select/desktop/layout_single_placeholder.xml index 745ddfd9b3..b6fb6c7b9c 100644 --- a/widget/testdata/select/desktop/layout_single_placeholder.xml +++ b/widget/testdata/select/desktop/layout_single_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/desktop/layout_single_selected.xml b/widget/testdata/select/desktop/layout_single_selected.xml index 4401d5f13a..3a5759a084 100644 --- a/widget/testdata/select/desktop/layout_single_selected.xml +++ b/widget/testdata/select/desktop/layout_single_selected.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/desktop/layout_single_selected_placeholder.xml b/widget/testdata/select/desktop/layout_single_selected_placeholder.xml index d3c22a298f..df72a2755d 100644 --- a/widget/testdata/select/desktop/layout_single_selected_placeholder.xml +++ b/widget/testdata/select/desktop/layout_single_selected_placeholder.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/desktop/move_moved.xml b/widget/testdata/select/desktop/move_moved.xml index fe7a703d38..d8970d07ad 100644 --- a/widget/testdata/select/desktop/move_moved.xml +++ b/widget/testdata/select/desktop/move_moved.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/move_tapped.xml b/widget/testdata/select/desktop/move_tapped.xml index a33c8f91f1..1bc0dc77e8 100644 --- a/widget/testdata/select/desktop/move_tapped.xml +++ b/widget/testdata/select/desktop/move_tapped.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/tapped.xml b/widget/testdata/select/desktop/tapped.xml index 8e777f040b..e458b45278 100644 --- a/widget/testdata/select/desktop/tapped.xml +++ b/widget/testdata/select/desktop/tapped.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/tapped_constrained.xml b/widget/testdata/select/desktop/tapped_constrained.xml index 154b3d420e..c8a4d4645f 100644 --- a/widget/testdata/select/desktop/tapped_constrained.xml +++ b/widget/testdata/select/desktop/tapped_constrained.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/desktop/trailing.xml b/widget/testdata/select/desktop/trailing.xml index 24e23eff65..4a508145ea 100644 --- a/widget/testdata/select/desktop/trailing.xml +++ b/widget/testdata/select/desktop/trailing.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/focus_focused_b_selected.xml b/widget/testdata/select/focus_focused_b_selected.xml index 7ddc9baf40..75d99fe3e0 100644 --- a/widget/testdata/select/focus_focused_b_selected.xml +++ b/widget/testdata/select/focus_focused_b_selected.xml @@ -8,7 +8,7 @@ Option B - + diff --git a/widget/testdata/select/focus_focused_none_selected.xml b/widget/testdata/select/focus_focused_none_selected.xml index 8f69eb8504..b9b1256011 100644 --- a/widget/testdata/select/focus_focused_none_selected.xml +++ b/widget/testdata/select/focus_focused_none_selected.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/focus_unfocused_b_selected.xml b/widget/testdata/select/focus_unfocused_b_selected.xml index a2036bd447..b0e6edb017 100644 --- a/widget/testdata/select/focus_unfocused_b_selected.xml +++ b/widget/testdata/select/focus_unfocused_b_selected.xml @@ -8,7 +8,7 @@ Option B - + diff --git a/widget/testdata/select/focus_unfocused_none_selected.xml b/widget/testdata/select/focus_unfocused_none_selected.xml index 78314b39ff..f8023d66b4 100644 --- a/widget/testdata/select/focus_unfocused_none_selected.xml +++ b/widget/testdata/select/focus_unfocused_none_selected.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/kbdctrl_a_selected.xml b/widget/testdata/select/kbdctrl_a_selected.xml index a2970ec1ae..e03b58b81d 100644 --- a/widget/testdata/select/kbdctrl_a_selected.xml +++ b/widget/testdata/select/kbdctrl_a_selected.xml @@ -8,7 +8,7 @@ Option A - + diff --git a/widget/testdata/select/kbdctrl_b_selected.xml b/widget/testdata/select/kbdctrl_b_selected.xml index 28387be042..ce434abfcc 100644 --- a/widget/testdata/select/kbdctrl_b_selected.xml +++ b/widget/testdata/select/kbdctrl_b_selected.xml @@ -8,7 +8,7 @@ Option B - + diff --git a/widget/testdata/select/kbdctrl_c_selected.xml b/widget/testdata/select/kbdctrl_c_selected.xml index f12cadb8f8..471b3f8eaa 100644 --- a/widget/testdata/select/kbdctrl_c_selected.xml +++ b/widget/testdata/select/kbdctrl_c_selected.xml @@ -8,7 +8,7 @@ Option C - + diff --git a/widget/testdata/select/kbdctrl_none_selected.xml b/widget/testdata/select/kbdctrl_none_selected.xml index 1d8234bcef..5ff13edaa1 100644 --- a/widget/testdata/select/kbdctrl_none_selected.xml +++ b/widget/testdata/select/kbdctrl_none_selected.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/kbdctrl_none_selected_popup.xml b/widget/testdata/select/kbdctrl_none_selected_popup.xml index f660211654..a7241c9c3e 100644 --- a/widget/testdata/select/kbdctrl_none_selected_popup.xml +++ b/widget/testdata/select/kbdctrl_none_selected_popup.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/center.xml b/widget/testdata/select/mobile/center.xml index 4f608bc9ee..39ba7a7342 100644 --- a/widget/testdata/select/mobile/center.xml +++ b/widget/testdata/select/mobile/center.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_empty.xml b/widget/testdata/select/mobile/layout_empty.xml index 09ab9428f0..a662d36d6a 100644 --- a/widget/testdata/select/mobile/layout_empty.xml +++ b/widget/testdata/select/mobile/layout_empty.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_empty_expanded.xml b/widget/testdata/select/mobile/layout_empty_expanded.xml index 207009f5ef..3eedb23ae8 100644 --- a/widget/testdata/select/mobile/layout_empty_expanded.xml +++ b/widget/testdata/select/mobile/layout_empty_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_empty_expanded_placeholder.xml b/widget/testdata/select/mobile/layout_empty_expanded_placeholder.xml index 62e8fbca89..a5a9bd5a60 100644 --- a/widget/testdata/select/mobile/layout_empty_expanded_placeholder.xml +++ b/widget/testdata/select/mobile/layout_empty_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_empty_placeholder.xml b/widget/testdata/select/mobile/layout_empty_placeholder.xml index 745ddfd9b3..b6fb6c7b9c 100644 --- a/widget/testdata/select/mobile/layout_empty_placeholder.xml +++ b/widget/testdata/select/mobile/layout_empty_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_multiple.xml b/widget/testdata/select/mobile/layout_multiple.xml index 09ab9428f0..a662d36d6a 100644 --- a/widget/testdata/select/mobile/layout_multiple.xml +++ b/widget/testdata/select/mobile/layout_multiple.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_multiple_expanded.xml b/widget/testdata/select/mobile/layout_multiple_expanded.xml index 9f1b2c7ca0..80b0712c51 100644 --- a/widget/testdata/select/mobile/layout_multiple_expanded.xml +++ b/widget/testdata/select/mobile/layout_multiple_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_multiple_expanded_placeholder.xml b/widget/testdata/select/mobile/layout_multiple_expanded_placeholder.xml index 4956c25b6d..b4a6bf5465 100644 --- a/widget/testdata/select/mobile/layout_multiple_expanded_placeholder.xml +++ b/widget/testdata/select/mobile/layout_multiple_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_multiple_expanded_selected.xml b/widget/testdata/select/mobile/layout_multiple_expanded_selected.xml index 5b7b9d64f5..981c30de72 100644 --- a/widget/testdata/select/mobile/layout_multiple_expanded_selected.xml +++ b/widget/testdata/select/mobile/layout_multiple_expanded_selected.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/mobile/layout_multiple_expanded_selected_placeholder.xml b/widget/testdata/select/mobile/layout_multiple_expanded_selected_placeholder.xml index ff4f546967..e9b6ea463a 100644 --- a/widget/testdata/select/mobile/layout_multiple_expanded_selected_placeholder.xml +++ b/widget/testdata/select/mobile/layout_multiple_expanded_selected_placeholder.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/mobile/layout_multiple_placeholder.xml b/widget/testdata/select/mobile/layout_multiple_placeholder.xml index 745ddfd9b3..b6fb6c7b9c 100644 --- a/widget/testdata/select/mobile/layout_multiple_placeholder.xml +++ b/widget/testdata/select/mobile/layout_multiple_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_multiple_selected.xml b/widget/testdata/select/mobile/layout_multiple_selected.xml index 0f7c615b58..28338edfca 100644 --- a/widget/testdata/select/mobile/layout_multiple_selected.xml +++ b/widget/testdata/select/mobile/layout_multiple_selected.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/mobile/layout_multiple_selected_placeholder.xml b/widget/testdata/select/mobile/layout_multiple_selected_placeholder.xml index 6a8b41271c..ee8fe4e34e 100644 --- a/widget/testdata/select/mobile/layout_multiple_selected_placeholder.xml +++ b/widget/testdata/select/mobile/layout_multiple_selected_placeholder.xml @@ -8,7 +8,7 @@ Foo - + diff --git a/widget/testdata/select/mobile/layout_single.xml b/widget/testdata/select/mobile/layout_single.xml index 09ab9428f0..a662d36d6a 100644 --- a/widget/testdata/select/mobile/layout_single.xml +++ b/widget/testdata/select/mobile/layout_single.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_single_expanded.xml b/widget/testdata/select/mobile/layout_single_expanded.xml index c3e1a45341..739c3d74ad 100644 --- a/widget/testdata/select/mobile/layout_single_expanded.xml +++ b/widget/testdata/select/mobile/layout_single_expanded.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/layout_single_expanded_placeholder.xml b/widget/testdata/select/mobile/layout_single_expanded_placeholder.xml index f22c7c5823..440cdfa7a3 100644 --- a/widget/testdata/select/mobile/layout_single_expanded_placeholder.xml +++ b/widget/testdata/select/mobile/layout_single_expanded_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_single_expanded_selected.xml b/widget/testdata/select/mobile/layout_single_expanded_selected.xml index b022d4bfaa..f4657c05cf 100644 --- a/widget/testdata/select/mobile/layout_single_expanded_selected.xml +++ b/widget/testdata/select/mobile/layout_single_expanded_selected.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/mobile/layout_single_expanded_selected_placeholder.xml b/widget/testdata/select/mobile/layout_single_expanded_selected_placeholder.xml index cf239729ba..c4237bd6f1 100644 --- a/widget/testdata/select/mobile/layout_single_expanded_selected_placeholder.xml +++ b/widget/testdata/select/mobile/layout_single_expanded_selected_placeholder.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/mobile/layout_single_placeholder.xml b/widget/testdata/select/mobile/layout_single_placeholder.xml index 745ddfd9b3..b6fb6c7b9c 100644 --- a/widget/testdata/select/mobile/layout_single_placeholder.xml +++ b/widget/testdata/select/mobile/layout_single_placeholder.xml @@ -8,7 +8,7 @@ (Pick 1) - + diff --git a/widget/testdata/select/mobile/layout_single_selected.xml b/widget/testdata/select/mobile/layout_single_selected.xml index 4401d5f13a..3a5759a084 100644 --- a/widget/testdata/select/mobile/layout_single_selected.xml +++ b/widget/testdata/select/mobile/layout_single_selected.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/mobile/layout_single_selected_placeholder.xml b/widget/testdata/select/mobile/layout_single_selected_placeholder.xml index d3c22a298f..df72a2755d 100644 --- a/widget/testdata/select/mobile/layout_single_selected_placeholder.xml +++ b/widget/testdata/select/mobile/layout_single_selected_placeholder.xml @@ -8,7 +8,7 @@ Test - + diff --git a/widget/testdata/select/mobile/move_moved.xml b/widget/testdata/select/mobile/move_moved.xml index 9fa98c83cf..dad9d1c541 100644 --- a/widget/testdata/select/mobile/move_moved.xml +++ b/widget/testdata/select/mobile/move_moved.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/move_tapped.xml b/widget/testdata/select/mobile/move_tapped.xml index ac9ea9aaba..18ec0f2581 100644 --- a/widget/testdata/select/mobile/move_tapped.xml +++ b/widget/testdata/select/mobile/move_tapped.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/tapped.xml b/widget/testdata/select/mobile/tapped.xml index 09fa240c6e..530b92b216 100644 --- a/widget/testdata/select/mobile/tapped.xml +++ b/widget/testdata/select/mobile/tapped.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/tapped_constrained.xml b/widget/testdata/select/mobile/tapped_constrained.xml index 7984f79f28..7d6ae39b11 100644 --- a/widget/testdata/select/mobile/tapped_constrained.xml +++ b/widget/testdata/select/mobile/tapped_constrained.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/mobile/trailing.xml b/widget/testdata/select/mobile/trailing.xml index 6837834ccc..9f5f1c2cdf 100644 --- a/widget/testdata/select/mobile/trailing.xml +++ b/widget/testdata/select/mobile/trailing.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select/move_initial.xml b/widget/testdata/select/move_initial.xml index b95d5e26ed..edef866828 100644 --- a/widget/testdata/select/move_initial.xml +++ b/widget/testdata/select/move_initial.xml @@ -7,7 +7,7 @@ (Select one) - + diff --git a/widget/testdata/select/set_selected_2nd_selected.xml b/widget/testdata/select/set_selected_2nd_selected.xml index 1c6df774b7..64e5368163 100644 --- a/widget/testdata/select/set_selected_2nd_selected.xml +++ b/widget/testdata/select/set_selected_2nd_selected.xml @@ -8,7 +8,7 @@ 2 - + diff --git a/widget/testdata/select/set_selected_none_selected.xml b/widget/testdata/select/set_selected_none_selected.xml index 78314b39ff..f8023d66b4 100644 --- a/widget/testdata/select/set_selected_none_selected.xml +++ b/widget/testdata/select/set_selected_none_selected.xml @@ -8,7 +8,7 @@ (Select one) - + diff --git a/widget/testdata/select_entry/disableable_enabled.xml b/widget/testdata/select_entry/disableable_enabled.xml index f2278867fb..8c21e77a02 100644 --- a/widget/testdata/select_entry/disableable_enabled.xml +++ b/widget/testdata/select_entry/disableable_enabled.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/disableable_enabled_opened.xml b/widget/testdata/select_entry/disableable_enabled_opened.xml index 24531a6eec..a406a38880 100644 --- a/widget/testdata/select_entry/disableable_enabled_opened.xml +++ b/widget/testdata/select_entry/disableable_enabled_opened.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/disableable_enabled_tapped.xml b/widget/testdata/select_entry/disableable_enabled_tapped.xml index f2278867fb..8c21e77a02 100644 --- a/widget/testdata/select_entry/disableable_enabled_tapped.xml +++ b/widget/testdata/select_entry/disableable_enabled_tapped.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/disableable_enabled_tapped_selected.xml b/widget/testdata/select_entry/disableable_enabled_tapped_selected.xml index f2278867fb..8c21e77a02 100644 --- a/widget/testdata/select_entry/disableable_enabled_tapped_selected.xml +++ b/widget/testdata/select_entry/disableable_enabled_tapped_selected.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_B_opened.xml b/widget/testdata/select_entry/dropdown_B_opened.xml index 26b63ea136..598666d4ce 100644 --- a/widget/testdata/select_entry/dropdown_B_opened.xml +++ b/widget/testdata/select_entry/dropdown_B_opened.xml @@ -13,7 +13,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_empty_opened.xml b/widget/testdata/select_entry/dropdown_empty_opened.xml index 24531a6eec..a406a38880 100644 --- a/widget/testdata/select_entry/dropdown_empty_opened.xml +++ b/widget/testdata/select_entry/dropdown_empty_opened.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_empty_opened_shrunk.xml b/widget/testdata/select_entry/dropdown_empty_opened_shrunk.xml index e4f22952d8..3e730ba386 100644 --- a/widget/testdata/select_entry/dropdown_empty_opened_shrunk.xml +++ b/widget/testdata/select_entry/dropdown_empty_opened_shrunk.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_empty_setopts.xml b/widget/testdata/select_entry/dropdown_empty_setopts.xml index 435c36c9fc..0dde8f3b42 100644 --- a/widget/testdata/select_entry/dropdown_empty_setopts.xml +++ b/widget/testdata/select_entry/dropdown_empty_setopts.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_initial.xml b/widget/testdata/select_entry/dropdown_initial.xml index f2278867fb..8c21e77a02 100644 --- a/widget/testdata/select_entry/dropdown_initial.xml +++ b/widget/testdata/select_entry/dropdown_initial.xml @@ -16,7 +16,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_tapped_B.xml b/widget/testdata/select_entry/dropdown_tapped_B.xml index ee8b585236..bdc0de4c2a 100644 --- a/widget/testdata/select_entry/dropdown_tapped_B.xml +++ b/widget/testdata/select_entry/dropdown_tapped_B.xml @@ -13,7 +13,7 @@ - + diff --git a/widget/testdata/select_entry/dropdown_tapped_C.xml b/widget/testdata/select_entry/dropdown_tapped_C.xml index 8b8191d13d..aa5687879d 100644 --- a/widget/testdata/select_entry/dropdown_tapped_C.xml +++ b/widget/testdata/select_entry/dropdown_tapped_C.xml @@ -13,7 +13,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple.xml b/widget/testdata/tree/layout_multiple.xml index 2b135e4417..ad4493266f 100644 --- a/widget/testdata/tree/layout_multiple.xml +++ b/widget/testdata/tree/layout_multiple.xml @@ -10,7 +10,7 @@ - + @@ -23,7 +23,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_branch.xml b/widget/testdata/tree/layout_multiple_branch.xml index 3a0084acf2..951678ac09 100644 --- a/widget/testdata/tree/layout_multiple_branch.xml +++ b/widget/testdata/tree/layout_multiple_branch.xml @@ -10,7 +10,7 @@ - + @@ -23,7 +23,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_branch_opened.xml b/widget/testdata/tree/layout_multiple_branch_opened.xml index ad10c20a85..9670887590 100644 --- a/widget/testdata/tree/layout_multiple_branch_opened.xml +++ b/widget/testdata/tree/layout_multiple_branch_opened.xml @@ -10,7 +10,7 @@ - + @@ -33,7 +33,7 @@ - + @@ -56,7 +56,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_branch_opened_leaf_selected.xml b/widget/testdata/tree/layout_multiple_branch_opened_leaf_selected.xml index 761f7488e4..26ce829e2b 100644 --- a/widget/testdata/tree/layout_multiple_branch_opened_leaf_selected.xml +++ b/widget/testdata/tree/layout_multiple_branch_opened_leaf_selected.xml @@ -10,7 +10,7 @@ - + @@ -33,7 +33,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_branch_opened_selected.xml b/widget/testdata/tree/layout_multiple_branch_opened_selected.xml index dc990ce239..9c429af46e 100644 --- a/widget/testdata/tree/layout_multiple_branch_opened_selected.xml +++ b/widget/testdata/tree/layout_multiple_branch_opened_selected.xml @@ -10,7 +10,7 @@ - + @@ -34,7 +34,7 @@ - + @@ -57,7 +57,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_branch_selected.xml b/widget/testdata/tree/layout_multiple_branch_selected.xml index 9b89f93a80..aab25776fc 100644 --- a/widget/testdata/tree/layout_multiple_branch_selected.xml +++ b/widget/testdata/tree/layout_multiple_branch_selected.xml @@ -10,7 +10,7 @@ - + @@ -24,7 +24,7 @@ - + diff --git a/widget/testdata/tree/layout_multiple_selected.xml b/widget/testdata/tree/layout_multiple_selected.xml index eb0e889e39..f56138d952 100644 --- a/widget/testdata/tree/layout_multiple_selected.xml +++ b/widget/testdata/tree/layout_multiple_selected.xml @@ -10,7 +10,7 @@ - + @@ -23,7 +23,7 @@ - + diff --git a/widget/testdata/tree/layout_single_branch.xml b/widget/testdata/tree/layout_single_branch.xml index e66c7c1048..107f4ac9c5 100644 --- a/widget/testdata/tree/layout_single_branch.xml +++ b/widget/testdata/tree/layout_single_branch.xml @@ -10,7 +10,7 @@ - + diff --git a/widget/testdata/tree/layout_single_branch_opened.xml b/widget/testdata/tree/layout_single_branch_opened.xml index 9e756f4a7d..41f13bb606 100644 --- a/widget/testdata/tree/layout_single_branch_opened.xml +++ b/widget/testdata/tree/layout_single_branch_opened.xml @@ -10,7 +10,7 @@ - + diff --git a/widget/testdata/tree/layout_single_branch_opened_leaf_selected.xml b/widget/testdata/tree/layout_single_branch_opened_leaf_selected.xml index cdb0787eac..4752068030 100644 --- a/widget/testdata/tree/layout_single_branch_opened_leaf_selected.xml +++ b/widget/testdata/tree/layout_single_branch_opened_leaf_selected.xml @@ -10,7 +10,7 @@ - + diff --git a/widget/testdata/tree/layout_single_branch_opened_selected.xml b/widget/testdata/tree/layout_single_branch_opened_selected.xml index e8722d6db0..79411a5beb 100644 --- a/widget/testdata/tree/layout_single_branch_opened_selected.xml +++ b/widget/testdata/tree/layout_single_branch_opened_selected.xml @@ -11,7 +11,7 @@ - + diff --git a/widget/testdata/tree/layout_single_branch_selected.xml b/widget/testdata/tree/layout_single_branch_selected.xml index 4c44e41b93..5abbae4dc2 100644 --- a/widget/testdata/tree/layout_single_branch_selected.xml +++ b/widget/testdata/tree/layout_single_branch_selected.xml @@ -11,7 +11,7 @@ - + diff --git a/widget/testdata/tree/move_initial.xml b/widget/testdata/tree/move_initial.xml index 8757fba251..71ae4c57a0 100644 --- a/widget/testdata/tree/move_initial.xml +++ b/widget/testdata/tree/move_initial.xml @@ -10,7 +10,7 @@ - + diff --git a/widget/testdata/tree/move_moved.xml b/widget/testdata/tree/move_moved.xml index cd8f7ec686..9ea4ab28cb 100644 --- a/widget/testdata/tree/move_moved.xml +++ b/widget/testdata/tree/move_moved.xml @@ -10,7 +10,7 @@ - + From 79bca53d8f7936a1f0e8e57a00696110b09e78fb Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 14 Jun 2024 10:34:50 +0100 Subject: [PATCH 36/78] Correct markup test for change in semantics --- test/markup_renderer_test.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/test/markup_renderer_test.go b/test/markup_renderer_test.go index c28c4f9fad..f203f678fc 100644 --- a/test/markup_renderer_test.go +++ b/test/markup_renderer_test.go @@ -95,7 +95,7 @@ func Test_snapshot(t *testing.T) { content: fynecanvas.NewImageFromResource(theme.VolumeDownIcon()), want: "\n" + "\t\n" + - "\t\t\n" + + "\t\t\n" + "\t\n" + "\n", }, @@ -103,7 +103,7 @@ func Test_snapshot(t *testing.T) { content: fynecanvas.NewImageFromResource(theme.NewThemedResource(fyne.NewStaticResource("resource name", []byte{}))), want: "\n" + "\t\n" + - "\t\t\n" + + "\t\t\n" + "\t\n" + "\n", }, @@ -147,7 +147,7 @@ func Test_snapshot(t *testing.T) { }(), want: "\n" + "\t\n" + - "\t\t\n" + + "\t\t\n" + "\t\n" + "\n", }, @@ -159,7 +159,7 @@ func Test_snapshot(t *testing.T) { }(), want: "\n" + "\t\n" + - "\t\t\n" + + "\t\t\n" + "\t\n" + "\n", }, @@ -171,7 +171,7 @@ func Test_snapshot(t *testing.T) { }(), want: "\n" + "\t\n" + - "\t\t\n" + + "\t\t\n" + "\t\n" + "\n", }, @@ -183,7 +183,7 @@ func Test_snapshot(t *testing.T) { }(), want: "\n" + "\t\n" + - "\t\t\n" + + "\t\t\n" + "\t\n" + "\n", }, @@ -192,7 +192,7 @@ func Test_snapshot(t *testing.T) { size: fyne.NewSize(theme.IconInlineSize(), theme.IconInlineSize()), want: "\n" + "\t\n" + - "\t\t\n" + + "\t\t\n" + "\t\n" + "\n", }, From c08d14fded20596f32f5791a874fe0dc9d15b77f Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 14 Jun 2024 10:42:38 +0100 Subject: [PATCH 37/78] Move to image comparison tests for theme override --- container/testdata/theme/icon-other-theme.png | Bin 0 -> 472 bytes container/testdata/theme/icon-test-theme.png | Bin 0 -> 549 bytes container/testdata/theme/text-other-theme.png | Bin 0 -> 1071 bytes container/testdata/theme/text-test-theme.png | Bin 0 -> 875 bytes container/theme_test.go | 9 ++++----- 5 files changed, 4 insertions(+), 5 deletions(-) create mode 100644 container/testdata/theme/icon-other-theme.png create mode 100644 container/testdata/theme/icon-test-theme.png create mode 100644 container/testdata/theme/text-other-theme.png create mode 100644 container/testdata/theme/text-test-theme.png diff --git a/container/testdata/theme/icon-other-theme.png b/container/testdata/theme/icon-other-theme.png new file mode 100644 index 0000000000000000000000000000000000000000..fc0a4953aedf8fbc3d23a3d52182034e61303da3 GIT binary patch literal 472 zcmV;}0Vn>6P)<@-0004>Nkl&9nT-OC{qqZ#oq=Wzx7lXlIJRT#2YTc4C7DW-IG>N1-(SQK}075vK zOvFe^q5*@%BU7R+qy$Gwa5^FJ)iKka{I_T@QjFXB$FD5Cpoe*Ck<^rtkZjrsbz;n&$hyX`00=!`W<>EJmYIR-SF! zo6V-z>lG=A5VCFicDr4#*Q}h!<55n+b=~E1sj4N~rmE_EKBttPPNzR56!Eq_olf&h z@AvzH66^IkKjC~n{~8x8S}R|TZSi%BH|dj3bV5pSqy(qjocKpNHz%Y7M@n#{1Scg? z`NyFwaU5q#L{Zd$M;yoZ`(2Er?h};K%jHtH#3$W56K&B6iJt%f0RR6}32JpGD(^-B O0000<@-0005(Nklwj~ zf{-bfV+_vcGo{oE0{{SokWzZNTr^Fylu#7Ki|l`4f=m*ss`?{ADYcaF=q-FC6w?t& zJc%Tpd@GT95Trytpa1h9m&*ksA&R0b%ZUfFEQ_M(w?wnqlq87|Vk~2^m?TM!M&ozg z_)I4ATHJ28pM0j%>Gb=3jx#*~$8pta^?JRo*Xy4&c|Cw*2?$}Y*Xwq>RvXIYG9hHS zTzVye5E={ytyasvd#O}PrBd_x{C>Z?EI|kv4u_RW#ooXmo6Qyqh1qPzoR(G+@cp)Z zI-NcSjK|}2I&HIIyWO_i?T>vDiNvdBuXm1Etyah55de@(CX2=5ulsx@F&d4g(`@VfQD=`$fZ3m>`n`LP!tSCZ literal 0 HcmV?d00001 diff --git a/container/testdata/theme/text-other-theme.png b/container/testdata/theme/text-other-theme.png new file mode 100644 index 0000000000000000000000000000000000000000..aa39d28464b92042580012ef5b9ede6c741eb5ea GIT binary patch literal 1071 zcmV+~1kn45P)n-Y+}ye%X=t%Z|KXcI3KW+6}F{ySuKgE?snDVuEGaKW6olw0DwWD~Q4GVf z8FhGgn5OB;$;nVC^hH0X(|LM&3IGH_bar+EfXCx;yWJ@I{QR8kDG&(a@p!sCZ=(u@ zqPDj7gOg0_=lKBul$MqvzpJaOt*xzO2dPwQGMNkp13?fh%X&PX)z#I@%S#m1YPBYl zsk*vaBoeVKdvS5Gv$NxHI5Zl~z`y|NGcq#5^L#WKotc^Wv|nZ<63N)uSV>6<07Rov zsZ^@h>vcNa^z^jP=Tj&Yqobn*1qJBTDH4fjnhu3R4u`{Hv8dH*ltiUcp;Q?L`l4S) zM+cIdpP%2~-=`>Qe0-cBh_0@#xw$!=PKV?c7Z;sQCrOe9gW>G#3;=94o6%@&Y-|L8 z+1c4hB*OFj@9|3{63OfO`g#DkzP>&>I>K>08jZSKuGZF8olXY;_xJaxo6%@wS=Q}# z+wFGL5(orhu^77c`~7!!cbNzMgkQ3p1p)y&h^y6Vo6VNmM=TcOIDU9|==FMOnpP^6 zX0y4cr)PbA-EOz1&hUeL<@pK(|9{mV9v+e}M3O`z5s$~MR%=U3OM81eMNuS4_Vx8? zG@7NQr9bGGoIS^Ju~am zFYa%9dwT#-US8hZ+>BZ<46CZDqG=icDk>^!YHDyCkH_QN+uJ86Cur4Cg>W2)ZqaJB z0FYr9_+tG5z}niHUau!fvcJFIWHK=fBbUp?V)4q#ir4GaXf%U^gB-`*-rnLkjtq{E zkC7RAkpW<6Xvku*U>IgLo6`;YiSawa{vei zgW+%($MLeVGNn?<^SsODT3A>>_Z}P^I2;a?4a2Z-IGkxwQvbiItgQUFE&|7KilQ(K zi^XD(kB_M#nM_txRK)XqI2=ws(t!^VVFoHlG=`D_%r`!g#MexoACac_@`8HS-KqYr72lOzdaY^59k5CnlSmStJfw6FZ~`Mi}{rIZR3 z`KhXEt&b6mv7x2N&*EV%hkBpCwx2m{KXcfA=CJ+DVO%eK$ol$vPfw4b@#5lQbab?$ zVD0Vg48xqAoz>Xy^77K*Z~#D8R~G=J(`i*zZ*FcXk^_L1l@(DGCnqP%e}#Cz|9E+M z`QlNMB$LS`0PsBj^z@`R`h33O;bD&BZf|e5wze{v3;=K(H!(5c@puqI*=%-aXXo_v zG!O{P%*?#Lz9y4NMNyWQmp_ccaoqdMvhw#Ce!o8y3W=ha$z=Na`uh9(gTY`rofZV4 zv$OO1`Z|}(4GauiU0pey&Ojgl04&S)_V#|Ah}!r$ozAJLDF7HBAHTo99~v53TwEL* z8=Ie>Z)?{B@HZ}r4 zOG^s?BoYap=OdBG@$qpq8cie;RY$45zR)zSuPC+uNRo7LaBy^V1ON*Q3z10V@$s>{ zyL)wY)$jLL9i{sG-QC>*077VKY02<^!WhS5vF+{c>FMcUFgQ3k7>!2tTO?UoMymG{ zMKK=H}*H zE>}1l{#ieL9A#PNc|H^h=?1Y_Oy4KGmF`q3B?tlloS&cX@9+D3zLAj;Ns`J8Q9=Ft z42q&Sj>8zgf8FJBH8eCRielK3u`KIwI7Cq_6bc{qR?GUQgE4+9*Ka8QDScR$<%&A5 z_w|A8XAaxX9DmC1vzlZXr3XMoe)=c>7y0IVl3^HYeT Date: Fri, 14 Jun 2024 11:47:31 +0100 Subject: [PATCH 38/78] Add missing test file --- widget/testdata/menu/desktop/layout_shortcuts_other.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widget/testdata/menu/desktop/layout_shortcuts_other.xml b/widget/testdata/menu/desktop/layout_shortcuts_other.xml index 1b3c1c3f39..d65e8f0d26 100644 --- a/widget/testdata/menu/desktop/layout_shortcuts_other.xml +++ b/widget/testdata/menu/desktop/layout_shortcuts_other.xml @@ -30,7 +30,7 @@ C - + @@ -38,7 +38,7 @@ D - + From 24241cc5f412caf9ef86b88f6e218da0becacf46 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 14 Jun 2024 11:50:41 +0100 Subject: [PATCH 39/78] Remove files refactored to the wrong place --- .../popup_menu/kbd_ctrl_first_active.xml | 36 -------- .../popup_menu/kbd_ctrl_first_sub_active.xml | 63 ------------- .../kbd_ctrl_first_sub_sub_active.xml | 89 ------------------- .../popup_menu/kbd_ctrl_second_active.xml | 36 -------- .../popup_menu/kbd_ctrl_second_sub_active.xml | 63 ------------- .../kbd_ctrl_second_sub_sub_active.xml | 89 ------------------- widget/testdata/popup_menu/kbd_ctrl_shown.xml | 35 -------- 7 files changed, 411 deletions(-) delete mode 100644 widget/testdata/popup_menu/kbd_ctrl_first_active.xml delete mode 100644 widget/testdata/popup_menu/kbd_ctrl_first_sub_active.xml delete mode 100644 widget/testdata/popup_menu/kbd_ctrl_first_sub_sub_active.xml delete mode 100644 widget/testdata/popup_menu/kbd_ctrl_second_active.xml delete mode 100644 widget/testdata/popup_menu/kbd_ctrl_second_sub_active.xml delete mode 100644 widget/testdata/popup_menu/kbd_ctrl_second_sub_sub_active.xml delete mode 100644 widget/testdata/popup_menu/kbd_ctrl_shown.xml diff --git a/widget/testdata/popup_menu/kbd_ctrl_first_active.xml b/widget/testdata/popup_menu/kbd_ctrl_first_active.xml deleted file mode 100644 index a0cbddd831..0000000000 --- a/widget/testdata/popup_menu/kbd_ctrl_first_active.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - Option A - - - Option B - - - - - - - - - diff --git a/widget/testdata/popup_menu/kbd_ctrl_first_sub_active.xml b/widget/testdata/popup_menu/kbd_ctrl_first_sub_active.xml deleted file mode 100644 index d088429229..0000000000 --- a/widget/testdata/popup_menu/kbd_ctrl_first_sub_active.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - Option A - - - - Option B - - - - - - - - - - - - - - - - - - - - - - - Sub Option A - - - Sub Option B - - - - - - - - - - diff --git a/widget/testdata/popup_menu/kbd_ctrl_first_sub_sub_active.xml b/widget/testdata/popup_menu/kbd_ctrl_first_sub_sub_active.xml deleted file mode 100644 index f11dd5e16f..0000000000 --- a/widget/testdata/popup_menu/kbd_ctrl_first_sub_sub_active.xml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - Option A - - - - Option B - - - - - - - - - - - - - - - - - - - - - - Sub Option A - - - - Sub Option B - - - - - - - - - - - - - - - - - - - - - - - Sub Sub Option A - - - Sub Sub Option B - - - - - - - - - - diff --git a/widget/testdata/popup_menu/kbd_ctrl_second_active.xml b/widget/testdata/popup_menu/kbd_ctrl_second_active.xml deleted file mode 100644 index ef81b77812..0000000000 --- a/widget/testdata/popup_menu/kbd_ctrl_second_active.xml +++ /dev/null @@ -1,36 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - Option A - - - - Option B - - - - - - - - - diff --git a/widget/testdata/popup_menu/kbd_ctrl_second_sub_active.xml b/widget/testdata/popup_menu/kbd_ctrl_second_sub_active.xml deleted file mode 100644 index fe0b26f5ad..0000000000 --- a/widget/testdata/popup_menu/kbd_ctrl_second_sub_active.xml +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - Option A - - - - Option B - - - - - - - - - - - - - - - - - - - - - - Sub Option A - - - - Sub Option B - - - - - - - - - - diff --git a/widget/testdata/popup_menu/kbd_ctrl_second_sub_sub_active.xml b/widget/testdata/popup_menu/kbd_ctrl_second_sub_sub_active.xml deleted file mode 100644 index bb543306ca..0000000000 --- a/widget/testdata/popup_menu/kbd_ctrl_second_sub_sub_active.xml +++ /dev/null @@ -1,89 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - Option A - - - - Option B - - - - - - - - - - - - - - - - - - - - - - Sub Option A - - - - Sub Option B - - - - - - - - - - - - - - - - - - - - - - Sub Sub Option A - - - - Sub Sub Option B - - - - - - - - - - diff --git a/widget/testdata/popup_menu/kbd_ctrl_shown.xml b/widget/testdata/popup_menu/kbd_ctrl_shown.xml deleted file mode 100644 index 1bdbcc9234..0000000000 --- a/widget/testdata/popup_menu/kbd_ctrl_shown.xml +++ /dev/null @@ -1,35 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - Option A - - - Option B - - - - - - - - - From 7bc98c647e896cb42c9bef33e72b4de89d48192b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Fri, 14 Jun 2024 12:59:03 +0200 Subject: [PATCH 40/78] [app][internal/app] fix build flags XDG files should not be included in mobile. For non-Android non-IOS mobile builds (e.g., running tests with `-tags mobile`) the `app_other.go` has to be included, to provide `OpenURL` and `SendNotification`. The whole scheme has clearly evolved over time. Might be useful to separate the different functionalities and get a more clear scheme in the end. --- app/app_other.go | 2 +- app/app_xdg.go | 2 +- internal/app/theme_xdg.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/app_other.go b/app/app_other.go index 6842be5e64..b14d4f7040 100644 --- a/app/app_other.go +++ b/app/app_other.go @@ -1,4 +1,4 @@ -//go:build ci || (!linux && !darwin && !windows && !freebsd && !openbsd && !netbsd && !wasm && !test_web_driver) +//go:build ci || (mobile && !android && !ios) || (!linux && !darwin && !windows && !freebsd && !openbsd && !netbsd && !wasm && !test_web_driver) package app diff --git a/app/app_xdg.go b/app/app_xdg.go index 93b9a75d7b..2bf9327fbc 100644 --- a/app/app_xdg.go +++ b/app/app_xdg.go @@ -1,4 +1,4 @@ -//go:build !ci && !wasm && !test_web_driver && (linux || openbsd || freebsd || netbsd) && !android +//go:build !ci && !wasm && !test_web_driver && !android && !ios && !mobile && (linux || openbsd || freebsd || netbsd) package app diff --git a/internal/app/theme_xdg.go b/internal/app/theme_xdg.go index 0ed53d77ee..87634699c8 100644 --- a/internal/app/theme_xdg.go +++ b/internal/app/theme_xdg.go @@ -1,4 +1,4 @@ -//go:build !wasm && !test_web_driver && !android && (linux || openbsd || freebsd || netbsd) +//go:build !wasm && !test_web_driver && !android && !ios && !mobile && (linux || openbsd || freebsd || netbsd) package app From 630e3d5438df4e980285f44247c875e7495a2a42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Fri, 14 Jun 2024 15:22:00 +0200 Subject: [PATCH 41/78] [fyne_settings] fix system theme detection for preview --- cmd/fyne_settings/settings/appearance.go | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/cmd/fyne_settings/settings/appearance.go b/cmd/fyne_settings/settings/appearance.go index 5b13ad7244..c311403c66 100644 --- a/cmd/fyne_settings/settings/appearance.go +++ b/cmd/fyne_settings/settings/appearance.go @@ -19,9 +19,10 @@ import ( ) const ( - themeNameDark = "dark" - themeNameLight = "light" - themeNameSystem = "system default" + themeNameDark = "dark" + themeNameLight = "light" + themeNameSystemLabel = "system default" + themeNameSystemSettings = "" ) // Settings gives access to user interfaces to control Fyne settings @@ -61,9 +62,9 @@ func (s *Settings) LoadAppearanceScreen(w fyne.Window) fyne.CanvasObject { def := s.fyneSettings.ThemeName themeNames := []string{themeNameDark, themeNameLight} if runtime.GOOS == "darwin" || runtime.GOOS == "windows" { - themeNames = append(themeNames, themeNameSystem) - if s.fyneSettings.ThemeName == "" { - def = themeNameSystem + themeNames = append(themeNames, themeNameSystemLabel) + if s.fyneSettings.ThemeName == themeNameSystemSettings { + def = themeNameSystemLabel } } themes := widget.NewSelect(themeNames, s.chooseTheme) @@ -105,8 +106,8 @@ func (s *Settings) LoadAppearanceScreen(w fyne.Window) fyne.CanvasObject { } func (s *Settings) chooseTheme(name string) { - if name == themeNameSystem { - name = "" + if name == themeNameSystemLabel { + name = themeNameSystemSettings } s.fyneSettings.ThemeName = name @@ -248,7 +249,7 @@ func (p *previewTheme) Color(n fyne.ThemeColorName, _ fyne.ThemeVariant) color.C switch p.s.fyneSettings.ThemeName { case themeNameLight: variant = theme.VariantLight - case themeNameSystem: + case themeNameSystemSettings: variant = internalapp.DefaultVariant() } From 4a39e89c058eb3c7127544691d2dc6f6289d27f3 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 14 Jun 2024 14:48:39 +0100 Subject: [PATCH 42/78] Exit early on About creation and avoid colliding id name --- internal/driver/glfw/menu_darwin.m | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/internal/driver/glfw/menu_darwin.m b/internal/driver/glfw/menu_darwin.m index 58e71e3d01..66157be086 100644 --- a/internal/driver/glfw/menu_darwin.m +++ b/internal/driver/glfw/menu_darwin.m @@ -83,10 +83,18 @@ void handleException(const char* m, id e) { exceptionCallback([[NSString stringWithFormat:@"%s failed: %@", m, e] UTF8String]); } -const void* insertDarwinMenuItem(const void* m, const char* label, const char* keyEquivalent, unsigned int keyEquivalentModifierMask, int id, int index, bool isSeparator, const void *imageData, unsigned int imageDataLength) { +const void* insertDarwinMenuItem(const void* m, const char* label, const char* keyEquivalent, unsigned int keyEquivalentModifierMask, int nextId, int index, bool isSeparator, const void *imageData, unsigned int imageDataLength) { NSMenu* menu = (NSMenu*)m; NSMenuItem* item; + if (strcmp(label, "About") == 0) { + item = [menu itemArray][0]; + [item setAction:@selector(tapped:)]; + [item setTarget:[FyneMenuHandler class]]; + [item setTag:nextId+menuTagMin]; + return item; + } + if (isSeparator) { item = [NSMenuItem separatorItem]; } else { @@ -98,7 +106,7 @@ void handleException(const char* m, id e) { [item setKeyEquivalentModifierMask: keyEquivalentModifierMask]; } [item setTarget:[FyneMenuHandler class]]; - [item setTag:id+menuTagMin]; + [item setTag:nextId+menuTagMin]; if (imageData) { char *x = (char *)imageData; NSData *data = [[NSData alloc] initWithBytes: imageData length: imageDataLength]; @@ -109,18 +117,10 @@ void handleException(const char* m, id e) { } } - if (strcmp(label, "About") == 0) { - item = [menu itemArray][0]; - [item setAction:@selector(tapped:)]; - [item setTarget:[FyneMenuHandler class]]; - [item setTag:id+menuTagMin]; - return item; + if (index > -1) { + [menu insertItem:item atIndex:index]; } else { - if (index > -1) { - [menu insertItem:item atIndex:index]; - } else { - [menu addItem:item]; - } + [menu addItem:item]; } [item release]; // retained by the menu return item; From b3d09d6e4cd1fa184980bad48ceb154d5e072cd9 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 14 Jun 2024 14:49:44 +0100 Subject: [PATCH 43/78] Don't mutate input and avoid getting index out of sync --- internal/driver/glfw/menu_darwin.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/internal/driver/glfw/menu_darwin.go b/internal/driver/glfw/menu_darwin.go index addce2adf0..908680544d 100644 --- a/internal/driver/glfw/menu_darwin.go +++ b/internal/driver/glfw/menu_darwin.go @@ -138,13 +138,18 @@ func exceptionCallback(e *C.char) { } func handleSpecialItems(w *window, menu *fyne.Menu, nextItemID int, addSeparator bool) (*fyne.Menu, int) { - for i, item := range menu.Items { + menu = fyne.NewMenu(menu.Label, menu.Items...) // copy so we can manipulate + for i := 0; i < len(menu.Items); i++ { + item := menu.Items[i] switch item.Label { case "Settings", "Settings…", "Preferences", "Preferences…": items := make([]*fyne.MenuItem, 0, len(menu.Items)-1) items = append(items, menu.Items[:i]...) - items = append(items, menu.Items[i+1:]...) + if i < len(menu.Items)-1 { + items = append(items, menu.Items[i+1:]...) + } menu.Items = items + i-- insertNativeMenuItem(C.darwinAppMenu(), item, nextItemID, 1) if addSeparator { @@ -168,6 +173,7 @@ func handleSpecialItems(w *window, menu *fyne.Menu, nextItemID int, addSeparator items = append(items, menu.Items[i+1:]...) } menu.Items = items + i-- insertNativeMenuItem(C.darwinAppMenu(), item, nextItemID, 1) if addSeparator { From 50676be139d8cd9cd55b20f2120799eee3d48661 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Fri, 14 Jun 2024 16:40:01 +0200 Subject: [PATCH 44/78] [fyne_settings] adjust constant name --- cmd/fyne_settings/settings/appearance.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/cmd/fyne_settings/settings/appearance.go b/cmd/fyne_settings/settings/appearance.go index c311403c66..79aba2ac16 100644 --- a/cmd/fyne_settings/settings/appearance.go +++ b/cmd/fyne_settings/settings/appearance.go @@ -19,10 +19,10 @@ import ( ) const ( - themeNameDark = "dark" - themeNameLight = "light" - themeNameSystemLabel = "system default" - themeNameSystemSettings = "" + themeNameDark = "dark" + themeNameLight = "light" + themeNameSystem = "" + themeNameSystemLabel = "system default" ) // Settings gives access to user interfaces to control Fyne settings @@ -63,7 +63,7 @@ func (s *Settings) LoadAppearanceScreen(w fyne.Window) fyne.CanvasObject { themeNames := []string{themeNameDark, themeNameLight} if runtime.GOOS == "darwin" || runtime.GOOS == "windows" { themeNames = append(themeNames, themeNameSystemLabel) - if s.fyneSettings.ThemeName == themeNameSystemSettings { + if s.fyneSettings.ThemeName == themeNameSystem { def = themeNameSystemLabel } } @@ -107,7 +107,7 @@ func (s *Settings) LoadAppearanceScreen(w fyne.Window) fyne.CanvasObject { func (s *Settings) chooseTheme(name string) { if name == themeNameSystemLabel { - name = themeNameSystemSettings + name = themeNameSystem } s.fyneSettings.ThemeName = name @@ -249,7 +249,7 @@ func (p *previewTheme) Color(n fyne.ThemeColorName, _ fyne.ThemeVariant) color.C switch p.s.fyneSettings.ThemeName { case themeNameLight: variant = theme.VariantLight - case themeNameSystemSettings: + case themeNameSystem: variant = internalapp.DefaultVariant() } From cfec87b85d69e06bb53ab2c7173b3200d88383d2 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 14 Jun 2024 18:47:16 +0100 Subject: [PATCH 45/78] We missed some AUTHOR additions --- AUTHORS | 2 ++ cmd/fyne_demo/data/metadata_bundled.go | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 5def3f5e99..18fe51397e 100644 --- a/AUTHORS +++ b/AUTHORS @@ -11,4 +11,6 @@ Jacob Alzén Charles A. Daniels Pablo Fuentes Changkun Ou +Cedric Bail +Drew Weymouth diff --git a/cmd/fyne_demo/data/metadata_bundled.go b/cmd/fyne_demo/data/metadata_bundled.go index 383d5eb2cf..2805627dff 100644 --- a/cmd/fyne_demo/data/metadata_bundled.go +++ b/cmd/fyne_demo/data/metadata_bundled.go @@ -8,5 +8,5 @@ import "fyne.io/fyne/v2" var resourceAuthors = &fyne.StaticResource{ StaticName: "AUTHORS", StaticContent: []byte( - "Andy Williams \nSteve OConnor \nLuca Corbo \nPaul Hovey \nCharles Corbett \nTilo Prütz \nStephen Houston \nStorm Hess \nStuart Scott \nJacob Alzén \nCharles A. Daniels \nPablo Fuentes \nChangkun Ou \n\n"), + "Andy Williams \nSteve OConnor \nLuca Corbo \nPaul Hovey \nCharles Corbett \nTilo Prütz \nStephen Houston \nStorm Hess \nStuart Scott \nJacob Alzén \nCharles A. Daniels \nPablo Fuentes \nChangkun Ou \nCedric Bail\nDrew Weymouth\n\n"), } From 2f4368c033f157eb2268cc0f8d21a227b860c9b5 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 14 Jun 2024 19:01:35 +0100 Subject: [PATCH 46/78] Correctly start the app event processing from ShowAndRun --- internal/driver/glfw/window.go | 2 +- internal/driver/mobile/window.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/driver/glfw/window.go b/internal/driver/glfw/window.go index 2605bee4f1..6f81a21532 100644 --- a/internal/driver/glfw/window.go +++ b/internal/driver/glfw/window.go @@ -227,7 +227,7 @@ func (w *window) Close() { func (w *window) ShowAndRun() { w.Show() - w.driver.Run() + fyne.CurrentApp().Run() } // Clipboard returns the system clipboard diff --git a/internal/driver/mobile/window.go b/internal/driver/mobile/window.go index 8e8571b8c0..1a45acd30e 100644 --- a/internal/driver/mobile/window.go +++ b/internal/driver/mobile/window.go @@ -186,7 +186,7 @@ func (w *window) Close() { func (w *window) ShowAndRun() { w.Show() - fyne.CurrentApp().Driver().Run() + fyne.CurrentApp().Run() } func (w *window) Content() fyne.CanvasObject { From b26152d70a9a6c9f3088b09c3de637a716a4e048 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Fri, 14 Jun 2024 20:45:12 +0100 Subject: [PATCH 47/78] Make sure initial rendering is correct Fixes #4937 --- container/theme.go | 1 + 1 file changed, 1 insertion(+) diff --git a/container/theme.go b/container/theme.go index 7cc55d10f4..cd4e29c3d7 100644 --- a/container/theme.go +++ b/container/theme.go @@ -30,6 +30,7 @@ func NewThemeOverride(obj fyne.CanvasObject, th fyne.Theme) *ThemeOverride { t.ExtendBaseWidget(t) cache.OverrideTheme(obj, th) + obj.Refresh() // required as the widgets passed in could have been initially rendered with default theme return t } From ffb34fe91d0b9d8ce73c552bae735d23b420d39c Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sat, 15 Jun 2024 14:56:49 +0100 Subject: [PATCH 48/78] Make sure that text in overridden widgets is picking up the right theme resources Unless overridden by FontSource of course. Fixes #4937 --- internal/cache/theme.go | 9 +++++++++ internal/painter/font.go | 33 +++++++++++++++++++++---------- internal/painter/gl/texture.go | 2 +- internal/painter/software/draw.go | 2 +- theme/theme.go | 2 +- widget/hyperlink_test.go | 6 +++--- widget/richtext.go | 2 +- 7 files changed, 39 insertions(+), 17 deletions(-) diff --git a/internal/cache/theme.go b/internal/cache/theme.go index a4c5c6de8f..25efb597d1 100644 --- a/internal/cache/theme.go +++ b/internal/cache/theme.go @@ -29,6 +29,15 @@ func OverrideTheme(o fyne.CanvasObject, th fyne.Theme) { overrideTheme(o, s, id) } +func WidgetScopeID(o fyne.CanvasObject) string { + data, ok := overrides.Load(o) + if !ok { + return "" + } + + return data.(*overrideScope).cacheID +} + func WidgetTheme(o fyne.CanvasObject) fyne.Theme { data, ok := overrides.Load(o) if !ok { diff --git a/internal/painter/font.go b/internal/painter/font.go index e54e22d3bd..77e795f5d5 100644 --- a/internal/painter/font.go +++ b/internal/painter/font.go @@ -95,7 +95,7 @@ func lookupFaces(theme, fallback fyne.Resource, family string, style fyne.TextSt } // CachedFontFace returns a Font face held in memory. These are loaded from the current theme. -func CachedFontFace(style fyne.TextStyle, source fyne.Resource, fontDP float32, texScale float32) *FontCacheItem { +func CachedFontFace(style fyne.TextStyle, source fyne.Resource, o fyne.CanvasObject) *FontCacheItem { if source != nil { val, ok := fontCustomCache.Load(source) if !ok { @@ -111,21 +111,29 @@ func CachedFontFace(style fyne.TextStyle, source fyne.Resource, fontDP float32, return val.(*FontCacheItem) } - val, ok := fontCache.Load(style) + scope := "" + if o != nil { // for overridden themes get the cache key right + scope = cache.WidgetScopeID(o) + } + + val, ok := fontCache.Load(cacheID{style: style, scope: scope}) if !ok { var faces *dynamicFontMap + th := theme.CurrentForWidget(o) + font1 := th.Font(style) + switch { case style.Monospace: - faces = lookupFaces(theme.TextMonospaceFont(), theme.DefaultTextMonospaceFont(), fontscan.Monospace, style) + faces = lookupFaces(font1, theme.DefaultTextMonospaceFont(), fontscan.Monospace, style) case style.Bold: if style.Italic { - faces = lookupFaces(theme.TextBoldItalicFont(), theme.DefaultTextBoldItalicFont(), fontscan.SansSerif, style) + faces = lookupFaces(font1, theme.DefaultTextBoldItalicFont(), fontscan.SansSerif, style) } else { - faces = lookupFaces(theme.TextBoldFont(), theme.DefaultTextBoldFont(), fontscan.SansSerif, style) + faces = lookupFaces(font1, theme.DefaultTextBoldFont(), fontscan.SansSerif, style) } case style.Italic: - faces = lookupFaces(theme.TextItalicFont(), theme.DefaultTextItalicFont(), fontscan.SansSerif, style) + faces = lookupFaces(font1, theme.DefaultTextItalicFont(), fontscan.SansSerif, style) case style.Symbol: th := theme.SymbolFont() fallback := theme.DefaultSymbolFont() @@ -138,14 +146,14 @@ func CachedFontFace(style fyne.TextStyle, source fyne.Resource, fontDP float32, faces = &dynamicFontMap{family: fontscan.SansSerif, faces: []font.Face{f1, f2}} } default: - faces = lookupFaces(theme.TextFont(), theme.DefaultTextFont(), fontscan.SansSerif, style) + faces = lookupFaces(font1, theme.DefaultTextFont(), fontscan.SansSerif, style) } if emoji := theme.DefaultEmojiFont(); !style.Symbol && emoji != nil { faces.addFace(loadMeasureFont(emoji)) // TODO only one emoji - maybe others too } val = &FontCacheItem{Fonts: faces} - fontCache.Store(style, val) + fontCache.Store(cacheID{style: style, scope: scope}, val) } return val.(*FontCacheItem) @@ -220,7 +228,7 @@ func float32ToFixed266(f float32) fixed.Int26_6 { } func measureText(text string, fontSize float32, style fyne.TextStyle, source fyne.Resource) (fyne.Size, float32) { - face := CachedFontFace(style, source, fontSize, 1) + face := CachedFontFace(style, source, nil) return MeasureString(face.Fonts, text, fontSize, style) } @@ -329,7 +337,12 @@ type FontCacheItem struct { Fonts shaping.Fontmap } -var fontCache = &sync.Map{} // map[fyne.TextStyle]*FontCacheItem +type cacheID struct { + style fyne.TextStyle + scope string +} + +var fontCache = &sync.Map{} // map[cacheID]*FontCacheItem var fontCustomCache = &sync.Map{} // map[string]*FontCacheItem for custom resources type noopLogger struct{} diff --git a/internal/painter/gl/texture.go b/internal/painter/gl/texture.go index 9dce2fcebf..5989dcd2aa 100644 --- a/internal/painter/gl/texture.go +++ b/internal/painter/gl/texture.go @@ -153,7 +153,7 @@ func (p *painter) newGlTextTexture(obj fyne.CanvasObject) Texture { height := int(math.Ceil(float64(p.textureScale(bounds.Height)))) img := image.NewNRGBA(image.Rect(0, 0, width, height)) - face := paint.CachedFontFace(text.TextStyle, text.FontSource, text.TextSize*p.canvas.Scale(), p.texScale) + face := paint.CachedFontFace(text.TextStyle, text.FontSource, text) paint.DrawString(img, text.Text, color, face.Fonts, text.TextSize, p.pixScale, text.TextStyle) return p.imgToTexture(img, canvas.ImageScaleSmooth) } diff --git a/internal/painter/software/draw.go b/internal/painter/software/draw.go index 35319752c7..9b246177b3 100644 --- a/internal/painter/software/draw.go +++ b/internal/painter/software/draw.go @@ -142,7 +142,7 @@ func drawText(c fyne.Canvas, text *canvas.Text, pos fyne.Position, base *image.N color = theme.ForegroundColor() } - face := painter.CachedFontFace(text.TextStyle, text.FontSource, text.TextSize*c.Scale(), 1) + face := painter.CachedFontFace(text.TextStyle, text.FontSource, text) painter.DrawString(txtImg, text.Text, color, face.Fonts, text.TextSize, c.Scale(), text.TextStyle) size := text.Size() diff --git a/theme/theme.go b/theme/theme.go index b325a5cb1f..6968f51f9d 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -196,7 +196,7 @@ func Current() fyne.Theme { // It looks for widget overrides and falls back to the application's current theme. // // Since: 2.5 -func CurrentForWidget(w fyne.Widget) fyne.Theme { +func CurrentForWidget(w fyne.CanvasObject) fyne.Theme { if custom := cache.WidgetTheme(w); custom != nil { return custom } diff --git a/widget/hyperlink_test.go b/widget/hyperlink_test.go index 03bbe7048d..afb0a52465 100644 --- a/widget/hyperlink_test.go +++ b/widget/hyperlink_test.go @@ -169,7 +169,7 @@ func TestHyperlink_SetUrl(t *testing.T) { func TestHyperlink_ThemeOverride(t *testing.T) { _ = test.NewApp() defer test.NewApp() - test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) + test.ApplyTheme(t, test.Theme()) hyperlink := &Hyperlink{Text: "Test"} bg := canvas.NewRectangle(color.Gray{Y: 0xc0}) @@ -180,12 +180,12 @@ func TestHyperlink_ThemeOverride(t *testing.T) { w.Resize(hyperlink.MinSize()) light := w.Canvas().Capture() - test.ApplyTheme(t, test.Theme()) + test.ApplyTheme(t, test.NewTheme()) hyperlink.Refresh() ugly := w.Canvas().Capture() assertPixelsMatch(t, false, ugly, light) - cache.OverrideTheme(hyperlink, internalTest.LightTheme(theme.DefaultTheme())) + cache.OverrideTheme(hyperlink, test.Theme()) hyperlink.Refresh() override := w.Canvas().Capture() assertPixelsMatch(t, true, override, light) diff --git a/widget/richtext.go b/widget/richtext.go index 6e542a0b89..73af8ce5ba 100644 --- a/widget/richtext.go +++ b/widget/richtext.go @@ -1110,7 +1110,7 @@ func splitLines(seg *TextSegment) []rowBoundary { } func truncateLimit(s string, text *canvas.Text, limit int, ellipsis []rune) (int, bool) { - face := paint.CachedFontFace(text.TextStyle, text.FontSource, text.TextSize, 1.0) + face := paint.CachedFontFace(text.TextStyle, text.FontSource, text) runes := []rune(s) in := shaping.Input{ From a56f123f33e5de097f6c95880744333607fdbbad Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sat, 15 Jun 2024 15:04:45 +0100 Subject: [PATCH 49/78] Update other test files for new internal API changes --- internal/painter/font_test.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/painter/font_test.go b/internal/painter/font_test.go index 074cdeb07f..8be4e69c5c 100644 --- a/internal/painter/font_test.go +++ b/internal/painter/font_test.go @@ -27,7 +27,7 @@ func TestCachedFontFace(t *testing.T) { }, } { t.Run(name, func(t *testing.T) { - got := painter.CachedFontFace(tt.style, nil, 14, 1) + got := painter.CachedFontFace(tt.style, nil, nil) for _, r := range tt.runes { f := got.Fonts.ResolveFace(r) assert.NotNil(t, f, "symbol Font should include: %c", r) @@ -77,7 +77,7 @@ func TestDrawString(t *testing.T) { } { t.Run(name, func(t *testing.T) { img := image.NewNRGBA(image.Rect(0, 0, 300, 100)) - f := painter.CachedFontFace(tt.style, nil, tt.size, 1) + f := painter.CachedFontFace(tt.style, nil, nil) fontMap := &intTest.FontMap{f.Fonts.ResolveFace(' ')} // first (ascii) font painter.DrawString(img, tt.string, tt.color, fontMap, tt.size, 1, fyne.TextStyle{TabWidth: tt.tabWidth}) @@ -117,7 +117,7 @@ func TestMeasureString(t *testing.T) { }, } { t.Run(name, func(t *testing.T) { - faces := painter.CachedFontFace(tt.style, nil, tt.size, 1) + faces := painter.CachedFontFace(tt.style, nil, nil) fontMap := &intTest.FontMap{faces.Fonts.ResolveFace(' ')} // first (ascii) font got, _ := painter.MeasureString(fontMap, tt.string, tt.size, fyne.TextStyle{TabWidth: tt.tabWidth}) assert.Equal(t, tt.want, got.Width) From 587fd87bfada4ffe0f49816aa25d4b4e660c0bb7 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sat, 15 Jun 2024 15:17:27 +0100 Subject: [PATCH 50/78] Correct a previously incorrect test result --- container/testdata/theme/text-other-theme.png | Bin 1071 -> 1020 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/container/testdata/theme/text-other-theme.png b/container/testdata/theme/text-other-theme.png index aa39d28464b92042580012ef5b9ede6c741eb5ea..db0cb8c0f486b58541d7a6105245e83a3d5e4c36 100644 GIT binary patch delta 998 zcmVb_-B!9z6L_t(|oa~rONHSd*$B#3UrrkuwqUbUc1YrwTQ7t0U2#GG% zHi#A#1TNgPXj8kOWziytF3VOy*HuWH3IYwf5>!@7ChCZZ4LXkJgYUff>AdfkllFZY z_+QQQpEEwc^UQP3I74)Gb%7ifmTiC(%JXF=A~8@X6e^X9Ab*Igpzu8J^?F&BO*E70 zmqj=L0FL7%Neav)zAVBa;W#dEa=riZe3>cFmznZ>nJLegnR1=)vj_7G<$AsT_<#5qh3ToUuMfkpFTthYi;JQt0D#?YPc*e!ZD(hvQmJGZ=HTD}Rg@rz z?(S}_Rx6Xq7>2pIxj8yIB1zIgsAN788?N)cT-lTEI6jFkmv7 zc%HY}Y?YOjX0y4lun+(+GBRQ`8eJ~e`T2Py66xsZ;D33(wzgI(m0}p?bUOWhzsuzk z2`9FGG)=QC>vp?QsL^P8dwcix_O`dT0RTRqZ*+8&B+1v;*Or!+larH;jg4Qk$1n)t z+1Z&?Ds66V-r3oCdU_H`_UjkK45BE?Znr}SQD`(8Js!{Q?k)fTB@Tr`Znqmk$Z=d% zRaHSj0e>19uMJl0>FMd~>uYq@ zVzDeNEZ{h9Hk$_r2a!n-M0ItwV0npD>i!cfUVph<4ggqNTYGqT_~ZDitE-urnaRn? zo}Ql5)6=)Nx0;$79LLk+6IDNkVcy^0QHTyIDk?s?gyT50lb4p3#%K8Q@{$H$iuy?; z5{ja3Z*Swy-Q8Uv5EvR7LTf^;R=2jcuCK4FR4ScLXSG@bfq+`AHW&;aA0N-p&+!Wz z8h;ufge=SY{r+#`Q>)bqh2rt?G4602x3si0Ha2E5nE(LMX!P>(G8T(PA`y*7qu1-v zFsIYGxVRV&hXDXKn@y+F4G#|k0G5}RtyZgeK1t&DD|9173cbwx{r<#9R!K=oQBhGS z6bc4|Nogb!k|e|7aJ*0cO@a+F{TFhEVPAeXgMaIHA42Hyc+$v{>;M1qe3>cFmzjPP zAJ6mIBLQf)7dT0LUavQch|y@&=kp27r2Uy?S%<^%|5ByUkLtf1RIc;=6#xML|G2iB Ud9zi>@&Et;07*qoM6N<$f(Rh+>;M1& delta 1050 zcmV+#1m*ku2d@Z_B!BivL_t(|oa~rQNGe|xz|ZKUVLBsYW+_p|gqtvuAR-8&TI3?z z6tyU5p>5iV3f#1bpk>jfRiuFsrHhI_gd`#>rA$$)iD^dv@a`X<)zdzF z@8tu3tMQ&Y=l<@UGjlKEZEbCk!w9}x;2rXQ*@372kVqsHMStNq{w*pz&j*7+hG9}0 zU##CZ$^n2-C@d~6e%1KG?;GV1LZR?gORm>n-Y+}ye%X=t%Z|KXcI3KW+6}F{ySuKg zE?snDVuEGaKW6olw0DwWD~Q4GVf8FhGgn5OB;$;nVC^hH0X(|LM&3IGH_bar+E zfXCx;yWJ@I{D1tM>?sfk;_-O8Ja3~4g`&2$_Jfm5>*x6a0F;)NBEPGvtF5iAWCy8K zYBHG&1_MD5EX#U4p4HXW%gaj?)oQgSlc~D8S|k#&EPHWrv9q(|a5yv?&A`9_>N7Gj z!t;DI8l9P$`LthVBofKk*jPzP2>?W+QK?j_*XwmU-GB7-w9n^LC={ckqXh*8=+r3^ ziD;S*g+dO8!(y?h)oPSPrBb0(83y{IUq?p=lAE8O-{0S-C~ACsoFIs>-ze70Jy%sJ~}$W zaXcE0x_?}**49>?P6q(@_xGrq(P(5@*6nuN?RL}>2n1rW7`pcR{daeFnFsxZU$UG9 z0s%URtJP|o&6e6nEEeN9et3B3^?GTVRw|Wdv$?0IXMKI$Znvk-@PmBi`3eO8f7Krz z9+EFal0+gAkH@W6YfDQ@dwV-YQ6x$B_4R2qnt!FGr9bGGoIS^Ju~amFYa%9dwT#-US8hZ+>BZ<46CZDqG=ic zDk>^!YHDyCkH_QN+uJ86Cur4Cg>W2)ZqaJB0FYr9_+tG5z}niHUau!fvcJFIWHK=f zBY&66#bWWw%8J+P)o3(>gM%E$-QM2fIF1aCkB^ZVdXWKOXlTe{v0xZxHk;E8`ib>R zt?o!9GBq`|ySvMA96=B&l}aoY`~Cj&^K$?Q27}>n7{~FlvNEMo$@9F+uVvmoHsUew6R#a5P^L#iQPCnBl zg@uK3xtw8`NF!ExNp&CM@Eu^*(n@#*O)5D2`RKiAKHdB5z)`(?*J z<@edm@wfB#Gx@?V7z}=+BFAxWkApA1&kV!(e7?VH^$!13{pBFJ?)P5+00960&l60I UhfBo%o&W#<07*qoM6N<$f@n7rTL1t6 From 2b1a497d9ebaa5748d1a1dd9c16753905c935a86 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sat, 15 Jun 2024 21:47:49 +0100 Subject: [PATCH 51/78] Simplify native menu handling code --- internal/driver/glfw/menu_darwin.go | 34 ++++------------------------- 1 file changed, 4 insertions(+), 30 deletions(-) diff --git a/internal/driver/glfw/menu_darwin.go b/internal/driver/glfw/menu_darwin.go index 908680544d..c6a4b8bc95 100644 --- a/internal/driver/glfw/menu_darwin.go +++ b/internal/driver/glfw/menu_darwin.go @@ -142,41 +142,15 @@ func handleSpecialItems(w *window, menu *fyne.Menu, nextItemID int, addSeparator for i := 0; i < len(menu.Items); i++ { item := menu.Items[i] switch item.Label { - case "Settings", "Settings…", "Preferences", "Preferences…": + case "About", "Settings", "Settings…", "Preferences", "Preferences…": items := make([]*fyne.MenuItem, 0, len(menu.Items)-1) items = append(items, menu.Items[:i]...) - if i < len(menu.Items)-1 { - items = append(items, menu.Items[i+1:]...) - } - menu.Items = items - i-- - - insertNativeMenuItem(C.darwinAppMenu(), item, nextItemID, 1) - if addSeparator { - C.insertDarwinMenuItem( - C.darwinAppMenu(), - C.CString(""), - C.CString(""), - C.uint(0), - C.int(nextItemID), - C.int(1), - C.bool(true), - unsafe.Pointer(nil), - C.uint(0), - ) - } - nextItemID = registerCallback(w, item, nextItemID) - case "About": - items := make([]*fyne.MenuItem, 0, len(menu.Items)-1) - items = append(items, menu.Items[:i]...) - if i < len(menu.Items)-1 { - items = append(items, menu.Items[i+1:]...) - } - menu.Items = items + items = append(items, menu.Items[i+1:]...) + menu, nextItemID = handleSpecialItems(w, fyne.NewMenu(menu.Label, items...), nextItemID, false) i-- insertNativeMenuItem(C.darwinAppMenu(), item, nextItemID, 1) - if addSeparator { + if addSeparator && item.Label != "About" { C.insertDarwinMenuItem( C.darwinAppMenu(), C.CString(""), From a00808dcff1bdb6db802f69a1cf3f964f51199f4 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sat, 15 Jun 2024 21:49:00 +0100 Subject: [PATCH 52/78] Correct name for file menu --- internal/driver/glfw/menu_darwin_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/internal/driver/glfw/menu_darwin_test.go b/internal/driver/glfw/menu_darwin_test.go index de8d600534..3a1c16afc9 100644 --- a/internal/driver/glfw/menu_darwin_test.go +++ b/internal/driver/glfw/menu_darwin_test.go @@ -40,7 +40,7 @@ func TestDarwinMenu(t *testing.T) { itemRecent := fyne.NewMenuItem("Recent", nil) itemFoo := fyne.NewMenuItem("Foo", func() { lastAction = "foo" }) itemRecent.ChildMenu = fyne.NewMenu("", itemFoo) - menuEdit := fyne.NewMenu("File", itemNew, itemOpen, fyne.NewMenuItemSeparator(), itemRecent) + menuFile := fyne.NewMenu("File", itemNew, itemOpen, fyne.NewMenuItemSeparator(), itemRecent) itemHelp := fyne.NewMenuItem("Help", func() { lastAction = "Help!!!" }) itemHelp.Shortcut = &desktop.CustomShortcut{KeyName: fyne.KeyH, Modifier: fyne.KeyModifierControl} @@ -59,7 +59,7 @@ func TestDarwinMenu(t *testing.T) { itemMoreSetings := fyne.NewMenuItem("Settings…", func() { lastAction = "more settings" }) menuSettings := fyne.NewMenu("Settings", itemSettings, fyne.NewMenuItemSeparator(), itemMoreSetings) - mainMenu := fyne.NewMainMenu(menuEdit, menuHelp, menuMore, menuSettings) + mainMenu := fyne.NewMainMenu(menuFile, menuHelp, menuMore, menuSettings) runOnMain(func() { setupNativeMenu(w, mainMenu) }) From 2af30b0af21d73958d334fb7d4b0f9bac6f5ad5a Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Sat, 15 Jun 2024 21:49:32 +0100 Subject: [PATCH 53/78] Test about menu callback and is not adding to length on macOS --- internal/driver/glfw/menu_darwin_test.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/internal/driver/glfw/menu_darwin_test.go b/internal/driver/glfw/menu_darwin_test.go index 3a1c16afc9..df0dd3ffd4 100644 --- a/internal/driver/glfw/menu_darwin_test.go +++ b/internal/driver/glfw/menu_darwin_test.go @@ -3,6 +3,8 @@ package glfw import ( + "os" + "path/filepath" "testing" "unsafe" @@ -40,7 +42,8 @@ func TestDarwinMenu(t *testing.T) { itemRecent := fyne.NewMenuItem("Recent", nil) itemFoo := fyne.NewMenuItem("Foo", func() { lastAction = "foo" }) itemRecent.ChildMenu = fyne.NewMenu("", itemFoo) - menuFile := fyne.NewMenu("File", itemNew, itemOpen, fyne.NewMenuItemSeparator(), itemRecent) + itemAbout := fyne.NewMenuItem("About", func() { lastAction = "about" }) + menuFile := fyne.NewMenu("File", itemNew, itemOpen, fyne.NewMenuItemSeparator(), itemRecent, itemAbout) itemHelp := fyne.NewMenuItem("Help", func() { lastAction = "Help!!!" }) itemHelp.Shortcut = &desktop.CustomShortcut{KeyName: fyne.KeyH, Modifier: fyne.KeyModifierControl} @@ -70,7 +73,9 @@ func TestDarwinMenu(t *testing.T) { assert.Equal(t, 5, testNSMenuNumberOfItems(mm), "two built-in + three custom") m := testNSMenuItemSubmenu(testNSMenuItemAtIndex(mm, 0)) - assert.Equal(t, "", testNSMenuTitle(m), "app menu doesn’t have a title") + assert.Equal(t, "", testNSMenuTitle(m), "app menu doesn't have a title") + assertNSMenuItem(t, "About "+filepath.Base(os.Args[0]), "", 0, m, 0) + assertLastAction("about") assertNSMenuItemSeparator(m, 1) assertNSMenuItem(t, "Preferences", "", 0, m, 2) assertLastAction("prefs") From 9de5027b34ae45526e5b241404456d1b7f65f9e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Mon, 17 Jun 2024 07:45:29 +0200 Subject: [PATCH 54/78] =?UTF-8?q?[theme]=20rename=20=E2=80=9Con*=E2=80=9D?= =?UTF-8?q?=20colors=20to=20=E2=80=9C*Foreground=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/fyne_settings/settings/appearance.go | 4 +- test/markup_renderer.go | 54 +++++++------- test/theme.go | 16 ++-- test/theme_test.go | 8 +- theme/color.go | 94 ++++++++++++------------ theme/theme.go | 28 +++---- theme/theme_test.go | 16 ++-- widget/button.go | 8 +- widget/testdata/form/layout.xml | 4 +- 9 files changed, 116 insertions(+), 116 deletions(-) diff --git a/cmd/fyne_settings/settings/appearance.go b/cmd/fyne_settings/settings/appearance.go index 3f3b024ac7..d2ac95913b 100644 --- a/cmd/fyne_settings/settings/appearance.go +++ b/cmd/fyne_settings/settings/appearance.go @@ -249,8 +249,8 @@ func (p *previewTheme) Color(n fyne.ThemeColorName, _ fyne.ThemeVariant) color.C switch n { case theme.ColorNamePrimary: return theme.PrimaryColorNamed(p.s.fyneSettings.PrimaryColor) - case theme.ColorNameOnPrimary: - return theme.OnPrimaryColorNamed(p.s.fyneSettings.PrimaryColor) + case theme.ColorNamePrimaryForeground: + return theme.PrimaryForegroundColorNamed(p.s.fyneSettings.PrimaryColor) } return p.t.Color(n, variant) diff --git a/test/markup_renderer.go b/test/markup_renderer.go index 7ce458c722..07e7f93bec 100644 --- a/test/markup_renderer.go +++ b/test/markup_renderer.go @@ -397,33 +397,33 @@ func nrgbaColor(c color.Color) color.NRGBA { func knownColor(c color.Color) string { return map[color.Color]string{ - nrgbaColor(theme.BackgroundColor()): "background", - nrgbaColor(theme.ButtonColor()): "button", - nrgbaColor(theme.DisabledButtonColor()): "disabled button", - nrgbaColor(theme.DisabledColor()): "disabled", - nrgbaColor(theme.ErrorColor()): "error", - nrgbaColor(theme.FocusColor()): "focus", - nrgbaColor(theme.ForegroundColor()): "foreground", - nrgbaColor(theme.Color(theme.ColorNameHeaderBackground)): "headerBackground", - nrgbaColor(theme.HoverColor()): "hover", - nrgbaColor(theme.Color(theme.ColorNameHyperlink)): "hyperlink", - nrgbaColor(theme.InputBackgroundColor()): "inputBackground", - nrgbaColor(theme.InputBorderColor()): "inputBorder", - nrgbaColor(theme.MenuBackgroundColor()): "menuBackground", - nrgbaColor(theme.Color(theme.ColorNameOnError)): "onError", - nrgbaColor(theme.Color(theme.ColorNameOnPrimary)): "onPrimary", - nrgbaColor(theme.Color(theme.ColorNameOnSuccess)): "onSuccess", - nrgbaColor(theme.Color(theme.ColorNameOnWarning)): "onWarning", - nrgbaColor(theme.OverlayBackgroundColor()): "overlayBackground", - nrgbaColor(theme.PlaceHolderColor()): "placeholder", - nrgbaColor(theme.Color(theme.ColorNamePressed)): "pressed", - nrgbaColor(theme.PrimaryColor()): "primary", - nrgbaColor(theme.ScrollBarColor()): "scrollbar", - nrgbaColor(theme.SelectionColor()): "selection", - nrgbaColor(theme.Color(theme.ColorNameSeparator)): "separator", - nrgbaColor(theme.Color(theme.ColorNameSuccess)): "success", - nrgbaColor(theme.ShadowColor()): "shadow", - nrgbaColor(theme.Color(theme.ColorNameWarning)): "warning", + nrgbaColor(theme.BackgroundColor()): "background", + nrgbaColor(theme.ButtonColor()): "button", + nrgbaColor(theme.DisabledButtonColor()): "disabled button", + nrgbaColor(theme.DisabledColor()): "disabled", + nrgbaColor(theme.ErrorColor()): "error", + nrgbaColor(theme.Color(theme.ColorNameErrorForeground)): "errorForeground", + nrgbaColor(theme.FocusColor()): "focus", + nrgbaColor(theme.ForegroundColor()): "foreground", + nrgbaColor(theme.Color(theme.ColorNameHeaderBackground)): "headerBackground", + nrgbaColor(theme.HoverColor()): "hover", + nrgbaColor(theme.Color(theme.ColorNameHyperlink)): "hyperlink", + nrgbaColor(theme.InputBackgroundColor()): "inputBackground", + nrgbaColor(theme.InputBorderColor()): "inputBorder", + nrgbaColor(theme.MenuBackgroundColor()): "menuBackground", + nrgbaColor(theme.OverlayBackgroundColor()): "overlayBackground", + nrgbaColor(theme.PlaceHolderColor()): "placeholder", + nrgbaColor(theme.Color(theme.ColorNamePressed)): "pressed", + nrgbaColor(theme.PrimaryColor()): "primary", + nrgbaColor(theme.Color(theme.ColorNamePrimaryForeground)): "primaryForeground", + nrgbaColor(theme.ScrollBarColor()): "scrollbar", + nrgbaColor(theme.SelectionColor()): "selection", + nrgbaColor(theme.Color(theme.ColorNameSeparator)): "separator", + nrgbaColor(theme.Color(theme.ColorNameSuccess)): "success", + nrgbaColor(theme.Color(theme.ColorNameSuccessForeground)): "successForeground", + nrgbaColor(theme.ShadowColor()): "shadow", + nrgbaColor(theme.Color(theme.ColorNameWarning)): "warning", + nrgbaColor(theme.Color(theme.ColorNameWarningForeground)): "warningForeground", }[nrgbaColor(c)] } diff --git a/test/theme.go b/test/theme.go index 1949e2ffe3..af9a239edc 100644 --- a/test/theme.go +++ b/test/theme.go @@ -40,10 +40,10 @@ func NewTheme() fyne.Theme { theme.ColorNameInputBackground: red(30), theme.ColorNameInputBorder: gray(10), theme.ColorNameMenuBackground: red(50), - theme.ColorNameOnError: red(210), - theme.ColorNameOnPrimary: red(200), - theme.ColorNameOnSuccess: blue(201), - theme.ColorNameOnWarning: blue(202), + theme.ColorNameErrorForeground: red(210), + theme.ColorNamePrimaryForeground: red(200), + theme.ColorNameSuccessForeground: blue(201), + theme.ColorNameWarningForeground: blue(202), theme.ColorNameOverlayBackground: red(44), theme.ColorNamePlaceHolder: blue(200), theme.ColorNamePressed: blue(250), @@ -101,10 +101,10 @@ func Theme() fyne.Theme { theme.ColorNameInputBackground: color.NRGBA{R: 0x66, G: 0x66, B: 0x66, A: 0xff}, theme.ColorNameInputBorder: color.NRGBA{R: 0x86, G: 0x86, B: 0x86, A: 0xff}, theme.ColorNameMenuBackground: color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff}, - theme.ColorNameOnError: color.NRGBA{R: 0x08, G: 0x0a, B: 0x0f, A: 0xff}, - theme.ColorNameOnPrimary: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0f, A: 0xff}, - theme.ColorNameOnSuccess: color.NRGBA{R: 0x0a, G: 0x0c, B: 0x0f, A: 0xff}, - theme.ColorNameOnWarning: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0a, A: 0xff}, + theme.ColorNameErrorForeground: color.NRGBA{R: 0x08, G: 0x0a, B: 0x0f, A: 0xff}, + theme.ColorNamePrimaryForeground: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0f, A: 0xff}, + theme.ColorNameSuccessForeground: color.NRGBA{R: 0x0a, G: 0x0c, B: 0x0f, A: 0xff}, + theme.ColorNameWarningForeground: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0a, A: 0xff}, theme.ColorNameOverlayBackground: color.NRGBA{R: 0x28, G: 0x28, B: 0x28, A: 0xff}, theme.ColorNamePlaceHolder: color.NRGBA{R: 0xaa, G: 0xaa, B: 0xaa, A: 0xff}, theme.ColorNamePressed: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x33}, diff --git a/test/theme_test.go b/test/theme_test.go index 93641012d0..f10711434b 100644 --- a/test/theme_test.go +++ b/test/theme_test.go @@ -26,10 +26,10 @@ var knownColorNames = []fyne.ThemeColorName{ theme.ColorNameInputBackground, theme.ColorNameInputBorder, theme.ColorNameMenuBackground, - theme.ColorNameOnError, - theme.ColorNameOnPrimary, - theme.ColorNameOnSuccess, - theme.ColorNameOnWarning, + theme.ColorNameErrorForeground, + theme.ColorNamePrimaryForeground, + theme.ColorNameSuccessForeground, + theme.ColorNameWarningForeground, theme.ColorNameOverlayBackground, theme.ColorNamePlaceHolder, theme.ColorNamePressed, diff --git a/theme/color.go b/theme/color.go index 06d26adc87..e6618769e3 100644 --- a/theme/color.go +++ b/theme/color.go @@ -66,6 +66,11 @@ const ( // Since: 2.0 ColorNameError fyne.ThemeColorName = "error" + // ColorNameErrorForeground is the name of theme lookup for a contrast color to the error color. + // + // Since: 2.5 + ColorNameErrorForeground fyne.ThemeColorName = "errorForeground" + // ColorNameFocus is the name of theme lookup for focus color. // // Since: 2.0 @@ -106,26 +111,6 @@ const ( // Since: 2.3 ColorNameMenuBackground fyne.ThemeColorName = "menuBackground" - // ColorNameOnError is the name of theme lookup for a contrast color to the error color. - // - // Since: 2.5 - ColorNameOnError fyne.ThemeColorName = "onError" - - // ColorNameOnPrimary is the name of theme lookup for a contrast color to the primary color. - // - // Since: 2.5 - ColorNameOnPrimary fyne.ThemeColorName = "onPrimary" - - // ColorNameOnSuccess is the name of theme lookup for a contrast color to the success color. - // - // Since: 2.5 - ColorNameOnSuccess fyne.ThemeColorName = "onSuccess" - - // ColorNameOnWarning is the name of theme lookup for a contrast color to the warning color. - // - // Since: 2.5 - ColorNameOnWarning fyne.ThemeColorName = "onWarning" - // ColorNameOverlayBackground is the name of theme lookup for background color of overlays like dialogs. // // Since: 2.3 @@ -146,6 +131,11 @@ const ( // Since: 2.0 ColorNamePrimary fyne.ThemeColorName = "primary" + // ColorNamePrimaryForeground is the name of theme lookup for a contrast color to the primary color. + // + // Since: 2.5 + ColorNamePrimaryForeground fyne.ThemeColorName = "primaryForeground" + // ColorNameScrollBar is the name of theme lookup for scrollbar color. // // Since: 2.0 @@ -171,10 +161,20 @@ const ( // Since: 2.3 ColorNameSuccess fyne.ThemeColorName = "success" + // ColorNameSuccessForeground is the name of theme lookup for a contrast color to the success color. + // + // Since: 2.5 + ColorNameSuccessForeground fyne.ThemeColorName = "successForeground" + // ColorNameWarning is the name of theme lookup for warning color. // // Since: 2.3 ColorNameWarning fyne.ThemeColorName = "warning" + + // ColorNameWarningForeground is the name of theme lookup for a contrast color to the warning color. + // + // Since: 2.5 + ColorNameWarningForeground fyne.ThemeColorName = "warningForeground" ) var ( @@ -183,15 +183,13 @@ var ( colorDarkDisabled = color.NRGBA{R: 0x39, G: 0x39, B: 0x3a, A: 0xff} colorDarkDisabledButton = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} colorDarkError = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} + colorDarkErrorForeground = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} colorDarkForeground = color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff} colorDarkHeaderBackground = color.NRGBA{R: 0x1b, G: 0x1b, B: 0x1b, A: 0xff} colorDarkHover = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x0f} colorDarkInputBackground = color.NRGBA{R: 0x20, G: 0x20, B: 0x23, A: 0xff} colorDarkInputBorder = color.NRGBA{R: 0x39, G: 0x39, B: 0x3a, A: 0xff} colorDarkMenuBackground = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} - colorDarkOnError = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} - colorDarkOnSuccess = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} - colorDarkOnWarning = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} colorDarkOverlayBackground = color.NRGBA{R: 0x18, G: 0x1d, B: 0x25, A: 0xff} colorDarkPlaceholder = color.NRGBA{R: 0xb2, G: 0xb2, B: 0xb2, A: 0xff} colorDarkPressed = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x66} @@ -199,29 +197,31 @@ var ( colorDarkSeparator = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xff} colorDarkShadow = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x66} colorDarkSuccess = color.NRGBA{R: 0x43, G: 0xf4, B: 0x36, A: 0xff} + colorDarkSuccessForeground = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} colorDarkWarning = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} - - colorLightBackground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} - colorLightButton = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} - colorLightDisabled = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} - colorLightDisabledButton = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} - colorLightError = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} - colorLightForeground = color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff} - colorLightHeaderBackground = color.NRGBA{R: 0xf9, G: 0xf9, B: 0xf9, A: 0xff} - colorLightHover = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x0f} - colorLightInputBackground = color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff} - colorLightInputBorder = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} - colorLightMenuBackground = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} - colorLightOnError = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} - colorLightOnSuccess = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} - colorLightOnWarning = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} - colorLightPlaceholder = color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff} - colorLightPressed = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x19} - colorLightScrollBar = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x99} - colorLightSeparator = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} - colorLightShadow = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x33} - colorLightSuccess = color.NRGBA{R: 0x43, G: 0xf4, B: 0x36, A: 0xff} - colorLightWarning = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} + colorDarkWarningForeground = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} + + colorLightBackground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorLightButton = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} + colorLightDisabled = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} + colorLightDisabledButton = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} + colorLightError = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} + colorLightErrorForeground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorLightForeground = color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff} + colorLightHeaderBackground = color.NRGBA{R: 0xf9, G: 0xf9, B: 0xf9, A: 0xff} + colorLightHover = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x0f} + colorLightInputBackground = color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff} + colorLightInputBorder = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} + colorLightMenuBackground = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} + colorLightPlaceholder = color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff} + colorLightPressed = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x19} + colorLightScrollBar = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x99} + colorLightSeparator = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} + colorLightShadow = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x33} + colorLightSuccess = color.NRGBA{R: 0x43, G: 0xf4, B: 0x36, A: 0xff} + colorLightSuccessForeground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorLightWarning = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} + colorLightWarningForeground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} ) // BackgroundColor returns the theme's background color. @@ -323,10 +323,10 @@ func MenuBackgroundColor() color.Color { return safeColorLookup(ColorNameMenuBackground, currentVariant()) } -// OnPrimaryColorNamed returns a theme specific color used for text and icons against the named primary color. +// PrimaryForegroundColorNamed returns a theme specific color used for text and icons against the named primary color. // // Since: 2.5 -func OnPrimaryColorNamed(name string) color.Color { +func PrimaryForegroundColorNamed(name string) color.Color { switch name { case ColorRed: return colorLightBackground diff --git a/theme/theme.go b/theme/theme.go index 1d1199d3a7..7125e119e8 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -106,8 +106,8 @@ func (t *builtinTheme) Color(n fyne.ThemeColorName, v fyne.ThemeVariant) color.C primary := fyne.CurrentApp().Settings().PrimaryColor() if n == ColorNamePrimary || n == ColorNameHyperlink { return PrimaryColorNamed(primary) - } else if n == ColorNameOnPrimary { - return OnPrimaryColorNamed(primary) + } else if n == ColorNamePrimaryForeground { + return PrimaryForegroundColorNamed(primary) } else if n == ColorNameFocus { return focusColorNamed(primary) } else if n == ColorNameSelection { @@ -238,12 +238,12 @@ func darkPaletteColorNamed(name fyne.ThemeColorName) color.Color { return colorDarkInputBorder case ColorNameMenuBackground: return colorDarkMenuBackground - case ColorNameOnError: - return colorDarkOnError - case ColorNameOnSuccess: - return colorDarkOnSuccess - case ColorNameOnWarning: - return colorDarkOnWarning + case ColorNameErrorForeground: + return colorDarkErrorForeground + case ColorNameSuccessForeground: + return colorDarkSuccessForeground + case ColorNameWarningForeground: + return colorDarkWarningForeground case ColorNameOverlayBackground: return colorDarkOverlayBackground case ColorNamePlaceHolder: @@ -312,12 +312,12 @@ func lightPaletteColorNamed(name fyne.ThemeColorName) color.Color { return colorLightInputBorder case ColorNameMenuBackground: return colorLightMenuBackground - case ColorNameOnError: - return colorLightOnError - case ColorNameOnSuccess: - return colorLightOnSuccess - case ColorNameOnWarning: - return colorLightOnWarning + case ColorNameErrorForeground: + return colorLightErrorForeground + case ColorNameSuccessForeground: + return colorLightSuccessForeground + case ColorNameWarningForeground: + return colorLightWarningForeground case ColorNameOverlayBackground: return colorLightBackground case ColorNamePlaceHolder: diff --git a/theme/theme_test.go b/theme/theme_test.go index 031d8d07f7..12e794674c 100644 --- a/theme/theme_test.go +++ b/theme/theme_test.go @@ -25,10 +25,10 @@ var knownColorNames = []fyne.ThemeColorName{ theme.ColorNameInputBackground, theme.ColorNameInputBorder, theme.ColorNameMenuBackground, - theme.ColorNameOnError, - theme.ColorNameOnPrimary, - theme.ColorNameOnSuccess, - theme.ColorNameOnWarning, + theme.ColorNameErrorForeground, + theme.ColorNamePrimaryForeground, + theme.ColorNameSuccessForeground, + theme.ColorNameWarningForeground, theme.ColorNameOverlayBackground, theme.ColorNamePlaceHolder, theme.ColorNamePressed, @@ -58,7 +58,7 @@ func Test_DefaultTheme_AllColorsDefined(t *testing.T) { } } -func Test_DefaultTheme_OnPrimaryColor(t *testing.T) { +func Test_DefaultTheme_PrimaryForegroundColor(t *testing.T) { darkColor := color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} defaultTheme := theme.DefaultTheme() extraColorName := "some unexpected other color name where primary defaults to blue" @@ -79,15 +79,15 @@ func Test_DefaultTheme_OnPrimaryColor(t *testing.T) { if name != extraColorName { testedColorNames = append(testedColorNames, name) } - t.Run("primary color "+name, func(t *testing.T) { + t.Run("primary foreground color "+name, func(t *testing.T) { oldApp := fyne.CurrentApp() defer fyne.SetCurrentApp(oldApp) fyne.SetCurrentApp(&themedApp{theme: defaultTheme, primaryColor: name}) t.Run("light variant", func(t *testing.T) { - assert.Equal(t, expectedColor, defaultTheme.Color(theme.ColorNameOnPrimary, theme.VariantLight)) + assert.Equal(t, expectedColor, defaultTheme.Color(theme.ColorNamePrimaryForeground, theme.VariantLight)) }) t.Run("dark variant", func(t *testing.T) { - assert.Equal(t, expectedColor, defaultTheme.Color(theme.ColorNameOnPrimary, theme.VariantDark)) + assert.Equal(t, expectedColor, defaultTheme.Color(theme.ColorNamePrimaryForeground, theme.VariantDark)) }) }) } diff --git a/widget/button.go b/widget/button.go index 2f02c6d5ee..80e4831543 100644 --- a/widget/button.go +++ b/widget/button.go @@ -365,20 +365,20 @@ func (r *buttonRenderer) buttonColorNames() (foreground, background, backgroundB if background == "" { switch b.Importance { case DangerImportance: - foreground = theme.ColorNameOnError + foreground = theme.ColorNameErrorForeground background = theme.ColorNameError case HighImportance: - foreground = theme.ColorNameOnPrimary + foreground = theme.ColorNamePrimaryForeground background = theme.ColorNamePrimary case LowImportance: if backgroundBlend != "" { background = theme.ColorNameButton } case SuccessImportance: - foreground = theme.ColorNameOnSuccess + foreground = theme.ColorNameSuccessForeground background = theme.ColorNameSuccess case WarningImportance: - foreground = theme.ColorNameOnWarning + foreground = theme.ColorNameWarningForeground background = theme.ColorNameWarning default: background = theme.ColorNameButton diff --git a/widget/testdata/form/layout.xml b/widget/testdata/form/layout.xml index de9444978a..0764e782e6 100644 --- a/widget/testdata/form/layout.xml +++ b/widget/testdata/form/layout.xml @@ -52,9 +52,9 @@ - Submit + Submit - + From afc0166385080130e9779a11e7b461fa0d2b4bba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Mon, 17 Jun 2024 10:00:31 +0200 Subject: [PATCH 55/78] fixed order of some code due to color name changes --- test/theme.go | 16 ++++++++-------- test/theme_test.go | 10 +++++----- theme/theme.go | 24 ++++++++++++------------ theme/theme_test.go | 10 +++++----- 4 files changed, 30 insertions(+), 30 deletions(-) diff --git a/test/theme.go b/test/theme.go index af9a239edc..92b0c62645 100644 --- a/test/theme.go +++ b/test/theme.go @@ -32,6 +32,7 @@ func NewTheme() fyne.Theme { theme.ColorNameDisabled: gray(20), theme.ColorNameDisabledButton: gray(230), theme.ColorNameError: blue(255), + theme.ColorNameErrorForeground: red(210), theme.ColorNameFocus: red(66), theme.ColorNameForeground: gray(255), theme.ColorNameHeaderBackground: red(22), @@ -40,20 +41,19 @@ func NewTheme() fyne.Theme { theme.ColorNameInputBackground: red(30), theme.ColorNameInputBorder: gray(10), theme.ColorNameMenuBackground: red(50), - theme.ColorNameErrorForeground: red(210), - theme.ColorNamePrimaryForeground: red(200), - theme.ColorNameSuccessForeground: blue(201), - theme.ColorNameWarningForeground: blue(202), theme.ColorNameOverlayBackground: red(44), theme.ColorNamePlaceHolder: blue(200), theme.ColorNamePressed: blue(250), theme.ColorNamePrimary: green(255), + theme.ColorNamePrimaryForeground: red(200), theme.ColorNameScrollBar: blue(220), theme.ColorNameSelection: red(55), theme.ColorNameSeparator: gray(30), theme.ColorNameShadow: blue(150), theme.ColorNameSuccess: green(150), + theme.ColorNameSuccessForeground: blue(201), theme.ColorNameWarning: red(100), + theme.ColorNameWarningForeground: blue(202), }, fonts: map[fyne.TextStyle]fyne.Resource{ {}: theme.DefaultTextBoldFont(), @@ -93,6 +93,7 @@ func Theme() fyne.Theme { theme.ColorNameDisabled: color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff}, theme.ColorNameDisabledButton: color.NRGBA{R: 0x22, G: 0x22, B: 0x22, A: 0xff}, theme.ColorNameError: color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff}, + theme.ColorNameErrorForeground: color.NRGBA{R: 0x08, G: 0x0a, B: 0x0f, A: 0xff}, theme.ColorNameFocus: color.NRGBA{R: 0x78, G: 0x3a, B: 0x3a, A: 0xff}, theme.ColorNameForeground: color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff}, theme.ColorNameHeaderBackground: color.NRGBA{R: 0x25, G: 0x25, B: 0x25, A: 0xff}, @@ -101,20 +102,19 @@ func Theme() fyne.Theme { theme.ColorNameInputBackground: color.NRGBA{R: 0x66, G: 0x66, B: 0x66, A: 0xff}, theme.ColorNameInputBorder: color.NRGBA{R: 0x86, G: 0x86, B: 0x86, A: 0xff}, theme.ColorNameMenuBackground: color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff}, - theme.ColorNameErrorForeground: color.NRGBA{R: 0x08, G: 0x0a, B: 0x0f, A: 0xff}, - theme.ColorNamePrimaryForeground: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0f, A: 0xff}, - theme.ColorNameSuccessForeground: color.NRGBA{R: 0x0a, G: 0x0c, B: 0x0f, A: 0xff}, - theme.ColorNameWarningForeground: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0a, A: 0xff}, theme.ColorNameOverlayBackground: color.NRGBA{R: 0x28, G: 0x28, B: 0x28, A: 0xff}, theme.ColorNamePlaceHolder: color.NRGBA{R: 0xaa, G: 0xaa, B: 0xaa, A: 0xff}, theme.ColorNamePressed: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x33}, theme.ColorNamePrimary: color.NRGBA{R: 0xff, G: 0xc0, B: 0x80, A: 0xff}, + theme.ColorNamePrimaryForeground: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0f, A: 0xff}, theme.ColorNameScrollBar: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xaa}, theme.ColorNameSelection: color.NRGBA{R: 0x78, G: 0x3a, B: 0x3a, A: 0x99}, theme.ColorNameSeparator: color.NRGBA{R: 0x90, G: 0x90, B: 0x90, A: 0xff}, theme.ColorNameShadow: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x88}, theme.ColorNameSuccess: color.NRGBA{R: 0x00, G: 0x99, B: 0x00, A: 0xff}, + theme.ColorNameSuccessForeground: color.NRGBA{R: 0x0a, G: 0x0c, B: 0x0f, A: 0xff}, theme.ColorNameWarning: color.NRGBA{R: 0xee, G: 0xee, B: 0x00, A: 0xff}, + theme.ColorNameWarningForeground: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0a, A: 0xff}, }, fonts: map[fyne.TextStyle]fyne.Resource{ {}: theme.DefaultTextFont(), diff --git a/test/theme_test.go b/test/theme_test.go index f10711434b..bd193fed3b 100644 --- a/test/theme_test.go +++ b/test/theme_test.go @@ -15,9 +15,10 @@ import ( var knownColorNames = []fyne.ThemeColorName{ theme.ColorNameBackground, theme.ColorNameButton, - theme.ColorNameDisabledButton, theme.ColorNameDisabled, + theme.ColorNameDisabledButton, theme.ColorNameError, + theme.ColorNameErrorForeground, theme.ColorNameFocus, theme.ColorNameForeground, theme.ColorNameHeaderBackground, @@ -26,20 +27,19 @@ var knownColorNames = []fyne.ThemeColorName{ theme.ColorNameInputBackground, theme.ColorNameInputBorder, theme.ColorNameMenuBackground, - theme.ColorNameErrorForeground, - theme.ColorNamePrimaryForeground, - theme.ColorNameSuccessForeground, - theme.ColorNameWarningForeground, theme.ColorNameOverlayBackground, theme.ColorNamePlaceHolder, theme.ColorNamePressed, theme.ColorNamePrimary, + theme.ColorNamePrimaryForeground, theme.ColorNameScrollBar, theme.ColorNameSelection, theme.ColorNameSeparator, theme.ColorNameShadow, theme.ColorNameSuccess, + theme.ColorNameSuccessForeground, theme.ColorNameWarning, + theme.ColorNameWarningForeground, } // Try to keep this in sync with the existing variants at theme/theme.go diff --git a/theme/theme.go b/theme/theme.go index 7125e119e8..e08feaee97 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -226,6 +226,8 @@ func darkPaletteColorNamed(name fyne.ThemeColorName) color.Color { return colorDarkDisabledButton case ColorNameError: return colorDarkError + case ColorNameErrorForeground: + return colorDarkErrorForeground case ColorNameForeground: return colorDarkForeground case ColorNameHover: @@ -238,12 +240,6 @@ func darkPaletteColorNamed(name fyne.ThemeColorName) color.Color { return colorDarkInputBorder case ColorNameMenuBackground: return colorDarkMenuBackground - case ColorNameErrorForeground: - return colorDarkErrorForeground - case ColorNameSuccessForeground: - return colorDarkSuccessForeground - case ColorNameWarningForeground: - return colorDarkWarningForeground case ColorNameOverlayBackground: return colorDarkOverlayBackground case ColorNamePlaceHolder: @@ -258,8 +254,12 @@ func darkPaletteColorNamed(name fyne.ThemeColorName) color.Color { return colorDarkShadow case ColorNameSuccess: return colorDarkSuccess + case ColorNameSuccessForeground: + return colorDarkSuccessForeground case ColorNameWarning: return colorDarkWarning + case ColorNameWarningForeground: + return colorDarkWarningForeground } return color.Transparent @@ -300,6 +300,8 @@ func lightPaletteColorNamed(name fyne.ThemeColorName) color.Color { return colorLightDisabledButton case ColorNameError: return colorLightError + case ColorNameErrorForeground: + return colorLightErrorForeground case ColorNameForeground: return colorLightForeground case ColorNameHover: @@ -312,12 +314,6 @@ func lightPaletteColorNamed(name fyne.ThemeColorName) color.Color { return colorLightInputBorder case ColorNameMenuBackground: return colorLightMenuBackground - case ColorNameErrorForeground: - return colorLightErrorForeground - case ColorNameSuccessForeground: - return colorLightSuccessForeground - case ColorNameWarningForeground: - return colorLightWarningForeground case ColorNameOverlayBackground: return colorLightBackground case ColorNamePlaceHolder: @@ -332,8 +328,12 @@ func lightPaletteColorNamed(name fyne.ThemeColorName) color.Color { return colorLightShadow case ColorNameSuccess: return colorLightSuccess + case ColorNameSuccessForeground: + return colorLightSuccessForeground case ColorNameWarning: return colorLightWarning + case ColorNameWarningForeground: + return colorLightWarningForeground } return color.Transparent diff --git a/theme/theme_test.go b/theme/theme_test.go index 12e794674c..b7c14887cf 100644 --- a/theme/theme_test.go +++ b/theme/theme_test.go @@ -14,9 +14,10 @@ import ( var knownColorNames = []fyne.ThemeColorName{ theme.ColorNameBackground, theme.ColorNameButton, - theme.ColorNameDisabledButton, theme.ColorNameDisabled, + theme.ColorNameDisabledButton, theme.ColorNameError, + theme.ColorNameErrorForeground, theme.ColorNameFocus, theme.ColorNameForeground, theme.ColorNameHeaderBackground, @@ -25,20 +26,19 @@ var knownColorNames = []fyne.ThemeColorName{ theme.ColorNameInputBackground, theme.ColorNameInputBorder, theme.ColorNameMenuBackground, - theme.ColorNameErrorForeground, - theme.ColorNamePrimaryForeground, - theme.ColorNameSuccessForeground, - theme.ColorNameWarningForeground, theme.ColorNameOverlayBackground, theme.ColorNamePlaceHolder, theme.ColorNamePressed, theme.ColorNamePrimary, + theme.ColorNamePrimaryForeground, theme.ColorNameScrollBar, theme.ColorNameSelection, theme.ColorNameSeparator, theme.ColorNameShadow, theme.ColorNameSuccess, + theme.ColorNameSuccessForeground, theme.ColorNameWarning, + theme.ColorNameWarningForeground, } // Try to keep this in sync with the existing variants at theme/theme.go From ceb9fc827cbcb69fe0fe3912ac691c422406eb10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Mon, 17 Jun 2024 10:04:08 +0200 Subject: [PATCH 56/78] =?UTF-8?q?[theme]=20add=20missing=20internal=20colo?= =?UTF-8?q?r=20=E2=80=9Cconstant=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This color used the wrong constant because it had already the same value as the background color when the constant for that one was introduced in 47bf4641db118b916d561acbc2c298a7501604a1. --- theme/color.go | 1 + theme/theme.go | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/theme/color.go b/theme/color.go index e6618769e3..4d344b7d7b 100644 --- a/theme/color.go +++ b/theme/color.go @@ -213,6 +213,7 @@ var ( colorLightInputBackground = color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff} colorLightInputBorder = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} colorLightMenuBackground = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} + colorLightOverlayBackground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} colorLightPlaceholder = color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff} colorLightPressed = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x19} colorLightScrollBar = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x99} diff --git a/theme/theme.go b/theme/theme.go index e08feaee97..cabcd36a83 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -315,7 +315,7 @@ func lightPaletteColorNamed(name fyne.ThemeColorName) color.Color { case ColorNameMenuBackground: return colorLightMenuBackground case ColorNameOverlayBackground: - return colorLightBackground + return colorLightOverlayBackground case ColorNamePlaceHolder: return colorLightPlaceholder case ColorNamePressed: From 5a972513cb9b6371c6032c606d79ced4854c0b71 Mon Sep 17 00:00:00 2001 From: Mark Gascoyne Date: Wed, 13 Sep 2023 17:39:31 +0100 Subject: [PATCH 57/78] Enable the TextStyle to be passed in as part of the TextGridStyle Fix TextGrid tests And underline to text style Add underline support to TextGrid widget --- text.go | 3 ++ widget/textgrid.go | 77 ++++++++++++++++++++++++++++++++++------- widget/textgrid_test.go | 4 +-- 3 files changed, 69 insertions(+), 15 deletions(-) diff --git a/text.go b/text.go index 7f34a5d384..3c8b6df12f 100644 --- a/text.go +++ b/text.go @@ -61,6 +61,9 @@ type TextStyle struct { Symbol bool // Use the system symbol font. // Since: 2.1 TabWidth int // Width of tabs in spaces + // Since: 2.5 + // Currently only supported by the TextGrid widget. + Underline bool // Should text be underlined. } // MeasureText uses the current driver to calculate the size of text when rendered. diff --git a/widget/textgrid.go b/widget/textgrid.go index 38735f72a3..1b6abb0fd0 100644 --- a/widget/textgrid.go +++ b/widget/textgrid.go @@ -43,12 +43,15 @@ type TextGridRow struct { // TextGridStyle defines a style that can be applied to a TextGrid cell. type TextGridStyle interface { + Style() fyne.TextStyle TextColor() color.Color BackgroundColor() color.Color } // CustomTextGridStyle is a utility type for those not wanting to define their own style types. type CustomTextGridStyle struct { + // Since: 2.5 + TextStyle fyne.TextStyle FGColor, BGColor color.Color } @@ -62,6 +65,11 @@ func (c *CustomTextGridStyle) BackgroundColor() color.Color { return c.BGColor } +// Style is the text style a cell should use. +func (c *CustomTextGridStyle) Style() fyne.TextStyle { + return c.TextStyle +} + // TextGrid is a monospaced grid of characters. // This is designed to be used by a text editor, code preview or terminal emulator. type TextGrid struct { @@ -350,12 +358,15 @@ func (t *textGridRenderer) appendTextCell(str rune) { text.TextStyle.Monospace = true bg := canvas.NewRectangle(color.Transparent) - t.objects = append(t.objects, bg, text) + + ul := canvas.NewLine(color.Transparent) + + t.objects = append(t.objects, bg, text, ul) } func (t *textGridRenderer) refreshCell(row, col int) { pos := row*t.cols + col - if pos*2+1 >= len(t.objects) { + if pos*3+1 >= len(t.objects) { return } @@ -367,26 +378,59 @@ func (t *textGridRenderer) setCellRune(str rune, pos int, style, rowStyle TextGr if str == 0 { str = ' ' } + rect := t.objects[pos*3].(*canvas.Rectangle) + text := t.objects[pos*3+1].(*canvas.Text) + underline := t.objects[pos*3+2].(*canvas.Line) th := t.text.Theme() v := fyne.CurrentApp().Settings().ThemeVariant() - - text := t.objects[pos*2+1].(*canvas.Text) - text.TextSize = th.Size(theme.SizeNameText) fg := th.Color(theme.ColorNameForeground, v) + text.TextSize = th.Size(theme.SizeNameText) + textStyle := fyne.TextStyle{} + var underlineStrokeWidth float32 = 1 + var underlineStrokeColor color.Color = color.Transparent + if style != nil && style.TextColor() != nil { fg = style.TextColor() } else if rowStyle != nil && rowStyle.TextColor() != nil { fg = rowStyle.TextColor() } + + if style != nil { + if style.Style().Bold { + underlineStrokeWidth = 2 + textStyle = fyne.TextStyle{ + Bold: true, + } + } + if style.Style().Underline { + underlineStrokeColor = fg + } + } else if rowStyle != nil { + if rowStyle.Style().Bold { + underlineStrokeWidth = 2 + textStyle = fyne.TextStyle{ + Bold: true, + } + } + if rowStyle.Style().Underline { + underlineStrokeColor = fg + } + } + newStr := string(str) - if text.Text != newStr || text.Color != fg { + if text.Text != newStr || text.Color != fg || textStyle != text.TextStyle { text.Text = newStr text.Color = fg + text.TextStyle = textStyle t.refresh(text) } - rect := t.objects[pos*2].(*canvas.Rectangle) + if underlineStrokeWidth != underline.StrokeWidth || underlineStrokeColor != underline.StrokeColor { + underline.StrokeWidth, underline.StrokeColor = underlineStrokeWidth, underlineStrokeColor + t.refresh(underline) + } + bg := color.Color(color.Transparent) if style != nil && style.BackgroundColor() != nil { bg = style.BackgroundColor() @@ -401,10 +445,10 @@ func (t *textGridRenderer) setCellRune(str rune, pos int, style, rowStyle TextGr func (t *textGridRenderer) addCellsIfRequired() { cellCount := t.cols * t.rows - if len(t.objects) == cellCount*2 { + if len(t.objects) == cellCount*3 { return } - for i := len(t.objects); i < cellCount*2; i += 2 { + for i := len(t.objects); i < cellCount*3; i += 3 { t.appendTextCell(' ') } } @@ -468,7 +512,7 @@ func (t *textGridRenderer) refreshGrid() { line++ } - for ; x < len(t.objects)/2; x++ { + for ; x < len(t.objects)/3; x++ { t.setCellRune(' ', x, TextGridStyleDefault, nil) // trailing cells and blank lines } } @@ -513,10 +557,17 @@ func (t *textGridRenderer) Layout(size fyne.Size) { cellPos := fyne.NewPos(0, 0) for y := 0; y < t.rows; y++ { for x := 0; x < t.cols; x++ { - t.objects[i*2+1].Move(cellPos) + // rect + t.objects[i*3].Resize(t.cellSize) + t.objects[i*3].Move(cellPos) + + // text + t.objects[i*3+1].Move(cellPos) + + // underline + t.objects[i*3+2].Move(cellPos.Add(fyne.Position{X: 0, Y: t.cellSize.Height})) + t.objects[i*3+2].Resize(fyne.Size{Width: t.cellSize.Width}) - t.objects[i*2].Resize(t.cellSize) - t.objects[i*2].Move(cellPos) cellPos.X += t.cellSize.Width i++ } diff --git a/widget/textgrid_test.go b/widget/textgrid_test.go index be1fa38f7e..4cef0cf868 100644 --- a/widget/textgrid_test.go +++ b/widget/textgrid_test.go @@ -27,7 +27,7 @@ func TestTextGrid_CreateRendererRows(t *testing.T) { rend := test.TempWidgetRenderer(t, grid).(*textGridRenderer) rend.Refresh() - assert.Equal(t, 12, len(rend.objects)) + assert.Equal(t, 18, len(rend.objects)) } func TestTextGrid_Row(t *testing.T) { @@ -266,6 +266,6 @@ func assertGridStyle(t *testing.T, g *TextGrid, expected string, expectedStyles } func rendererCell(r *textGridRenderer, row, col int) (*canvas.Rectangle, *canvas.Text) { - i := (row*r.cols + col) * 2 + i := (row*r.cols + col) * 3 return r.objects[i].(*canvas.Rectangle), r.objects[i+1].(*canvas.Text) } From 540c1fbbbb2f43f806d370ef5f30f0e74dbacddb Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Mon, 17 Jun 2024 12:12:50 +0100 Subject: [PATCH 58/78] avoid naming collision --- widget/textgrid_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/widget/textgrid_test.go b/widget/textgrid_test.go index 4cef0cf868..e2f153566f 100644 --- a/widget/textgrid_test.go +++ b/widget/textgrid_test.go @@ -234,8 +234,8 @@ func assertGridContent(t *testing.T, g *TextGrid, expected string) { } } -func assertGridStyle(t *testing.T, g *TextGrid, expected string, expectedStyles map[string]TextGridStyle) { - lines := strings.Split(expected, "\n") +func assertGridStyle(t *testing.T, g *TextGrid, content string, expectedStyles map[string]TextGridStyle) { + lines := strings.Split(content, "\n") renderer := test.TempWidgetRenderer(t, g).(*textGridRenderer) for y, line := range lines { From e940a888eeb4001c2bb50e5b9c858ffe8afd8ab5 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Mon, 17 Jun 2024 12:13:11 +0100 Subject: [PATCH 59/78] Add support for italic in monospace as well --- widget/textgrid.go | 37 ++++++++++++++----------------------- widget/textgrid_test.go | 23 ++++++++++++++++++++++- 2 files changed, 36 insertions(+), 24 deletions(-) diff --git a/widget/textgrid.go b/widget/textgrid.go index 1b6abb0fd0..48d62637fd 100644 --- a/widget/textgrid.go +++ b/widget/textgrid.go @@ -386,9 +386,22 @@ func (t *textGridRenderer) setCellRune(str rune, pos int, style, rowStyle TextGr v := fyne.CurrentApp().Settings().ThemeVariant() fg := th.Color(theme.ColorNameForeground, v) text.TextSize = th.Size(theme.SizeNameText) - textStyle := fyne.TextStyle{} + var underlineStrokeWidth float32 = 1 var underlineStrokeColor color.Color = color.Transparent + textStyle := fyne.TextStyle{} + if style != nil { + textStyle = style.Style() + } else if rowStyle != nil { + textStyle = rowStyle.Style() + } + if textStyle.Bold { + underlineStrokeWidth = 2 + } + if textStyle.Underline { + underlineStrokeColor = fg + } + textStyle.Monospace = true if style != nil && style.TextColor() != nil { fg = style.TextColor() @@ -396,28 +409,6 @@ func (t *textGridRenderer) setCellRune(str rune, pos int, style, rowStyle TextGr fg = rowStyle.TextColor() } - if style != nil { - if style.Style().Bold { - underlineStrokeWidth = 2 - textStyle = fyne.TextStyle{ - Bold: true, - } - } - if style.Style().Underline { - underlineStrokeColor = fg - } - } else if rowStyle != nil { - if rowStyle.Style().Bold { - underlineStrokeWidth = 2 - textStyle = fyne.TextStyle{ - Bold: true, - } - } - if rowStyle.Style().Underline { - underlineStrokeColor = fg - } - } - newStr := string(str) if text.Text != newStr || text.Color != fg || textStyle != text.TextStyle { text.Text = newStr diff --git a/widget/textgrid_test.go b/widget/textgrid_test.go index e2f153566f..9d37aa287b 100644 --- a/widget/textgrid_test.go +++ b/widget/textgrid_test.go @@ -203,6 +203,20 @@ func TestTextGridRender_RowColor(t *testing.T) { assertGridStyle(t, grid, "112", map[string]TextGridStyle{"1": customStyle, "2": TextGridStyleWhitespace}) } +func TestTextGridRender_Style(t *testing.T) { + grid := NewTextGridFromString("Abcd ") + boldStyle := &CustomTextGridStyle{TextStyle: fyne.TextStyle{Bold: true}} + italicStyle := &CustomTextGridStyle{TextStyle: fyne.TextStyle{Italic: true}} + boldItalicStyle := &CustomTextGridStyle{TextStyle: fyne.TextStyle{Bold: true, Italic: true}} + grid.Rows[0].Cells[1].Style = boldStyle + grid.Rows[0].Cells[2].Style = italicStyle + grid.Rows[0].Cells[3].Style = boldItalicStyle + grid.ShowWhitespace = true + grid.Resize(fyne.NewSize(56, 22)) // causes refresh + + assertGridStyle(t, grid, "0123", map[string]TextGridStyle{"1": boldStyle, "2": italicStyle, "3": boldItalicStyle}) +} + func TestTextGridRender_TextColor(t *testing.T) { grid := NewTextGridFromString("Ab ") customStyle := &CustomTextGridStyle{FGColor: color.Black} @@ -247,7 +261,7 @@ func assertGridStyle(t *testing.T, g *TextGrid, content string, expectedStyles m if r == ' ' { assert.Equal(t, theme.ForegroundColor(), fg.Color) assert.Equal(t, color.Transparent, bg.FillColor) - } else { + } else if expected != nil { if expected.TextColor() == nil { assert.Equal(t, theme.ForegroundColor(), fg.Color) } else { @@ -260,6 +274,13 @@ func assertGridStyle(t *testing.T, g *TextGrid, content string, expectedStyles m assert.Equal(t, expected.BackgroundColor(), bg.FillColor) } } + + style := fyne.TextStyle{} + if expected != nil { + style = expected.Style() + } + style.Monospace = true + assert.Equal(t, style, fg.TextStyle) x++ } } From 237167e03f3246ed5f831abc3bf5578336fe1a44 Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Mon, 17 Jun 2024 17:38:58 +0100 Subject: [PATCH 60/78] Correct build flags --- internal/app/theme_darwin.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/app/theme_darwin.m b/internal/app/theme_darwin.m index b830ba1358..c4175dac33 100644 --- a/internal/app/theme_darwin.m +++ b/internal/app/theme_darwin.m @@ -1,4 +1,4 @@ -//go:build !ci && !ios +//go:build !ios && !wasm && !test_web_driver #import From 9177057b99d6639056487f6725c6e921a8bb723e Mon Sep 17 00:00:00 2001 From: Jacob Date: Mon, 17 Jun 2024 21:39:45 +0200 Subject: [PATCH 61/78] Add NewTempWindow to the new test window file --- test/window.go | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/window.go b/test/window.go index 17bba3b92c..36b17dc7e1 100644 --- a/test/window.go +++ b/test/window.go @@ -1,6 +1,8 @@ package test import ( + "testing" + "fyne.io/fyne/v2" ) @@ -18,6 +20,16 @@ type window struct { menu *fyne.MainMenu } +// NewTempWindow creates and registers a new window for test purposes. +// This window will get removed automatically once the running test ends. +// +// Since: 2.5 +func NewTempWindow(t testing.TB, content fyne.CanvasObject) fyne.Window { + window := NewWindow(content) + t.Cleanup(window.Close) + return window +} + // NewWindow creates and registers a new window for test purposes func NewWindow(content fyne.CanvasObject) fyne.Window { window := fyne.CurrentApp().NewWindow("") From 7994aa12a3bd4a940b1fd14d8db984fd788d5e58 Mon Sep 17 00:00:00 2001 From: Jacob Date: Mon, 17 Jun 2024 23:48:12 +0200 Subject: [PATCH 62/78] Fix incorrect formatting --- dialog/custom_test.go | 2 +- widget/popup_test.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/dialog/custom_test.go b/dialog/custom_test.go index 94cb648430..c82da1285d 100644 --- a/dialog/custom_test.go +++ b/dialog/custom_test.go @@ -117,7 +117,7 @@ func TestConfirm_SetButtons(t *testing.T) { } func TestConfirmWithoutButtons(t *testing.T) { - test.NewTempApp(t) + test.NewTempApp(t) w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) size := fyne.NewSize(200, 300) w.Resize(size) diff --git a/widget/popup_test.go b/widget/popup_test.go index c1d6e98a5b..183a23a022 100644 --- a/widget/popup_test.go +++ b/widget/popup_test.go @@ -325,8 +325,8 @@ func TestPopUp_Layout(t *testing.T) { } func TestPopUp_ApplyThemeOnShow(t *testing.T) { - test.NewTempApp(t) - w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) + test.NewTempApp(t) + w := test.NewTempWindow(t, canvas.NewRectangle(color.Transparent)) w.Resize(fyne.NewSize(200, 300)) pop := NewPopUp(NewLabel("Label"), w.Canvas()) From b994b85c4b6c8f4f067e74988bc9fc641fbef059 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Tue, 18 Jun 2024 06:18:10 +0200 Subject: [PATCH 63/78] =?UTF-8?q?[theme]=20rename=20=E2=80=9C*Foreground?= =?UTF-8?q?=E2=80=9D=20colors=20to=20=E2=80=9CforegroundOn*=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cmd/fyne_settings/settings/appearance.go | 2 +- test/markup_renderer.go | 54 +++++----- test/theme.go | 108 +++++++++---------- test/theme_test.go | 8 +- theme/color.go | 130 +++++++++++------------ theme/theme.go | 26 ++--- theme/theme_test.go | 12 +-- widget/button.go | 8 +- widget/testdata/form/layout.xml | 4 +- 9 files changed, 176 insertions(+), 176 deletions(-) diff --git a/cmd/fyne_settings/settings/appearance.go b/cmd/fyne_settings/settings/appearance.go index d2ac95913b..39a01a906a 100644 --- a/cmd/fyne_settings/settings/appearance.go +++ b/cmd/fyne_settings/settings/appearance.go @@ -249,7 +249,7 @@ func (p *previewTheme) Color(n fyne.ThemeColorName, _ fyne.ThemeVariant) color.C switch n { case theme.ColorNamePrimary: return theme.PrimaryColorNamed(p.s.fyneSettings.PrimaryColor) - case theme.ColorNamePrimaryForeground: + case theme.ColorNameForegroundOnPrimary: return theme.PrimaryForegroundColorNamed(p.s.fyneSettings.PrimaryColor) } diff --git a/test/markup_renderer.go b/test/markup_renderer.go index 07e7f93bec..7ca62ebc97 100644 --- a/test/markup_renderer.go +++ b/test/markup_renderer.go @@ -397,33 +397,33 @@ func nrgbaColor(c color.Color) color.NRGBA { func knownColor(c color.Color) string { return map[color.Color]string{ - nrgbaColor(theme.BackgroundColor()): "background", - nrgbaColor(theme.ButtonColor()): "button", - nrgbaColor(theme.DisabledButtonColor()): "disabled button", - nrgbaColor(theme.DisabledColor()): "disabled", - nrgbaColor(theme.ErrorColor()): "error", - nrgbaColor(theme.Color(theme.ColorNameErrorForeground)): "errorForeground", - nrgbaColor(theme.FocusColor()): "focus", - nrgbaColor(theme.ForegroundColor()): "foreground", - nrgbaColor(theme.Color(theme.ColorNameHeaderBackground)): "headerBackground", - nrgbaColor(theme.HoverColor()): "hover", - nrgbaColor(theme.Color(theme.ColorNameHyperlink)): "hyperlink", - nrgbaColor(theme.InputBackgroundColor()): "inputBackground", - nrgbaColor(theme.InputBorderColor()): "inputBorder", - nrgbaColor(theme.MenuBackgroundColor()): "menuBackground", - nrgbaColor(theme.OverlayBackgroundColor()): "overlayBackground", - nrgbaColor(theme.PlaceHolderColor()): "placeholder", - nrgbaColor(theme.Color(theme.ColorNamePressed)): "pressed", - nrgbaColor(theme.PrimaryColor()): "primary", - nrgbaColor(theme.Color(theme.ColorNamePrimaryForeground)): "primaryForeground", - nrgbaColor(theme.ScrollBarColor()): "scrollbar", - nrgbaColor(theme.SelectionColor()): "selection", - nrgbaColor(theme.Color(theme.ColorNameSeparator)): "separator", - nrgbaColor(theme.Color(theme.ColorNameSuccess)): "success", - nrgbaColor(theme.Color(theme.ColorNameSuccessForeground)): "successForeground", - nrgbaColor(theme.ShadowColor()): "shadow", - nrgbaColor(theme.Color(theme.ColorNameWarning)): "warning", - nrgbaColor(theme.Color(theme.ColorNameWarningForeground)): "warningForeground", + nrgbaColor(theme.BackgroundColor()): "background", + nrgbaColor(theme.ButtonColor()): "button", + nrgbaColor(theme.DisabledButtonColor()): "disabled button", + nrgbaColor(theme.DisabledColor()): "disabled", + nrgbaColor(theme.ErrorColor()): "error", + nrgbaColor(theme.FocusColor()): "focus", + nrgbaColor(theme.ForegroundColor()): "foreground", + nrgbaColor(theme.Color(theme.ColorNameForegroundOnError)): "foregroundOnError", + nrgbaColor(theme.Color(theme.ColorNameForegroundOnPrimary)): "foregroundOnPrimary", + nrgbaColor(theme.Color(theme.ColorNameForegroundOnSuccess)): "foregroundOnSuccess", + nrgbaColor(theme.Color(theme.ColorNameForegroundOnWarning)): "foregroundOnWarning", + nrgbaColor(theme.Color(theme.ColorNameHeaderBackground)): "headerBackground", + nrgbaColor(theme.HoverColor()): "hover", + nrgbaColor(theme.Color(theme.ColorNameHyperlink)): "hyperlink", + nrgbaColor(theme.InputBackgroundColor()): "inputBackground", + nrgbaColor(theme.InputBorderColor()): "inputBorder", + nrgbaColor(theme.MenuBackgroundColor()): "menuBackground", + nrgbaColor(theme.OverlayBackgroundColor()): "overlayBackground", + nrgbaColor(theme.PlaceHolderColor()): "placeholder", + nrgbaColor(theme.Color(theme.ColorNamePressed)): "pressed", + nrgbaColor(theme.PrimaryColor()): "primary", + nrgbaColor(theme.ScrollBarColor()): "scrollbar", + nrgbaColor(theme.SelectionColor()): "selection", + nrgbaColor(theme.Color(theme.ColorNameSeparator)): "separator", + nrgbaColor(theme.Color(theme.ColorNameSuccess)): "success", + nrgbaColor(theme.ShadowColor()): "shadow", + nrgbaColor(theme.Color(theme.ColorNameWarning)): "warning", }[nrgbaColor(c)] } diff --git a/test/theme.go b/test/theme.go index 92b0c62645..aaf0e61d2b 100644 --- a/test/theme.go +++ b/test/theme.go @@ -27,33 +27,33 @@ func NewTheme() fyne.Theme { return &configurableTheme{ colors: map[fyne.ThemeColorName]color.Color{ - theme.ColorNameBackground: red(255), - theme.ColorNameButton: gray(100), - theme.ColorNameDisabled: gray(20), - theme.ColorNameDisabledButton: gray(230), - theme.ColorNameError: blue(255), - theme.ColorNameErrorForeground: red(210), - theme.ColorNameFocus: red(66), - theme.ColorNameForeground: gray(255), - theme.ColorNameHeaderBackground: red(22), - theme.ColorNameHover: green(200), - theme.ColorNameHyperlink: blue(240), - theme.ColorNameInputBackground: red(30), - theme.ColorNameInputBorder: gray(10), - theme.ColorNameMenuBackground: red(50), - theme.ColorNameOverlayBackground: red(44), - theme.ColorNamePlaceHolder: blue(200), - theme.ColorNamePressed: blue(250), - theme.ColorNamePrimary: green(255), - theme.ColorNamePrimaryForeground: red(200), - theme.ColorNameScrollBar: blue(220), - theme.ColorNameSelection: red(55), - theme.ColorNameSeparator: gray(30), - theme.ColorNameShadow: blue(150), - theme.ColorNameSuccess: green(150), - theme.ColorNameSuccessForeground: blue(201), - theme.ColorNameWarning: red(100), - theme.ColorNameWarningForeground: blue(202), + theme.ColorNameBackground: red(255), + theme.ColorNameButton: gray(100), + theme.ColorNameDisabled: gray(20), + theme.ColorNameDisabledButton: gray(230), + theme.ColorNameError: blue(255), + theme.ColorNameFocus: red(66), + theme.ColorNameForeground: gray(255), + theme.ColorNameForegroundOnError: red(210), + theme.ColorNameForegroundOnPrimary: red(200), + theme.ColorNameForegroundOnSuccess: blue(201), + theme.ColorNameForegroundOnWarning: blue(202), + theme.ColorNameHeaderBackground: red(22), + theme.ColorNameHover: green(200), + theme.ColorNameHyperlink: blue(240), + theme.ColorNameInputBackground: red(30), + theme.ColorNameInputBorder: gray(10), + theme.ColorNameMenuBackground: red(50), + theme.ColorNameOverlayBackground: red(44), + theme.ColorNamePlaceHolder: blue(200), + theme.ColorNamePressed: blue(250), + theme.ColorNamePrimary: green(255), + theme.ColorNameScrollBar: blue(220), + theme.ColorNameSelection: red(55), + theme.ColorNameSeparator: gray(30), + theme.ColorNameShadow: blue(150), + theme.ColorNameSuccess: green(150), + theme.ColorNameWarning: red(100), }, fonts: map[fyne.TextStyle]fyne.Resource{ {}: theme.DefaultTextBoldFont(), @@ -88,33 +88,33 @@ func Theme() fyne.Theme { if defaultTheme == nil { defaultTheme = &configurableTheme{ colors: map[fyne.ThemeColorName]color.Color{ - theme.ColorNameBackground: color.NRGBA{R: 0x44, G: 0x44, B: 0x44, A: 0xff}, - theme.ColorNameButton: color.NRGBA{R: 0x33, G: 0x33, B: 0x33, A: 0xff}, - theme.ColorNameDisabled: color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff}, - theme.ColorNameDisabledButton: color.NRGBA{R: 0x22, G: 0x22, B: 0x22, A: 0xff}, - theme.ColorNameError: color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff}, - theme.ColorNameErrorForeground: color.NRGBA{R: 0x08, G: 0x0a, B: 0x0f, A: 0xff}, - theme.ColorNameFocus: color.NRGBA{R: 0x78, G: 0x3a, B: 0x3a, A: 0xff}, - theme.ColorNameForeground: color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff}, - theme.ColorNameHeaderBackground: color.NRGBA{R: 0x25, G: 0x25, B: 0x25, A: 0xff}, - theme.ColorNameHover: color.NRGBA{R: 0x88, G: 0xff, B: 0xff, A: 0x22}, - theme.ColorNameHyperlink: color.NRGBA{R: 0xff, G: 0xcc, B: 0x80, A: 0xff}, - theme.ColorNameInputBackground: color.NRGBA{R: 0x66, G: 0x66, B: 0x66, A: 0xff}, - theme.ColorNameInputBorder: color.NRGBA{R: 0x86, G: 0x86, B: 0x86, A: 0xff}, - theme.ColorNameMenuBackground: color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff}, - theme.ColorNameOverlayBackground: color.NRGBA{R: 0x28, G: 0x28, B: 0x28, A: 0xff}, - theme.ColorNamePlaceHolder: color.NRGBA{R: 0xaa, G: 0xaa, B: 0xaa, A: 0xff}, - theme.ColorNamePressed: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x33}, - theme.ColorNamePrimary: color.NRGBA{R: 0xff, G: 0xc0, B: 0x80, A: 0xff}, - theme.ColorNamePrimaryForeground: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0f, A: 0xff}, - theme.ColorNameScrollBar: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xaa}, - theme.ColorNameSelection: color.NRGBA{R: 0x78, G: 0x3a, B: 0x3a, A: 0x99}, - theme.ColorNameSeparator: color.NRGBA{R: 0x90, G: 0x90, B: 0x90, A: 0xff}, - theme.ColorNameShadow: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x88}, - theme.ColorNameSuccess: color.NRGBA{R: 0x00, G: 0x99, B: 0x00, A: 0xff}, - theme.ColorNameSuccessForeground: color.NRGBA{R: 0x0a, G: 0x0c, B: 0x0f, A: 0xff}, - theme.ColorNameWarning: color.NRGBA{R: 0xee, G: 0xee, B: 0x00, A: 0xff}, - theme.ColorNameWarningForeground: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0a, A: 0xff}, + theme.ColorNameBackground: color.NRGBA{R: 0x44, G: 0x44, B: 0x44, A: 0xff}, + theme.ColorNameButton: color.NRGBA{R: 0x33, G: 0x33, B: 0x33, A: 0xff}, + theme.ColorNameDisabled: color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff}, + theme.ColorNameDisabledButton: color.NRGBA{R: 0x22, G: 0x22, B: 0x22, A: 0xff}, + theme.ColorNameError: color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff}, + theme.ColorNameFocus: color.NRGBA{R: 0x78, G: 0x3a, B: 0x3a, A: 0xff}, + theme.ColorNameForeground: color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff}, + theme.ColorNameForegroundOnError: color.NRGBA{R: 0x08, G: 0x0a, B: 0x0f, A: 0xff}, + theme.ColorNameForegroundOnPrimary: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0f, A: 0xff}, + theme.ColorNameForegroundOnSuccess: color.NRGBA{R: 0x0a, G: 0x0c, B: 0x0f, A: 0xff}, + theme.ColorNameForegroundOnWarning: color.NRGBA{R: 0x08, G: 0x0c, B: 0x0a, A: 0xff}, + theme.ColorNameHeaderBackground: color.NRGBA{R: 0x25, G: 0x25, B: 0x25, A: 0xff}, + theme.ColorNameHover: color.NRGBA{R: 0x88, G: 0xff, B: 0xff, A: 0x22}, + theme.ColorNameHyperlink: color.NRGBA{R: 0xff, G: 0xcc, B: 0x80, A: 0xff}, + theme.ColorNameInputBackground: color.NRGBA{R: 0x66, G: 0x66, B: 0x66, A: 0xff}, + theme.ColorNameInputBorder: color.NRGBA{R: 0x86, G: 0x86, B: 0x86, A: 0xff}, + theme.ColorNameMenuBackground: color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff}, + theme.ColorNameOverlayBackground: color.NRGBA{R: 0x28, G: 0x28, B: 0x28, A: 0xff}, + theme.ColorNamePlaceHolder: color.NRGBA{R: 0xaa, G: 0xaa, B: 0xaa, A: 0xff}, + theme.ColorNamePressed: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x33}, + theme.ColorNamePrimary: color.NRGBA{R: 0xff, G: 0xc0, B: 0x80, A: 0xff}, + theme.ColorNameScrollBar: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xaa}, + theme.ColorNameSelection: color.NRGBA{R: 0x78, G: 0x3a, B: 0x3a, A: 0x99}, + theme.ColorNameSeparator: color.NRGBA{R: 0x90, G: 0x90, B: 0x90, A: 0xff}, + theme.ColorNameShadow: color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x88}, + theme.ColorNameSuccess: color.NRGBA{R: 0x00, G: 0x99, B: 0x00, A: 0xff}, + theme.ColorNameWarning: color.NRGBA{R: 0xee, G: 0xee, B: 0x00, A: 0xff}, }, fonts: map[fyne.TextStyle]fyne.Resource{ {}: theme.DefaultTextFont(), diff --git a/test/theme_test.go b/test/theme_test.go index bd193fed3b..d2c8215dd5 100644 --- a/test/theme_test.go +++ b/test/theme_test.go @@ -18,9 +18,12 @@ var knownColorNames = []fyne.ThemeColorName{ theme.ColorNameDisabled, theme.ColorNameDisabledButton, theme.ColorNameError, - theme.ColorNameErrorForeground, theme.ColorNameFocus, theme.ColorNameForeground, + theme.ColorNameForegroundOnError, + theme.ColorNameForegroundOnPrimary, + theme.ColorNameForegroundOnSuccess, + theme.ColorNameForegroundOnWarning, theme.ColorNameHeaderBackground, theme.ColorNameHover, theme.ColorNameHyperlink, @@ -31,15 +34,12 @@ var knownColorNames = []fyne.ThemeColorName{ theme.ColorNamePlaceHolder, theme.ColorNamePressed, theme.ColorNamePrimary, - theme.ColorNamePrimaryForeground, theme.ColorNameScrollBar, theme.ColorNameSelection, theme.ColorNameSeparator, theme.ColorNameShadow, theme.ColorNameSuccess, - theme.ColorNameSuccessForeground, theme.ColorNameWarning, - theme.ColorNameWarningForeground, } // Try to keep this in sync with the existing variants at theme/theme.go diff --git a/theme/color.go b/theme/color.go index 4d344b7d7b..4ddb994e5e 100644 --- a/theme/color.go +++ b/theme/color.go @@ -66,11 +66,6 @@ const ( // Since: 2.0 ColorNameError fyne.ThemeColorName = "error" - // ColorNameErrorForeground is the name of theme lookup for a contrast color to the error color. - // - // Since: 2.5 - ColorNameErrorForeground fyne.ThemeColorName = "errorForeground" - // ColorNameFocus is the name of theme lookup for focus color. // // Since: 2.0 @@ -81,6 +76,26 @@ const ( // Since: 2.0 ColorNameForeground fyne.ThemeColorName = "foreground" + // ColorNameForegroundOnError is the name of theme lookup for a contrast color to the error color. + // + // Since: 2.5 + ColorNameForegroundOnError fyne.ThemeColorName = "foregroundOnError" + + // ColorNameForegroundOnPrimary is the name of theme lookup for a contrast color to the primary color. + // + // Since: 2.5 + ColorNameForegroundOnPrimary fyne.ThemeColorName = "foregroundOnPrimary" + + // ColorNameForegroundOnSuccess is the name of theme lookup for a contrast color to the success color. + // + // Since: 2.5 + ColorNameForegroundOnSuccess fyne.ThemeColorName = "foregroundOnSuccess" + + // ColorNameForegroundOnWarning is the name of theme lookup for a contrast color to the warning color. + // + // Since: 2.5 + ColorNameForegroundOnWarning fyne.ThemeColorName = "foregroundOnWarning" + // ColorNameHeaderBackground is the name of theme lookup for background color of a collection header. // // Since: 2.4 @@ -131,11 +146,6 @@ const ( // Since: 2.0 ColorNamePrimary fyne.ThemeColorName = "primary" - // ColorNamePrimaryForeground is the name of theme lookup for a contrast color to the primary color. - // - // Since: 2.5 - ColorNamePrimaryForeground fyne.ThemeColorName = "primaryForeground" - // ColorNameScrollBar is the name of theme lookup for scrollbar color. // // Since: 2.0 @@ -161,68 +171,58 @@ const ( // Since: 2.3 ColorNameSuccess fyne.ThemeColorName = "success" - // ColorNameSuccessForeground is the name of theme lookup for a contrast color to the success color. - // - // Since: 2.5 - ColorNameSuccessForeground fyne.ThemeColorName = "successForeground" - // ColorNameWarning is the name of theme lookup for warning color. // // Since: 2.3 ColorNameWarning fyne.ThemeColorName = "warning" - - // ColorNameWarningForeground is the name of theme lookup for a contrast color to the warning color. - // - // Since: 2.5 - ColorNameWarningForeground fyne.ThemeColorName = "warningForeground" ) var ( - colorDarkBackground = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} - colorDarkButton = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} - colorDarkDisabled = color.NRGBA{R: 0x39, G: 0x39, B: 0x3a, A: 0xff} - colorDarkDisabledButton = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} - colorDarkError = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} - colorDarkErrorForeground = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} - colorDarkForeground = color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff} - colorDarkHeaderBackground = color.NRGBA{R: 0x1b, G: 0x1b, B: 0x1b, A: 0xff} - colorDarkHover = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x0f} - colorDarkInputBackground = color.NRGBA{R: 0x20, G: 0x20, B: 0x23, A: 0xff} - colorDarkInputBorder = color.NRGBA{R: 0x39, G: 0x39, B: 0x3a, A: 0xff} - colorDarkMenuBackground = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} - colorDarkOverlayBackground = color.NRGBA{R: 0x18, G: 0x1d, B: 0x25, A: 0xff} - colorDarkPlaceholder = color.NRGBA{R: 0xb2, G: 0xb2, B: 0xb2, A: 0xff} - colorDarkPressed = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x66} - colorDarkScrollBar = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x99} - colorDarkSeparator = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xff} - colorDarkShadow = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x66} - colorDarkSuccess = color.NRGBA{R: 0x43, G: 0xf4, B: 0x36, A: 0xff} - colorDarkSuccessForeground = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} - colorDarkWarning = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} - colorDarkWarningForeground = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} - - colorLightBackground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} - colorLightButton = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} - colorLightDisabled = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} - colorLightDisabledButton = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} - colorLightError = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} - colorLightErrorForeground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} - colorLightForeground = color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff} - colorLightHeaderBackground = color.NRGBA{R: 0xf9, G: 0xf9, B: 0xf9, A: 0xff} - colorLightHover = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x0f} - colorLightInputBackground = color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff} - colorLightInputBorder = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} - colorLightMenuBackground = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} - colorLightOverlayBackground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} - colorLightPlaceholder = color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff} - colorLightPressed = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x19} - colorLightScrollBar = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x99} - colorLightSeparator = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} - colorLightShadow = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x33} - colorLightSuccess = color.NRGBA{R: 0x43, G: 0xf4, B: 0x36, A: 0xff} - colorLightSuccessForeground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} - colorLightWarning = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} - colorLightWarningForeground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorDarkBackground = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} + colorDarkButton = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} + colorDarkDisabled = color.NRGBA{R: 0x39, G: 0x39, B: 0x3a, A: 0xff} + colorDarkDisabledButton = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} + colorDarkError = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} + colorDarkForeground = color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff} + colorDarkForegroundOnError = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} + colorDarkForegroundOnSuccess = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} + colorDarkForegroundOnWarning = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} + colorDarkHeaderBackground = color.NRGBA{R: 0x1b, G: 0x1b, B: 0x1b, A: 0xff} + colorDarkHover = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x0f} + colorDarkInputBackground = color.NRGBA{R: 0x20, G: 0x20, B: 0x23, A: 0xff} + colorDarkInputBorder = color.NRGBA{R: 0x39, G: 0x39, B: 0x3a, A: 0xff} + colorDarkMenuBackground = color.NRGBA{R: 0x28, G: 0x29, B: 0x2e, A: 0xff} + colorDarkOverlayBackground = color.NRGBA{R: 0x18, G: 0x1d, B: 0x25, A: 0xff} + colorDarkPlaceholder = color.NRGBA{R: 0xb2, G: 0xb2, B: 0xb2, A: 0xff} + colorDarkPressed = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x66} + colorDarkScrollBar = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0x99} + colorDarkSeparator = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0xff} + colorDarkShadow = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x66} + colorDarkSuccess = color.NRGBA{R: 0x43, G: 0xf4, B: 0x36, A: 0xff} + colorDarkWarning = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} + + colorLightBackground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorLightButton = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} + colorLightDisabled = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} + colorLightDisabledButton = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} + colorLightError = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} + colorLightForeground = color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff} + colorLightForegroundOnError = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorLightForegroundOnSuccess = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorLightForegroundOnWarning = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorLightHeaderBackground = color.NRGBA{R: 0xf9, G: 0xf9, B: 0xf9, A: 0xff} + colorLightHover = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x0f} + colorLightInputBackground = color.NRGBA{R: 0xf3, G: 0xf3, B: 0xf3, A: 0xff} + colorLightInputBorder = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} + colorLightMenuBackground = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} + colorLightOverlayBackground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorLightPlaceholder = color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff} + colorLightPressed = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x19} + colorLightScrollBar = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x99} + colorLightSeparator = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} + colorLightShadow = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x33} + colorLightSuccess = color.NRGBA{R: 0x43, G: 0xf4, B: 0x36, A: 0xff} + colorLightWarning = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} ) // BackgroundColor returns the theme's background color. diff --git a/theme/theme.go b/theme/theme.go index cabcd36a83..063ba483c2 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -106,7 +106,7 @@ func (t *builtinTheme) Color(n fyne.ThemeColorName, v fyne.ThemeVariant) color.C primary := fyne.CurrentApp().Settings().PrimaryColor() if n == ColorNamePrimary || n == ColorNameHyperlink { return PrimaryColorNamed(primary) - } else if n == ColorNamePrimaryForeground { + } else if n == ColorNameForegroundOnPrimary { return PrimaryForegroundColorNamed(primary) } else if n == ColorNameFocus { return focusColorNamed(primary) @@ -226,10 +226,14 @@ func darkPaletteColorNamed(name fyne.ThemeColorName) color.Color { return colorDarkDisabledButton case ColorNameError: return colorDarkError - case ColorNameErrorForeground: - return colorDarkErrorForeground case ColorNameForeground: return colorDarkForeground + case ColorNameForegroundOnError: + return colorDarkForegroundOnError + case ColorNameForegroundOnSuccess: + return colorDarkForegroundOnSuccess + case ColorNameForegroundOnWarning: + return colorDarkForegroundOnWarning case ColorNameHover: return colorDarkHover case ColorNameHeaderBackground: @@ -254,12 +258,8 @@ func darkPaletteColorNamed(name fyne.ThemeColorName) color.Color { return colorDarkShadow case ColorNameSuccess: return colorDarkSuccess - case ColorNameSuccessForeground: - return colorDarkSuccessForeground case ColorNameWarning: return colorDarkWarning - case ColorNameWarningForeground: - return colorDarkWarningForeground } return color.Transparent @@ -300,10 +300,14 @@ func lightPaletteColorNamed(name fyne.ThemeColorName) color.Color { return colorLightDisabledButton case ColorNameError: return colorLightError - case ColorNameErrorForeground: - return colorLightErrorForeground case ColorNameForeground: return colorLightForeground + case ColorNameForegroundOnError: + return colorLightForegroundOnError + case ColorNameForegroundOnSuccess: + return colorLightForegroundOnSuccess + case ColorNameForegroundOnWarning: + return colorLightForegroundOnWarning case ColorNameHover: return colorLightHover case ColorNameHeaderBackground: @@ -328,12 +332,8 @@ func lightPaletteColorNamed(name fyne.ThemeColorName) color.Color { return colorLightShadow case ColorNameSuccess: return colorLightSuccess - case ColorNameSuccessForeground: - return colorLightSuccessForeground case ColorNameWarning: return colorLightWarning - case ColorNameWarningForeground: - return colorLightWarningForeground } return color.Transparent diff --git a/theme/theme_test.go b/theme/theme_test.go index b7c14887cf..0bb1c4ae83 100644 --- a/theme/theme_test.go +++ b/theme/theme_test.go @@ -17,9 +17,12 @@ var knownColorNames = []fyne.ThemeColorName{ theme.ColorNameDisabled, theme.ColorNameDisabledButton, theme.ColorNameError, - theme.ColorNameErrorForeground, theme.ColorNameFocus, theme.ColorNameForeground, + theme.ColorNameForegroundOnError, + theme.ColorNameForegroundOnPrimary, + theme.ColorNameForegroundOnSuccess, + theme.ColorNameForegroundOnWarning, theme.ColorNameHeaderBackground, theme.ColorNameHover, theme.ColorNameHyperlink, @@ -30,15 +33,12 @@ var knownColorNames = []fyne.ThemeColorName{ theme.ColorNamePlaceHolder, theme.ColorNamePressed, theme.ColorNamePrimary, - theme.ColorNamePrimaryForeground, theme.ColorNameScrollBar, theme.ColorNameSelection, theme.ColorNameSeparator, theme.ColorNameShadow, theme.ColorNameSuccess, - theme.ColorNameSuccessForeground, theme.ColorNameWarning, - theme.ColorNameWarningForeground, } // Try to keep this in sync with the existing variants at theme/theme.go @@ -84,10 +84,10 @@ func Test_DefaultTheme_PrimaryForegroundColor(t *testing.T) { defer fyne.SetCurrentApp(oldApp) fyne.SetCurrentApp(&themedApp{theme: defaultTheme, primaryColor: name}) t.Run("light variant", func(t *testing.T) { - assert.Equal(t, expectedColor, defaultTheme.Color(theme.ColorNamePrimaryForeground, theme.VariantLight)) + assert.Equal(t, expectedColor, defaultTheme.Color(theme.ColorNameForegroundOnPrimary, theme.VariantLight)) }) t.Run("dark variant", func(t *testing.T) { - assert.Equal(t, expectedColor, defaultTheme.Color(theme.ColorNamePrimaryForeground, theme.VariantDark)) + assert.Equal(t, expectedColor, defaultTheme.Color(theme.ColorNameForegroundOnPrimary, theme.VariantDark)) }) }) } diff --git a/widget/button.go b/widget/button.go index 80e4831543..b9fdf74c6a 100644 --- a/widget/button.go +++ b/widget/button.go @@ -365,20 +365,20 @@ func (r *buttonRenderer) buttonColorNames() (foreground, background, backgroundB if background == "" { switch b.Importance { case DangerImportance: - foreground = theme.ColorNameErrorForeground + foreground = theme.ColorNameForegroundOnError background = theme.ColorNameError case HighImportance: - foreground = theme.ColorNamePrimaryForeground + foreground = theme.ColorNameForegroundOnPrimary background = theme.ColorNamePrimary case LowImportance: if backgroundBlend != "" { background = theme.ColorNameButton } case SuccessImportance: - foreground = theme.ColorNameSuccessForeground + foreground = theme.ColorNameForegroundOnSuccess background = theme.ColorNameSuccess case WarningImportance: - foreground = theme.ColorNameWarningForeground + foreground = theme.ColorNameForegroundOnWarning background = theme.ColorNameWarning default: background = theme.ColorNameButton diff --git a/widget/testdata/form/layout.xml b/widget/testdata/form/layout.xml index 0764e782e6..0bdb264027 100644 --- a/widget/testdata/form/layout.xml +++ b/widget/testdata/form/layout.xml @@ -52,9 +52,9 @@ - Submit + Submit - + From 7185c5191aefe39f41bc2e7ad152abd940551341 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Tue, 18 Jun 2024 11:08:01 +0200 Subject: [PATCH 64/78] use test theme to avoid test failures on theme adjustments --- container/apptabs_mobile_test.go | 3 +-- container/doctabs_mobile_test.go | 3 +-- .../testdata/apptabs/mobile/hover_none.xml | 2 +- .../testdata/doctabs/mobile/hover_none.xml | 4 ++-- dialog/form_test.go | 5 +--- dialog/testdata/form/hint_initial.png | Bin 10029 -> 10434 bytes dialog/testdata/form/hint_invalid.png | Bin 11329 -> 11716 bytes dialog/testdata/form/hint_valid.png | Bin 11087 -> 11276 bytes driver/software/render_test.go | 22 ++++++++++-------- driver/software/testdata/button.png | Bin 1557 -> 1454 bytes driver/software/testdata/button_important.png | Bin 1491 -> 1603 bytes driver/software/testdata/canvas.png | Bin 2487 -> 2664 bytes driver/software/testdata/canvas_mobile.png | Bin 2479 -> 2640 bytes driver/software/testdata/entry.png | Bin 354 -> 363 bytes driver/software/testdata/entry_focus.png | Bin 445 -> 470 bytes driver/software/testdata/label.png | Bin 0 -> 225 bytes driver/software/testdata/label_dark.png | Bin 226 -> 0 bytes driver/software/testdata/label_light.png | Bin 229 -> 0 bytes driver/software/testdata/label_ugly_theme.png | Bin 0 -> 363 bytes widget/button_test.go | 7 +++--- widget/entry_validation_test.go | 4 +--- widget/form_test.go | 15 ++++++------ widget/hyperlink_test.go | 3 +-- widget/label_test.go | 3 +-- widget/slider_test.go | 5 ++-- widget/table_test.go | 7 +++--- widget/testdata/button/disabled.png | Bin 761 -> 1094 bytes widget/testdata/button/high_importance.png | Bin 1171 -> 1260 bytes .../button/high_importance_hovered.png | Bin 1212 -> 1285 bytes widget/testdata/button/hovered.png | Bin 1115 -> 1246 bytes widget/testdata/button/initial.png | Bin 1102 -> 1138 bytes widget/testdata/button/success_importance.png | Bin 1209 -> 1142 bytes .../testdata/entry/validation_set_invalid.png | Bin 3158 -> 3174 bytes .../testdata/entry/validation_set_valid.png | Bin 2105 -> 2159 bytes widget/testdata/form/disable_disabled.png | Bin 2720 -> 3583 bytes widget/testdata/form/disable_initial.png | Bin 3843 -> 4029 bytes widget/testdata/form/disable_re_enabled.png | Bin 3843 -> 4029 bytes .../disable_validation_disabled_invalid.png | Bin 5315 -> 5971 bytes .../disable_validation_disabled_valid.png | Bin 3621 -> 4500 bytes .../disable_validation_enabled_invalid.png | Bin 5856 -> 6150 bytes .../form/disable_validation_enabled_valid.png | Bin 4741 -> 4955 bytes .../form/disable_validation_initial.png | Bin 5856 -> 6150 bytes widget/testdata/form/disabled.png | Bin 2806 -> 3080 bytes widget/testdata/form/hint_initial.png | Bin 8234 -> 8450 bytes widget/testdata/form/hint_invalid.png | Bin 6724 -> 7130 bytes widget/testdata/form/hint_valid.png | Bin 7639 -> 7728 bytes widget/testdata/form/hints_rendered.png | Bin 3501 -> 3338 bytes .../validation_entry_first_type_initial.png | Bin 4889 -> 5367 bytes .../validation_entry_first_type_invalid.png | Bin 6674 -> 6993 bytes .../validation_entry_first_type_valid.png | Bin 5939 -> 6085 bytes widget/testdata/form/validation_initial.png | Bin 9195 -> 9437 bytes widget/testdata/form/validation_invalid.png | Bin 9864 -> 10111 bytes widget/testdata/form/validation_valid.png | Bin 8589 -> 8713 bytes widget/testdata/hyperlink/focus.png | Bin 729 -> 786 bytes widget/testdata/hyperlink/initial.png | Bin 656 -> 716 bytes .../label/label_importance_danger.png | Bin 1327 -> 1178 bytes .../testdata/label/label_importance_high.png | Bin 1314 -> 1408 bytes .../testdata/label/label_importance_low.png | Bin 934 -> 1174 bytes .../label/label_importance_medium.png | Bin 1340 -> 1359 bytes .../label/label_importance_success.png | Bin 1340 -> 1283 bytes .../label/label_importance_warning.png | Bin 1197 -> 1390 bytes widget/testdata/table/col_size.png | Bin 2543 -> 2659 bytes widget/testdata/table/filled.png | Bin 598 -> 601 bytes widget/testdata/table/row_size.png | Bin 3460 -> 3512 bytes widget/testdata/tree/refresh_initial.png | Bin 2421 -> 2408 bytes widget/testdata/tree/refresh_replaced.png | Bin 2751 -> 2769 bytes widget/tree_test.go | 4 +--- widget/widget_test.go | 6 ++--- 68 files changed, 39 insertions(+), 54 deletions(-) create mode 100644 driver/software/testdata/label.png delete mode 100644 driver/software/testdata/label_dark.png delete mode 100644 driver/software/testdata/label_light.png create mode 100644 driver/software/testdata/label_ugly_theme.png diff --git a/container/apptabs_mobile_test.go b/container/apptabs_mobile_test.go index 8c8672dee7..2dc7bc79cf 100644 --- a/container/apptabs_mobile_test.go +++ b/container/apptabs_mobile_test.go @@ -8,7 +8,6 @@ import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/container" - internalTest "fyne.io/fyne/v2/internal/test" "fyne.io/fyne/v2/test" "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" @@ -116,7 +115,7 @@ func TestAppTabs_DynamicTabs(t *testing.T) { func TestAppTabs_HoverButtons(t *testing.T) { test.NewTempApp(t) - test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) + test.ApplyTheme(t, test.Theme()) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text2")} diff --git a/container/doctabs_mobile_test.go b/container/doctabs_mobile_test.go index 2679c510fd..e339d7998d 100644 --- a/container/doctabs_mobile_test.go +++ b/container/doctabs_mobile_test.go @@ -8,7 +8,6 @@ import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/container" - internalTest "fyne.io/fyne/v2/internal/test" "fyne.io/fyne/v2/test" "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" @@ -156,7 +155,7 @@ func TestDocTabs_DynamicTabs(t *testing.T) { func TestDocTabs_HoverButtons(t *testing.T) { test.NewTempApp(t) - test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) + test.ApplyTheme(t, test.Theme()) item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text1")} item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text2")} diff --git a/container/testdata/apptabs/mobile/hover_none.xml b/container/testdata/apptabs/mobile/hover_none.xml index 1a870fe902..ea9f224dc8 100644 --- a/container/testdata/apptabs/mobile/hover_none.xml +++ b/container/testdata/apptabs/mobile/hover_none.xml @@ -12,7 +12,7 @@ - + Text1 diff --git a/container/testdata/doctabs/mobile/hover_none.xml b/container/testdata/doctabs/mobile/hover_none.xml index aa57bfba17..1142de040c 100644 --- a/container/testdata/doctabs/mobile/hover_none.xml +++ b/container/testdata/doctabs/mobile/hover_none.xml @@ -28,14 +28,14 @@ - + - + Text1 diff --git a/dialog/form_test.go b/dialog/form_test.go index 69f17f37f2..57e1c03a3b 100644 --- a/dialog/form_test.go +++ b/dialog/form_test.go @@ -5,9 +5,7 @@ import ( "testing" "fyne.io/fyne/v2" - internalTest "fyne.io/fyne/v2/internal/test" "fyne.io/fyne/v2/test" - "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" "github.com/stretchr/testify/assert" @@ -86,9 +84,8 @@ func TestFormDialog_CanCancelNoValidation(t *testing.T) { } func TestFormDialog_Hints(t *testing.T) { - test.NewTempApp(t) - test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) + test.ApplyTheme(t, test.Theme()) w := test.NewWindow(nil) w.SetFullScreen(true) diff --git a/dialog/testdata/form/hint_initial.png b/dialog/testdata/form/hint_initial.png index 3bcf34a472180dd0c3446515e7ccede62ed5597f..de2e5a7d015b2e1054b7ed8652da67dd60f39716 100644 GIT binary patch literal 10434 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 literal 10029 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 delta 1474 zcmV;z1wH!14ATpcBYy>&Nkl4$bpV=?7J?Im8~r5Dq0Rk0?*?(u3R6njV=n5vUODo z0(dlszw>of3ILRsnC4~U+OyjFj}+?XGLoh`aP>=)S%iz%SW_EKj>TyXLFaB7Q1vj~S9v^A9q^V^yDFLcArKg>ub3v)?& zJQfLDa(~f^Z`2kSUmy$fgyKxRt5#i6Kys&$ewlrIQayT33k(<+jh~+_WKPD6vGZ+g z&k?1ghlQKb%GpAG3dR`fFVVe6)IP6X&|~<6f=1bzN?&=2DFEUteF&^(RFKLy!nMjTOHs_jzI8D^gY>Doi7dt@OEKAvzqs zyMI8-_V`o^$+4){!xqdCGUCzc%k1RLp?@PF;D;q& z?K+l2Ky0|J>6n0?{4Yte<1h&(MR8h^c&qm0dD`n?{?n9ZB@(m0YT9JJvJTd3ipHxh zxtPC@_l=7}yG!{Md9s~9CfU&meN)p*VSgZk_0{}zL}+N#7*^N1gH=g({By^kppYJq zYhINE3}2kme)xqsCLrtJAnLxkvFU(*CV{u{D1&}WpwOp*=5Kl7D!Xu%wRPRqb72UA zz{?*JHAVu_)6W`PS!M!1x?ZpG{b^d!*sKg95;*!3-Si1BUz9gA=@@oIR}cF)@PCbS z_$+@E38D;IJ9*nH9c=Y`vd)>Y1#is zW`eoJMPnlQ911skyZQo)89!4bWGCV&vAVLU+B4eRY1mmrVj@gl1q##1^6lOO^=jFC z9#*zFP3L~4wg^<5NtSGrb?#POxqssa->M%TQ*X};0#T#txK?>=w5+MFSzGQ7e!Xq~vLY-fOoHw{@Ts>9Mq80a;eYr3u_aL$ zqnHR#ROogO>KJZD5oYM=2aiwhfL%4o_w^qTy&l%<8CuxgH=ZPtQr6KkOu5_3+}<&d z_F&%y@0LOoAVeXk5CsTP2nthmJjvEWBc}48h1ISGqn#KjrIY93SZ=N`+KG|!p6Ami z7IvLsNwnt~?Z*Il8h86H?>h^Amql%_Q#*e|mWjw5gRp3{w|g$8dX(#@-1Tn+5CFg* c0RRC1|5E2qS~`amZvX%Q07*qoM6N<$f?d+XO#lD@ diff --git a/driver/software/testdata/canvas.png b/driver/software/testdata/canvas.png index be7bb58ff3e7b6c16cdce29c68de62026131b6d3..51ab1a034e62071421c043e4ffa9405837587910 100644 GIT binary patch delta 2656 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 diff --git a/driver/software/testdata/canvas_mobile.png b/driver/software/testdata/canvas_mobile.png index 33ff74c552130ef678ec2ac4244161da5d996cb4..707db69e13668bfbcd553d838cabb69e24d0416b 100644 GIT binary patch delta 2632 zcmZ9OS5%XU5`cdsO2<$Z(9l8JvO!l$fKY-I5e!HXL6G7KEG5*XiTw0ll@@wOY@jjJ z1O!&93R1-odgvq~LAq=n?z#8uoyVD%Dc||d)bkDVXG($Wg2wtNtB|72A_r5Lk?1?O z?N{EL_}ACO(Pi10-?-v>P|#b|&<3__$#p9mk@yrik`Db$8^&xv9=_@yzQ2nT4QwPi24o88@N68N{Y03j=4iyiqQKx7Ek9Q#@-qBfHyV43qr3Uh!4G43lzFi*!&ng&!1 z^JY=-&{c+Nhs=6$t;|e5|8X~0D!qJVTIs7zIp|K%>clxbMeQ(@Jd(QTNYguj)ay!_3?52?!14v zWk7ywAi0!$Hqnh~VP5O3Q}YpOS2%2AFWOb@0K+C0-|L!J*cu2#zCa|IMK$*&aOLpt z&Y_##gGOMHvdV40k^H{j3X*tXKA&{2}peBxTFR0D&;(ZxHsL{1ybgbIs|V zcelzjY1X<#PutF71nS{<38Y%*0P!pDnP^S{MWNlphMZaEJ8G`~M(W;4e{~#ovHC)s zQjfk-nZz&{CS@_iiHXi{33l8eZ?1vqv4bU*Bg7eIZOz=);5=HURLt;+7cwFu^>A{d zD6j=gNnB+Pe#qv#u(0qHY+pUd1#}gbD$c-VW3S{@j3$|VQaUBldY`Pc^CWjYrI!&3 zwWTiC_^C26F#cCN(sG#h@85&}Bz z-J_l5n;QBP;^1)T=<4dK;Jpx(WL9iK0y6-G_-PaaKrz}ViR=9N=T-`=(IX=x!rUyo zHDY{xd@vZSq3b?d-^+@Mg}y8)$B2XKd-cHx;SyV+9~&>~N7t5o5m3nXK{#i(JzNm0 zjlUtzgv5SqLqV%+5jGcCRKlR9#)&ODQm|Q5pU1Ipof6YXgnx|77|f z3TK0b^9CP)xT(vWG5NUVBym;w{n(Of@>V7N z{kJ}26vIl};NHZ<#QpvKpFblM3>0!?Kv~)I+}!8>s_3Q#6&4kZdEf^J2eDY}$B!S4 zjg2>`7M7NyBO?n~3v27~k&)<%r>CC}6TltB%1|kdN{ttPio;!%k&%&*a1IYAG&k?h zb;eBAJ9dQaDgb3KUTnULV!oJG)6}Gc=pWW^yi5%w_9K!eYz#!TnrPCSz20erJ!?q98hh6EiT^jMYOiIzH(?Y z#KF|BWQZr~iYF!~vvY7T1IP4HGaxcH780j-MNQ49_0pwF^8Cqlb@DH7lZJbFyu3Uxrw!V5bVMQ2Bx1q@DdUdz3Cz*#>V9ZfgcUfW_J$sA7uU7(f;$$^ZEF? ze@ovHpSlgYV%&r495V{q(TgEI(TtVJ zEB#S`zco94J`@T*AHRWlp}uttQ9THks#oJ)nJg8P5L7hZn(MCgiI+G%Y9FH0l|yqL zpFZ|fr%tzA%bBLXQ9J$mvbFUPKY1@DH8nLo{TvX!J8rYYD+K5o8z+sfr6wnT#krlg zp7FqI2y=^OOioXGsTPt*Bw1P6yxiQb?rw%gR#sN(?ZK82GTFhwq4>#@o$X$+yNbCB z3og;(j2o-2EGB_l0x(#c&un{NU*GH3uNm2>C?-JH%q+vOGRk>>chZruLWWMYtxE`l zi->#X=H_;G$>OX)86H1A?@OSMm{2H`aP3)l<%x-j^}tpFfxwU%!~2JaVRjQMp)bMC z%NNrMwKL7-mbOEd0{U4*Gh_u)Zp!efh{lK~S}CYpOe>L6c6lunKd+L};8!)`*im?$ z{`YxG$|K>v#l`7L7WId8x z{$AB$@U??yCwn_-c91LH8TH0;Z>*A?l{Fd);YoR4LbLaz%c={fU)S%Z^=We)&rZuW h3EiFA>R6kI=X{>e^X-?bl+D%vMIz9a z=B`nB%hVg#i=(QoeQ~oVg`w}#gxVz%^~xd7oaC^KYMuO|;hW~;1EYhFS-QqUl9zFp z164U=O0aOnJdCtSE&Eo)qfv#Cc2T>y=f{f%ux}tTs{#VhgtHf9awaBh4rNK86;3#9 zRBvtFu0OX`(9L^@U#Z{9TbJwwtKpAme}otlq}pEHl%33=a)T$5B4O@vL z9B_RVp3L}fk)02b&pdx*)lHoh+s8~UK1PX7T~3eRq=b&m#1PqFDNL>%%sa=VphaW% zC2csTwP#Sfl|KaIZP+d2)$K5}2EmWF9yO?EMHC6u)Y&0*Y6u%d=Yz-24-6mCXV$(2I=G6u9WS;lhlMh{ zUHK}6zzdU+%cykxiYfHk{*_yMkMypKAbk8=+dNTp^4J3Qt{El02sDpa;^}U)oe;`k*M6vc!SSC8sch%F;{v_S zmIMbcXLGi}RdhDXtLA0KZXX(rG9-#+APrQvoyBp+^5~vl+>Mdbxq0yWy zRN+j^J1Ef_eBFN7ivUeF;jXkNKWAlQ-%*$`aP8QgCb(DughezYej{UT_!-mZF`0nPKBykZ%Dn|2Hx@ZBhgZKM9gSd2AEn&NS`&)DDjx%a28 z1mQKR8OGssz4v`v;X@Z+2rR~fDfMwXn<+c;_85!27@FDvfA`b+M{oQwjXu3y$B2I=yO;Oi@E8on(Ghfv+U~YOs&u+(4{^pBH&v$UZqBUD zb^Dy_u0{q=u-R-WVF(owWM^j=7B6kiGj0q*&I+m}YoZYdgtd*0mX=mzL{sJefrSNLzkYk};K74?dwT+> z8gmE}i;IiBg=U5M`Kq$A8gdP%!ErIj#dSZ3dB0&#^`ETZ&YKep@cUh#KYutkZLalSQ807%cuLK+(W`E!dJke!>Web2V6tPGr{z4NUyjp81I zxah7vW{q717|wDPbb4=JpIOYez_>V6ceS9PAdAK7Ohb=*zP`eZ7o@&$ZF63Fz-3Y)Rweb2j*gB{mB{lOc^+_u zS1dIprPP_%PGo!=*yj}Xf3^3edfbqyMf8EC`CjFov{;jXnCpq-^NEzPIsJGVEKRd( zR6^HC3i3&RFdXlvNTm6O3boEy;PJF)qd%lWVB9-XFIYHK!7pnK5!CKry!e0JI;nH^ z!Gi}z@3oUG9)p;Z-Mzhz_V(1OqJe8Fii)-l`F7(-3Z|*4DXdgRSe z8tq$ES5i_^R8&-18PcK6$HC9fkA5N}BZGg-%E~s|EGajimJXU~Mrmjy`i=4fOPmT9 zH+Sml>S}9iGcz-X$}cem-;l`)HD38-a%}|13nbYIo{@GeFckqtUPZ37wgOjH&f~v` zXU;@NM~fZNdFfSgMCVF>K#ie;mZoMPtHJH~JplM+Q`IB_MzYJW){qiLgiMO_?71wJ z!zn#DWhEtjY7amd8SwxvfMAPDX?kWRkyle$=~U|4ra&(%s~+b71Ug;Eqp7-DW*8h= zxFwu0J3HHN=4$NR|VKDD>E*U-?&Qa76%8Y*@#Z@RV4iMQu# z!pX_W&dyiy3!knmHPr8J?tST{=X<^RfkMEa9#zNTaB(Z=5wm)n(A&ANRLg{8wz09M zDkafM6(O8jzi#rz#x0<=^kPZyWaH@I-~no{d5TuKw|?&_M9lH%|0-`UY&rsIk~2$1}dCGBFzEYw-*Ao=i?dx{y|$gTGB0kN%$Lg^Uq-b diff --git a/driver/software/testdata/entry.png b/driver/software/testdata/entry.png index 5c9db547e5e3b723e7ebe0da3725c3da7eaea7ca..44c524e4a7340eb5d094ca221f1736b89d64e377 100644 GIT binary patch delta 336 zcmV-W0k8hz0_y^hB!4nVL_t(|ob1=Xio!q;$MK&NvzkKTK(Pt||GbIs-&-saQ`oG? zC@d_j<6#C4Ik@6rW3}HVFwKXVDm&iq_W+j5WnI^^*{moEq)SAYx$8RToKD67cDr3& z*9n=Qi0G@YZCh*Y%hSz7#9A9;G{z)c@%emCr_QQc zLI{`31%N^{pU(lr7}HAcdG7%zL_`F@7&8#2R|TN^kdB61?pO2~CVSb-UiPw=z3gQ# zd;jwukH?2R5djcF7|`f{sdXh{W&mYbDm+A0RROr&ZZEIvIslu^Mnt^#$qzf3Ocsj; zfYa&pdXG8h+DW!;nr6G*rj_119*_D;D%R`u^?JSE@5Y$2EcMo@iZL?t;cz&g&pH|F i$Mq$Y{^~mb0RR86F@9!pO|%mL0000;*{VU9%Jxhnvqn<^bmql{@o2;ScwpR#zo z+r1zjtsRKQZ?9=o+ji&khxb!9>XFMu)V1uow(ol)nyWLWU4IBmnI?ZaeHvq!8MW5; z8kfSJWQ?q}Mk%HDw?(lO?3D_-%6SG>PHW?n%` z3a*1CF~*2QRM*uCno`nxLg%hkwLx6=jg1HZ=$xBRYu^uty$~XV5M#{9#27=k0q}nR zIt&8<%uN!FeL!!GIff9%am@Hf0kCP*W>Z;fiD(fve2Jj~*Czn6`u}W#R7a?S6!9`T8g*vFw z4^X8;!BM5($0eg6f|psBF5=K2SSwxBBDK-Bh+tbP+NLLo#B`A2B;8=0Q6!xT|b}qm~Xd7y=f>>RhDI59+kp#CzYGkOru)ty9;M9BlSuFfZZOw z`KnOufFlNgg_7g4hp%P;Zd8i^NGW#+pf?TqN`L0%$2EY`i3lR`fk;#pgaKHw5P+^m z`)sdK+;ThNd4K)??%B<}-OTUL6PLtGyu?eq#7n%y`~N)p*Xf-H6G7f~Ki~HS0lS{Z zA}L^NafYr$HRz|uBJbVgJAktV5(I%D?}DKLh#~UC83VX|**Kluu=NkVKUS5)nn4?9 zjsbYo`5YAo%d&1=F&e+ii@4l>;of`hZu@3;I3G-x=`|zT(F29bJYUGl^ZTC`cb|QD m`ua;ek>WnRxBLnK0RR6q(0GRv^)zt+0000HW+A-bLgUL0T{ zTOwKxpacjiHmCO8qIU%WTRwnGkF0LXW`$3m*`N*iA}Ed{5r3!iAh9yKK5(qM3;9^# zgf`1;&yQnafn$D?E_-{BjHBt}84|K3?>B~q zd2y@8XO^HB5z*F}-3}F7=GZN)<`6(4WHbT~u{k736oK?j{q2RcdmE`2Qn43%u@`%> z7kjbyhrG$fMt@iy=RAy0|A=`C0&E5lj=%#*SL4yn zLZVv{VAZNsyLRouqk#MXQB+hkF)^Wu(dz2z9v&We6c7jyD=RAn1qC>lo12?>y9pS5 z@7}%5n>WL`N=iyGF)`FJ`o)VEhYufybH9A~LZrEaHOma7(Tt;wg;AqNjUF|6a2gE= b00960EuA1H-x$&m00000NkvXXu0mjfXFXPn literal 0 HcmV?d00001 diff --git a/driver/software/testdata/label_dark.png b/driver/software/testdata/label_dark.png deleted file mode 100644 index 44d4d755d9babe31a89b76ee071f210d2fa7a0e8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 226 zcmeAS@N?(olHy`uVBq!ia0vp^azL!Y!2~1)H_O@qsg<5Cjv*Cuk_5%4CoJGiSTu3x zVz+)N+pI4e45D0IT*AYr`z%)Xops~dwKkok)YQ`F=W;o$&CJps9pS9lvU$RbFqRpX z#n)z;W`ERBuy-&qF?sVQCo^fwym@gM85(k|EKEm^9*vBx<(+f-^l9%scUgM&6+V8p zDfRS&7+&75bLPmrlKA`N^P)_b!=6Pn$YBEU|=-zba4!+nDgf5#;ijQGRHqI z;}vgj$jx0QVkE%JMmW156`>SsH(yjW(lQVM<-2JuhbXee)Q$}6R z^EiUPU3*=#b4{Pp`M}u|y%d)^y!|EYQ+Y4Pj=%lY4-2{FhZVCdeSU7dzh637R#>yq r>z^~wq2Wiq+it+>`mdr44FCUcer^zUM@^O)7>Ep>u6{1-oD!M zQ5J6e27WpdV_0Z3@ejHXms&R(f=WU}C}IN^GGO~8HZf9ey#Y}ldHAiEGc)aV<#dKK zt!Zv<4*mn+KP}*!==tm}Oolc>D4)-l%jF-^^H~^%vD@twMSmIMb@@aHrPJx(YZ3qy zMMCJs`Ip;PnKmPkqG@lBobj+wxhy2Oq)JA zjthswBuVN`l7A$_;jqW!>8Q3&(#~@$2!h}5Hw1AU4+et_!-%5z-o&M)rN*>NlC-h0 z(UJh0&1N#0a=BddQ(E@v_xlAwc&~SQdYWOF)6>&G_C7p35Cnl?nA7P5fLt#3{QNA- za;qBV=jSVxN;Dd6eo6~IaU7qSnc+C@<6)DNlMKVeVt+AJRSjJyCno@aVc6Q*8UXC< z>?n$&ce&l}(a}+wre#?cMN!WcP19bl*Wqwr7$(c|<>h52lks}JR;#sAsRV;TgwXNv zaVLG6Or}sM3n>A zLjeO_+03$RrBZ2Df0N^Cwc6I!767cSu3D|u4@MRWh4uCICNB#B z1VQ+GK26g$H#bYA63_Fqv$KLA?CtH@Y&HOh$K$C~%4{~Ps#>j9_xJY~78dUB@4xD~ zZ6uS)JUu-DKwn>{}qFCX>lTBC)cvlF4LbS?=%e2LOGI=v%bI;Rpl*6h$2z95i#6pZ5s>u~-Zt z#Phsfekh8f7aJIcO-xMaiOpuS`rlGEn@uDV9LJ4~jWxgDVsF2%B$LU%PVoEv7K=sy zEsA0`n*{);(>Xpqt_Mq{(tCBnU!-6dO@Gs>s=ifEQ4~p%2qD9(N{XTgg81OYo!jkx z+iW?X@p!y3c>hAHmolJf+H2YH3VNY&@E?O8&^u>$7d@ZdMbBq<(VaeV+~}*W%`nXO z>iH^Ynl?o0eA?~yR_o(`AsB|~2iLdM`J^by<#I6$^Gn_0IBv06Se9-4Zf~snNGp;Y s8XEdWZQn$9?n90Ae0CTA1ONd4|44I{E;d>uKL7v#07*qoM6N<$f=Esx2LJ#7 delta 738 zcmV<80v-Lv2>At&BYy(GNkl3ema*0AD#*!c<)2Y|1fDLlu`iToHI7!JldOwy!Xzz z7n=8Yq?DZZ{dXcggz)Ji2_eq8VI-dD^xnVLq-QY{()Z_U?SFX|SN!=cIv31O=d$?e zoW`fLO(T8Zbeg8oS`$LDECYbYS@n44`_p@$=Q;W_&+|9$F=py?&S|Z?-Z;jnwSMQG zaZcP?YY&G*?_`Y87_(lll~U(!)LPed-M4`A&1Q3x0Zr2oLT<{Gn{}2g=dK*No9CkTFa1`-(SLnR=U0r32o$C{>5?hX~@7~o5 zX*_?SuB_MVix zoakhX-Lv+26Qq>G1nhs$?w0DfH}OLA?uE4oAx3AJ5uJL_t(|oMLftabXw%fN7u|KqoNj&*24F(D<^#oT<)=hDv-K zEa*~$AN=_B=iL2|v-jSA^6m$k6tj|&5}YF|%sDwxUrC&sg=t8}GYd15tO%EjuISO5 z?>>G1gDi#OpHyc>ZjPZBjc9;}gEhrT9!(I%pN2|&^mP)gfPbNaAesn@KZjzT#0t3B znbAasWIiMVjQVqUfl+@BFF>h3?>+x;@A(HRIfjOSB7dI0^U|SYg+s}T3wK{p&q*`^ z9*t6zWo{`%v0*NRnp&p)K9!>A0%^ykV0Hv$?qeEsno!u|67cR<62RR?cS z)os)SHf05J}fq~(}m!JDCJ`&~UBGUcD`jeZ3bxTVy0|SFz`hwd}-{VoKDJOhx zS{#waGB7ZF|M|OZ`ALTV{}1*?C`bq_+kZW|cYnv^4QCgYd0%_haGka5GR5o3#Gik*iOSTz%S_Xj2qyN}eqP-?3Jd zw=|LT7S~2(t?l@0g^|=1-Tg*7|z^!kw1O!r!PO} zmwFLn%fS1Sfq`LGfg3+J`-=THs^=d8`&mVvO44g}-3BLY9_XvtV&)xk< zU-!@ooV$lU)QaNI*?aGQfemd9T~YA)$M3oO9-s-L%x8c4{^#h;ccOf3BE0OZEJH8r ze*N|5ux^9n73yfT|YFez^Ffm7XSnR0RR7LYNIMfOs=K?0000YypsQ?iiHs7Q#35QnV+_%Z zj%}ihipCGV%n7w|i`xuQhRLSJZ<~TSh_ zH_9mOz4u&mftcM}UfQle+x7o}KReHmqax9Q-;M!|5$HPK4lqoz&Upo%KpBS)GI4{(oGUvm5jKC7EXxbEO3et#?Qk zBzf@fm=9sc9Na$vdFSy^^iyKsWHCDY6say-Bo7^1*xVfSYKI_3oFb2OhLu!dkoO%O z0POo9GExAm1qM{89R4fI2H#^J;Xn z0ku5KO@9R8jZedge27X0BpzUwE6#c+2%^R-9%;*9v&%etTcq`px)QxRrzWNcjdd)IpA zwa2+^Jv4ok(0aS1I{2|L9)ubzZnP_Y#(x6PK7H6g2zG780C=XSbGTEO?upQ^&PorJ z;wSINS0*^6_4kZ>d^UUViB^$XcH+RL8MJz@pBM1^) zyL*i~l%<1-AY2Wpwsf{0@dW$t#dk^Y zLI?B|l7ZL8Pc^m_q)B*7^0fg|fz{97C`c_iY((>minF4aacV!Z07*qoM6N<$f-jFowEzGB diff --git a/widget/testdata/button/high_importance_hovered.png b/widget/testdata/button/high_importance_hovered.png index b5561064e5a63f957324f972c40848e53a8dba4b..6f6444dd7e4c962d8db9c5b78e798999f59bf1a7 100644 GIT binary patch delta 1265 zcmV4#JhARtx+)^< ztjq)CB=W(}-+wONezRo9wP$a?qDe6;DJj7@(xNBQ+b?7(6#vA!YjJb1(%pGf20Was(QcY(f++sfRS}`DlYeLh^pw#(g5uAim?yCU zP7d^PXGrElGQg-mhZh+2=kNlQ`t!lFcMqPuqmpB22q^OBrCZN@a%cPG&c1y68TFh* z6F|N{51zdnP&n_+hp%rwd<`g^ckt|8syd9yfJ}d`+j}Xxa`Cqx&^F}P@4uoe7q8!U znW}E1CO~gD5Pt)vuRhv1V<(#6pTGYyTUWn&_c=Yp3YW%^k_AW3-$N7BQWD=cJDVg2 z+_?Yp>yO{Ynli*|A=#geGj>d0eGHdu{q!9#-+iu2bH^&HsVMgI*KY;}hSOIcGcYh1 zs7bN1GAl|8lj?@VhUKCHJeww_5U+&zk3%Q`2YX^wkfG{l0s{CU(D%PJAZ4<(dji|Hy^wL<%KkNH!F>IAHK1& zGVyYAOsxz~s9SELB}=PxiwR7%<)lPG3GeBvk7uquCeM&tk6wTK@tc{MscOnLP{IL^ z1KfQAYJ0d@s;}L9DXw;zg`RwNn2oEYI@wO8$e-yUmOggc3=9k#_FpF3pTB`%jWB1Mg2!K^{K`oy`ZY z1{KZ^bJzd#_y4);PkimQLtOOTGpC#B$bT!#h}?brmVtpm5}Zdwg?Jel7|!2#QZaG! z=dVAeR)rE{%fR~+l0NykIo9sE*gR`D*yr5oA(jjb4FCT#&R%x{%=mAjE!zUFmW(u{ z{q40k9=y6>(`f--4kE1}*`KcFYC6gi5Vn*kKZGG8F5vH=0~HkG$8Q1?6Vr>mO@GKD zTpVn@#r~c7KCeG~Wn*C$7J#PST{AL1efja_`%gY@4jwLch#(^)VMO|)c5H45D+EX?p`103-2aPaY9i8Ov5PLd2C?Pm`!FzV0Y1xEcj zya0+nfByb6a4w-H`1%9gBPjm7cxoG8hieFdD|cR_iJ-+!OF_Ckn{Q<#r~m1XE<-LF6XoWJq1f91L781wdwqw9x;6&UsB@B)AU b00960!8@Y!v*QMt00000NkvXXu0mjfp2~!y delta 1192 zcmV;Z1Xufo3cLxBB!7cRL_t(|oa~uxY*S?v$Dil6xA)%m-mWWSi~BHFUP2~WsIajB zF$U8)U~}jsMEL@4WNcw33Ray7YK)q=p&yJOE-bCEm=H5GF;UQ!g)hb!x6p3Jw?Q`q zvDkL&``Y_vZdnNTwi|8f*7fE8t$bDnd~mGe9g@_#@`rVUsk6*zNC^4KMd zEn>0+t@cQS&Zf{+pir+KG#s}-?-g_1nfbKc+oLtqKbOTXG1$fHlIB#R=ywb&xr z4haD0yXe0>9+51HI8Bz|(wekb>K~HsmWb18m%fH9m2HxitcWvdAGQ{isAXo$ zycM$frQ$8?q|Lf>SPoAM97(*E!qj zl_hHAjk8{cm9oD7rB4VI1paoS6aaAe)Qn?h4sz!v{FyC;mPDrhV@yNA@hM@iv=q{@ zLsk7SDt|+O{Wd%JV`%g$-QJ+8ER_|hkdN9l{t)-(7v6MoDlvHCkY;ODoEA1#yX){3 z6w>wCOem62!F;e@Wo#i`K5qOvQ@;Uk(Bsb^caKfcCp$Ecu0pRlSbvCbs>T2Mhrv;J z@JYd&)CAmGrEvSW1np0hGZ^My_;?xsaN+F|U4NNufh#9&v5oII6TB?|07K#7Mxia< z+vC3BWSi@V-UI3b2IbLy&)RZ%wDtE5+rq^pLNmZW%Nb4HlO07@?DS&!ZLCJG(*Mo~ zZ?s&C=yfR`p{pMfk_yX#V|&#?>c)it)|Co|U9yFnH{+)|HNQ;Ir@s#jkA+h<^?^9e zmw$p6M`r;5jWxKwtthpdD59B(VFAMlPVNcvL)P#Orx3T@XS}~&XIc%)nl)(68cpwc z|LIi69hooL{&q6avY`Trae@dW-i~FErB~liGG#hu0gk^*`7gP^031Byn;e#hQHT)Nq+(% zap(*2fmxADQv`yc(BhB!8tzL_t(|oa~uzOcQ4u$A9;nJ+3XY7{*34um}OcZdy097=_ZY zV&)4Gg)z`&0!s{YBuGdU7@0;PFbpz@gJr(J7fZ|}3n?)s+X%x1Sdf^=B7X`+5u{Lt z<0j?6_IkI-C4^p~Udz9=>*p2E-E;SRKRnOV=jqc;TCEoT2Y;ZA4zN!6JiUuef-;L? zEJ4^1!Z2)uBDoL8vN*>fiv@9<;Feu~vKYpYB#YyoCImlC(~I$WdKW%V?_#B%TZ4nQ1_!TFm^EZYo{{0< zwG|b$6%~=;;eV?aX-&Yx!on5`HivD56ZWc9moHp+&EKCS$pp2!&tNc)kFQNgcfhSy zyP|uZ+PJuj=gtuX!51YGiB_$CIyUzB$&*!0>plWc;rA6We3F!OIx|!FUL5~AKRD2M^3NU0GAJ zWGe(s+l7B+XdWp^mJ}B5RjI^OKB&=bQ7DSb%I03Y5K}+>=+W$qj46uJ4-Ure+o#^Y zKc}FeZ(yLbsOasesNvDk8JgCr)sKgV{rvonAAdUr0RD3Mdny%0Q6lq;^_-oX%Rhe} z0Di2g3E8&INzI{=k&`(&B3}ytegttcEe!y^ID2-?WICwPe3h4%nwWU8vT}Q9C;-&f z)wOqaDmHJnG7L@AB~?|WMMXV&eNI7v_*UHc99rOEZ|}tXz{cpwE0y2hxN&oSV!OeLJXZyNcYzSP zeC-!9vH~~U9Z#en-XPIRLbGQ{KbjM$=bR)*JWR>&jA4ejMch$^vY#2nN&JM)Aa1@ z;>!MVIYAIp6va6l)$$0|PnSJC1%apUd$xDs^Yku!p5BF>C&#iImt-|@6tVNfmsxW? z4&1pXvRJ_LRXL6m9GVFCw}|5;b3=2CM8YEE_|w{dAC6^lmc^}B%%Qi0`*@7wBo@m$ oW?LsbuhZPa=jmPi8vp?R|Nm^JY`nl#iU0rr07*qoM6N<$f`j~FjsO4v delta 1094 zcmV-M1iAa(3EK#eB!41FL_t(|oa~uRNIF{>#$P{kaHbDzLMk2K z+_b8VwF%k=?OOE#Nft!yA`%xxp;^$X9F=wk7nPvT3x$q(N6oq11|moM-_fkd`mJW( zGjq=KFlXL#-WefH)9?e}f3<*5;@4+&AuJ406qQUSv)ODemw)>TNoB(0@kAmKilSn% zxJWB250TG&qP)t3KEn#;&0C71zPm~0QKi#qRxrysOQKT{zwA4rjXA9pS;E|!*-0AO@o}8SJB#Gm=$z)P0l>m@PBs?BZ zEEc0_8prYO?rx1n%efF_Vxf^Vq!ujlllGr z_4W0mqa&Nmc6D_H02Yfyr_+%nDHIAN63OuJuz%C(RIAk`&D(dapBjyZnRxg2_t9vy zyiRUzZYYZ4@pxNXTTJR^f&ie?>HL2G^767)tL^LS)9G|&OMRD5qtU3>>j5AT2$bzJ zo6Y{GLnvh4X9PhyIyz)B830(VR)s=waB%R~GiI~7zrVk{QQqaVA~ZHOGD&V|Xo&S) zM}Hs?m`tXgo}S&^-TnQ2f*@XemRc%*y-yTH^?H3M6k1qVFc=IpO-G|qywY9ZIqmgMk zJUnC$)N1v>zyJWKRI1L-&R{Tje0+=`2!F>RN?1P`TrStc!vk~N+uN&BsQ@4vjlKwK zXlSrlEG0SxW=BPmq(C5eJ$wIo20@UTnwr-ar&6hGHjAPtkH;(88*BY6+2?nG<@2}B zt}cFkRu@0g=UX}Y+fi5&=ADZ~qR-XyQ4|`<^I7=Y@S7r)N?DOSpJK7N3anxnRzFzZ zv;Su^pAM4AHq)$ M07*qoM6N<$f+fZs6#xJL diff --git a/widget/testdata/button/initial.png b/widget/testdata/button/initial.png index 92b6ace8d1fde951a46546b89b37ddddcafb3bb2..fb8cac9b38858dcb50633971499b25e50188f59c 100644 GIT binary patch delta 1117 zcmV-j1fu)S2=WM!B!4+cL_t(|oa~uTNFwha$3NqY%D5^!EW7OC$1b~j*_Cyd-(lD5 z5}JSLT2M(wRuF;xf$9)K33e$1y%b))U?p_u5>$r_B5z(wEIssxERz1v6#hNT41W1G z5IJt8W`*YKl+Qf#Jnz@c^gPczgDI6tcmeR9JHQiB@hmSe&VO%)VUo!tMNtTXJX55? zNvG3%J|D+%4C8ub+)svKqR}W#)1@d000@H6G#!h@7>3~-%J57klTRD$vB(z5@T4f} zY4bc5G);3#GCWK4am|I7GTv4^%ZrL5k=<@rtJOu#R!q3-`drZK_1)dw z+=ejBYPG(3^TzFV-*)1}#Kf;(zc_{4+uQZ^^?3#O^5qMT2x~#=+4fLKp+5spFe*BKrk4jD1YkU;2^II05Cc_N|I!2Yil0K zZ|)CWTwL5y6~nNhp&^Y%b8n-Ii;EVEC3`W=!sGFLJ|6&Rwc4|@GqzBrQq|Pd5Cm~} zcsM;h9SVg2fFOvLmKK>zhN5UV9G;(__xt?@gQ26Ny1_3rMjP$)DQ3;-aJNPhqRefN#INv@u$RI0PH69DGs=01M>ct_2>y}i1+ zx*VGY0HILW*4739&CSh`NJOX8SuB>u#>Tokkk@lt$T)P3-|s&?Jq3XG@88Si^1>SV^yw3h;|#;}_4NV3t5>f8fW4GnuUD(p zj*pM8udlmYF0a>HaMTBRy4~)Tl@$P}uC6ZFlh5a~Z^rCqM>HB;U0sbtA^Cw;PQ{jYf0r$>ZfW z^FO~QNs=CqN2yd!PEIZ?ETAa*{rh*1$FsDwG&MD~v9S>jhd+Gy001W^CjfAMehvUK znQUNSKr9xU&E{Nsd45m!`HaP4TCLV(GJmlq>|z5!kn1HxAP}(GYyhyewY9vwtWv3J zYipy?XpUXvF@Li3^z^)Y_m2I0W@d(6l*r}shK2^V@c8)HZnx(z```Rb5Cl!rH)Dv! zVv$G`kHQYTv^!xO_WsZ^SMF-iplLHK;WR4PSLlyiuygrcZKB6-4WPsEEH jZ_AjM;`wg?009607J7#GF7M;`00000NkvXXu0mjf0y#N_ delta 1081 zcmV-91jhUF2+jzQB!3l2L_t(|oa~y*OFCN|z`xFn{&c93qB0OkO>5ysB8!T4G1Why zM2o^GH?@g2E?N|AY9Yk53U>vin~JccpjD)1w3E1`NYIlD6$)O)$9SOuDYY8S>gVIL za?Uw3=lkKjIbz9V63PJNw*&YgDxReUmYKvbOgtWEUigiW@_&TKuVHkpBX*^!q zJQR<|qtWOOhF5q50s)4lx8ECehGB|b5&)vnXl74*;~9^~e>SA=B2y&2J%2Wy@8Xm8 zEEmrbrs7#zR6M!y?+XPA<{Qbf@8izZ)s@9!0f6c0>87Tp!bMeh-t7A#kqGxUeLf#W zQ8Y~hfKVu$oPV6uXf)pwWIo_H{`xUbPq*7`wOSL2L@EVE(ed%|&d$!lh5985;OTTa zZ8lrhtf8SHk|f`IacODk;^HDLQ6`hk&(CwIH^ue!HBHma&CMT_N%PEkeA;X_r_=df z?#9N(^YgP_ug{t*lgZef=jG)k04Nj+48s~48gh+cWq)NwEEb#1X6~=#(4L7z!fLg; z-R@66+TGo4G#XJ9&6=A`CXGfT09Y)RnwlCm(d+ddA0LOqVTnXSlB7bR0Dw>^+0%UF4yYn z>fzy`$z-~@xd8x!!JyS@!{IQ7VIq-eVq$`#D1Vhol~cd{()y`ZtJ#kC`1t7e`}6zA z?d>g1(+GmBudlNm2LSHw?f^im)w*1+<>lqp*4BZ60j*Y>cc@?TBuTQpy&V8N9#7t$ z?97B=7(1SE9B*rDtFNyIfU&VLxm@maI{$e=uh$O_4(3+0E0U!_vqynm~tu+`7 zIhq2yK8Hdf48vac-v3^}aa<@AzAhYzL}IZRK@dD1FYDI|v%mfON%O3nvrCJLXK7KE zp6|`kMMvh<;G5_7PK-szC!U$thD8dW&reHv$$CL5jj6fjB9DwQf*{OT`L^2{# zTz|PiUf}cjS!bCno+U|Ht}7)>xp@8`00960rL(Q2{gyPG00000NkvXXu0mjfQ+pz| diff --git a/widget/testdata/button/success_importance.png b/widget/testdata/button/success_importance.png index 88b62a07625e0ca360af6c4589055cc26017a7b1..94e12cd8202ef5a3cb59eee03315b410987002b0 100644 GIT binary patch delta 1121 zcmV-n1fKi33HAt(B!4|gL_t(|oa~w1Yh1+}$DesSbI#f1*Z#WcY9Wnl*sInw1re__ z6?0id@TGz;h#=k+1X2G6Z^SF>MW7WF@kWH&8>P||p$H*~ZN17$u~urLHq!R&o;`DB z=8>~W+wAEk+1(_YWV4^EotblXp6|>v&pb1SkB*MQ4uEd90e@|xtFyDdp_*prvV}{9Opr-6vBAN?yMW;JZ(2x=&h5A+>tY;}s@W;=wyU$V z=<4h&)~b`-pnv4XHW;jQ-q#fL4<^Ta0I0lG!u~D2C$&BmbcV}MG9;iRpzettI>aKrt)6UlmTRxl8D%c(n-%sHaFD)0EpABI4|pW4}Zit?U7qFex_3Q0lUvY^_akZ zOZqka8aQBI(+gXk^061A1r z$fkvT(10T1T-BS(gcUjVVBDDb4eOK;yR zip)`>2vT&u@se_sgtvvEGzVfn<;as6GpOSukv-V@9l)A&>L(*Job=76Me90sHEuJ& z1uyYYKN91fWcbv}q3t((T(T>iUE%6zsGnLkn6J#{Z|*j05fLn?7enZ&y_aI3N0fd- ziGS~;IP3CB=bp|cgY@R>gkCgHU%nZlo(O7<*u@4*EYsp_pKC`e! zus0bCdX0&%T@n)YYS>68TRx`eRvoG7cQTc}aXC)ZiO&jjv0ebbs zB*&yCE}6H%(Q#eq>g+7KIy;LUsgvpskr_W4bPeUJ7f=rIoh7PxQH`_x^wM<~--zD{#&s27kbj4iF~dp3#LcyL6Uy zw5pB$tk=!dNJI(|il~*?@@UaUoH_d_GR#AV-3=}3r(uj|J_TY)DSg#Y^to@(vW}%L z2>_qDKj~(jhN6#WtJ)aeNQ*_wED;~ie%2e_Jd4G}St353OKakp2Pd00RAQyC#66>n zxMyIj!mC%|)qf_1Swt4(c|S>MP>wbzNADx+&5N`sgzlM6GV0_*$zVwaOPzcuon)9A z%w$6J%o1{HwK)-=?EhE%zc@C^5J=g5+qbe?`DylJD&8E z_I0iMJ)LWQk79&RCUki=P|m0SW+UF>Cc&N~Jhcp2hWSv7+W3op0RWPbWt+HtJ+@-N zSJ>qf+JBe5>|7x&*-m$k!;K&HA13)ky=$-k42j({KL+}HDoCl6_od^2CL6o3B^g;N zT@};ZxX$!TzF6#_Wn(Zpp!YvYHf55{<<^WXPHJBfAP?Zw(^`AGcH*FNte5>f#D6ZY!JgZAgkJ-IQT`7AtjE?}(wm7WanJPb zK&}#bPXO5Gs+tfdvV~j+E%TbU@g{G(-YOJ$$MmtDgYG&{*VX&J)lWT6?9T|#-h}Z0 zFA+rl^zyRw`U`ihh>{ePFn`G> zoP28L;3SkJf;0xBbG;uj^v|F@mkI{Y_&z(jhN_;^}Lh-=jU z8!0%|Q1S81qjNqeSX$&$Qf00960jU170ehI5n00000NkvXXu0mjf DjKWTd diff --git a/widget/testdata/entry/validation_set_invalid.png b/widget/testdata/entry/validation_set_invalid.png index 17dbd3c54d985b8e9de0e373c9410eaaa3d3d077..f8018c7693db9d4a12a3d1934cc4a7ea31e827bd 100644 GIT binary patch literal 3174 zcmeHKX*3(!8g)A;MX9-_R*{-@;G&dD(Z)QLnv!zGkhX@H5{g??%~3JbTw~fQX%Taz zt(u3l6h#x&h={3;sf5VO{r%qi{rLeEzmjLLN zsRL)tIHp$4Sk&uPG=zXM?0>7et= z!jR-XpO+`d!)P z46S(N0LKJH;-B!o?@s*g1^o5(KDW*Q!+7vB>^xi)cc4XQ1B?4L3-0w zx^4|_;OB)@nF9OkK6t0+M`~NoHHe-DI*VMwV9|$O5$l_%NmwZIRFhO>}4HTZHF7z_e;DqjOFx3@Lq11|^>c*68QDREx3QTTCu`)$>=piGg|F2)57w z4J0&bj|W}Uw{AYyxcc)VV0fVYO3U$=y!`PaOFpwW6@7s3mA_^df&>2!%o+kw|DX zIx#CgK0Y(^RM7}vsDVgZSzg}QXQ|k>1d`e(C!LE%#8XVSqF6m?61F8*m4+_M`wZo2 zbVRHbmXuJDU7SKKExJ^XOp2SE+n+&Xb)F-AA?0>UjYOl+4pK^6#ph1e&g|{mw=0xK zhlgdZhAqu^KXL6k%6+M8R=4=_Q9#>Al#ADaaiqJXE19ytme7DJhq~Jryn6LYTaX>F zPPWBP=fR7i(;3pbrFtPhzPxm#5zB(^-}k^rZEvqk@yf5Qt;G`9tlx8yS4(g>oQ{sp z(W6HPcgHcdWroO&{htIZ77OW!cmRQ%m9MI+(-2R?|0YM{@p#V3@bGXJi-Xk<=hoNT zYs5YX#fFq8S1x4Y(WkeSzr!Ujf$lYJ_T7(05aB%QXGXD2Esi?3pis|8+S6f?a zTWYwsJq0l+v8kPy`S$IAf-)8ck`WXE^uX47$InuO$oke+#L8q{z7}M3Bcst+4qGTt zEpre(kfys;Gjce95q#xS@RSLG0WJ>RtRWg_tMgGC$BZDm%^a*p-}1RLcog8 z{&8_}AP~r#{(X;w+d$@&z36e1U_BWD0Rb4!O(;>TYu6jWaj9@x50lBvVZdn$%YBT8+N?d9d=WpRhDq9T@){r$;AnxpStl7O_FAtHEx=K-*PX=&-* zyX%gQj)QFt>c6+PtgIBtDxhp`Ztk2=l~maM`>Shf8RnG@>SfoWn;RO&U^w5+wJQys z@_Mxmqo}Q9p$6E5s%svH-W-a8f`YcS8ctj$sBu~{>5Q!G z?Mzfg1}NLf**R~qO;t_p!Jo6Fj!0g4B_*Xn)YA_XMoxY{MnAuXUQ+{5YWwWJfHd0s z^62{a0rUkiF|p}~1f|dYd%W%Oo9Ckhef;#kb^4D&|c zk-`>o)CxyCa4yeA$*RhFN3`Pj_MBMjxf3(cT z{P>u%u*+aD5QbndIF@}FLv76PlEh9)^BfB#ceZ_X+-Jp7)dU3v3C!i%0SZS1U~Iln zg?cXEN$!Mf#Q@w)fj*T=MV&Qvu78kjUI~vf2j@oQ`7T0EgI(=!4fu>V8aM!NC40qq z*bqFQ_6oOLu^^)-UXwMBWVztuZGIDO~m9K_Sp+WrfNbR*W*`1NzYHion!!@{c4e=aY#hp&heH#w1STa=RrhQKL{4OWb97Z)XHP=^H zwF|7~gYVQ%MB&NUE~W*jKg7e`-Tfb=F6A8^v$RdHK4PW+241D|Xd6fe{1 z`)lLdb^>Z#eeO`{IAB;XrJ~nq2HMWfmOEVMN4P49O6;|o>t~nJziOe zz?E;pl|xSJ6wQ)m_<21;kHRkWZEkGFmjZZzq=jSh3*bP5Y<^xswNql&pDIn{PzcX% zh}j4qDEs5zgxHTPze^!H2iB+9&@$xBs0@b~1lRhaugpCpO3-vkq)zcQ^MYE#AJMC{!KbSmE;ueZ*_oA;b+W$j~ s_g^}{|8M_$H~c^3giJWf#l>bPF>Np1UbxcF`9E-h%xp~Sfp_Eo1rYZjcmMzZ literal 3158 zcmeHKYdF;17XK#-jZD4cl3ZWc6eAQd=psV7B%>KZM2eKexGT3_Be%v-GA5&O$*sX8 zVTiZfNeE3iE*Xr$3=QKl&i^@I&-?v+Is19`-p}68-fQjkTkE%;wUg{^EyYA-L;(O0 zv$|w{6`Zrc-YzTvjtPu3T>yZ{S(%@^7Mi#N#Mt8KX9hGB#Pe_mdiWCY~&G5KnFZ1>k3HMd> z-kVb&KG|z)p^)lN(v!W~I@qj@T)i`vK_yrG+ic(O)J!nM<5P)2sjUW#Tt;B*)#oaT zFDSbU24}xr6zMOBpL00BrlAy`2{p0)OJ3DH?J%k6a>#4w;id)XN19L`aTK#geBw|t zl8`+5lz$Y4eI$B071a!AVRzXn zwk}B;f)&ka>Q;1ssZ#ev(lXP|GXG=NBV4XpK6JHKTUrM2P*iu;bW7*wm{?`%+~_Vo z!2c=`!~bKWVdDPaf=AE5JKnBpTwvh@Fm`F6#dY(*_1g0;%*LIT2H9;kFcWj6*j-e2;(n} z)kim(O}Yfvxl$CoKa4F+PENw2aqyqZJ&nyNcKp<~f2BAd*>ZL?;bguERmQ87l$W!9 z)&)IR5fa!_J?c+I-|oxPYV-B=m6nwid>k7aOEAXx`1n{qUz;x?zNb<}Vw+dD!3*U` zzmSmAKqw+FF)`5?v-Ix7tL$uNM@KImX_765^@A#Iw!Ok-(b45u(;tRPoz1out0ApG z^XFu#GzGJ~jEql#KlS<$)d6E4i=!^&f1MvFg1a>oU(*cB8=ikeue}dHc5DyOG%+za zI5;#!zNUFaZJ?K69269U+m`b9scpF72aQ+oC*Z^t&+QT-?8Ns+f0pH+?R>^37205( zZ)(6~q@_n1BQVo~c_Tf$TrjY46A`jVyK zrr~RIFusWG`=5+WdbL6{-(t<8Pb1gJG(p+U0W0F9IrRP>z1v3*@YT=3VzHpC73F4T zWBBj8PEL5wmPE0m{-<3Oq4t`1m)Za=O-%uSif(-P%Q`Gl5&DkKVh&ekw>djGjj}>g zr%ATXZf^X!f;3IF*-)SAGjO;at<%`Z2%DUoeFF8TJ6l3Rg2iGvZ0SNAZ`?4s-7Cvm zK8`GtmY2`EuL2_E?d?rQm-|Tjv?hv;jg4WJ$FD3f#S>aqvu6lq`$>igY{!!(126OQ z^K)}$fe%qzr(1P|goHRD)uSh{Bv+^U18E2fg<@mUgew(Dvv77w z*o*PyLY-*M!kZ2!4GlvlTN1L}!bJeX)UNjSbmCRc760#LC@(Ls^;C=zfzd~dVSkqT z#lA~LldpEbPeKX?=1E_=!o$PSE-ohWX>?XaNl8YNjbSPd4uAQ{eCpHskR`*}rkq>)# zM|H+*=235Uk=Nz zA?Kw}fB5m^2M7*mvgK(>7)%E;K&QK0zb*_Md>VK2MO_f1bLXy~ALyvvpFw>Wzc3h# z(rcPeTPYr&1b7ZIq6uKoi0x~w^2YIvV*7m;=jZo4CXq;~sj2PUygYf{zWS&wZU?ug zyZaXEJ7e`oiUqD?=7Hg#en)HRa$(pubqTmf&Bv8Zlg?d#L95vJ)%|oaiw@Tp-5HMQ zQ;)tdf6E&_P=v$pgSo3W=3ilM1^tNal~$0{pFDJ+!nr09A){5^=<@H&>k5d_2i(O` zJRT3`N(Ja1zF6H_O3bUoR*S40fwcA)Qe>=s|YxD>PyN|uWatl z&dz>u`A2oGAT*3s2^b8qyS>W!mdD@~Sf;trB98zZ4yO#sgk^CH0ya93(z}yu>X@m3 zGb^q5q<+DtX6b7$adOsCo8}vRT4vUq!Tx0xYP?8CT5$v;f*mNUj`j4JedAuFC=5~= z(kcx}96@!@%@u>OYs;qxyHy%Mg?*_%+Hvp}#wr`35HYX*_sG4KFQqzxQFhkkME7kZ z+A~Q{r6*o5IGCxfV&+yf@OfUn((bYvuHW|=L0=c*rTcPfZ7)!ce1*qL(8U2=UEQm5 zQvC0zj{;npNMN+&O?}nHY|~Avi|9AxuE~}C@7OU)3(EF!hu#`IT_)=NOpA6i6nk@d zuRr~uOLX^Iv{baHE@WmVfkD(e9g}okq)4R8Izd%$jb{_9x4UX*Rp>kwKOa47KIJ(; zn@}4e4*6bpxU?#(axlvqW!iq1TB4xzsq28`NduZKZ%##tikAEMtwUSm3Qsucuy!TD zNXKgSK3g%OR$t&etFp;1icB{*@I>Z=r4S`#qU?UfalCc7w(Wr|Z@e`bS?V-$@5#jW z!|%r<22f8_e!H8KOS5;H=xshbQZBU1S4$jCk0g1-?V0qep9%B}S@!$ diff --git a/widget/testdata/entry/validation_set_valid.png b/widget/testdata/entry/validation_set_valid.png index f57bc89ff75cf54660f70add63d95eab91e1b22d..68f5012eb46282573b5017501e4a410a3a9d7ab7 100644 GIT binary patch delta 1744 zcmV;>1~2)!5bqF>B!4zZL_t(|ob206OcUP%$MHkkX|d1}g`%iDfXedh#QG)2s@VG!i75*#syKMiE%-cg<4Qz(ZoauZ_yYLq=nKJIvs8uC5k@Ot;$yK=EQicuWY736lp04u3OjWha}>mYtn# zu~_ta{q`Tyzk;S|Uaxn0dU|$tHqN0oPgqn`l%1U&=QQ*iolduR&D7M?*w|P+Lv4~! zu0KuF#>U1}RW%xoT!`@thr`Ru%SNLyKR-V=H`nX+#cgS-xNEP@Y=O&7K7rDbJhDJdy)b924Dy^D*BLWtEha_5SQ zih+RvIaEeQMpadn)oPuXm{?j`itMwyWWVw8@vg3}U@*9S6UDd+_wL<$>(;GMDD>&m zC%@lcP*5PZU%7I{;cyHM4f%Y&n>TM36cm_DCPh(%5PwTcOFo}391ceY(d+e1O-+## zY*|@ZO-+r*F^yLqkKEnVI$V^|8I9 z#M-fbv9H3ctgLW2{OsAYP$(4HSX^9OT3XuD(&G2~g%B2trLL~-&Ye4N-n?--ov&ZN z_INz&2Y>nS;lrg%m+W@?;NYMT;`s67@87>)US1YLbar;iea6Sf+uPeyQc{+dmNq<+ zs;VlF$8-1YUAg$oW^-X-VQg23h^nds0|S+nm4kzW$;rt_j~?yn>VJ~|WwY5zN=mF&Yieq$yngxHAUQcX zpFe+&oIFQHMs_Tr)9ExA3{RdsS-)|I`^A1DU0GS_=;(O*^l3#!MMp=6!{Ly>&`?!X z`=8O#(HAdXL?6fHa@p;6v)NoxQQ`4;Mn*=25NFPuX>Dz_*=+Ok^FMz4h(3a%D01OS z>wjNwD}%vcx7*L1JJ-M4cAHG5`uci#g<`Q- z4j(=&ga`xzLWo0$4sAG;%jG(8;zUtVQD0x5+!79lWeJnXbpHJL=ttsqyUWYV<&9Tb zTADl`?2KSA*xA`RF)>kBSJ&Fwx-0!+UxikywYj-j(==68lai9|-Mgo0n$PFEeSiD* z<;$0AYHC8EkWQ!T?(Y8j^{e0S@9F8ediAQ$=evLZ{>P6W*ALa--`~*CFg!f`>(?*2 z<>AAJ7cX8sb?THHLEg^)joaJw3IxwXwaa7|4pv&CN%S9NCqA z|2@4${}WMpZ8AAIxxrT^CCR(>#ec=c-_D#VDJhDgEG#T&nikoZoSdvEioCQlXvHvVwU0q#RSlIBt zHoO4{uG!+?s;d5W2NK=Nnyv4jSixZM!Gj08H9OK{ZrTtN!ec^sObBmF34hl=o2CTX z;`MfPn_+m0RR6b9o+{hrH94<0000HKD%% delta 1688 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 JXQ&(T{{#xkJDmUk diff --git a/widget/testdata/form/disable_initial.png b/widget/testdata/form/disable_initial.png index db47ca478951aabba326f3d883069c7243b9af98..60186d0b564e16bdcb9e50d3cd529c9cc3a4e1ff 100644 GIT binary patch literal 4029 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 Ao&W#< literal 3843 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 diff --git a/widget/testdata/form/disable_re_enabled.png b/widget/testdata/form/disable_re_enabled.png index db47ca478951aabba326f3d883069c7243b9af98..60186d0b564e16bdcb9e50d3cd529c9cc3a4e1ff 100644 GIT binary patch literal 4029 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 Ao&W#< literal 3843 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 diff --git a/widget/testdata/form/disable_validation_disabled_invalid.png b/widget/testdata/form/disable_validation_disabled_invalid.png index 26bc5792cd1d9f9763a71a063a970a5690cf646f..8f2f51ac9ddefeb7971f60aa9d7fedcb6192ad11 100644 GIT binary patch literal 5971 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 literal 5315 zcmZWtcQjnx*S=&hN*FOwqK;k%QKAbWf>9=Vi56WLEkq~LMad8(Y8WJH5FvVvGDL|o z6QabcMDM+P^L}gn*7sZM`{UlbZaMqxyZ7_#^XwC+ud8vB;tmA>05>%ssXZoKy9tLI zn3!-bNophm0BF3Xnu_6z?2VidU!$IuW2d8O{7QCqcBCnXN(wQ#O)RYWi$XdX$uq3_ zo5vOwW+M6YsEm;!;YyTcJ~SeeSbNjRqk1f#lhYj2T#m_n=o9r;Fwzsv5ygyl26I0i z#0E^CZ)AL1&+ZuN55Ow*>w4c>uHDo4v4O933O$#XXnUs^MDq$l40=hcf0;wnIUf-l zXTzw50Cm}%$={IEw?914EIJ}i!Cd_q7^1c}6Z9c|d++9mZ)73)R=ALpVDR+42-M9R zi?y^mWpO#vDl`>+tNV9wfr(*(ii7W1yd^*MVB`e5Mb27wcI#NF(|oT4BUMn>enj9JfpmkI+C@Y3Z*yCYTzj7cU360~RO5 z+Zq1q-=Df+JBA)9>$_WCMPgzBgxjo&9c+5h@^K&D@Alm%p0?;{t#9vTC$3s~nBPO; zcnw@^WbotJP%klAO_~uUN+ijmH`K#!8l%~hnOQCYg;uB^+tGSN>|e+3D$K?6_RaV^ zT}z{opGjK}osDN5} z$C1tm{)4hZi(RAVLT9>&1q*e|73LMvNJ?2b?E32Rw|tHb_jc>;4?5;eObW-r&NdqI zFT$#>BA?67n^akaoNv|>0X#fB6B83Zi*?Rtk6XzAejy=wuRoF4rGdV_hU=?yjl?@7 zK!e}ruZ~w_>+9>VNUn#kGbNmUtd17W1#P!{{rZ*QUxsz4td!LAel*WnEu*fBi%VeO zS$7=W?vm2kYN1)J<4smMDB!s@^DR9+y=l9(>B|>MQPHXoA3hWmaEgke*2X_sRn?c5 zZ(v2+zL-}?I1Vz(`w8n-U@-QCS5i_^E5mvB-XZ*F14{h*7I)Lq(j@QQD=8_N^BGp` zO=2ZjJYU_S_Pa%Fb`&&oCUD7Ydd8UVD<#*+*>b+sR99CAgclbVudS^uFFOM5ts&=r z8@N#%&bbypfW=N#SWJzNg8*D}z<%}9UXV%(H~Cz1DxV&kyx*YcK~fT793=z18=3jY z@|$T7 z+M1ejY31_`iC`@=GyGTgX@b$a5)uw(aDM)V;M2RnePmjNMZK|+k%NOnT!E>+ zzUS%)%q%@9^Yn^jaw&EQ(aLp^h`Pn!E2W8zkz#`m32NSG2D$r z^V>T)ZU3sHgn?iRA!i4#nIs6{>x`nLRV4&HPccXu0AS-YGtGXR<})c!1_q({8rKOy zLH+({DyAC$?OB(f#S3`^Oqe$M3IOw!OKPvC;Jd>P)_sMddSKh6M!FFTxkyPxVm&8KG zy~*rT-S+c==#7ny{gq*%_?OI`Gc%SkT` z?Ci{u_g`yvrsCCkZ)jrTzx$`BKb7wWz^j*QX<=buVv>=Q!zzANZdOakvdNPtH-VkN z7BU*PK`d5VODo!L?QqkvIfkeLkU ziZr*d2*|BB6*kWo#%^wIvh?DgNsEkZ`cb~LsWT7ArP1wJ^6syBRzLlLI!`xn|9M#I z&SKuW=<8h0FZK0{M8!W042?EdS3l#QWx${OB81w+D(qCl?p9YCH8XrvWkjE$GRb$Ig|N{@Fdq1pvoy9jCIr0Q2Dg=%mI9 z2tqpDr@sxy*T+#p*2m^Bvtqiv=cP z^ge{nHaw+WiOx1(rCUvmij()HEkvA_>VM_LzZ!|dEG+hggz6Y33*oZYb%ullyfUwmUYt zcD~Pk*`sh(-4O7kPh}}JIW2YRyZx{;DJF9@XnFK$El!=L6IqCge0b64V`3djZ#_ts z!#BBr6TW(@`a~d-T@?({A;!kge3WvsbK)Q!A8gXOK5eed<|e%nimwbTKwOnux_hWr zR6Kek(sr)c@I38ea=mZe$d%<|MdFXaKe>27MmN|__IPG{eut_pI@i2I@wD9g;%SeU zxn*tqKz4hjWg?xLPGW0@m6&^oQAO!NOAV`c`I`6cuzTcU)pldVowe?J)-jLNP2Q*c zbO;P&eJfAWUvm&MS2p1Us3TCguC3>1+0c1tg5!-EDsF2&FR&H;s0wZ$o=De4h z60Iv_&tDeWs0m}3R3Nv6|Kodif9om3+>0!l99f<)!_G>p8#5ler%t02Wn%rL=*hTTjVsDM$Ilp(v5+# z{xL2mm2@YlwqNLo-pv4KqVth4W`;e@zRiObdlc-gI67pZEu5RY&5HPz5#mNo7G=ah zKM8%AHCf@q!X#;yM|xRA93aTu+U1Ye7tPH5HOiTym&e$#tg5af=|}#h&v(9x+n6?9 zj}bnXZZpBi=>Du-o-Z7H;`4SO^-Zl@2x;RUXs6^1K;ZTwP@8$*gc zhX&3-Ptn9j(JQ^EB(#Lt;V(03RA#GLB0iuab-C$&xN6Hyqgze7N7t8Op}ijM`<*B@ zWSP(_8kObmw-*lGW=;;Mh=HhJ@yD+mSMkSv>|y+Gq2l}WC-P18ltr)3|GG%v&clfD zeXLQ+QaVF9$~d$>6{)zonyk+ywrilI_ftFX)0BGt69W?wlaVFu6Ml@%xacR%Tc4-# zWMLgM$4|fQ8E#;a{s`pG3pQYhz1O9gmRTL9w_3xre10r=Z6FwCsXCmql583BKBo<$ z+efN|OuWmZ;*eybcX^LERqW;s0a@cV)lK#gv+we?7 zqr(>k&Ap7ccZS!djoTW(t*WM$ybrO?ZPqgUm})?6JG^O19`*9Fva%Pl{*tc)P;dbOa_!zFZ(BtdEecenDnW38Kg}#U!rL#y>QXH66`}UiSV<4(lRSfk$C&KXs5Y+;HEp#O6@w1R)!S`r% zYAV;m_N5|zt?5+O1akiek~)inLh*kN1MBh_SzZ(6!PulO zl zK+DSFq6bgIc9OOxW6~mmH+53!FO=?~kdiTCM;S)zY10`e(7pJb8r63KXKBu7Yzl%M zbza`X*2pLXUvU-KdAh<{V3kQw_2;tf(x9xNWna0Lh~yJHlY4L;TNLSBXzq$48_iK+ z9ry$?=@v`tiAu7t%Z~NaB3O4KA&Ul!S1x=Ix1(Thib~!tu&p-D*5zZ%7?n(fpt;G9 zSIzbK$VO7>HpJ(XNL6E5-IEq~=6g2%+%i5-Z?+taQiDGf^KDf2Oz`&CY*2$s0>ux83>T($JfemKI4#|1?x#hn8p3 zv3B8y1yo(ZrlZEjj9y-j)=90fD4K6e4G9Gi3Ed)0tcipwvL)9a`;T`Ac1Fc(YnqF` zu7F`{q+N(%gq;hh`YADiMUK`85z=fW{D%CUGc0`+T#YakKO8E>6RE`Z$2v$J z#D9v>^CP8$B^MFyRE6n`5K#5M)~Qml3o>wwHCK8^q(yPUCVWRw?_#6zxHjXyKG6>P xDwg)&V*TJq7sg2X?heQQmDJrZLZf_r4enKmLQ6=r6E-ISO?6$hN>!Ve{{xC)GM)ec diff --git a/widget/testdata/form/disable_validation_disabled_valid.png b/widget/testdata/form/disable_validation_disabled_valid.png index e47d9fb297656c427d7a4802a1622caa9d582351..791c045ba85328e13bd39cf4ba74eb42d16594d2 100644 GIT binary patch literal 4500 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 literal 3621 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 KrBaGA3;q|gjR3a* diff --git a/widget/testdata/form/disable_validation_enabled_invalid.png b/widget/testdata/form/disable_validation_enabled_invalid.png index edd815f604b1c6af2927734f7d947092a1d43184..46dcde00a39f2cfcd20e76aeeb01f4fb65824013 100644 GIT binary patch literal 6150 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 diff --git a/widget/testdata/form/disable_validation_enabled_valid.png b/widget/testdata/form/disable_validation_enabled_valid.png index c0f4ac6982af729a656fab467f2fe9d90803a59e..57b2f739d26dc5ea258941ac68c47d71e383cff7 100644 GIT binary patch literal 4955 zcmcIoWmHsOyFV(O{%Hn~5J%|_X^?gpkWOik5D+9(kdSmJ8DJb5VL(Jc1f)S!BnPAh zi6I=iy9VT*_r3M$e!OR$TKmH}Ywzdz)lM*i>(Ej`r~m+<)zj592A@B`%ZuVFcrQ(E zA_o9QK0Qr!(~z8v+-H`IL@=51$$R@i~l7!Jb{R&mrJ>QhG=BRFiW<=6S4n1YwD7fPa`AvrNa4);xTq!w38 z-zUZ`zy|v7O10nZ%lXb3dbBYCMDkqoe$N;Y5~e1}t9z{{nuj*@J>xGaSy|cS zuV^SeBcsezP$4&&sy5k-!D!hBqla)$HN5`8HxYrCIAR#P905)|mR*%O+Z6=NMS7)%&q<{z?G)gilob_rco)^+-<^1d@IJ3D^(@sA%r z*0>J_C3?BLTbP&>4L$1C?_byP_TI?$ZEFlz9_UKp=3wu%M2CiketA5VnU|NBn~RT2 zcVx@V%rv*Q&Pq!gj$7fXuBmx(j1TT~s#cfJ#t!uLDTe=5Iu}IsDJJFRVLP2h{i(T;1JOpC3HxNxNlkZeFC5GSl#cu)jP=&nf>a zCFjfh=4LJmWnpHPk(2Y0dtly=L~zogC=O<3jHzHaaZ|3sT+wH`!E3xy zOH*?vq@}+f#>&b{O^pCYI_`*yiu(BYphWGW?3I<2N?_JrEIrMjE&P!C|2O>#KgqF0GyxU3NZ7MxJgRQGCDp^9rKM{%8i7Sw8FY> z4XnXby>GC;|A+VQjRZ3s9UX7ox)rLTs-OS?zApM-TwIiY_;B`Sq&)(K!{hNhIas&8 zMSm|ZuMGXM(a})}K1AoY-7mKFwY7IL^pmumJv`Xi*;lu>?ZE>qq0yb6iR^@xmG{V= zo*n^tdA1u8;^N{eDk_SK**x(pE012hAdZw89;+&r+{-tRG%wkls?SEF4YFk)&$fkq z$|Cs5KY8**ALGB+n~{{16tL89)%rXT2J4?`eUY1!0{}0MHX4Js^T57>K~3&3NkblA zoE^&fO!Jgyty9r_XJBA(kz~)tR+g75K0mm_Ig8_EK~Pgsef$1>e}CUm#@)lCXVHH! zUzHv)lA0wN|SC&$Vy++AG-m|kDOjus4YBhOUwd+>O!t|w7ExJo-} z{8bGB_<|$XlNLTZ}NZ7aT2N$_x(v=;Nt!%06>umgodOfEb_J?8IRC4T~kx0 zWCEET@@3X&FnUh6O&?=iKDHCo{`^qTTPkd?=Qh}C`HI1n;fl>co4vigYf}%-BJ?p) z+!Rsr!CSUQMya{Exk*U|mX>VOlNm5SxK`=c9_l7rMv^Pdk&@_*jfonD1Q&$-M-pM3kHMf>c+#N zb_X3-lD&nPUfXQ4d2gynoE7~6ajc1J0FDB+1Ya&o2fFB(l52O0Km`CldBl~=g%Ly8%lRr5KlOR0|RgE z_DmG;qWTIA=jZ1^h8P$axR5JjmCRLoCdtF&V5)fAFpmT%E-9(BuJb%QSOvMr2=a&~ zNgIJcysF-sX(f(X*k1vBX4`0|j3p!_2J@8H4PQ4$Y83wX`E&0yw9$6JL40erz1?@V zEm@Tj(Rq4$${o5BX)1{A?q2yFDk?0TBkri->G{D_@bTlv7mFzS5_m3^9GCKQY4CF* zB1t?HA@LRupkev8c6NFaWt-<5m)rA9RGq!O`l6`&7-Ku0WP+_IiYI<)$<2-@8|x;C z77-C4TLmE{pN!~qx|xrSj*bR-Ur;b{fG%Rwi3LIW;xGQ3X23O83vNLy99ca(9ab+L z!D6wFI&~HvQZjF0OVf=3U_0Q+k+!zBPX{0Iv_6vZsG9^Ekb~rd>4)TN!Xlebr@znD znk{Y~oJd(t96nanR17mHpaj=aN=m9{k^{1$^)He5U)9*9>L%g-d=vH>UK)k2g^71o zJwGPakvwF2MVu~njSA3xBn`=8@GyRFDhNp;1H?lp+=nGWef-8w1xeC|A`8!ax`!S~ z``y7|v9y4Lc+q&VeVK{9y%B=B@g>ox8ckf`SrM`0w%{^S~NmW`;yh64M}WGwQpG%ZG{ip zg9JuCRp6hygnU6NbSA2gT`Iu5!hWbl{HOT;Z(aY(4X8u-yBFr>J_T(~!e>vC2`6WV z>+_O-l)ugUX(vHkeSBsv`PmIYVgP#`i5zjb!Nm7r)8)`UEKj!9)D%IP@c%@3QoMk#rVpI_MW)7*%ms?1J;J_e)@8Bkt$c?*fkAunEV ztAxsniEa0zr9gav_90FvjsB{XTYr3FV(sV8keu(UCo4NuNb|6;(tba5Xg5YNrS#C}pnMkSNx2WS_|1RIQ-0Buur)vbWaSqx6nVNbbTd+I4rH9w zRVx#dk;`cIlsDyQWT#GC_{GL3R!yvV=x93GCcAj=L`3yVcgDyC=i|nY8tQ@fg(6Lo znl_12-n&5!RU+fwXI97Ps`kdY44xn)b4st7h zgZg4vUA&$khF7I%%c*L36#5q!<3HncA}5n1kMI~iFP ziHY(=Yn=9^6|kW9;)F0Lgb)Y6zsmTzRZ(rh!o+yvaXAOZn`QG^jZ*u`?%M~M1pMjZ zVAjh9<4Hb?%B0*Df5R=p5!7xdU&fS%zyClM8eDw1H0pU6OUohpu!Ri*QSicjoSvS( zVQ>}rJvH_HA6Lr-wp28l{l<;F^z`)9RHKIveHEnFF<{+~;WqeI0woF)LY^$X(8m;ZkB%?!U#eX!UyW5u#M zF8Z$aq>q1Sm$_{~Nv+T}Y-iL#Rm)!ZbB*UZrQL6cO-7@n;4l2!qU_$HNVtv2(b18f zp5E%}D%j-pb&ty%R}Wan=hnu`LGw^PmYH6g>jSOXJUZOny#lzny9;IL|2tw`0ovNy z06--_KQFJ%Yg|-EM+bUDp$$uw5_ZD5Qt^y9b!1QvM##PH&1tk74x`Kdbhh zjCJ3;6#2>wh^uxNwfdWmO6xnylSZrvJl6OM9nv&xLt-feV-0p5DV9q%elTR0iIzq? zAUJS7AYKa#3%Q8FTxFG&vD^wl16_&i`&hYIekfE{MuwT0xx+kN#dy`;UBCVO)t8<{ zvBT7PNC9XT@dN+zMfPpBW@ck48$pzXrtYki_2D)rRYew0BU>dY_i)+Hujxhc)h!j; zQvpkE0dWt_%HJU=-Pv&F{UaXXSegfaOX<6v=A?5z5U(KqTI`c~Rk3uhg{6+TML|1Q z@b=R5QFe0{e;W+*Kw`KG3jTWKozDk{p4b8v9*@`RA$STx1sQyODs zV33rOGWfgNIUpb)aGj{~Y>x!sVMqY|vyT4D=16$a-y8*1&ygOkSyqqQNfEt{R++MQ z)`^7C2TF9>g&*S~^{e4k-5H*GLRZ8>i!>{TJSC_wx<>dXlM}6b&&j>$rlXyiRK`Dk zXw$lM-x)+yZF1kS^IbDjMUkLsU{QX(%q`E4hE5Unqc2hdVoQ&Y_!KPGk&K%Iz* zjRiCLRbVEBkQ5zF0wx&?3kzokBoZkF1`u#WNJuC~L&CK;{l||V8yg$0eVL@>hCd-#$BR%1leuO=IZ#G7zRS;RJ9C|buo}aJeRy?JP zAWz{~&_CoDz|rA272p`B^fR~97OeZmvkhNSl@+#QJpOKY{-2=2_wOotslC@b4)3yt z-mm$vEVAC-e;lxgJqkXxQ5zI0Ni)J$Sk*xJ`4>QVor(DTZhy78dpsN7p1nd!O1h4# zD1ZNc=ineQF)>Hl!`R9St&iy)7-)M!AOpi}y-#jkT_BjDB@%kD*o*W1L5#6SNJz-j zr?vkMRN@7*8iDL0SMesT~eQ&emQT`RshIJjk~%+%B0 zf3MoP%hO9Se6*ZC?z>~PrBn4=9tyhxFc9iv(scQ?p=42xZ|mynjLVo1ooDml#)!9U zb7LdBXyjw1%uF$;;&KTIJNtdUn|}ij^gWGJccH7DX3{+rUUbOLg4H-i!9Y7?;-Jj- znuObZAzrgPr?w2*m~_FwBulqW$E?;IvM`PMmPe2@o)NzSUrAc>16Romoon&q!2jtN zSBy*4^Fkl>vL%N1m@On$x0C56px|04$&NQcBeQ9_+ literal 4741 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 diff --git a/widget/testdata/form/disable_validation_initial.png b/widget/testdata/form/disable_validation_initial.png index edd815f604b1c6af2927734f7d947092a1d43184..46dcde00a39f2cfcd20e76aeeb01f4fb65824013 100644 GIT binary patch literal 6150 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 diff --git a/widget/testdata/form/disabled.png b/widget/testdata/form/disabled.png index 15f478f45c2905835335c04bb5fb143a507b5520..ca7ff885f4a8861d067e8151f29dc9ba0491d2ec 100644 GIT binary patch literal 3080 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 delta 2799 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 eddx)iGx z0(p2SFD0(-p1#|J=T0ttduK4Y==3|8iRZHr0~(nzF_$=()Gc~I82*5!xR#GP3O=ihXhqm*FE$r|d2f zxwO2Hy(c+wXn&O!`}60|$)(45pX0W_PCLd4DX@$|Vv4I2sb@TSdD3NCp_Q7Jb{`+B zgD}awwrrJu*p$0y(h5g}$RP`lVPbq-;wuveVTZfBJ1-xf&@U;;_lg?D3AwDfOk+8g zG!ng)B|d9V%6kKqyhDHb!jUda2299;*Fn?Mr%$Up=jP_p)9D^Q% z7!?)O-Q9h;36ET%8=H zc7iGOXMS3Y_+#Jv^j$Rk8~oGy&HQ@+89Zb)8G=`u%Y;$$G2 znwoIh=_E!zYh(O3WJvFc^M)nk=Ds-Tk_r*L#zk=>Q@^5Be#>elP{x^y$iWL5HS*tq zQpQU$GDLD+(2+guC=DO`al77~XSXb^R_gtvuxmZ?Tmxj*y+ z@;<4M=Oebjn;m0q*MibgB^n={oOn98U`5XS-pkDx5+AB`u*Cl!A3Oa)hD0WFQA7rt zX@_bNVAfM(xcKe2rk@+BG9XK3_11@{K~f5s}_DFr2BWDfZ7UtqFav9z-KQCjLM zXR3Wh!e_-(()A6oRc*V-<~b9vv0+|wq^Yh>PEO9xw7=XUCMMQWtfr%@i?jM?r<_8~ z*S9$-NmE}xbElBs=K1bDT^*gb>HMqx+OHl3Wo%*(rSPzDaFiBH5Yr2PsL*=P*WgFh zSgdyC5BB6>mYCmksU83l|I%&C-Hly>!aGe(3ofbxP70{{6ZF9QW6y# zYfx$07l1`TN0aQdIm{45@3H>n$(uxgVz5q`n~@O_=ELbJsi}fKS10i-%3za$k5uzy zMEXs}2WE=frGJh;|aUz@=cMfNsuCPbWX{ z=E+32zaW;7lspV@j_)(gYH4hwV+b;l8spV7Fep=Jo3yHe6?I-l%b08yOG!(wnnmQ~ z{3@z;j&$*)&6O|8Y?_vP;1Y?z>t%s28O@0vs0*;5)h2V z;Cw|Tr>d^`;`bi0tVmtZZmCg!Zh7b(_GhDQo(wU+C4E6WJUkImgi<;`DZ>dM zOmlN{z#T+Fycu{zL|seH4h|I^40Z46si@=-zp}CnIQL>>W0&ikHUV*YYRA-mzEs?A zbIn#^txrLVf^w%Q($mvtknGLZa56EOqAm`bYC5f7@jN(bX04zqc#d#+{6$V!Shzmx z4Kc%R2@_nyYim5ezhB{cHDu{g(g03EoZP^KU%H4_bx{%6{zb>aCkLXBjt)~_dZ!NzpQ?6cC!d|YYkqw`}74(Nd8=5Q3`4zM!YX2Yp+qatnmvMWr!NA_7se~sTHmN*cHQP;bsqM(#&4VfX; zYW()jr87C4%n~jCVI%GUzTH)REgejnZOErqF^F`Gi(vg8zLa7I<#!u213x@pK}^LK z&WFMDnTFlg3DoVf<}0ggLMobH&$go zx*b-ciT>V+6>}E^Zv5u~+Tg-92 z7gSL~?7*z7aMc?b{(vp+&ew-=^#332Z5ORBTAQ|)VyjG882clJp z?i?Y#L7vnZG~La|%S*>^zj8KjSICNArUk?&n32iJNmW%rd;F6ua)3|?l_@8i;VoVY96V<@h zm^?)G_<+Q&t$`jnBS()%*|Z^newfmU`=R!rou!vmOeTrCMF_+ z?del_Wn}}PNbT*pMvlu`ZUvPPpt9IlTPrFnmz9*H^H>Z+BJdI^1UwfO^F9V9n0=V| zpm|i!RM6VmDs<53wA}3TPnj(>c~Nredk;LXfk1q3FE_Whx4(V+MycmWTo)2P(plPD=I2Lk-XS%I9T`|$q^PAd3}OVCY6A;FDxvqubW28@c7+& z2aV>xNirWy_J5+Qt9w2EhI4h<_wM#actq^x1i_DrR>+?N-=xI17$g=F6vVDwi3#Dd znfo<9J`RAeva$kxGbm+^w^uv(!RU~c-@o5!YtMQiy`&{G<_jk#(Wg7tw-N8HthNpA zuBO2})YsR$E&H4gaJFDV$nW1rgZwBi=ChgmnwhyYJ|1A_Ne5wKWJH%Of)!6@W@Zu* z5ea6*#uKXnF>G!Pc4|VdMT~yw%{OZZvO8)MbY2iUrVxB170~2 zYeEc!U-FPS>Nss^15gDQVMnDkm_#`_ITI5Tfaf4CF0Ro6dQ|9*Y?TfXR$86zt}eZLXFOS=~vfsW4h>>2n$T3X2p z`Kh8lS0rL6`?XHIa49khimAD|)U2$#xsPRCot+n#msP)hmFP9RVrDM*@xyAN)*+IT zGgH861Jw0bVDls=hjn~z4KGZ3cxsOHT0o-ra_~71p)<#a;H0*_W0oP8I0sk`>VGB8NhuR8$wbIM8-L zGn~5BB~3TS=YEG>l>ashfb?2Azw^ruEDpI z6%taEfk#3DoZjVTmfvt?$)uGMSY{=qy<0MIadE(h^VK#3y}b~KVus-TWeJSIT%5Lw zj@M-k%nmm+ECN2>Z2{MMoHNl_Sj_Q#A9y{zyoC5A-FdrAxq&YgsKxSZS~9Kxb!;Xy ze~tfb@g!S9|8QEPYw#mnV7TVz=NJEKOmT`<>%doTpV($h67g@>NaWZrqLE?dz~Mvl z^Vj_e&%mnO{mF~P_HLxK8vdlIkGa@F5ii$P?@T`J^0{G<6L>Y}K1baE+Jg;p{9qmU zehCxgQ)p-?ID6lsudi=aH7AZn*ztYRYC0iko&`9WHYh8R#2-+i>*Jzi9!skNt-z~f zVPS!TgF{jqH)j`)cdu=3`ZeD%y0^ENN*oXN?Iv~mqo7Pc#-Be!f$vXDOa#QllId=o z9bJ!~`WbWij?Vk%1Jef(!G`iSg)CPw%eI@|f%!%5@Z>8f?kW%j1O5HLd4`7eB)>38 zmr;7a`niTo_=pwMK#fHIdL0PEUlMCSSEpH|>!+|HyTg+c=NV;-QE^pJ6DWIXy;$W5 zop3R^fZgmfB^NVPy9{~7+XI_Eo0HU2G|4kEO45apd1Ca7DMvSL*dSFX)yA1d7cfV% z9(<4tp;2+7*`EK7Cw~?WGMG=fzeft&Y78EGl99Ua^Lh*E-Fl~XI4!G?6d}<1g)DA2 zJy(h)_&V{(SOQBiDRZ=+vG#^y!*}nL12aN+LxYoF_iz}t*CD(Q?T9NVaBb1<;|sDC zG`TswqIhZDDfP!Iq<%!|kL*8p{C_#l|L9tuz#PO;>}}@ol9C zy?Np+8U!t;mDxD+W?9eLS^8v~UGO&P=H`A9J1GV?f(*BX4*AxMpz7WCe5}Lt9F>&U5S!LpIxU>4NlVF$EY*i)t95?e~hKBYHA(>thR}(b1oyv{O(?@Fvb@izA zJ_`r`??1+`&X{L+4hS|!bZQ#W^2x-@lJ0Co=-fIc3C*4)-rZm_qD`tZWayuvbgU%E z*7(mB{qQ|DA=0XN;p6W{@aqa^?RdUq;rqrv^}F$zsUY+B@w%768(!~X-Y{{tFH!X} zZX#iWG7H^PWPB@G!08DIsu@C%AvE+rgx%vz+K@|2UptV7COe5wd(`JQ-pL zNA($yXZa8b3)hv2nz{Ks^FUd)eUQrUI&u@WogNw(aT4?HS-7^CCxl4 z?e1W?)jH8`9uHF9oZ5XbD}6WObJE#27&Tw?)v{V`YrSYU^T70h@!I)bqUa%ew&m;_ z+MF6PDx&V|P5Iqv7j13R(JI|aAKLqL%(Ex-hT6w@B!SJO2(G;ix@5?2c(=a~|QY z#No4JbHU1E!|Zn^HmsEKH7ddn1O7bw2N^Zt-;j$lia$rv`^Cy|17CbCV*9tRChp-M zmr-zh8NJ71(BtNS#aQ6_{f+~>@l}NXkefe5z>^kz{&(Eja%9HQU7y$mUGMLWcW;6l zKQgO}Z=64CFP^>-SpxB|KoH(9ah{VX?FHq~nU3pZf#W%$hA5lebD^!YxF>!(xKD-~ zQqRV%tz0d-a&@6ET=4w%t!lMz*YViu7Z?2Y;i_>fHoLqV4wRUcA8?9iV;5r!d_-)g(WN z3Z6P~No0YMLeyVFoknucI;q{XmfjY|?8Y}W;`Nqwdj#b5Fh-^j2^X7VE*ERdUuGW?HSIzYMpsC zZ||}`_%uTixk3hSNeGb)Wjd1P5_(7g3{`kQmNHMYhZw}GY?@aL`bw4*+g z0fdOezWa|{Ihm$!C16kg(Al&NGz@%FrC*H5=E;yoDtPnME#zA_`|eXCnWYqmbMovy zmGZF!5&y@qAMyVGT>F0_H&3cxn#Q&M{{dblC6;}k>c)rHY?Mf$P z^D-)mu#v|nmMXd%sKKAJ3tsW>EqY=eJoLRV0uha$J~;vj4beYBPSBaUC|(o`NshNkb7g=gVc2R>~QISP-o`$0xoi)@m?E$D>^7$a;aM%F3fj zO#?ISSHN2c3pW-N6jWBi@?ob-T$-)#{1(MpPmQ)e86}sV?R42hNiq6E9qBeby%1@f zjPZSsf~wtWC?dNIxj@)HT_Zywt_W=hsR3h27Wg$ z2P#31SN+l&v_~#vPWmgaiaKJ3C7gy^-m)FW|a6^Lrr4 zjC*!4g(p6)bf0TtVF3kPY+^!!IBrKr$L4Ux&gP~CcM3?V{SMcp#i6;mxj-_2aLn^= zu?!3wK=1!P!(KW__ z)@slMu{aw$J0@f>jc+6oF>6|X(w)wBf)V81Zt+(4AQioJf#_N~W3{^?s8i{DbHBh7yVI)RlE3xbY zYa5}P9>tRpP~dd21JT?nFWzyC9N(}ozsHIdIh&b+>sDlfd}JXnuKYO0PH17Bp9_S# z)I8=Z8ruhccV0m01LFkb{W}Ep2E1ko#!626%9{1*(>nWA2~*Q`kUqNz>RDUw@{9;e zs;Vm~MFZIeT=KxcKwe(nbcr?wgEumo??{MBY^e!8oR_!ikA5~J9ylfmGw|sRR^AkrEaK)Vu zn+1LrdUSNOJ#AZh@ZrOUi{D8GRv$kOnLE9C6FD^0$;8C8GE^%YP4f;03m{4O`V|5x z09ok4x0Mw`$ZJc>r~9`{9-9v!uYG((AlcQ`)v=ubXb#1OS$}flxPUz)>_}E*&fGlp zYaTECTpTxu0SXG35mgRyHZ6%hcEM?83qmu7+7yu2ZV(9Wo?&Mg zsj;^m%ZhE+l0?ndpf3vfU_Pcq>#9PV;KLQhyLa}zpYGu#CGRE#J+Oy->Nw6&6BZG9 z%*Y75xG(Ck2P6$^Qi*2NA!8qS>3W_pGjr%x6ACR7Zwe+9fwUGx7OJXa-{j-%El3zn z&d+fmnAq5*I#mi^59a?x{DK+8Zyq+(+djqf;pSz?>sD9nMR2>%|DLmQmOdcE@L=-Bsu&~T~EnHmg7o^z=x@=E?e62x1 zL{#*)k0px`AOFYq@4bC}b?%48T3S@ns-RZ_lDsjiDr#zK9k^>>+>=r&9?S7>phebi zTA7}nj_ipYFy#)H0+ISLXp=-!^Du*N;NfvPSZXS5_%)3)b?;1W0Tu@r+Tb5HuCS-G zpsfgkdU|@o$j$az0g$KdJ zQd2{Kd7|LdU$~T^#54kR$7y4*LS)Yk!*|r4>Iq`YnOwR~m-AoC=MCbQ&3EiTFFH<6 zPPZ=8gUVWc9$bd_zV*Zgqc{El3zs9!=AyLT8L7ZeBP8^wsjK?9Ac}yJhJWnA*2}y=yh?9`aGnq+3NTy5~ zPUay(ncYw8cYnXTzU%&RueH)z+v@o2z2EQWc|A{0bkM4o$(hI@2)eAUrmPG8{s8_I zl3oDck4uT`A&42LuB@Q%m${MUZ>VQ*wyo{rQI!Odg%PP;F}iT!!b5o$9r@>Z=uwAj ztj?QawPL{=)$yY~Z0@!1y_T>8)$#Gp1!4|0En>CaM7W`+9k=4(fy#1}6fA0H3;2$~X6 zbV{pWoSmJWoT^RM7DU@cd#o!E;^OHj`0cEC@`6J7D?~{>d%u6D^w==PeJl;~*b%4U zPhw(b7NK}hVfg9IO+}mz1xbWPUZuH-iK!`^E#V?0j76zkryg4M8gq1vjqQ7EHJinr zh0fl5R!>W$06{9V*@A*JMAtOMIy0Y>iHNadue=GfQG8DFf=q!)4NheLIUXg=_H%#S z!lF4~znFzpL<@Di{<8ICQRwd7yJOjOvD{)}VhDs+*VAhbHAj6yt(ha=6%`dxa6LV} zVZ;wwk$bi)Gp3rFnxUa`FUcUc!No+Irp|aS?h{_dTGfq2cgro~BUiNu?UsWJ_>kLV~u7 zi;JZtyTTO#0fFU#EJsJjz}39edQ%raKRmP6(~XupHP|fm;nDBl?iMl2T_+(hb!z@N**zi&n>R!8~2Ei;@s@cCsudfk2Q( zD%KcZzWBW9XszhZojY&SJ<+ym`OmLfHrh3Le-AwmHe4rwczJp01WgaxFT!4?q?|3w zoilox!a63>e6T#U1urPx4*}&f${#y;p_e+eg$#qEmZ1Mzm zvO2(P{q(brT+$GRg~`g#?_1*je!wX>oP^W2=h@j*kea4um0+dbm3e6-zTAv1)_Z%d z-K5UN+t)W%nG=$?uz*2x^PSPqql1G3=c!sN2A`ELxQT(A3xUX7lx-EZbH3Q5j`BDE zbW8AYlC~@XL`zSfnwqMrs#<1T^RA)6zqaa0dGtbcc64Jyg9rmf$$dv*2B%?vX|^aU zhnmU6thS?yyu62#m6EDtq@)n^?Uqeeg-tj{l_ASz3ayH~h8cnWwK?*l9BPC;kJ;lS zIcPR~R8bOOMp)L7+xKP&GdJ}Rb1j_Kkbf*K7$GRA7Z@l7S)QF7 z(#75>7{(pBtO+wv;B-hKjH6?f$&aS2ls7s0ye1|l4@Hf1biOz(cjaMRT%sy;oNy#0 zBm=r3wlQaCAtm=U3x?fUqLXD7Dnzg-u&bq|rA0-Kd%E;OSoYqlwo>$^RPXh!{&P+K zxi|R}(Syr@{{9o(Uoq7;wsK1)1!yw*zt_88kM88~tqYP3)m_)*dNDU=+4$kdj~`#Y zeAy9q_w@8s99^nL;c&Q!h=}b*Zxi@I=u!K*B3lAIJ-tMslMW9p1K-CK$MMq9(a|{H zl{as=Zcw<$-Y_qCrt0Rl-4#neJUraj*GCqfGlZF#m|%)iVZTytSp4Dz^^_qWLlieR z_Y-AK@<@;Kv(vRT2P&$Bf>#0LDKsef?yto@Dwr%vQxm`ACwJJRy*1s?x#(fUpQ6wE zP!#J1=VCx{Ad%murW)VACEdcZlgegiCna^-RteB)Dk!vr8!C<1kyM4XAx`p~DbSb3@}U$4Hb0MO*2>jd@Mzdw>fhbjVVtoHkOuChheh~Kp~Mne zTU(=}RTUJ%su<-t)$$o%=jYqjRtazBI8gq}nf|$Qz^eXU5V>)Leeomw7Fi39=2)X8Fh@@!p5ARb{5(Qzj$&yXc7l!1 zc4_9@G|Wx-^_2IV44v1c_+F)D3T~=9B~{J28-olD@_ar1Ub(ebTx%yHWGYY4d_yi{ z?hciAv{$hwDz;-VQ#NiXMX>O$d0qV->qhA$foLFa&4fSGrE$@v&&f z)Gc80bP|zEUKYeMLn~TD&?EJ_Ryi|MI4N(6Z4?kcYg>8I;DiKm4cSQ^?53%7;XiIV zX`O(cln5Emm#mT0gK#!VCoR-J8qPk`FVqh?+3Bu&LGXbH$*bq&wDEg$s>@pBguS)C z-VbcQ*f}l|JX~XAV^!6QFM7z_)!>xTyT`NVuez+0Q&WpZ9U4prtSd|pl2||B=bxj( z!ov9JG;ul`lQoy}4dtqqcl_4J%MxN@$_@D!7Z(e(v!iBVx;!rnvO{j)y!oVW@tyv= zOZ0-Kts$(?bMTdvbe)zwS!3~VcNvhtJgvEF%i+@L@gJbY+0yYY(B40CIQ*XtE?3DdOSZrzp!BK2(eN|iy@JukYT+WE<1Y`d?-+j zfB*m-uCA`u)(eY$si{I1TX?+Z(r3mR<4vFxX=$I9cL8*inKzRc40?EaYO1O62ncAY zt6zPh3(5w>uL=Zg3q@-1^fQJts+SwK8^9tO&i9Pb~=cK%>fE&UT8I&!#Aqfcy zso131Njorzj`O9?XeuG|Cc{Ggud90_BO@^}F&!O>P+L5!l(_Tc4?JEecL>nX+WLA? zQIRLum0!P3PESQBE&-yfb;9ZvI$f(HKPjoG277z0t0n-7cr=*8liDFFf8Zb! z6X92>X=vP8fFxN2?QuV{`$BG#ngLmM|pWD3;lC-)qi_V0r+8A z$bQk-)eD4#2BoG(_wVPAuSY7*4~CxYK7W2CQgLW%>Npp6%EQ4iKUw1lJpx}6vq4qO z&CPjv+~VTm+}vF=Gpyf@wTa}Oco9OGO-Ic}9V`LqdOWliA&1;iR)3K(0Vekhj^?Aw$&ZhMgQC zv@zQnI`iHezz+e`wD(nWOfAP$@K5&niJgnfmTTy-2?SB}!mp58`b9~6_j|CvHhO;g zGgQ5ab7p4d20F9eXLAzZ&^7WqHa1+S=yt99-sO&ED@FE@xXb`fS3^4^)BCq0yAn*OE1w-R2cTLe9X%C9uixCToCS zL;!(z=KJ%zjQ85eXpunzi{ygS4vLLRwUH#AMbcxgEo@)_U18W1_-8BCB82fHH34*R zc(^%L=L+=tLKt-R_%0_iGqY6=B2V{lW#~E#24hRGt1v7DqYLreya`Yq5U+0GNC2%N zZF@bXn@ZWEM?ZU?0!r!a)mSIDu{xe;b*>ilGanin^7i(=ckdn`b>WKq{Ex<+-<$kt z&cg8Z`n=7d=Plj_;D@!tQ$`7|?-$`>phy0@OGXkLq}B@#31W_h}az>Osd^x3>gfnIDK^UutkGT(KK`1!jOR3vE|5QEoN#<;!-r+}V)N z>Bky`OX~_|68`0Y&8Ij{J}W6B0#(x2&R~qNGF^ln<1|9B83|0ex|S zik`myODxvN%&cSx1NM!EhDQ69w7r>wZ&6z)AfaZj)vrKMYm5cxVjnzs;2cpQi$ikh z0p(M~kury|$4L2ZHJzUwmlGVXTb%zrvXPOIn-+uen2jh<{mtnHF&-Wa7%7qn4mmj( zv^^jF*90~;HUMX&qw+gCI+UU*wSq9=?7z2WjvHrB1$lVX_~}~zd=D&ZJ-f|#gA&d& z|E{QL`0H0e(|SvpLO>mD(0d=W{J<-jK1*TXT6V$=7{nx4M8J>5n%(?Za&q#f=H@>? zXXTK{x1$bxe0&p5;zrB2Oi-L2EU{hT&4jhdGLJjwfir>pVerTEua-{C&bm%@s^<<( z&&=Fn>i5%15%EyR`2_?xAkuqUKHi*8A_7Zzu7|9bWeHt4II5jPQkEs)cTiXqJPQqD zU@&a-Dbe9M+3uu*;p?j|H0dxNx6nrhQU6?uQep5Mnj_5}hQ(Q?l4e-M!|3S0# zR%I0yhTEjG_V)HpPW^T5cswyNF-WAtr!lt)*|D~9ul{Bbn{b;WwuJFL75SwPYMKaR zTU$4GY?Rily^TmiM<4le*b}{$!1u7)pZV_Y*frV&2+}^Z*6uYG*CvX+!0@j!VDFCm z4QOt$`Vl5^$mR+2*m|J;~yY z%HveOy$g&^b2RzpM5c|9acc|QJ6^dkaf4b%%4LZVPv2+g%i}`WD`F)7M^O52YWqjy z@DIfKTS5H)FML!^#DBJ}LKlEl!xLNhI+KRCxo37+4`F^A*!%ez=IO@K2l@%N*;dKO z$T-{Wr@gfi&FBY?4o|XoNhgX($Uwot)X>M+`T5mXRe1_#5ZN`XZfsP?{*Wz2xuID; ztZ3qN3r*QYw?-IQGlNaBEZMScixnAkR`IFowcpI1x<5>>s$uSM-_XG9A)?tY|GNwN zccT5z1$G6vg~cqeDZ$`}Ow~B1CL|hSVE;fp?m12?n;HTj&L+ zBA@qYpeX}qZ!q0TqxV4+UjNq2pFs=4Bnba*A-}sL9^dQ$XanLtJ1zO{uU}3DJm9cD zn|9F-4)2CAk7<+>R1FQkfi~gw>(_IGlarHwn-~xn*8GnZbai!4PEJ5p8XmKSxrQ36 ztErJvQJo*Hmvv`ajg61{_PpQ*zEghQTvD30X_dW0@S!BnvXB1G|E1AGK$Gb)9V4g#dr)J^bq>;!2e1e>< zDE9K@%Rt3I=HlSs5R)#NrD$~ohz1DHN?SWYC6}@JCAvV!qJ^c~JyKBwf%vhw7>Tcs zkj(52j7?8x%0iEik6#Rpdi?n00Jyc7ZXu)^&EkM)cC9OTerz3t>}J>6?0iWde-@@lz%DmV^XM%BQ%nkPLbbB5G#l z38-hJk2k7BL_}_9ZSAcN15OH)+S}RjKRa9o-UXttnb`~|n}9(eSq7H+Gw=%w!W50b z>;QGC3@Xcr8EPFZWw?H9S_R_=hz^4Qg;m7O@?Q(PhuSjx;1(nFlmh+yK79Bf9kBPd zx_ab&Nn_*j3vSIclr1Q>{QV^}cV$FGDoRTFoy4P~qlYoozkmM*hWhp`Pochpc!r~c z1E>QDAkIWJc#?a=^wX#0iE6ZrjAWjmis9wsD|w*>Ns3ve_b)XyNf&7|LOGkc8i#97th&BwKj0(|HtZOTG$SJ;aA`h%{u6~H z2%>&Ml=8X!Qw4tZ{LI(Zb}2=`1T0rZdip_7ON|+E_bnScJ3AX2{d@NaAUXkKBIsMS zeG;fO?d|OY0{#lQgv&HADBx{BJOIcaf_bQOn()|N(rPfJ9M4u~5g~(wg@twQ-HWs` z)YbiZw7vDmOe5uOCv=0r6cfo%?OnlBDDF$3AmyueDKDCW6`k+?R!(@SKEAtE*39WAVF(;4#sVM}lA$&+@*e=Gu2`VPPSN?p@aHUg7L>ufb~oVAs+jYuE>( zX_&ll0M9C3AstoTb$LpC>}X)?&;1&EY8QElT@ z-o=X-=V7(ck7`%<1Ey|)K8~BQc$`UPWn+U2-?Z5-jN(mJ+%J*U>g7_ylU}`gHI`l| z{@Jr8&*k_Ta(!O!z5Cm*s?D#g--aiV!8@)MU$36iu8d+%yq;8|UQR#>l?S#kCxKX- zo}Lblx||&v0){|15naF>_Yw4JOmRMoy~%PX^Hk+S&UKq|L7}X#uWx0=G4jc} z!pqC6tLnwhb}VA{Du#Z+G9 zP*e$aXo{TZLKb>?ago^b_3-K(E2bcJM%yHBqjc?!^mPTeRMH%)<)0vlFl|st%~G-6 zuJ%~$1&93jQ3a>Nz{rSAOdOh>rGgC0Efs(wD=R;a$g&4)p{At;@N$1|55YhYOD8Z{ zZLbHS$ykXA$h3bprwq)@Hs|LPGc%jq@gMEe>w)?xX1~tO1?jiBsR@1$4#4u|%a`EY zfrgoiiVCdk_Pi3n>W`gRmNdH}Y zJf&*778jz;cjH@PO3Hm59m}bOs6pRynX^g9GOcodclVuvEGZLXV-SfetEzxJ0Zd>>-CIdDqE-q%3 z@@YC)hy~I+JXuE+ytcWSRjdv{HO2sU0V9GEmH2`JXr~nv2#OnBr|Ydmv2S!&PY!ou zpFZ7i@J!aY2P$tSrrt%5z`#IoE#HH@&UKcJjg2n0>k=Kmr7%Ohljs&It=!U$sKPKa zBO?$L=0kr7K+FRTI7pJ_f!qc5H)e`x1)$9vs2D;uA>w#E=8g8d9MY{!Mf z@Wu;Koh(HhAlZm^VTCShDFGoe(SBk!?fiyEC8+;Zmj4GW{<6jcQ>;!76(7$=hu^n2 zZI}W4AfJ`s_@#4b<;2EBU#zDU>%s*_19;>9lBiE=$M7&s^1br5+F%g~%9-?uo(i{O z$U;kG^bhYj%pBr$c#!dcqZ<>I^m&u}7SmPIny35W3{gOefw=s6II66q^H!gih4fiD tVYmB5Ig(7hoC3-J0k@CmR1kE2t}H&2j%Ueu2ma3vQon;%E>*M)|1YEgv+n=^ literal 6724 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 HXc7J&w!XfT diff --git a/widget/testdata/form/hint_valid.png b/widget/testdata/form/hint_valid.png index 5c1bff20b3f634a89e113b419bd4cf7fbafff9db..51bb93b912376389dd0474dc759cc4b17f3670f3 100644 GIT binary patch literal 7728 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 E0kl6Rn*aa+ literal 7639 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 diff --git a/widget/testdata/form/validation_entry_first_type_initial.png b/widget/testdata/form/validation_entry_first_type_initial.png index 0e59c487f82de71c2479aa97a0afba1ff763cab0..cd6c83a86e8a28ffa2c0f8b786ddafa91da81d70 100644 GIT binary patch literal 5367 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 literal 4889 zcmbuDc{J4V`o}F3%Ge^=vSf`ZVQ5InAWhk6>?4IRvc*_JVIpK-$C|NB*2y4b3r*5g zh>R`UWSQ*QLw?`x?|1LH=bqnxcg~rab3QYl`8?;D=Xt;0&nL#jNT1_`&7)xX{>F}bN;epbGie^CA$zApmU$#+7};*gu^#ud=)jdO04bWnd?_%%E< zKs;axhG|*+zO|y@jIs_>%hY*~_<8VH4DzT2-TUWoo3F^>Ndgpu+q+Mdh;eP?n8|4_7zhivd2iJm9tZR(K zN+D20s+ROSXC@Zjq~qc&A3)s9PE5}jl^Nd&2;p*#=3{teFWA3bocxBXR(}OS4Ga8x#Bg^^6As3jEoHXW{j$;>fz>qaeaNg)jM+BY2&Pm5-KXS zMMXt*b(?*KI>?HxdMb(?GZ!AF1dT)*5jKXZY?G6d(bQ@^w%OU)@67>wh1TY z9#RXiJU2IoNR=_=OHWPZ6%%u~eS2$vwOtZBIy$=Yy_q^OaaBs4HP|u9N#pUKgDTqw zZn%&C&@4oET&{qw1cKJqp!v~W?_(Pq8*X@G zw(yl;D13p~{^$4hn3psncz?MeT7&TR=%R=--feUlQ*b$eGxPfK


&t999=rKLY- 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 diff --git a/widget/testdata/form/validation_entry_first_type_invalid.png b/widget/testdata/form/validation_entry_first_type_invalid.png index 14ea1ad202774bb9c7b3efc5d834bc927de6d4d9..6bbbf07d2ab8d9af3ceeed68e1d35c0401476f61 100644 GIT binary patch literal 6993 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

J(0mC)p{ov+?P-00` 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 diff --git a/widget/testdata/form/validation_initial.png b/widget/testdata/form/validation_initial.png index a3257067917a07a7b49a3de824a3173282c7ff81..e8fe0ec588dad62a13ac5ea086ea117b9f311c07 100644 GIT binary patch literal 9437 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 diff --git a/widget/testdata/form/validation_invalid.png b/widget/testdata/form/validation_invalid.png index ff8a834d4524d3fcd8fc8a4d0a9fda93a0655fb2..478177d2438c9c5536b75121f6424671955d8886 100644 GIT binary patch literal 10111 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 ROTZ5hX$b}KGEu|e{{mQs1X%z8 diff --git a/widget/testdata/form/validation_valid.png b/widget/testdata/form/validation_valid.png index 23eff09d58160cf19770150fd7610ce120f70131..8cbf5b95e06b7548143e46db950a70f62747460b 100644 GIT binary patch literal 8713 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 literal 8589 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 diff --git a/widget/testdata/hyperlink/initial.png b/widget/testdata/hyperlink/initial.png index 96c32430ea9fef496d48c4da1c45b16bef973207..173001d4ed19e0b1021ef1166bccae13027b8c47 100644 GIT binary patch delta 692 zcmV;l0!#gn1#W(zF7;)8&f;_CuOpFW+40SOYHy?jldGHAX1H+Hs zf4_YHOQiK&?9B5^jKW(_<5z|=4BmhF4PpHH`~U0Dzi&SMf`2;s|9=MqF;fk}-@pIu zIsfYN{Z9~a3oRilO(Awx=I8Ie@4xWo!`ELao(epiED3J%3=9k_4?Ow)3%k=vP6yfk z$}!F|S08+Q_V#;gf|j+m5Ca2)tC3h?pz_^kU(et9z|X}hEyBUi&BnmM@bBOMkKcZO z{Pz3b|NkV10e@B?CCuSxDHY#+=J~rHAkEB7(N3~Quf9{0<+<|U)5hb^85kILoOuaR zeEiybD=p#mN1ov~lQb9TDDwUM{ny1v48oNY<5UpmW?*30b>?MPicV*$&gNs!k6(ZH z_a9ClV*=7*frFLl_uqei|Nn=e`!ByO+53orf#LSkuYd8~XD{CUkm;*9ztmVsf{S=F zNehFQ?|-qgGOa!I^ylw?Xi}fP{aLo}$;tyyt0L7B-Q{Z+UI!;z!e){d2Iua)fB)ro zj-N6oJ2L|V0}m&&x(p8k1B0p*H!mm1Gyneo`}XtS@4q0MzkL7A&BY=nz>eQc(!${P zpZ`_!u78$)L_t(|oMQR^|3AZk0;Ykre$)k{E*N#es0&72FvwiMf=j}s z@#nMm|Ih^eOj$ajS&29O=Cl9mQjGZ3Fyg8kUw>lw3wA*M{Ga;r%t=llw{o)m=jS3| zA{>1A!QkEY^I#J@eq}hrK$H*4;9zCs;b4>yfV-Gs+xdTouYdn#V`20&VKz~QI%xlu z|NE}|`SF`UR+!Pth*^k-v46{-kKg}K+V+=$fg#zMnHz^oNKOZ>>wZt$`Nv3+Sx%TC zW7f|-mp}ov@$|ojRlhW(nJiS9-hcW3@b&-qU%{p`G755o5EJfz!x;ux!Nb=K%Z~ir zS;HYK3^M=EKYzvd)k9zap$z9CevkNC{ceV&TVc1~wK3W+p}mQk7)N z@&NfkONL=*4ZE2tbLWQNo~^%bJSCy!M_L$22{L{A^?yI!ftiyHT}ptPA>EZZ*_pX? z(XUC{{!B{+Wm;kyp`?X@r8=VsFJtT4-`{?MxSzf=Tz&+yC(k*_qhD z{^H~O|M>^Qv-bqdBrOcsSQuuev)3&DX;%4zla=w;-~Xx3%(`-{r|$fZn(#x2m*Lw_ z26<7Y?r>O85E&^k*=R6(wf*E~V^~?lE+dTHOq?YWe(>o#!}nhdLfj0jFfaW6!|?VC z0~h;$K2DUJ_x=k5Gt+-Q+~pXVE}$Y9_?l_d1*0w)b-}0$MqPjafB*mh|Nk#(z%d4P RT_^wm002ovPDHLkV1j6OO^^Tp diff --git a/widget/testdata/label/label_importance_danger.png b/widget/testdata/label/label_importance_danger.png index f2530a9e1f7b767acfec900b2d0aa6ff5010ddf0..16b708b5db5cb14fee4891e70b82d4add2abb33e 100644 GIT binary patch delta 1157 zcmV;01bX|g3YrO!B!6K^L_t(|oa~ujh?LbE$G^`x^S-n0`iK4bGb~Zi646r1BofRN zg-Sw@z!Eajo1}{fFQSY7fsjSfO;BB0QV`)qMQKY#gixSm8Ci<0?q0ZVw!$_$JMZ7~ zjd^GPxt`g5XOwM&^Vx;nVb470IiK^K=e)aH*t~f&99N=f#fmV#j&0 z=a0LH=~Eo6eZPg_#zx*d zmLj>6!3(CmXE@r_kk`u^CJSKl$8D!sk0BQ;kS=A?RC?Hj${NHS;{Sp|a}k|CsiOo<)4D{E-1$O?XzROVD>RIgY{ui008;5cMhivJ9Pr1u*w9 zY$wh_9aeq>`&?JkK;PYp=r*LkL;JvfmKSAf6Y_Zuu75-FGYS>pH4H3fIzf=V47M{q z2i--zlhG5X)En6%Xa@}tK$S#YhU`M+rs3c>Fx`z{km~<5k283dl|jg9(d!sL!=ac< zn7nQVV#rUT*CKwdkq*^By>wB%sagSa05>yT!=zjEY9vcxc4KCkZTmc$Z3y2$t2M$> zr0Wpvk$+jeq98a1?=4e0jI_&EVkO8YQryDmgy^rOS|+EcHz7WV>fn13cS4^Ry_`vl z;5`&iX7$?%y`SYG8H(&g*dg9QX#sEyg##!pV|seRa&E@UuQEEg52_W+&VNz{wlU0J zRd;wMSg%@_G3kNo9WL?{Jaoq^7_sGVj}{l0q~UIo~} zP)J4YKv;(SknPPqj2<&}d+-Qfz*~)UE#j~0RAsGhB>U1K{zDQh8NMHuGs$0@dFy5T z)=2h|HJW{BeUib$62_*Q*4voT4UKWPZ-4eG5_t)2PqXqML#g%`y-!-BY~*^z{WAF` z^@#4IUdZ%EHF@TT;J1OVaKKPJuor4C+QuhVZ@t&+|FE-ZG|(?%ay%oZY$>ghj(F~p!^=`hCTYJ2k0~12ZIlPZ>-JW;aUCNI0V#j&0^df39kx}B!BivL_t(|oa~u@OjT7Jz|Xlq-g`VWHAUiQ8jvEIWr5^a<&crV z5~h_V(`;kbA2Iu}uqMl9V`zT_%m^hZ96Bp%rAyfxL7OmrCGy4_h9THXNI~EM!F%uC zbMHOvaUZ|N0q%P)itT*HALpF=ec$i*e7N@>#^W%?fHDc@zkhDve+uVU9@ga3A{qT)! zI`30^063lKM3L~`J~2Pf#|%E9)r)kwPPt{%o)`CYqv}d^EL$ydbCXZ)0r7aDWUl2> z(ztc8zGd(YZhtn5`GC@B(WSk>COk9Cb-nNcA(Tx&%9eWQXXKJL!<8|f3kb>Qzn8CB z;rs<$N*Y`qF+mO;k@~5%p<7U zBz(AEjek*EnjNpd0`+=!U941FBOG{J`(^>wh9h&Qkn_&y)S0;xojHjymM&d%Y}tez z4s~6~%@J~QFvju~^U$*!)J4~!_l1HZ7-OZmX(%yH?r2xnm0PyK#5kq3WxBc<>8SFY zC(oOE#ge1y7@aD0?#*x)YHS!xjFans@#M5x27eRd)P7w1v&7+FkmTg47ql$k(h)*n>=Ph$l&CI1>~iSuOlS zky;wyQq#p_1^k}Z0Lw~0nYh&SvEEj%^)#>~0I2txpPy`PfJT3@ti)4JXOL}e+^W@@ zHh-%n$OF%hpLxDu5nO=RL6%j2n6-~{&u^VFgD3+1#3$U(07XG#eKuhuK$22##;q+% zyNyds9=oQ~P3{f51fbWC_Qq}B#YR4?vDUqwM=&r50>Edyswp@qSn24%k_5Tox(I>W z9ZXP&)?zvxo17|DT>y&%*bPsC`xZkY!YM92otXC*s|YSd9sl9G$TopOPk->*U%RJ~>rg zffJ82W_YSDvd^WVugdU^>tOgC#7&Jr^S!C{eqr3T#&rNkrc0LUKl%g}97d;30DqPT z5c65t-0}zr$KuDvdc7g9P&j-LeRl@B-!EZ?+5MO1lCzIsLX@@{U&?ti=7obiIYI+dnICM+CAu9$^# zbH>XoL;o*DhI%1Gy^x_^$WSk2s24KS3mNK#4D~{WdLcu-kfC14{1X5G{}un8BX+w~ SW=Ajp0000krTLI!B@PGfiff)+&0tb14gS@~& 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 diff --git a/widget/testdata/label/label_importance_low.png b/widget/testdata/label/label_importance_low.png index 09ceafec4c6e793e5209ec889a5c7725bc0d470e..2016916f60afbf9e62cf286b4886be58556fa9a8 100644 GIT binary patch delta 1154 zcmV-|1bzFa2bKwtBYy;4Nkl%7sF9+m zVzHRbW_{lu4u6NXZAa+@05G4=$Kx?YQP?nwqVoAX$8nM*34-7_4#P10et#dJs_JI5 zxw^WNBxyFAy?psn5Cq${`~5zI5XB@CiBhS=aol>nHVh*Of{0IgkGfkfmqk%ruh+3y ztkr6vZ54)Lv)Pnod9heP2tR!IaQl|2*Xxx^#j-5ZG=Hnr>YF!j{uaqF499T*00`l3 zw{u-r*Y$Wjj_wMApzFHt`#jHUn$~DEJkMLLR)s>L(P*HUbUNK?wIGCx#Uh{2@7tqr zkM&|%*6-iH0RV*eFekAK7A(6X$X!Jg+01_M=9=kxh!Gy(uD7K>uBczSvY04Nj+rfFK1C5j@;vYk!` z6(G|zTdfvN(?Jkunl>7Zy4@}SU^<2u=R^`FX@(K@j$r6h+13@%{3-lQ0Y~E-n;B zaerNRHk)~#cjs`XX$}U1i2Wb(Z{K$(lL^oBl}ZI2D;&q&@|tsbc?luZG!0#9ng$`9 z&*uODS(dBS>Yc+Gh9OB(KA%Sw=jKX5X`r8mVZ3_vYJU!7v)Slt^T_qG&&GA#A3uK7 zYPCwGf|l#a$;r*58YLP8LA%|q*XydPqJR3*Znx3)lw}z^|6v#&9^~8YcC*=}QYmEf zc6z-Y%d+p^zYl_dVHn48zJLE7@d2ra`W}{LS&E`O&$~8(SQv&u!TXj^pFaKk`7=sU zeE061X_~0|MuDOzmSuw=@O?kxuRP@Y?wz~+kZUQjEW28*qDaYPGS8kp`}5~d^n05S(c=+M;_m>@^E#c*?J<%h6^lht6uaGS^iq8^Pr^$SOw$~X$7g3}rfELHaQ_=G zuIo-FlSdnl{9g(W@q&kV!9%>@AztthFL;O-Jj4qg;sp=!f`@p)L%iVmCjbEd|3Iz+ Urm>OcL;wH)07*qoM6N<$f=G};F8}}l delta 913 zcmV;C18)4538n{-BYy*JNkle>S)2oGsQu3zRq4 z^M)A5yy)Gt=eY^LKTKr^haab>Oo?-DlK2Gvw*&Z(lDvdTUcw|VVUm|H$xE2zB~0=X zCV2^yyo5aOPJ&(Osp3nMBn%E;~Hb?x`ylH@qZ|#yeqtkb502H{{HSq z`x#=rD5Z=s@#7j}j>jWh_b2WOZ&KH_l#+8kolfr?;XcSuPId=c>z|i$vll6)QVL^S zRTZVww;zwkzV9){jIs0fAYIoD!!VglrYEjXXRU=)&GXz^%Q^RdZQC}_b3%xevMkHC zZH+OMQpOm@|9`&^thH_1j^juO;hZCcB3F7t-EG@eDMcwA$8odSSZkqux7$f6i=x07 zZ@1g)x7&Wd7eY`png{ppVx2?d=UAl;^opYPZ|PFZPCfp_DEb3qNJob$_$jOexj({qyrPv_q83K{w-+FU7-K?+qA04WnoK6J?D>2SsRYR~41=|Hxm*@S0YPpy z8|NHCsA(F`IrOipYQ0`-t$&-&H+#wR++Sx|1{cFHWLf67-8tv;=rhAGkQ06oN@?Hs zK`)=-oPRe>Gn>s2LS5H^EC8fHa-C0yG4`=xjN`rBa35XVoRH)`)qywp)f)K|#@ z`3SFNSso4t9}jFvhICsTJF~%sR&YwgvWLb8Tl<&-!e;TC} zoT}&Z`F*AICjJ^P)>=6J#6N5Qgulki50k!^3X{BqNnXMvFJY3GFv&}pG nle~mUUcw|VVg45Y0RR7n7Q##3&@J2m015yANkvXXu0mjfHLKEv diff --git a/widget/testdata/label/label_importance_medium.png b/widget/testdata/label/label_importance_medium.png index 9e0a62ef516797365fc50de2e94d0167cfba2703..6c1417c880ccd8d37b1bcab8cff394eeceacc01c 100644 GIT binary patch delta 1316 zcmV+<1>5?(3eO6VB!3o3L_t(|oa~ufh*Db^fY;U;$B8aZlMU67!&Fx03% z%iLqroD;0?X}kUB|Nr%|Zj3!jr4k^f!TPTo_@9Ejz(HQ%Ab&4#kQX?}3moJH4)OvA zd4Yqxz(HQ%ATMx`7dXfZ9OMNKdvtV^N!iS0E4^Jb3W=^XCA7UAuOz zT)8q9i*?Z-m&?`Zbh~%&7K_C%UcBfcLw7KpFF1}54-YfXJ2*HvIXOu`i^bw~>(+JE z9yoO9kW?xq2!G=B>(||7=#HMbEY=0%1`NZLN~J_1X*QdFzyHaTC(ULP8rj?1E0f6v2M2K+ z=kxigRBFM31^4dVYXzv)>To!m$z*UG_xXG~ckUb-8h`ro<%`{JFBXe*%<%B=jvYIA zJYFOcxqttDtyW_=(i!Z#YPEWNeEh?Q4;&81VzCGW0(zY1&Yhc>mH9d@h$W8jY>BJTx?9G#X2# z5}(gE7=H|>PoFLpi@{)UVq)UdsZ(^!nl)>#T)9%MRs(^6OeQ;f_AK+k&S1X8x!Mq@Ucp&8b$T`QN%^?E(MfBSqs ztJUgsI^*&9^x#6FV7J>==TEy0}B@}Y?nbK5+#$#)}cl}kByB%y-dgDaveT=*lM*>6g4?H z>3?#$T3@|?|Gw22J=aK*qzP@_B-uRa{ zZ{9ea&UP6%98R@bo%)6(Ne+j@uz{yfpZ50lZrZeIbaZsZiWQF@J!;n*4VTNU)oQKY zZr{EgjYb*P`qlF&lgR)8Zr;4fBsiT;FMnUYoXuu88V!2GUbbu*^E*+!UiWxB3WXw< z%Xz)tLZQ&Hw{SS@a5xy|pUSV^cOO4~ykyA|tybI9^S9!~ix-cKjI;~(`Fxd1MW@qY z7{+3;^m=`%RPy`%006mMZZH@+mLmuP$8niV=J9ywH|>ry0D#-=-m_=V>eZ|1*?%n( ziI~q#rt@WbdHPK@n>~5*6xG+)mrkdT967>p zyx4604!da4A~u_y&*v$M>KIJ#&3{uD!ks&J&YU?D3CXq;P-MVG7*?xDqKgJ86&)=|NLo%6Ue%Ag9e~gzo2K`?O4)OvAd6BRi8u=># a0RR6ch!{7?z#dEh00003O#)I zP^{?%Z^dk|c?usMF~Pg6Qw>HyVw8zrVGX z-@kwF_xpQ#dIUiT27||sAMfq$9UUEIS@y(<6KYJURNA+1ACBYW^4PIs+6Oy> z`C>AecJAB>0B|^e9Hmkzl}asGuz=&ZQmN$g`3Qml00@E*i9~ko+6B!}EEZXoJ$dpZ zNs<5ni^Z~g_im@t37ukneSI4@ZoGBt)`}G?>~=cQ9vT|T z<#J!Yes#Ou>IOv9wAbsEB#9u1ix)3446|+9HUNOtYTdDaV@IJ-SiE@gFZMDvHr8qz zjYdh5)b-!p-5rTU)bk%deyr7M(`6_W3KT`DQUCyhgM%bV@;v|ZrPpHp`t^Z8VC&Yc zI-M?&NH`ph)}^IOm$nK60MzSsf*^9aTu)EW<;$1VOE`{~%VmvTX0VR*`aeljKd{KM ztk>&xf3R$S*)pfoIb8->mjANC4F-cO%Nh%?*=&lUJb3Wn*|TSF-n?0}W=-o-S6A1M zwbko&9LHO=ZQi_j(V|6K2dgn|ItB&?FbvzWWs8PUf6h-abyVqba003B)ojZ4K+kPpEqG|f&%a#KutuX% zsZ?sUn)X|o&E_wA-|g@3?>JZ##gUPbB}xQ$4J0OUV#m!-C$^_xR$4e3Hz3wY_erI?m&eaN z`Sk9&w4v_YxdSjCK>phWTu`tVG}sFo>;(<>f(Cm*gT0`^UVqSFFKDnAG}sFo>;(<> zf(Cm*gT0{f>!q+!Xe>1R=WWlnv)^RB>+)*3x>%j6JYYk+uu<6C-aGjEV7d&`;n$0n z(7Jrre_o5RR9W?|jfl|_TT_(>@|$@rsYyjitclZQm=5YoPBsO4OqcWWd}aO%&wCy( z1gI`no3SReVSl2O2vL^xM32(B^l`vp=1|ZDw##Y>En11bTz%Q&dNbyXoR?B3q(%zt*quhVt+xA$Mmuf>`ONASV- z501h|XC%pfn^i6=LQCKczHqhh?E15hMcR~YF&5zx)QF-7bg&o9ZRR?B$9uNN^>Sb3 zs3Fy7`}vLh#m8FQwQY?yQA_RrhUh5&#*+kf%D7aI>YkQvN5QS?+r{gaaLTas=AY zfq#zA0_I=MyQJG#XdH!(x_mc&7=KrrbGkP7O>NYv+Lr!W5_G}mT%UR#F2E0zpX+m2i?&?Sr3WA5pVE8?2 zKZXB{7pBL=%keKZ9sa)*8terP_JRg`L4&=Z!Cuf{FKDnAG}sFo>;(<>f(Cm*^LGFM a0RR62Kj4tgTO-r}0000%>&kuotr&cRv>31CsU0t*>UMQ zfoL70KxbVLDt$D=70qh+Sf#Vd_R1{u3W+7H&$hxMUiPsvqDfDC?f5A|VY23RMCWKy)*SObT|N=<=N&gwj2o(( zw(tIiy4e^6Q~rD|#sq{mjZP2s@v}%w&BRbL$87OOMXEKk7mrb04mcj#zN5VGdhbyy z999Nt`!vDYlZs|;dBLUf7u3rcbEK&&@KX`@Tx0J!%>cvr`~=DLOyqL)170@1GPXf+ zS}#V701(A~Jp}a!%fvH7f6T(`OJ3{p#n`}Sk zoE;zLosZ*Eu|dM}%T$`GDFix0Da=rarZnq1Z^8p&_Js^+Fch+04|A5gWur+W!6=we z`l!DguyW2+YP zX1EFB!U2P;rZv;XFYGbaFw=`o`oKC8isE-xcVCW!}lDg6RR(QOgFM# zyg+XjMS$IEJ+0KX#m~r6M|a-^gy*T){zT)?^^q-xBz@;;;D+%iWV0jXfn>)J)_sxI zM6HJ($`h4;u~Oy;ODI?F6*6%M$KpTtH=T^!jk1+tiX)& zszbXbslb4Z$0T<|O>lr2B|RR)>r~+K*-Y$O0^3*HguYmkt8MWphbyt+fZJ2KW>F_4zt{1CjgJ;=`C4j{}hLZ#9?*#SdF#0X#mt@i36?|Ds~tiGPj zmK{qe<$|y=#$tS+xvE8rlKIP7$dj9JS496pAQ0A1L8{a$Vs`Y9>YrN+FPrT@Gl6fI|tuyW6D7a3Px2mLpjuS0PO003-n XGtCp)M#$H?R(~kS3moJH4)OvAd4Yqx zz(HQ%ATMx`7dXfZ9OMNK@&X5WfrGrjL0;hCMx&8WTyyidK)`xDQl5DYhEPk(*ozlA z0Dv7kTsmE3YD%6#eIik+smb2ZFjZ1AJ2;q~L59rW+b?GGj8+@rpI51j*Va*51M2IYcDsCfT4FZO3=C+tZ-4(oqlvoRtGc@l;V{X?Xtj~L zI+sF`u-oMi9vBh{zVl-l>+Y^yPLnBMvnfcDX>WgNFoe0!dGh2?b+u=BSQU-pXU{&* z&!1l;Nn6`!W21d?Qtouhnw!TD9{ljVNU=DjP{dgli$;lHP#6e^T3c;eZJ4{8ogF=J zz!r%RYJYXCrDg2cvDe`+VY4Z#tEr<$hq;)7f?!9-vv?eT^F~!wz-*dD`V#RaxmX8iR)qTWA^w0BAI^hK8w&7yl2l`q7+Tz&CL^5tM0~)qQA$|T)zCYxOmQHQ~YEv@7^iX z@BMzUM3Mpkl$8adQKF$?lDn={(lS}%dl^bfW+_U_NdW-3-BOQ7QdSm#dij=z5B06B zwtt&93mFEht)+T;^yypg-zz^CCISFRBnw_lra&x4?A<%T-AW{Iy*|X#%QEKCH3?eL>dK#-_Kht$oYkr`n`f%3ypJDixqmBM zgQUSQ?sehYqer^kyC(|@=DGc$q-2&P`S#|I^b5w#=Z=obLxMX)VqZ>#&d#Uj&;Rz}gL28A zJ$34p%O$&dbsf*baGX&n;xvt?4>f%FY3JSfd11!Et5?Uz#uR*{6cz?6D*RWjl=2@d zl@j>FL00-ILHee0RR6`_yi<%F}$Jx0000w|SWw=3$%CdFo|5D&=7q*>xTA6((B~$*v#Bqf5E-(^LqdMS>DUiEIk6K(*k@>gP^!Mh7@;*0>Fu0>iwm1%=@LJmMMAQDE1 z26X!|2Bbh}7))zovYphr5te)0jLG5AL)G^x1QnEICEKWfLbn==&Er6uhLzqnyL{-7X42t(kt_>jJ9ySYg-4h(gUBq_ZnH+^O>S0hWkpIn`YIe z?Wwq1TFK;ed*h`udZG+4GylN*_~$3vIw9ZvzX~L)o5!P>1$#aRo)o&eVd=VG!=nZtnmN-bQ0Zmv zK^R^9ls55FLbhv!*8`iLNB}pQ1S=BzYvQK8rB+RLe)0wW42T7eV)4#MX{SutwH*CX ztnGvA?srxyCxt6D(lQr+66iX5U)7VZ!}ZOviYxmMS^qvHgl1?AyvKI(yAP4`gLfa! zJBx~rzs1(^?)IiOKt5D7N7#%1D#V_ZpNxsFT+Vfyr?m z-zKJIA)p?2usC@Vv6FN3V_r)x&2@afHyS}Su|PmrS(AiXa2A{j=0vVagOCG_v475L zuGgJNSkG9p=n0Dy+aX%T1XoE`hdEUL%nq6kq^&u1_nr{vGqP9nzG4jCVNM7ZQzQn9 z=v#^^z9X+M?gaL8$PPQAx?lq` zyMT9}Z0pgH$Zw05*17~T8XNM$w;0BlpWnJ z2!f9%@v-lMw-M7MO;p+auXk;yDXl0U56Y$}B>yH)AOjz2s7$3gc*;OMUb&cDrhED) zo6Gk0wXBr*b6=|8hD7h^4>)SLz_u4hXEJlzL-Fmh!&B}s{p`8#lf;EWTBiUi9=b5| zL$UAABPv$?zR}PKxeoQb0g!b~x#Zf?dqaM#UD4NkI$V;-aM{ov>bQe1=UO96YB~aa z9Z}!_e8^UQW&b~GRH0HEjmeW3-@ba$l}B`OZiSO^%EjkZeK~_~$A6Xj(K)_5QMZdH h^8VYaC@=`LyX$FCs8ju9ifIP=UVv|qPb)S$=U?<=PXYh{ diff --git a/widget/testdata/table/col_size.png b/widget/testdata/table/col_size.png index 1bad739bb373df39d6d274116235ac1a378d0ed7..f91036a820fe950fc770db0b8e7bded7e51b2013 100644 GIT binary patch literal 2659 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 diff --git a/widget/testdata/table/filled.png b/widget/testdata/table/filled.png index 7f1f39eca59e13eed9acd3bca5c9a4de88579c24..44b916d2037735d708155b086e3e36b1d2a9373a 100644 GIT binary patch literal 601 zcmeAS@N?(olHy`uVBq!ia0vp^TR@nD2}o{QKQWbofl0yB#WAE}&YQc2S%)1294=b? z$k6(}Bl=Z=CeOh`KNqN75_=!&X{u*;SWNEEoo#Qq|9z_c&YlqaNTIX&OU?iE``_!O zK3CoBF?=>>*&4H@H)K=_CmeAUV)rD-u&QbQGD})4_}ZLLC!Zy ze}8{`s`l%zuGPU|vxD^ZMjNI+)ttY_(gS3t3g09PLX0PQN2jC|Pq?$T-~o^od}r;9 zNkdCFaREq7Ad{%(W#RSwX`Ae3LxS0!k%8g=eRa|MU-FUE&~#gLa&JdS%~tD+{g^FO%^BDmGr{|9t0$#mbs1@4OtO zajtUC`RI?~dE2)A{(F4$$(nPXx2-I)QZC;dV~h{YoD;ON=E^(Yli>j>6mqv>C3!hW z?pC;Pw_@cMcPmzsZ<9~~Ba@#22Nbzmv68$TBzG%ZxLdJui@Oyo$v2bn0V)*StyoE3 z4wAbSF5InHxy9XzmE@a~5CJ8Vp8*90?pCZMFO%^BK$GABJ153df3uYJc{xbpAc=$Y c6954J|ErfeZhq?ASpWb407*qoM6N<$f*+!U;{X5v diff --git a/widget/testdata/table/row_size.png b/widget/testdata/table/row_size.png index 73ccb197806be573ce1caa0f60c88ed50f589a45..4293c13ee4ef1bf38f640f676ff5cbc4f89e706d 100644 GIT binary patch literal 3512 zcma)5(51Ho0wTSu0nyMwKnT4B z>4*@K03r}BXpj;F6qNGjuJ_jaaM%0rX04esd(JsC=gj%-|K0~@VP?R=F31i7fjEo| zZ(0In^xr4zDd1}2@Z%})Jj&=M+$!Yh`ZF(+3)5W#ZV&JekbFq^-K&*4F&CRHa%`AV zI#N88qTgK0_{eN|MZ)wRO0fDBhnLsye(ITWihhY{iK%y^V&k1xdfeIPz0O!FitU4x zZ}9a5^6&@o1?4`Q$uHc*?TF?C24ft@b;iG(&e!yR@FVP9@am|qNTf`}_FFzhCJk1~ zspE}HjF;lT(T}b6i;2WL(ClGX7(I945^MS|D+h7Bx^f(eUA6_=cZOfb8?aj=-P7u;a*z^2EcS`ozTnIdWrxhbq}|C#S(i`V z>C;-A@6Z`TSNwZGk|Vu2bbc=Xt+QO#ZK7Of@h^kr_!TPQ%sR{hAOTm9YZ^n^KMjbl zk2@N@y)u&P@9*DGUteYOZ75TUg_-$zViT9MZC7W*tCg;u@5eIgVV_W5zi6dl!JFN@ zO1SP|9XK5B<+VXJ*Pfr55fB#c@LA}LkB^snah2)N9KD_6*v4D>ayKBL?4CK9$N=k})(E9%GtuA9@V|-$hg$@@Z(dWd+asB{{J;Fx>5o>+M zJZgJBUc+@W`w9i`tePG#zcS9Xw6yH4f(E=^-}p9tVD9MUl}w&2V*d^)OHh#c>Wk0I zOB-@s%DUj98WWOBzM{Mh7vK^V9ruxUYTxgPWBI$rrO_@j?6wPa@aVV2N(grrL*<=X zr#J5Bu*mZAa`|?8@4?O&lDw?zU$uAtSP<7zyn1!oxq0_n?Q0%Wu`)PNIllF&<5HC6rD zJ9;I%B;oj2d~a_8js8(r$F_~*46GsnY1!aPELx6iDlioAI}o03+35Lv2<_%+xLni z`TI9}mV7B2K}jz@iNrsGOs!Yj6CcpdOQOGr7T|3ovN zcCly*<$*#;G@w+|3^b^vJ~~!bSv}5Nx&nllkiHTKD~yZ~Xa3dLgDAK9b+|L`cK?35 z#LV2>-23;7el6WgG#ZUL?lKe#c-%9MM;R}qg$6j7Nt3UP9p$EH8r*6DFgvN)Sy>M4 zA-6}Vx()iW%F0beMcwY#f&v41czM0&TX|mA+BH_x)I7OAv$?r>`V4P$Pf_qf1hJ}W zeYVj9l1WRJ?;IQ-$0G#}Eo^P2{kCJaK#?i@SR?>7B4W?_;X~SU%`o5buUh*a%7xm8 zbltS5@bK`R)iLMkIiIcw`eM($fhXH;WLkipp58?j?`wr){MezD@4%6aEbM|rZo@f# zgjS!kZ}Ob^pmF8O6<|_8Z=k(jixBB`b8|C=LTPGJMmCL(nk10wf;Q~v=%EZr91i!# zm2OWyQ3~kEa(K--Zsii-6+>fVnt^K{I>LVHFerfkl)iAOi|#351Ot;eO%^&Me%E## z7a#>5B!@gRW5Fh3aPWDCcMI zisCVx&-}~h9`irXjT7T4~F8t)^CqDAmmAs%jKtedR_Cf0vm6eq>HCmy&(xzmg0k7FN z51pNh2!z$6p9|V(YCLHvZDb{ZQ?xVi+edJ+V%Xc|UizMvE}y8XZxP_a#l<}*f{Gau z;$mXbNmN3gg*7xgJw4so?mWKCvfMC3NLY9e#Vwi~y%YOmYa!~_?n7H@$Li@A4lFVw zGxI>>vc34~?xKG#Deew6FX2*G1UB)m2H=jPLJ097VCmX|w|Z@sQm=RFua9e=#9zG( zYG{1$1w05E{I}+tI5R?_(C1;BEdy$_UwhvU%y=%}dR0##Fdr_QxRzB^oNw9hW|p;Y zT1S`c-gk5Ry)KbHWvoCcwBz%V?^E^Qnzpu!62q?b zv9Ym_AA<`BQ71>iOU5b-2^+xe$<584WiF2L~e~qww(d33m-NwQql4 z6^lGLI8ZJeqXpz-W#yR=L?ic+tC)DnWBL+_q46}2Qr(+3yZLUg!>(_s~MM)zyxTC~G&j(s}Qb{pHjH$L;Oy-#@of z6BFHie9XQJCMx)Yy1r zd|X8^Wh7VL+}Kz~Muu_Ta(;du&`b>g*souuqnypm%=Gp3A3ZuqlX9A*(|rR2l_=Iu zPLV6a*#NhKq}Qvft0e}hHMVusUd$POEN$=C@bGXk7seL&%|+m^Yim?u0v6jHCoL|% zygF7GUb;9{d1u}`I5afW!$SstT}f%m{n~d_{FkBOVOYM2Py06W{#QUq8gWQl0|SFH z6ylH?2a6`q%5i=z4yv#L^ryZ)CjMJItLJ{KuoHRMF(WHf^_h!;g8SE%i#d#?{I0Zt&f?-?y0`)1sxu_f;BXhA zTUc1ABsd1-24F~T$KFT#h=_>8eW5%*^2d(^n@YGyzDX03#C%LAmzwkO@qOD1O}j2B zDG7xpX)An6GzhogZU`q>T-cj15cQgCs;;QG1L9c*#wm+_P9y6o^VM(hhV-8ocO&#vJ_YU&=4f^;oBsh#S;AzTvF2amNZ5F zZoY#d1vNGH+ZrSFk6C`|+UD&2^lx%jLF|E&-@=rY`#Jym^TO%=y=P`p(u^bpAe4-b zj<)+Q-H3|PHYEcxa7kP5wsN7VDqA!%uekVfr0MwHx9PUlR)TQLqzAUgYBA{x2mQNF z-T;xo>Ha07jGuR_Z7!zh7Z9W%5FG&^;M>@I%tb`bEG(oVDGlRVXKLzMI7KWjDEWNW z;PMbsP*qjc()vuHsBTm`C6botQ6kM$ctq^%7fm`Wnyv;C64w|-H4A?;pZQ*L!0_p+gZ>$XgccnFR?UJ4?GaIznz#(3i1N?)~pN1`c>f0Y8IB38D!ey$B!jg zZ-}J>W%T~Egb@S+iCq*&qtO7q8$td;!6(N@m@|B_uc=IMS%+qeSC%nS<_LtSDVZH} zqjD-kVyIsB$udbK+zGDs?A?hZVfvf8n%bdjSyhz~Kfj@wSlH zg$8ZRt^~E+sd321<9cXPZ@C_AFJV?=~z;(IF~fqD8AT(SPXSQqd@U>q0>#;!UC z$&b4^NnN_V@DBZSj&EjWrjw)DZ)KQ5;r9Vi-qQjA#dfJPl*lOW8a%>tFR6w^|NbPI zZWyf@F1FMoGjWD1V2(3CKmT~4PsNksyWF2rQ&TfIXqY>)S4Pllx z{@n?$r%_qeky0h$y2Z!6-3eB6oX>;r==u4Yl}${~vPZqfiAMUH2G&k~sHS;~G<(O($0$W5kBZwj zM{ml=wC)UVrR6`&7w`;Ea2?hg*(Lh;49~pS7`(Bu9Xxy@#I7+y4N>!|q&=G<(81{V zFx&|dy~x+U-7qjPU?>tc?OzLh$P^>5qLPEdby13=E~RQ+f;@Bj?IwTkD0|OG!Q67+ z{s-TuJ55yis#axPnqaF|Fk5c^7P0rm0u714B2@%}Rb%7uQ$2rf@u+bnhsG7utbe#F zHw#KSJxJy8%p^txstm|a1Kl3fEb&ks$Uk(BccJZJq}g(_JSonBc={_PB_+uzDH%8% zr=c^;*QUA5+^m}(4XFp3iI&D|Ibl7buk@t*nJ<)zo12?kT3TvrgXUWv-MMpzgM))e zB&L)|GkorxieA&6%qWd9t)9{@Ed0LPIY45AR~n*OE!i@&v%~fl3E*4wpIzpGJOz)B z%*n1&NE$ay6pA!xby2Ak7}$w{?8N) z-I|%`9b4P1IZ{}&OKbS<n|)TophO*nNojr&@+|`h|F>#W#Y}wvR_@f97c0)rWqc>8L@~~(jk~ZW2mE3>C zICuu-=HpXG?+X*Dr$rCkZRs=Lh4z!;QTZ9DRJ&ySr(m_PE@m zLpH}=Zf^&)yScl%&X0|~d9NUKpG*bqCvwXJI#yPrOT=ezi024!mDoEgSNQT1w#Ro)OfDD7LOb&9~5o)8BJ2 zp~`MK#z1nEj1Zqw!8J5AGz2bmxK@l4K=Lgb8DOU}qmxV6nG%A#-oAZ%aBx7IO`xaI z1p{1aoZfW}NhV+*djfEu#<`%+O;(_`U%X(P$8XF^7?hh=1>tojt+-)c_bRGVgy-X3jmOH zREZ$MKXg)Uj1+++imk~|R#aptkU)M$9rb01k-qhu#=_lW&mZNa90ln(JI_&S#-?Uw zX2!=U+abv%gFZL5O&s~1oSlg-8mK2MY?k&kx-5;T`MAb3JBQV-L)_=`Ez81D{_en=)Cw5b@%Q{ceg=k=>E=pD;y4| z0;Hv-dDDzuT7y#CJp4Z878MvLVj%9Ok*mx_HHne5uX*_Bk+-+^sG_T*Bjd9;m0zoC zYEUTD@ZjLY)?tNtLCeEU+-eGcZ_FNnzAG=8iIXd$2+mSXm@87>~YHHdX zzUvkq9v&EoH!6*T$J*N3CL|;{;q8u*#>USk{m!@RN90D}2vTkinp2Vlr z^p^qPUBHaBon6@O7tLwMh0#%RpIFiRS}A_)vg4=Nua9-;62;uRdwK{$CC{!1)ws5D zasoizgBP9tE+2LQc~ANCfqdC!vo0nT=|ejXgOVy z1(UEF9;^p98GpN~Vv562S>%@Y#56AlCYN+yTT~C*X1S$eKeBhm@PJGaf|w!@0sj7M zVHM@&px6&1+f^*0qtB+Nxko5<|HPzLp-{yiC zpGt+IkV$bAzLm))ohS{TqSZy^mr!&r`VBv6KNYAMd+qYIb>^w@$ z^lAsg2vcuJSgR&Dpvq=Ax6DSOw6wJ7_D!!Pe?zQIv|KMXhJ}xBOFbSTn&)rw$#`rT zfYX&2=nhJP_~aOo;FHMREHp1zqG)Fpj44w$SVi>Co35O)lDc zoJ@(}(HU1H)9XRK9hEgTUAg-{*LmtYJM;0oKaC%j`>;Oc9!uKU0ZR~Qeo&2hC6#?V zpaJMEEe5ww*z`+Nh`zXWY;31jj$&}305a>n97K=2cXgQ+ov1P*MaK|g9n6<2>S83C zK_GZL(B+n+3$>%Z1w=(f>FUOrS3GET36`7Pd>G1a%z||&8Cd&;K`(*{myrRbBep>! z!fom&-Spg_yrt@LiN~xDpS5R0cM|c!=bZFu2m{SOEUiGfLo(TYJ z(Qe1-&R>(&v_uWTbSM0}N=;{{d*U-Xz`)qJb$%ys?p>084K_ntHuzt0=@8!@=5cFq zpa-VbkyTHCb;QS$dmXe)!H(pgvD_$%9UdCum_k1FbjU8q&o2}ALn2FFzh)JD-sh#N zs=5$!B!J-M;dzmp+uz@BU1j4QbI9RxI)Q3*#@k7FVUr@rE3#EoZdN$^S~su?W}U~m z$beHxBofFJ<-D|lYuB$|mzGY0C4wwT=|L*ISPezHyDuy*!XQ^IEG!zG@Ny_2PCl7X z0~YM4uTAx&dBwP21Jk6clG3Dy+~9W_0nNyX-f<|vEg*2%F0uCdZttg8jt?$=#2i6r zX=!UazDww`fJ*317t#i+l-?h{zP?Q$K@bRtE=$zWjwV>l$t%57fO$oIM@L6}J)4Z{ z*|7Squ&C&-si_lFQ&%96--P?*20{9O#yMsJSW@MT+S?zH9YMVZGcES}!R9@vgKE4N z`P)6&4|0RA29k*vE6|i{{9fEoH_#DD%}l|of3gbQ+2!gD>CfRpVh5)y5Fr^Mp2a8$GcZcCM~t=-S!E$CVuV>) zeyc&4s>;@+h<4}WT-e}p{OObb{WDx#0f38(@F-f0Na3R<*k{E=Hh=_%@>;eX8)X35{8E9bA2_b+;*hGe1Lc$0QX__Un zXac-hP13gLIBy<$YKB?2{E#SE%WP|KcMI9RL!gV-mClJzIyN6b56a? zzq&hX9EToPQ&ZD$b-CpU?9;zZ^+Ui~XoDJ6Q#*Fm^_G)Y;>W(p;coem4j=lJ zG1Qs^eu`KKnPk7Xt*xywm}G{HO?tIB5$ub78v4f6Ebq=)Ff`3~4pWhC(%7YY!T-4y z;%@3uuTxP+PW|Mmb;xNz>qn>ZD@a-?Ttm|$cZ>}CxXTVh_6wC|i=3F98$!o+*_Q4< zv{rpI)lj*{=g9v>;IDW%Y)!}X!xaLflSj8H*;acc9BGS5o=e0#sf;6Y;EBra7~L!% zc);6dotx^2Z+b$NwUae*EwMFBri3GF-Bt8EHbogee*M(q<865ocYl9BE-nsZb5wou zwXv*u0aVscrBcD_M@ah{W7XA0S)HCAaGRS$>eiy!xq8=G_%Cc(AURgFfJP#qa@OoIlhi=O;dWu)8YEau%3DE8oDz@ zUnBhnSrg_rlFL(yOQce%TrMvzE@rV4$KdpIvUHm5t#8CCI9+;457fO{&y#K>)e~2i2P^Bjo9N(R zv0e9EJm;d3kwM;1%Gl&&xK`#r39+0RCX-oXg~4D{@rEwCW0co)`qF%7R!`7t1|#AJ zjo>_a;vSIm_CE8Ix&oS}?!Fp-e<3C&M$AdQcePI_tW&Af3Yp7y*o<%a-nyt40g%ed zN~Ka+GkIBu-%8xQ?d;q~1)a5djBa@T{8!)H*v9v=O9TSpd#qil5EIG1cR0)PWF?nN z3=A|lr9K{Eoz)rrY4}pRX{+jh&~Dl`w|VbYi;f0>1l3ne;;xii^WDpMw&vhI|DiK zlAX1N{$FZquLaQuf_{+P#~eR#g3spz-MjYkT~%bu3P2EZE33u`c3*IeUFl#*Y$a*# zM~1g^=m9(g(iQyYV+=W1FS?_8UUuns7`~K3+I1l9ZI9+0xsE0hiJ#=?12^??FW=VR zDg2Lc@FsZj_^~~bYJW=vqjckl8zW48J}VF8(F*hffk4#IEi5bmTu@8aCMG7lolmt$ z2W61Gu3VXX_04+Qb=ezjO81y8P49wUh2?`)oVWKq2R}R4Uq|ht7vJ?essva3{$}!B z1pte-wl-g<#kYB|?H*oUUMN&Z!$b>*qYH)VfWh|q{dwn|pSk1za%x#3v68uEKXIATv}+QP z2&NE0Z||qIwOG5-xBgM8gMIP0RaI3Nk+icA2m}gkiJEH@xszHV&^iTE64I`uiB6|q zx3k+LrG$othT#%K!~`4;my)9T9%&yZ78DKNa#AQ11qB5S4GkqJ9V_R*6BahjCatDv zI)peJ0KjotT7)!v;2=>eATcp^ND{w0gmm2RHK|YJ&JtwYtuHG>;-U?D8R-{b)YrrG z^;@NW!ZJr37P~)3h83&U7buPniR=D`TI}Q}?A-Rb<|P{8M)?30M|!ya;VqZ2H99;T z@p+J5Vwo8YJgGZZ&jN;PO=j2D@+I-SjZsX^Y0{p&8(&5og->aKK-F~{X=!OGdvbF3 z0z0zMx};AMPsz!#S1uNa^V8G+XyKOCIWJF)0&=SgulC!)pE+~Jr`Ad*3n1~qpfe0%@Kx;y+Q$bF%Gmh0jk$S# zSy>qX)Zd+1+EuQFW9E1ffT>wob+8DioZuwXcLth?%!2{5SX!zN3Z$VfTU%L;3=Jtd z!MMvlu16B82?9M!70RaCzuc_$c2gNHVv$r%}LZf-g{ zI(0K`ygGB3vq7F>sh_7h*aeXnW)ehL6l%ONd~AJvJ^ciDXJ-ehtDE-L-x69%qaA!m z(;QWe?1QM{Yv;Gg6A97L(fK_u9`<3MWM^kjPfr7PEh;J+ZUefY8`*pgniJXauY?v$ viq@3JWGlU66H)m1=Kte=83Bb1_%x|h1mr?zif0_^19GOSRPT literal 2421 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 QV*mgE07*qoM6N<$f)!e<4*&oF diff --git a/widget/tree_test.go b/widget/tree_test.go index cf9260adf6..1817233731 100644 --- a/widget/tree_test.go +++ b/widget/tree_test.go @@ -7,9 +7,7 @@ import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/data/binding" - internalTest "fyne.io/fyne/v2/internal/test" "fyne.io/fyne/v2/test" - "fyne.io/fyne/v2/theme" "fyne.io/fyne/v2/widget" "github.com/stretchr/testify/assert" @@ -327,7 +325,7 @@ func TestTree_Move(t *testing.T) { func TestTree_Refresh(t *testing.T) { test.NewTempApp(t) - test.ApplyTheme(t, internalTest.LightTheme(theme.DefaultTheme())) + test.ApplyTheme(t, test.Theme()) value := "Foo Leaf" tree := widget.NewTreeWithStrings(treeData) diff --git a/widget/widget_test.go b/widget/widget_test.go index 8a34b7cfe1..f3b0666f05 100644 --- a/widget/widget_test.go +++ b/widget/widget_test.go @@ -9,11 +9,9 @@ import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" - internalTest "fyne.io/fyne/v2/internal/test" internalWidget "fyne.io/fyne/v2/internal/widget" "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/test" - "fyne.io/fyne/v2/theme" ) type myWidget struct { @@ -35,7 +33,7 @@ func TestApplyThemeCalled(t *testing.T) { widget := &myWidget{refreshed: make(chan bool)} window := test.NewWindow(widget) - fyne.CurrentApp().Settings().SetTheme(internalTest.LightTheme(theme.DefaultTheme())) + fyne.CurrentApp().Settings().SetTheme(test.NewTheme()) func() { select { @@ -53,7 +51,7 @@ func TestApplyThemeCalledChild(t *testing.T) { parent := &fyne.Container{Layout: layout.NewVBoxLayout(), Objects: []fyne.CanvasObject{child}} window := test.NewWindow(parent) - fyne.CurrentApp().Settings().SetTheme(internalTest.LightTheme(theme.DefaultTheme())) + fyne.CurrentApp().Settings().SetTheme(test.NewTheme()) func() { select { case <-child.refreshed: From 384bff18f06c4fc369e6f14dacf1a3a92e1fb9af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Tue, 18 Jun 2024 11:10:58 +0200 Subject: [PATCH 65/78] =?UTF-8?q?[theme]=20extract=20=E2=80=9Cnamed?= =?UTF-8?q?=E2=80=9D=20color=20=E2=80=9Cconstants=E2=80=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- theme/color.go | 40 ++++++++++++++++++++++++++++++++-------- theme/theme.go | 32 ++++++++++++++++---------------- 2 files changed, 48 insertions(+), 24 deletions(-) diff --git a/theme/color.go b/theme/color.go index 4ddb994e5e..b50c2b5359 100644 --- a/theme/color.go +++ b/theme/color.go @@ -206,6 +206,14 @@ var ( colorLightDisabled = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} colorLightDisabledButton = color.NRGBA{R: 0xf5, G: 0xf5, B: 0xf5, A: 0xff} colorLightError = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} + colorLightFocusBlue = color.NRGBA{R: 0x00, G: 0x6c, B: 0xff, A: 0x2a} + colorLightFocusBrown = color.NRGBA{R: 0x79, G: 0x55, B: 0x48, A: 0x7f} + colorLightFocusGray = color.NRGBA{R: 0x9e, G: 0x9e, B: 0x9e, A: 0x7f} + colorLightFocusGreen = color.NRGBA{R: 0x8b, G: 0xc3, B: 0x4a, A: 0x7f} + colorLightFocusOrange = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0x7f} + colorLightFocusPurple = color.NRGBA{R: 0x9c, G: 0x27, B: 0xb0, A: 0x7f} + colorLightFocusRed = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0x7f} + colorLightFocusYellow = color.NRGBA{R: 0xff, G: 0xeb, B: 0x3b, A: 0x7f} colorLightForeground = color.NRGBA{R: 0x56, G: 0x56, B: 0x56, A: 0xff} colorLightForegroundOnError = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} colorLightForegroundOnSuccess = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} @@ -218,7 +226,23 @@ var ( colorLightOverlayBackground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} colorLightPlaceholder = color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff} colorLightPressed = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x19} + colorLightPrimaryBlue = color.NRGBA{R: 0x29, G: 0x6f, B: 0xf6, A: 0xff} + colorLightPrimaryBrown = color.NRGBA{R: 0x79, G: 0x55, B: 0x48, A: 0xff} + colorLightPrimaryGray = color.NRGBA{R: 0x9e, G: 0x9e, B: 0x9e, A: 0xff} + colorLightPrimaryGreen = color.NRGBA{R: 0x8b, G: 0xc3, B: 0x4a, A: 0xff} + colorLightPrimaryOrange = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} + colorLightPrimaryPurple = color.NRGBA{R: 0x9c, G: 0x27, B: 0xb0, A: 0xff} + colorLightPrimaryRed = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} + colorLightPrimaryYellow = color.NRGBA{R: 0xff, G: 0xeb, B: 0x3b, A: 0xff} colorLightScrollBar = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x99} + colorLightSelectionBlue = color.NRGBA{R: 0x00, G: 0x6c, B: 0xff, A: 0x40} + colorLightSelectionBrown = color.NRGBA{R: 0x79, G: 0x55, B: 0x48, A: 0x3f} + colorLightSelectionGray = color.NRGBA{R: 0x9e, G: 0x9e, B: 0x9e, A: 0x3f} + colorLightSelectionGreen = color.NRGBA{R: 0x8b, G: 0xc3, B: 0x4a, A: 0x3f} + colorLightSelectionOrange = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0x3f} + colorLightSelectionPurple = color.NRGBA{R: 0x9c, G: 0x27, B: 0xb0, A: 0x3f} + colorLightSelectionRed = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0x3f} + colorLightSelectionYellow = color.NRGBA{R: 0xff, G: 0xeb, B: 0x3b, A: 0x3f} colorLightSeparator = color.NRGBA{R: 0xe3, G: 0xe3, B: 0xe3, A: 0xff} colorLightShadow = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x33} colorLightSuccess = color.NRGBA{R: 0x43, G: 0xf4, B: 0x36, A: 0xff} @@ -380,24 +404,24 @@ func PrimaryColor() color.Color { func PrimaryColorNamed(name string) color.Color { switch name { case ColorRed: - return color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} + return colorLightPrimaryRed case ColorOrange: - return color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} + return colorLightPrimaryOrange case ColorYellow: - return color.NRGBA{R: 0xff, G: 0xeb, B: 0x3b, A: 0xff} + return colorLightPrimaryYellow case ColorGreen: - return color.NRGBA{R: 0x8b, G: 0xc3, B: 0x4a, A: 0xff} + return colorLightPrimaryGreen case ColorPurple: - return color.NRGBA{R: 0x9c, G: 0x27, B: 0xb0, A: 0xff} + return colorLightPrimaryPurple case ColorBrown: - return color.NRGBA{R: 0x79, G: 0x55, B: 0x48, A: 0xff} + return colorLightPrimaryBrown case ColorGray: - return color.NRGBA{R: 0x9e, G: 0x9e, B: 0x9e, A: 0xff} + return colorLightPrimaryGray } // We return the value for ColorBlue for every other value. // There is no need to have it in the switch above. - return color.NRGBA{R: 0x29, G: 0x6f, B: 0xf6, A: 0xff} + return colorLightPrimaryBlue } // PrimaryColorNames returns a list of the standard primary color options. diff --git a/theme/theme.go b/theme/theme.go index 9dbd5a58a3..98ecd77249 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -268,24 +268,24 @@ func darkPaletteColorNamed(name fyne.ThemeColorName) color.Color { func focusColorNamed(name string) color.NRGBA { switch name { case ColorRed: - return color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0x7f} + return colorLightFocusRed case ColorOrange: - return color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0x7f} + return colorLightFocusOrange case ColorYellow: - return color.NRGBA{R: 0xff, G: 0xeb, B: 0x3b, A: 0x7f} + return colorLightFocusYellow case ColorGreen: - return color.NRGBA{R: 0x8b, G: 0xc3, B: 0x4a, A: 0x7f} + return colorLightFocusGreen case ColorPurple: - return color.NRGBA{R: 0x9c, G: 0x27, B: 0xb0, A: 0x7f} + return colorLightFocusPurple case ColorBrown: - return color.NRGBA{R: 0x79, G: 0x55, B: 0x48, A: 0x7f} + return colorLightFocusBrown case ColorGray: - return color.NRGBA{R: 0x9e, G: 0x9e, B: 0x9e, A: 0x7f} + return colorLightFocusGray } // We return the value for ColorBlue for every other value. // There is no need to have it in the switch above. - return color.NRGBA{R: 0x00, G: 0x6C, B: 0xff, A: 0x2a} + return colorLightFocusBlue } func lightPaletteColorNamed(name fyne.ThemeColorName) color.Color { @@ -354,24 +354,24 @@ func loadCustomFont(env, variant string, fallback fyne.Resource) fyne.Resource { func selectionColorNamed(name string) color.NRGBA { switch name { case ColorRed: - return color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0x3f} + return colorLightSelectionRed case ColorOrange: - return color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0x3f} + return colorLightSelectionOrange case ColorYellow: - return color.NRGBA{R: 0xff, G: 0xeb, B: 0x3b, A: 0x3f} + return colorLightSelectionYellow case ColorGreen: - return color.NRGBA{R: 0x8b, G: 0xc3, B: 0x4a, A: 0x3f} + return colorLightSelectionGreen case ColorPurple: - return color.NRGBA{R: 0x9c, G: 0x27, B: 0xb0, A: 0x3f} + return colorLightSelectionPurple case ColorBrown: - return color.NRGBA{R: 0x79, G: 0x55, B: 0x48, A: 0x3f} + return colorLightSelectionBrown case ColorGray: - return color.NRGBA{R: 0x9e, G: 0x9e, B: 0x9e, A: 0x3f} + return colorLightSelectionGray } // We return the value for ColorBlue for every other value. // There is no need to have it in the switch above. - return color.NRGBA{R: 0x00, G: 0x6C, B: 0xff, A: 0x40} + return colorLightSelectionBlue } func setupDefaultTheme() fyne.Theme { From 9c2475278aaa1adade10979412de448911071bd1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Wed, 12 Jun 2024 14:42:58 +0200 Subject: [PATCH 66/78] [theme] move primary color name values into internal/theme Thus, they can be used by an internal implementation of *PrimaryColorNamed which then can be deprecated. --- internal/theme/theme.go | 13 +++++++++++++ theme/color.go | 17 +++++++++-------- 2 files changed, 22 insertions(+), 8 deletions(-) create mode 100644 internal/theme/theme.go diff --git a/internal/theme/theme.go b/internal/theme/theme.go new file mode 100644 index 0000000000..46abeeb5b9 --- /dev/null +++ b/internal/theme/theme.go @@ -0,0 +1,13 @@ +package theme + +// Primary color names. +const ( + ColorBlue = "blue" + ColorBrown = "brown" + ColorGray = "gray" + ColorGreen = "green" + ColorOrange = "orange" + ColorPurple = "purple" + ColorRed = "red" + ColorYellow = "yellow" +) diff --git a/theme/color.go b/theme/color.go index b50c2b5359..7d15732f35 100644 --- a/theme/color.go +++ b/theme/color.go @@ -4,6 +4,7 @@ import ( "image/color" "fyne.io/fyne/v2" + internaltheme "fyne.io/fyne/v2/internal/theme" ) // Keep in mind to add new constants to the tests at theme/theme_test.go as well as test/theme_test.go. @@ -11,35 +12,35 @@ const ( // ColorRed is the red primary color name. // // Since: 1.4 - ColorRed = "red" + ColorRed = internaltheme.ColorRed // ColorOrange is the orange primary color name. // // Since: 1.4 - ColorOrange = "orange" + ColorOrange = internaltheme.ColorOrange // ColorYellow is the yellow primary color name. // // Since: 1.4 - ColorYellow = "yellow" + ColorYellow = internaltheme.ColorYellow // ColorGreen is the green primary color name. // // Since: 1.4 - ColorGreen = "green" + ColorGreen = internaltheme.ColorGreen // ColorBlue is the blue primary color name. // // Since: 1.4 - ColorBlue = "blue" + ColorBlue = internaltheme.ColorBlue // ColorPurple is the purple primary color name. // // Since: 1.4 - ColorPurple = "purple" + ColorPurple = internaltheme.ColorPurple // ColorBrown is the brown primary color name. // // Since: 1.4 - ColorBrown = "brown" + ColorBrown = internaltheme.ColorBrown // ColorGray is the gray primary color name. // // Since: 1.4 - ColorGray = "gray" + ColorGray = internaltheme.ColorGray // ColorNameBackground is the name of theme lookup for background color. // From 88c1bf124312405c10f179e5a6c76f1517e26752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Tue, 18 Jun 2024 11:12:09 +0200 Subject: [PATCH 67/78] [theme] move implementation of .PrimaryColorNamed() to internal/theme Thus, it can be shared with the settings app even if the theme package method gets deprecated. --- internal/theme/theme.go | 37 +++++++++++++++++++++++++++++++++++++ theme/color.go | 29 +---------------------------- 2 files changed, 38 insertions(+), 28 deletions(-) diff --git a/internal/theme/theme.go b/internal/theme/theme.go index 46abeeb5b9..bd8f7a15a5 100644 --- a/internal/theme/theme.go +++ b/internal/theme/theme.go @@ -1,5 +1,7 @@ package theme +import "image/color" + // Primary color names. const ( ColorBlue = "blue" @@ -11,3 +13,38 @@ const ( ColorRed = "red" ColorYellow = "yellow" ) + +var ( + colorLightPrimaryBlue = color.NRGBA{R: 0x29, G: 0x6f, B: 0xf6, A: 0xff} + colorLightPrimaryBrown = color.NRGBA{R: 0x79, G: 0x55, B: 0x48, A: 0xff} + colorLightPrimaryGray = color.NRGBA{R: 0x9e, G: 0x9e, B: 0x9e, A: 0xff} + colorLightPrimaryGreen = color.NRGBA{R: 0x8b, G: 0xc3, B: 0x4a, A: 0xff} + colorLightPrimaryOrange = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} + colorLightPrimaryPurple = color.NRGBA{R: 0x9c, G: 0x27, B: 0xb0, A: 0xff} + colorLightPrimaryRed = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} + colorLightPrimaryYellow = color.NRGBA{R: 0xff, G: 0xeb, B: 0x3b, A: 0xff} +) + +// PrimaryColorNamed returns a theme specific color value for a named primary color. +func PrimaryColorNamed(name string) color.Color { + switch name { + case ColorRed: + return colorLightPrimaryRed + case ColorOrange: + return colorLightPrimaryOrange + case ColorYellow: + return colorLightPrimaryYellow + case ColorGreen: + return colorLightPrimaryGreen + case ColorPurple: + return colorLightPrimaryPurple + case ColorBrown: + return colorLightPrimaryBrown + case ColorGray: + return colorLightPrimaryGray + } + + // We return the value for ColorBlue for every other value. + // There is no need to have it in the switch above. + return colorLightPrimaryBlue +} diff --git a/theme/color.go b/theme/color.go index 7d15732f35..58ecce9941 100644 --- a/theme/color.go +++ b/theme/color.go @@ -227,14 +227,6 @@ var ( colorLightOverlayBackground = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} colorLightPlaceholder = color.NRGBA{R: 0x88, G: 0x88, B: 0x88, A: 0xff} colorLightPressed = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x19} - colorLightPrimaryBlue = color.NRGBA{R: 0x29, G: 0x6f, B: 0xf6, A: 0xff} - colorLightPrimaryBrown = color.NRGBA{R: 0x79, G: 0x55, B: 0x48, A: 0xff} - colorLightPrimaryGray = color.NRGBA{R: 0x9e, G: 0x9e, B: 0x9e, A: 0xff} - colorLightPrimaryGreen = color.NRGBA{R: 0x8b, G: 0xc3, B: 0x4a, A: 0xff} - colorLightPrimaryOrange = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} - colorLightPrimaryPurple = color.NRGBA{R: 0x9c, G: 0x27, B: 0xb0, A: 0xff} - colorLightPrimaryRed = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} - colorLightPrimaryYellow = color.NRGBA{R: 0xff, G: 0xeb, B: 0x3b, A: 0xff} colorLightScrollBar = color.NRGBA{R: 0x00, G: 0x00, B: 0x00, A: 0x99} colorLightSelectionBlue = color.NRGBA{R: 0x00, G: 0x6c, B: 0xff, A: 0x40} colorLightSelectionBrown = color.NRGBA{R: 0x79, G: 0x55, B: 0x48, A: 0x3f} @@ -403,26 +395,7 @@ func PrimaryColor() color.Color { // // Since: 1.4 func PrimaryColorNamed(name string) color.Color { - switch name { - case ColorRed: - return colorLightPrimaryRed - case ColorOrange: - return colorLightPrimaryOrange - case ColorYellow: - return colorLightPrimaryYellow - case ColorGreen: - return colorLightPrimaryGreen - case ColorPurple: - return colorLightPrimaryPurple - case ColorBrown: - return colorLightPrimaryBrown - case ColorGray: - return colorLightPrimaryGray - } - - // We return the value for ColorBlue for every other value. - // There is no need to have it in the switch above. - return colorLightPrimaryBlue + return internaltheme.PrimaryColorNamed(name) } // PrimaryColorNames returns a list of the standard primary color options. From a5b7f88054dd2fbd13f484f127d3a3498f4fd24a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Tue, 18 Jun 2024 11:12:36 +0200 Subject: [PATCH 68/78] [theme] move implementation of .PrimaryForegroundColorNamed() to internal/theme Thus, it can be shared with the settings app even if the theme package method gets deprecated. This also introduces separated color values for the various variants which are copies of the background colors used before. And last but not least, the internal method is named correctly. The public one will vanish soon. --- internal/theme/theme.go | 48 ++++++++++++++++++++++++++++++++++------- theme/color.go | 21 +----------------- 2 files changed, 41 insertions(+), 28 deletions(-) diff --git a/internal/theme/theme.go b/internal/theme/theme.go index bd8f7a15a5..417a510f8d 100644 --- a/internal/theme/theme.go +++ b/internal/theme/theme.go @@ -15,16 +15,48 @@ const ( ) var ( - colorLightPrimaryBlue = color.NRGBA{R: 0x29, G: 0x6f, B: 0xf6, A: 0xff} - colorLightPrimaryBrown = color.NRGBA{R: 0x79, G: 0x55, B: 0x48, A: 0xff} - colorLightPrimaryGray = color.NRGBA{R: 0x9e, G: 0x9e, B: 0x9e, A: 0xff} - colorLightPrimaryGreen = color.NRGBA{R: 0x8b, G: 0xc3, B: 0x4a, A: 0xff} - colorLightPrimaryOrange = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} - colorLightPrimaryPurple = color.NRGBA{R: 0x9c, G: 0x27, B: 0xb0, A: 0xff} - colorLightPrimaryRed = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} - colorLightPrimaryYellow = color.NRGBA{R: 0xff, G: 0xeb, B: 0x3b, A: 0xff} + colorLightOnPrimaryBlue = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorLightOnPrimaryBrown = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorLightOnPrimaryGray = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} + colorLightOnPrimaryGreen = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} + colorLightOnPrimaryOrange = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} + colorLightOnPrimaryPurple = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorLightOnPrimaryRed = color.NRGBA{R: 0xff, G: 0xff, B: 0xff, A: 0xff} + colorLightOnPrimaryYellow = color.NRGBA{R: 0x17, G: 0x17, B: 0x18, A: 0xff} + colorLightPrimaryBlue = color.NRGBA{R: 0x29, G: 0x6f, B: 0xf6, A: 0xff} + colorLightPrimaryBrown = color.NRGBA{R: 0x79, G: 0x55, B: 0x48, A: 0xff} + colorLightPrimaryGray = color.NRGBA{R: 0x9e, G: 0x9e, B: 0x9e, A: 0xff} + colorLightPrimaryGreen = color.NRGBA{R: 0x8b, G: 0xc3, B: 0x4a, A: 0xff} + colorLightPrimaryOrange = color.NRGBA{R: 0xff, G: 0x98, B: 0x00, A: 0xff} + colorLightPrimaryPurple = color.NRGBA{R: 0x9c, G: 0x27, B: 0xb0, A: 0xff} + colorLightPrimaryRed = color.NRGBA{R: 0xf4, G: 0x43, B: 0x36, A: 0xff} + colorLightPrimaryYellow = color.NRGBA{R: 0xff, G: 0xeb, B: 0x3b, A: 0xff} ) +// ForegroundOnPrimaryColorNamed returns a theme specific color used for text and icons against the named primary color. +func ForegroundOnPrimaryColorNamed(name string) color.Color { + switch name { + case ColorRed: + return colorLightOnPrimaryRed + case ColorOrange: + return colorLightOnPrimaryOrange + case ColorYellow: + return colorLightOnPrimaryYellow + case ColorGreen: + return colorLightOnPrimaryGreen + case ColorPurple: + return colorLightOnPrimaryPurple + case ColorBrown: + return colorLightOnPrimaryBrown + case ColorGray: + return colorLightOnPrimaryGray + } + + // We return the “on” value for ColorBlue for every other value. + // There is no need to have it in the switch above. + return colorLightOnPrimaryBlue +} + // PrimaryColorNamed returns a theme specific color value for a named primary color. func PrimaryColorNamed(name string) color.Color { switch name { diff --git a/theme/color.go b/theme/color.go index 58ecce9941..5ebea581da 100644 --- a/theme/color.go +++ b/theme/color.go @@ -345,26 +345,7 @@ func MenuBackgroundColor() color.Color { // // Since: 2.5 func PrimaryForegroundColorNamed(name string) color.Color { - switch name { - case ColorRed: - return colorLightBackground - case ColorOrange: - return colorDarkBackground - case ColorYellow: - return colorDarkBackground - case ColorGreen: - return colorDarkBackground - case ColorPurple: - return colorLightBackground - case ColorBrown: - return colorLightBackground - case ColorGray: - return colorDarkBackground - } - - // We return the “on” value for ColorBlue for every other value. - // There is no need to have it in the switch above. - return colorLightBackground + return internaltheme.ForegroundOnPrimaryColorNamed(name) } // OverlayBackgroundColor returns the theme's background color for overlays like dialogs. From 13cf81a4cc8e70e54916132e6d82160d528f2b52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Tue, 18 Jun 2024 11:13:18 +0200 Subject: [PATCH 69/78] use internal *PrimaryColorNamed() methods --- cmd/fyne_settings/settings/appearance.go | 9 +++++---- theme/theme.go | 5 +++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/cmd/fyne_settings/settings/appearance.go b/cmd/fyne_settings/settings/appearance.go index e1c5d6ae01..944441112a 100644 --- a/cmd/fyne_settings/settings/appearance.go +++ b/cmd/fyne_settings/settings/appearance.go @@ -12,6 +12,7 @@ import ( "fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/container" internalapp "fyne.io/fyne/v2/internal/app" + internaltheme "fyne.io/fyne/v2/internal/theme" intWidget "fyne.io/fyne/v2/internal/widget" "fyne.io/fyne/v2/layout" "fyne.io/fyne/v2/theme" @@ -185,7 +186,7 @@ func newPrimaryColorButton(name string, s *Settings) *primaryColorButton { } func (c *primaryColorButton) CreateRenderer() fyne.WidgetRenderer { - r := canvas.NewRectangle(theme.PrimaryColorNamed(c.name)) + r := canvas.NewRectangle(internaltheme.PrimaryColorNamed(c.name)) r.CornerRadius = theme.SelectionRadiusSize() r.StrokeWidth = 5 @@ -225,7 +226,7 @@ func (c *primaryColorButtonRenderer) Refresh() { } else { c.rect.StrokeColor = color.Transparent } - c.rect.FillColor = theme.PrimaryColorNamed(c.c.name) + c.rect.FillColor = internaltheme.PrimaryColorNamed(c.c.name) c.rect.CornerRadius = theme.SelectionRadiusSize() c.rect.Refresh() @@ -254,9 +255,9 @@ func (p *previewTheme) Color(n fyne.ThemeColorName, _ fyne.ThemeVariant) color.C switch n { case theme.ColorNamePrimary: - return theme.PrimaryColorNamed(p.s.fyneSettings.PrimaryColor) + return internaltheme.PrimaryColorNamed(p.s.fyneSettings.PrimaryColor) case theme.ColorNameForegroundOnPrimary: - return theme.PrimaryForegroundColorNamed(p.s.fyneSettings.PrimaryColor) + return internaltheme.ForegroundOnPrimaryColorNamed(p.s.fyneSettings.PrimaryColor) } return p.t.Color(n, variant) diff --git a/theme/theme.go b/theme/theme.go index 98ecd77249..36b7effb10 100644 --- a/theme/theme.go +++ b/theme/theme.go @@ -8,6 +8,7 @@ import ( "fyne.io/fyne/v2" "fyne.io/fyne/v2/internal/cache" + internaltheme "fyne.io/fyne/v2/internal/theme" ) // Keep in mind to add new constants to the tests at theme/theme_test.go as well as test/theme_test.go. @@ -105,9 +106,9 @@ func (t *builtinTheme) Color(n fyne.ThemeColorName, v fyne.ThemeVariant) color.C primary := fyne.CurrentApp().Settings().PrimaryColor() if n == ColorNamePrimary || n == ColorNameHyperlink { - return PrimaryColorNamed(primary) + return internaltheme.PrimaryColorNamed(primary) } else if n == ColorNameForegroundOnPrimary { - return PrimaryForegroundColorNamed(primary) + return internaltheme.ForegroundOnPrimaryColorNamed(primary) } else if n == ColorNameFocus { return focusColorNamed(primary) } else if n == ColorNameSelection { From 6547f25953c116ca1d399bdfabe83d8fac2bde18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Tue, 18 Jun 2024 11:28:52 +0200 Subject: [PATCH 70/78] [theme] remove now unused (and not yet released) .PrimaryForegroundColorNamed() --- theme/color.go | 7 ------- 1 file changed, 7 deletions(-) diff --git a/theme/color.go b/theme/color.go index 5ebea581da..2636aa3218 100644 --- a/theme/color.go +++ b/theme/color.go @@ -341,13 +341,6 @@ func MenuBackgroundColor() color.Color { return safeColorLookup(ColorNameMenuBackground, currentVariant()) } -// PrimaryForegroundColorNamed returns a theme specific color used for text and icons against the named primary color. -// -// Since: 2.5 -func PrimaryForegroundColorNamed(name string) color.Color { - return internaltheme.ForegroundOnPrimaryColorNamed(name) -} - // OverlayBackgroundColor returns the theme's background color for overlays like dialogs. // // Since: 2.3 From 68570545030df47b6f3428c0edd7709c8d4e10ac Mon Sep 17 00:00:00 2001 From: Andy Williams Date: Wed, 19 Jun 2024 12:55:58 +0100 Subject: [PATCH 71/78] Also clear memory that Go has reserved when we get an OS request for mobile. Move the code to shared (not for simulator though). --- internal/driver/mobile/app/android.go | 5 +---- internal/driver/mobile/app/darwin_ios.go | 5 +++++ internal/driver/mobile/app/darwin_ios.m | 4 ++++ internal/driver/mobile/app/mobile.go | 15 +++++++++++++++ 4 files changed, 25 insertions(+), 4 deletions(-) create mode 100644 internal/driver/mobile/app/mobile.go diff --git a/internal/driver/mobile/app/android.go b/internal/driver/mobile/app/android.go index d2111b6b0e..550efce9bb 100644 --- a/internal/driver/mobile/app/android.go +++ b/internal/driver/mobile/app/android.go @@ -57,8 +57,6 @@ import ( "log" "mime" "os" - "runtime" - "runtime/debug" "strings" "time" "unsafe" @@ -278,8 +276,7 @@ func onConfigurationChanged(activity *C.ANativeActivity) { //export onLowMemory func onLowMemory(activity *C.ANativeActivity) { - runtime.GC() - debug.FreeOSMemory() + cleanCaches() } var ( diff --git a/internal/driver/mobile/app/darwin_ios.go b/internal/driver/mobile/app/darwin_ios.go index b0c68babf7..81be772aa8 100644 --- a/internal/driver/mobile/app/darwin_ios.go +++ b/internal/driver/mobile/app/darwin_ios.go @@ -210,6 +210,11 @@ func lifecycleVisible() { theApp.sendLifecycle(lifecycle.StageVisible) } //export lifecycleFocused func lifecycleFocused() { theApp.sendLifecycle(lifecycle.StageFocused) } +//export lifecycleMemoryWarning +func lifecycleMemoryWarning() { + cleanCaches() +} + //export drawloop func drawloop() { runtime.LockOSThread() diff --git a/internal/driver/mobile/app/darwin_ios.m b/internal/driver/mobile/app/darwin_ios.m index 799f330540..bfdfbdeb68 100644 --- a/internal/driver/mobile/app/darwin_ios.m +++ b/internal/driver/mobile/app/darwin_ios.m @@ -70,6 +70,10 @@ - (void)applicationWillTerminate:(UIApplication *)application { lifecycleDead(); } +- (void)applicationDidReceiveMemoryWarning:(UIApplication *)application { + lifecycleMemoryWarning(); +} + - (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray *)urls { if ([urls count] == 0) { return; diff --git a/internal/driver/mobile/app/mobile.go b/internal/driver/mobile/app/mobile.go new file mode 100644 index 0000000000..a13f9c5125 --- /dev/null +++ b/internal/driver/mobile/app/mobile.go @@ -0,0 +1,15 @@ +//go:build ios || android + +package app + +import "C" +import ( + "runtime" + "runtime/debug" +) + +// clean caches - called when the OS wants some memory back +func cleanCaches() { + runtime.GC() + debug.FreeOSMemory() +} From 51bb698976fc6075d5a615c1d8b602a09da237a3 Mon Sep 17 00:00:00 2001 From: ErikKalkoken Date: Wed, 19 Jun 2024 22:28:21 +0200 Subject: [PATCH 72/78] Fixes #4935; Show disabled app tabs as disabled in popup menu --- container/apptabs.go | 10 +++- container/apptabs_desktop_test.go | 21 +++++++ .../desktop/tapped_overflow_tabs_disabled.xml | 57 +++++++++++++++++++ 3 files changed, 86 insertions(+), 2 deletions(-) create mode 100644 container/testdata/apptabs/desktop/tapped_overflow_tabs_disabled.xml diff --git a/container/apptabs.go b/container/apptabs.go index 8e09cccbf6..e7f4e4eccc 100644 --- a/container/apptabs.go +++ b/container/apptabs.go @@ -330,13 +330,19 @@ func (r *appTabsRenderer) buildOverflowTabsButton() (overflow *widget.Button) { index := i // capture // FIXME MenuItem doesn't support icons (#1752) // FIXME MenuItem can't show if it is the currently selected tab (#1753) - items = append(items, fyne.NewMenuItem(r.appTabs.Items[i].Text, func() { + ti := r.appTabs.Items[i] + mi := fyne.NewMenuItem(ti.Text, func() { r.appTabs.SelectIndex(index) if r.appTabs.popUpMenu != nil { r.appTabs.popUpMenu.Hide() r.appTabs.popUpMenu = nil } - })) + }) + // Fixes #4935 + if ti.Disabled() { + mi.Disabled = true + } + items = append(items, mi) } r.appTabs.popUpMenu = buildPopUpMenu(r.appTabs, overflow, items) diff --git a/container/apptabs_desktop_test.go b/container/apptabs_desktop_test.go index 2b8c494173..e7cae471e0 100644 --- a/container/apptabs_desktop_test.go +++ b/container/apptabs_desktop_test.go @@ -307,3 +307,24 @@ func TestAppTabs_Tapped(t *testing.T) { test.TapCanvas(c, fyne.NewPos(186, 10)) test.AssertRendersToMarkup(t, "apptabs/desktop/tapped_overflow_tabs.xml", c) } + +func TestAppTabs_TappedAndDisabled(t *testing.T) { + test.NewApp() + defer test.NewApp() + + item1 := &container.TabItem{Text: "Test1", Content: widget.NewLabel("Text 1")} + item2 := &container.TabItem{Text: "Test2", Content: widget.NewLabel("Text 2")} + item3 := &container.TabItem{Text: "Test3", Content: widget.NewLabel("Text 3")} + tabs := container.NewAppTabs(item1, item2, item3) + tabs.DisableItem(item3) + w := test.NewWindow(tabs) + defer w.Close() + w.SetPadded(false) + w.Resize(fyne.NewSize(200, 100)) + c := w.Canvas() + + tabs.Append(&container.TabItem{Text: "Test4", Content: widget.NewLabel("Text 4")}) + + test.TapCanvas(c, fyne.NewPos(186, 10)) + test.AssertRendersToMarkup(t, "apptabs/desktop/tapped_overflow_tabs_disabled.xml", c) +} diff --git a/container/testdata/apptabs/desktop/tapped_overflow_tabs_disabled.xml b/container/testdata/apptabs/desktop/tapped_overflow_tabs_disabled.xml new file mode 100644 index 0000000000..c8b8030fbb --- /dev/null +++ b/container/testdata/apptabs/desktop/tapped_overflow_tabs_disabled.xml @@ -0,0 +1,57 @@ + + + + + + + Test1 + + + Test2 + + + + + + + + + + + + + Text 1 + + + + + + + + + + + + + + + + + + + + + + + Test3 + + + Test4 + + + + + + + + From ca1c01344cad787e9d804857ff22b4ebd01a90ab Mon Sep 17 00:00:00 2001 From: ErikKalkoken Date: Thu, 20 Jun 2024 13:03:16 +0200 Subject: [PATCH 73/78] Remove comment with the issue reference --- container/apptabs.go | 1 - 1 file changed, 1 deletion(-) diff --git a/container/apptabs.go b/container/apptabs.go index e7f4e4eccc..2d659746a1 100644 --- a/container/apptabs.go +++ b/container/apptabs.go @@ -338,7 +338,6 @@ func (r *appTabsRenderer) buildOverflowTabsButton() (overflow *widget.Button) { r.appTabs.popUpMenu = nil } }) - // Fixes #4935 if ti.Disabled() { mi.Disabled = true } From 935739c95b8313b1e2186431ed1b849f625d4f04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Wed, 12 Jun 2024 17:01:00 +0200 Subject: [PATCH 74/78] [theme] deprecate static color lookup helpers and PrimaryColorNamed() --- theme/color.go | 50 +++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/theme/color.go b/theme/color.go index 2636aa3218..401f15ef75 100644 --- a/theme/color.go +++ b/theme/color.go @@ -243,11 +243,15 @@ var ( ) // BackgroundColor returns the theme's background color. +// +// Deprecated: Use Color(theme.ColorNameBackground) instead. func BackgroundColor() color.Color { return safeColorLookup(ColorNameBackground, currentVariant()) } // ButtonColor returns the theme's standard button color. +// +// Deprecated: Use Color(theme.ColorNameButton) instead. func ButtonColor() color.Color { return safeColorLookup(ColorNameButton, currentVariant()) } @@ -268,6 +272,8 @@ func ColorForWidget(name fyne.ThemeColorName, w fyne.Widget) color.Color { } // DisabledButtonColor returns the theme's disabled button color. +// +// Deprecated: Use Color(theme.ColorNameDisabledButton) instead. func DisabledButtonColor() color.Color { return safeColorLookup(ColorNameDisabledButton, currentVariant()) } @@ -275,13 +281,15 @@ func DisabledButtonColor() color.Color { // DisabledColor returns the foreground color for a disabled UI element. // // Since: 2.0 +// +// Deprecated: Use Color(theme.ColorNameDisabled) instead. func DisabledColor() color.Color { return safeColorLookup(ColorNameDisabled, currentVariant()) } // DisabledTextColor returns the theme's disabled text color - this is actually the disabled color since 1.4. // -// Deprecated: Use theme.DisabledColor() colour instead. +// Deprecated: Use Color(theme.ColorNameDisabled) instead. func DisabledTextColor() color.Color { return DisabledColor() } @@ -289,11 +297,15 @@ func DisabledTextColor() color.Color { // ErrorColor returns the theme's error foreground color. // // Since: 2.0 +// +// Deprecated: Use Color(theme.ColorNameError) instead. func ErrorColor() color.Color { return safeColorLookup(ColorNameError, currentVariant()) } // FocusColor returns the color used to highlight a focused widget. +// +// Deprecated: Use Color(theme.ColorNameFocus) instead. func FocusColor() color.Color { return safeColorLookup(ColorNameFocus, currentVariant()) } @@ -301,6 +313,8 @@ func FocusColor() color.Color { // ForegroundColor returns the theme's standard foreground color for text and icons. // // Since: 2.0 +// +// Deprecated: Use Color(theme.ColorNameForeground) instead. func ForegroundColor() color.Color { return safeColorLookup(ColorNameForeground, currentVariant()) } @@ -308,21 +322,29 @@ func ForegroundColor() color.Color { // HeaderBackgroundColor returns the color used to draw underneath collection headers. // // Since: 2.4 +// +// Deprecated: Use Color(theme.ColorNameHeaderBackground) instead. func HeaderBackgroundColor() color.Color { return Current().Color(ColorNameHeaderBackground, currentVariant()) } // HoverColor returns the color used to highlight interactive elements currently under a cursor. +// +// Deprecated: Use Color(theme.ColorNameHover) instead. func HoverColor() color.Color { return safeColorLookup(ColorNameHover, currentVariant()) } // HyperlinkColor returns the color used for the Hyperlink widget and hyperlink text elements. +// +// Deprecated: Use Color(theme.ColorNameHyperlink) instead. func HyperlinkColor() color.Color { return safeColorLookup(ColorNameHyperlink, currentVariant()) } // InputBackgroundColor returns the color used to draw underneath input elements. +// +// Deprecated: Use Color(theme.ColorNameInputBackground) instead. func InputBackgroundColor() color.Color { return Current().Color(ColorNameInputBackground, currentVariant()) } @@ -330,6 +352,8 @@ func InputBackgroundColor() color.Color { // InputBorderColor returns the color used to draw underneath input elements. // // Since: 2.3 +// +// Deprecated: Use Color(theme.ColorNameInputBorder) instead. func InputBorderColor() color.Color { return Current().Color(ColorNameInputBorder, currentVariant()) } @@ -337,6 +361,8 @@ func InputBorderColor() color.Color { // MenuBackgroundColor returns the theme's background color for menus. // // Since: 2.3 +// +// Deprecated: Use Color(theme.ColorNameMenuBackground) instead. func MenuBackgroundColor() color.Color { return safeColorLookup(ColorNameMenuBackground, currentVariant()) } @@ -344,11 +370,15 @@ func MenuBackgroundColor() color.Color { // OverlayBackgroundColor returns the theme's background color for overlays like dialogs. // // Since: 2.3 +// +// Deprecated: Use Color(theme.ColorNameOverlayBackground) instead. func OverlayBackgroundColor() color.Color { return safeColorLookup(ColorNameOverlayBackground, currentVariant()) } // PlaceHolderColor returns the theme's standard text color. +// +// Deprecated: Use Color(theme.ColorNamePlaceHolder) instead. func PlaceHolderColor() color.Color { return safeColorLookup(ColorNamePlaceHolder, currentVariant()) } @@ -356,11 +386,15 @@ func PlaceHolderColor() color.Color { // PressedColor returns the color used to overlap tapped features. // // Since: 2.0 +// +// Deprecated: Use Color(theme.ColorNamePressed) instead. func PressedColor() color.Color { return safeColorLookup(ColorNamePressed, currentVariant()) } // PrimaryColor returns the color used to highlight primary features. +// +// Deprecated: Use Color(theme.ColorNamePrimary) instead. func PrimaryColor() color.Color { return safeColorLookup(ColorNamePrimary, currentVariant()) } @@ -368,6 +402,8 @@ func PrimaryColor() color.Color { // PrimaryColorNamed returns a theme specific color value for a named primary color. // // Since: 1.4 +// +// Deprecated: You should not access named primary colors but access the primary color using Color(theme.ColorNamePrimary) instead. func PrimaryColorNamed(name string) color.Color { return internaltheme.PrimaryColorNamed(name) } @@ -380,6 +416,8 @@ func PrimaryColorNames() []string { } // ScrollBarColor returns the color (and translucency) for a scrollBar. +// +// Deprecated: Use Color(theme.ColorNameScrollBar) instead. func ScrollBarColor() color.Color { return safeColorLookup(ColorNameScrollBar, currentVariant()) } @@ -387,6 +425,8 @@ func ScrollBarColor() color.Color { // SelectionColor returns the color for a selected element. // // Since: 2.1 +// +// Deprecated: Use Color(theme.ColorNameSelection) instead. func SelectionColor() color.Color { return safeColorLookup(ColorNameSelection, currentVariant()) } @@ -394,11 +434,15 @@ func SelectionColor() color.Color { // SeparatorColor returns the color for the separator element. // // Since: 2.3 +// +// Deprecated: Use Color(theme.ColorNameSeparator) instead. func SeparatorColor() color.Color { return safeColorLookup(ColorNameSeparator, currentVariant()) } // ShadowColor returns the color (and translucency) for shadows used for indicating elevation. +// +// Deprecated: Use Color(theme.ColorNameShadow) instead. func ShadowColor() color.Color { return safeColorLookup(ColorNameShadow, currentVariant()) } @@ -406,6 +450,8 @@ func ShadowColor() color.Color { // SuccessColor returns the theme's success foreground color. // // Since: 2.3 +// +// Deprecated: Use Color(theme.ColorNameSuccess) instead. func SuccessColor() color.Color { return safeColorLookup(ColorNameSuccess, currentVariant()) } @@ -413,6 +459,8 @@ func SuccessColor() color.Color { // WarningColor returns the theme's warning foreground color. // // Since: 2.3 +// +// Deprecated: Use Color(theme.ColorNameWarning) instead. func WarningColor() color.Color { return safeColorLookup(ColorNameWarning, currentVariant()) } From 280c8105c57d3f7383eaf3064be5897cff3bd4ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Tue, 18 Jun 2024 11:17:34 +0200 Subject: [PATCH 75/78] [widget] move progressbar test into test package This also changes the layout test to markup --- widget/progressbar_test.go | 62 ++++++++++++-------------- widget/testdata/progressbar/empty.xml | 11 +++++ widget/testdata/progressbar/full.xml | 10 +++++ widget/testdata/progressbar/half.xml | 11 +++++ widget/testdata/progressbar/themed.xml | 11 +++++ 5 files changed, 71 insertions(+), 34 deletions(-) create mode 100644 widget/testdata/progressbar/empty.xml create mode 100644 widget/testdata/progressbar/full.xml create mode 100644 widget/testdata/progressbar/half.xml create mode 100644 widget/testdata/progressbar/themed.xml diff --git a/widget/progressbar_test.go b/widget/progressbar_test.go index 2095349815..ab0ee39e47 100644 --- a/widget/progressbar_test.go +++ b/widget/progressbar_test.go @@ -1,20 +1,23 @@ -package widget +package widget_test import ( "fmt" "testing" + "github.com/stretchr/testify/assert" + "fyne.io/fyne/v2" + "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/data/binding" "fyne.io/fyne/v2/test" - "github.com/stretchr/testify/assert" + "fyne.io/fyne/v2/widget" ) var globalProgressRenderer fyne.WidgetRenderer func BenchmarkProgressbarCreateRenderer(b *testing.B) { var renderer fyne.WidgetRenderer - widget := &ProgressBar{} + widget := &widget.ProgressBar{} b.ReportAllocs() for i := 0; i < b.N; i++ { @@ -28,7 +31,7 @@ func BenchmarkProgressbarCreateRenderer(b *testing.B) { func BenchmarkProgressBarLayout(b *testing.B) { b.ReportAllocs() // We should see zero allocations. - bar := &ProgressBar{} + bar := &widget.ProgressBar{} renderer := bar.CreateRenderer() for i := 0; i < b.N; i++ { @@ -40,13 +43,13 @@ func TestNewProgressBarWithData(t *testing.T) { val := binding.NewFloat() val.Set(0.4) - label := NewProgressBarWithData(val) + label := widget.NewProgressBarWithData(val) waitForBinding() assert.Equal(t, 0.4, label.Value) } func TestProgressBar_Binding(t *testing.T) { - bar := NewProgressBar() + bar := widget.NewProgressBar() assert.Equal(t, 0.0, bar.Value) val := binding.NewFloat() @@ -65,7 +68,7 @@ func TestProgressBar_Binding(t *testing.T) { } func TestProgressBar_SetValue(t *testing.T) { - bar := NewProgressBar() + bar := widget.NewProgressBar() assert.Equal(t, 0.0, bar.Min) assert.Equal(t, 1.0, bar.Max) @@ -76,7 +79,7 @@ func TestProgressBar_SetValue(t *testing.T) { } func TestProgressBar_TextFormatter(t *testing.T) { - bar := NewProgressBar() + bar := widget.NewProgressBar() formatted := false bar.SetValue(0.2) @@ -94,46 +97,37 @@ func TestProgressBar_TextFormatter(t *testing.T) { } func TestProgressRenderer_Layout(t *testing.T) { - bar := NewProgressBar() - bar.Resize(fyne.NewSize(100, 10)) - - render := test.TempWidgetRenderer(t, bar).(*progressRenderer) - assert.Equal(t, float32(0), render.bar.Size().Width) + bar, c := barOnCanvas() + test.AssertRendersToMarkup(t, "progressbar/empty.xml", c) bar.SetValue(.5) - assert.Equal(t, float32(50), render.bar.Size().Width) + test.AssertRendersToMarkup(t, "progressbar/half.xml", c) bar.SetValue(1) - assert.Equal(t, bar.Size().Width, render.bar.Size().Width) + test.AssertRendersToMarkup(t, "progressbar/full.xml", c) } func TestProgressRenderer_Layout_Overflow(t *testing.T) { - bar := NewProgressBar() - bar.Resize(fyne.NewSize(100, 10)) - - render := test.TempWidgetRenderer(t, bar).(*progressRenderer) + bar, c := barOnCanvas() bar.SetValue(1) - assert.Equal(t, bar.Size().Width, render.bar.Size().Width) + test.AssertRendersToMarkup(t, "progressbar/full.xml", c) bar.SetValue(1.2) - assert.Equal(t, bar.Size().Width, render.bar.Size().Width) + test.AssertRendersToMarkup(t, "progressbar/full.xml", c) } func TestProgressRenderer_ApplyTheme(t *testing.T) { - bar := NewProgressBar() - render := test.TempWidgetRenderer(t, bar).(*progressRenderer) - - oldLabelColor := render.label.Color - render.Refresh() - newLabelColor := render.label.Color - assert.Equal(t, oldLabelColor, newLabelColor) - - textSize := render.label.TextSize - customTextSize := textSize test.WithTestTheme(t, func() { - render.applyTheme() - customTextSize = render.label.TextSize + bar, c := barOnCanvas() + bar.SetValue(.2) + test.AssertRendersToMarkup(t, "progressbar/themed.xml", c) }) +} - assert.NotEqual(t, textSize, customTextSize) +func barOnCanvas() (*widget.ProgressBar, fyne.Canvas) { + bar := widget.NewProgressBar() + window := test.NewWindow(container.NewVBox(bar)) + window.SetPadded(false) + window.Resize(fyne.NewSize(100, 100)) + return bar, window.Canvas() } diff --git a/widget/testdata/progressbar/empty.xml b/widget/testdata/progressbar/empty.xml new file mode 100644 index 0000000000..f3c2463189 --- /dev/null +++ b/widget/testdata/progressbar/empty.xml @@ -0,0 +1,11 @@ + + + + + + + 0% + + + + diff --git a/widget/testdata/progressbar/full.xml b/widget/testdata/progressbar/full.xml new file mode 100644 index 0000000000..609d21aab7 --- /dev/null +++ b/widget/testdata/progressbar/full.xml @@ -0,0 +1,10 @@ + + + + + + 100% + + + + diff --git a/widget/testdata/progressbar/half.xml b/widget/testdata/progressbar/half.xml new file mode 100644 index 0000000000..d89fd0a368 --- /dev/null +++ b/widget/testdata/progressbar/half.xml @@ -0,0 +1,11 @@ + + + + + + + 50% + + + + diff --git a/widget/testdata/progressbar/themed.xml b/widget/testdata/progressbar/themed.xml new file mode 100644 index 0000000000..495a9f67d0 --- /dev/null +++ b/widget/testdata/progressbar/themed.xml @@ -0,0 +1,11 @@ + + + + + + + 20% + + + + From 29cd29057ace067645adf3498e19e42123a6a84f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Fri, 14 Jun 2024 08:20:18 +0200 Subject: [PATCH 76/78] [widget] progressbar uses correct color for label This already improves the situation in #4845 a little bit. For fixing this issue, the primary colors have to be adjusted regarding contrast (and theme variant). --- widget/progressbar.go | 4 ++-- widget/testdata/progressbar/empty.xml | 2 +- widget/testdata/progressbar/full.xml | 2 +- widget/testdata/progressbar/half.xml | 2 +- widget/testdata/progressbar/themed.xml | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/widget/progressbar.go b/widget/progressbar.go index 9a37f9053b..72f19439aa 100644 --- a/widget/progressbar.go +++ b/widget/progressbar.go @@ -81,7 +81,7 @@ func (p *progressRenderer) applyTheme() { p.background.CornerRadius = inputRadius p.bar.FillColor = primaryColor p.bar.CornerRadius = inputRadius - p.label.Color = th.Color(theme.ColorNameBackground, v) + p.label.Color = th.Color(theme.ColorNameForegroundOnPrimary, v) p.label.TextSize = th.Size(theme.SizeNameText) } @@ -154,7 +154,7 @@ func (p *ProgressBar) CreateRenderer() fyne.WidgetRenderer { }, label: canvas.Text{ Text: "0%", - Color: th.Color(theme.ColorNameBackground, v), + Color: th.Color(theme.ColorNameForegroundOnPrimary, v), Alignment: fyne.TextAlignCenter, }, progress: p, diff --git a/widget/testdata/progressbar/empty.xml b/widget/testdata/progressbar/empty.xml index f3c2463189..b4a4588233 100644 --- a/widget/testdata/progressbar/empty.xml +++ b/widget/testdata/progressbar/empty.xml @@ -4,7 +4,7 @@ - 0% + 0% diff --git a/widget/testdata/progressbar/full.xml b/widget/testdata/progressbar/full.xml index 609d21aab7..9fa0bd3bf9 100644 --- a/widget/testdata/progressbar/full.xml +++ b/widget/testdata/progressbar/full.xml @@ -3,7 +3,7 @@ - 100% + 100% diff --git a/widget/testdata/progressbar/half.xml b/widget/testdata/progressbar/half.xml index d89fd0a368..dae712b48f 100644 --- a/widget/testdata/progressbar/half.xml +++ b/widget/testdata/progressbar/half.xml @@ -4,7 +4,7 @@ - 50% + 50% diff --git a/widget/testdata/progressbar/themed.xml b/widget/testdata/progressbar/themed.xml index 495a9f67d0..f39fc2e6ac 100644 --- a/widget/testdata/progressbar/themed.xml +++ b/widget/testdata/progressbar/themed.xml @@ -4,7 +4,7 @@ - 20% + 20% From 032d2df60486cc142b7eeb8ba970e6825f0aee91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Fri, 21 Jun 2024 14:14:45 +0200 Subject: [PATCH 77/78] [test] markup renderer no longer knows about primary color variants --- test/markup_renderer.go | 7 ------- test/markup_renderer_test.go | 34 ---------------------------------- 2 files changed, 41 deletions(-) diff --git a/test/markup_renderer.go b/test/markup_renderer.go index a0e5e93ac7..d3da0c163d 100644 --- a/test/markup_renderer.go +++ b/test/markup_renderer.go @@ -64,13 +64,6 @@ func (r *markupRenderer) setColorAttrWithDefault(attrs map[string]*string, name return } - for _, n := range theme.PrimaryColorNames() { - if c == theme.PrimaryColorNamed(n) { - r.setStringAttr(attrs, name, "primary-"+n) - return - } - } - rd, g, b, a := col.ToNRGBA(c) r.setStringAttr(attrs, name, fmt.Sprintf("rgba(%d,%d,%d,%d)", uint8(rd), uint8(g), uint8(b), uint8(a))) } diff --git a/test/markup_renderer_test.go b/test/markup_renderer_test.go index d31216ecdc..bce4c61405 100644 --- a/test/markup_renderer_test.go +++ b/test/markup_renderer_test.go @@ -48,14 +48,6 @@ func Test_snapshot(t *testing.T) { "\t\n" + "\n", }, - "circle with named primary color": { // we won’t test _all_ valid values … it’s not that important - content: fynecanvas.NewCircle(theme.PrimaryColorNamed(theme.ColorPurple)), - want: "\n" + - "\t\n" + - "\t\t\n" + - "\t\n" + - "\n", - }, "circle with stroke": { content: func() fyne.CanvasObject { c := fynecanvas.NewCircle(color.NRGBA{R: 200, G: 100, B: 0, A: 50}) @@ -220,14 +212,6 @@ func Test_snapshot(t *testing.T) { "\t\n" + "\n", }, - "line with named primary color": { // we won’t test _all_ valid values … it’s not that important - content: fynecanvas.NewLine(theme.PrimaryColorNamed(theme.ColorBrown)), - want: "\n" + - "\t\n" + - "\t\t\n" + - "\t\n" + - "\n", - }, "line with stroke width": { content: func() fyne.CanvasObject { l := fynecanvas.NewLine(color.NRGBA{R: 17, G: 42, B: 128, A: 255}) @@ -299,14 +283,6 @@ func Test_snapshot(t *testing.T) { "\t\n" + "\n", }, - "rectangle with named primary color": { // we won’t test _all_ valid values … it’s not that important - content: fynecanvas.NewRectangle(theme.PrimaryColorNamed(theme.ColorOrange)), - want: "\n" + - "\t\n" + - "\t\t\n" + - "\t\n" + - "\n", - }, "rectangle with stroke": { content: func() fyne.CanvasObject { r := fynecanvas.NewRectangle(color.NRGBA{R: 200, G: 100, B: 0, A: 50}) @@ -340,16 +316,6 @@ func Test_snapshot(t *testing.T) { "\t\n" + "\n", }, - "text with named primary color": { - content: fynecanvas.NewText("foo", theme.PrimaryColorNamed(theme.ColorYellow)), - size: fyne.NewSize(50, 50), - pos: fyne.NewPos(20, 20), - want: "\n" + - "\t\n" + - "\t\tfoo\n" + - "\t\n" + - "\n", - }, "text with alignment center": { content: func() fyne.CanvasObject { t := fynecanvas.NewText("bar", theme.ForegroundColor()) From d31ed150c750b14725c07b75dbe695e59c125d8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tilo=20Pr=C3=BCtz?= Date: Fri, 21 Jun 2024 14:31:39 +0200 Subject: [PATCH 78/78] replace usage of deprecated color functions by theme.Color() --- canvas/text_test.go | 4 +-- cmd/fyne_demo/tutorials/animation.go | 4 +-- cmd/fyne_demo/tutorials/icons.go | 4 +-- cmd/fyne_demo/tutorials/welcome.go | 8 ++--- cmd/fyne_settings/settings/appearance.go | 4 +-- cmd/fyne_settings/settings/scale.go | 4 +-- container/apptabs.go | 4 +-- container/apptabs_desktop_test.go | 30 +++++++++---------- container/apptabs_extend_test.go | 14 ++++----- container/doctabs.go | 4 +-- container/doctabs_desktop_test.go | 30 +++++++++---------- container/doctabs_extend_test.go | 14 ++++----- container/innerwindow.go | 8 ++--- container/split.go | 10 +++---- container/tabs.go | 22 +++++++------- dialog/base.go | 4 +-- dialog/color.go | 6 ++-- dialog/color_button.go | 2 +- dialog/color_button_test.go | 4 +-- dialog/color_picker_test.go | 2 +- dialog/color_wheel.go | 4 +-- internal/driver/common/canvas_test.go | 5 ++-- internal/driver/glfw/canvas.go | 2 +- internal/driver/glfw/menu_bar.go | 4 +-- internal/driver/glfw/menu_bar_item.go | 10 +++---- internal/driver/mobile/driver.go | 4 +-- internal/driver/mobile/menu.go | 6 ++-- internal/driver/mobile/menu_test.go | 4 +-- internal/driver/mobile/menubutton.go | 4 +-- internal/painter/gl/painter.go | 2 +- internal/painter/gl/texture.go | 2 +- internal/painter/software/draw.go | 2 +- internal/painter/software/painter_test.go | 4 +-- internal/widget/scroller.go | 4 +-- internal/widget/shadow.go | 30 +++++++++---------- test/canvas.go | 2 +- test/canvas_test.go | 2 +- test/markup_renderer.go | 36 +++++++++++------------ test/markup_renderer_test.go | 30 +++++++++---------- widget/button_internal_test.go | 14 ++++----- widget/check_internal_test.go | 12 ++++---- widget/entry_cursor_anim.go | 4 +-- widget/entry_cursor_anim_test.go | 7 +++-- widget/gridwrap.go | 6 ++-- widget/label_test.go | 4 +-- widget/list.go | 6 ++-- widget/list_test.go | 14 ++++----- widget/menu_internal_desktop_test.go | 2 +- widget/menu_item_test.go | 2 +- widget/pool_test.go | 6 ++-- widget/popup_test.go | 2 +- widget/radio_group_extended_test.go | 2 +- widget/radio_group_internal_test.go | 2 +- widget/richtext_test.go | 2 +- widget/table.go | 22 +++++++------- widget/textgrid_test.go | 4 +-- widget/tree.go | 8 ++--- widget/tree_internal_test.go | 12 ++++---- 58 files changed, 236 insertions(+), 234 deletions(-) diff --git a/canvas/text_test.go b/canvas/text_test.go index 5af9e76a59..558e6f22c8 100644 --- a/canvas/text_test.go +++ b/canvas/text_test.go @@ -121,7 +121,7 @@ func TestText_Layout(t *testing.T) { }, } { t.Run(name, func(t *testing.T) { - text := canvas.NewText(tt.text, theme.ForegroundColor()) + text := canvas.NewText(tt.text, theme.Color(theme.ColorNameForeground)) text.Alignment = tt.align text.Resize(tt.size) @@ -200,7 +200,7 @@ func TestText_CarriageReturn(t *testing.T) { }, } { t.Run(name, func(t *testing.T) { - text := canvas.NewText(tt.text, theme.ForegroundColor()) + text := canvas.NewText(tt.text, theme.Color(theme.ColorNameForeground)) text.Alignment = tt.align text.Resize(tt.size) diff --git a/cmd/fyne_demo/tutorials/animation.go b/cmd/fyne_demo/tutorials/animation.go index 532c9bad2a..ebda929c92 100644 --- a/cmd/fyne_demo/tutorials/animation.go +++ b/cmd/fyne_demo/tutorials/animation.go @@ -117,7 +117,7 @@ func newThemedBox() *themedBox { func (b *themedBox) CreateRenderer() fyne.WidgetRenderer { b.ExtendBaseWidget(b) - bg := canvas.NewRectangle(theme.ForegroundColor()) + bg := canvas.NewRectangle(theme.Color(theme.ColorNameForeground)) return &themedBoxRenderer{bg: bg, objects: []fyne.CanvasObject{bg}} } @@ -142,6 +142,6 @@ func (r *themedBoxRenderer) Objects() []fyne.CanvasObject { } func (r *themedBoxRenderer) Refresh() { - r.bg.FillColor = theme.ForegroundColor() + r.bg.FillColor = theme.Color(theme.ColorNameForeground) r.bg.Refresh() } diff --git a/cmd/fyne_demo/tutorials/icons.go b/cmd/fyne_demo/tutorials/icons.go index d6a258b904..d136737472 100644 --- a/cmd/fyne_demo/tutorials/icons.go +++ b/cmd/fyne_demo/tutorials/icons.go @@ -70,10 +70,10 @@ func checkerPattern(x, y, _, _ int) color.Color { y /= 20 if x%2 == y%2 { - return theme.BackgroundColor() + return theme.Color(theme.ColorNameBackground) } - return theme.ShadowColor() + return theme.Color(theme.ColorNameShadow) } func iconList(icons []iconInfo) []string { diff --git a/cmd/fyne_demo/tutorials/welcome.go b/cmd/fyne_demo/tutorials/welcome.go index 32e3b74ad2..d0600d7980 100644 --- a/cmd/fyne_demo/tutorials/welcome.go +++ b/cmd/fyne_demo/tutorials/welcome.go @@ -50,8 +50,8 @@ func welcomeScreen(_ fyne.Window) fyne.CanvasObject { widget.NewLabelWithStyle("\nWith great thanks to our many kind sponsors\n", fyne.TextAlignCenter, fyne.TextStyle{Italic: true})) scroll := container.NewScroll(content) - bgColor := withAlpha(theme.BackgroundColor(), 0xe0) - shadowColor := withAlpha(theme.BackgroundColor(), 0x33) + bgColor := withAlpha(theme.Color(theme.ColorNameBackground), 0xe0) + shadowColor := withAlpha(theme.Color(theme.ColorNameBackground), 0x33) underlay := canvas.NewImageFromResource(data.FyneLogo) bg := canvas.NewRectangle(bgColor) @@ -63,11 +63,11 @@ func welcomeScreen(_ fyne.Window) fyne.CanvasObject { fyne.CurrentApp().Settings().AddChangeListener(listen) go func() { for range listen { - bgColor = withAlpha(theme.BackgroundColor(), 0xe0) + bgColor = withAlpha(theme.Color(theme.ColorNameBackground), 0xe0) bg.FillColor = bgColor bg.Refresh() - shadowColor = withAlpha(theme.BackgroundColor(), 0x33) + shadowColor = withAlpha(theme.Color(theme.ColorNameBackground), 0x33) footerBG.FillColor = bgColor footer.Refresh() } diff --git a/cmd/fyne_settings/settings/appearance.go b/cmd/fyne_settings/settings/appearance.go index 944441112a..14aaea5f7a 100644 --- a/cmd/fyne_settings/settings/appearance.go +++ b/cmd/fyne_settings/settings/appearance.go @@ -191,7 +191,7 @@ func (c *primaryColorButton) CreateRenderer() fyne.WidgetRenderer { r.StrokeWidth = 5 if c.name == c.s.fyneSettings.PrimaryColor { - r.StrokeColor = theme.PrimaryColor() + r.StrokeColor = theme.Color(theme.ColorNamePrimary) } return &primaryColorButtonRenderer{c: c, rect: r, objs: []fyne.CanvasObject{r}} @@ -222,7 +222,7 @@ func (c *primaryColorButtonRenderer) MinSize() fyne.Size { func (c *primaryColorButtonRenderer) Refresh() { if c.c.name == c.c.s.fyneSettings.PrimaryColor { - c.rect.StrokeColor = theme.PrimaryColor() + c.rect.StrokeColor = theme.Color(theme.ColorNamePrimary) } else { c.rect.StrokeColor = color.Transparent } diff --git a/cmd/fyne_settings/settings/scale.go b/cmd/fyne_settings/settings/scale.go index 6ff98f0a92..ec423084a9 100644 --- a/cmd/fyne_settings/settings/scale.go +++ b/cmd/fyne_settings/settings/scale.go @@ -70,7 +70,7 @@ func (s *Settings) makeScaleGroup(scale float32) *widget.Card { func (s *Settings) makeScalePreviews(value float32) []fyne.CanvasObject { var previews = make([]fyne.CanvasObject, len(scales)) for i, scale := range scales { - text := canvas.NewText("A", theme.ForegroundColor()) + text := canvas.NewText("A", theme.Color(theme.ColorNameForeground)) text.Alignment = fyne.TextAlignCenter text.TextSize = theme.TextSize() * scale.scale / value @@ -83,7 +83,7 @@ func (s *Settings) makeScalePreviews(value float32) []fyne.CanvasObject { func (s *Settings) refreshScalePreviews() { for _, scale := range scales { - scale.preview.Color = theme.ForegroundColor() + scale.preview.Color = theme.Color(theme.ColorNameForeground) } } diff --git a/container/apptabs.go b/container/apptabs.go index 2d659746a1..9becbb065f 100644 --- a/container/apptabs.go +++ b/container/apptabs.go @@ -51,8 +51,8 @@ func (t *AppTabs) CreateRenderer() fyne.WidgetRenderer { r := &appTabsRenderer{ baseTabsRenderer: baseTabsRenderer{ bar: &fyne.Container{}, - divider: canvas.NewRectangle(theme.ShadowColor()), - indicator: canvas.NewRectangle(theme.PrimaryColor()), + divider: canvas.NewRectangle(theme.Color(theme.ColorNameShadow)), + indicator: canvas.NewRectangle(theme.Color(theme.ColorNamePrimary)), }, appTabs: t, } diff --git a/container/apptabs_desktop_test.go b/container/apptabs_desktop_test.go index e7cae471e0..2d57c0dec8 100644 --- a/container/apptabs_desktop_test.go +++ b/container/apptabs_desktop_test.go @@ -92,9 +92,9 @@ func TestAppTabs_DynamicTabs(t *testing.T) { assert.Equal(t, "Test2", tabs.Items[0].Text) test.AssertRendersToMarkup(t, "apptabs/desktop/dynamic_appended_and_removed.xml", c) - tabs.Append(container.NewTabItem("Test3", canvas.NewCircle(theme.BackgroundColor()))) - tabs.Append(container.NewTabItem("Test4", canvas.NewCircle(theme.BackgroundColor()))) - tabs.Append(container.NewTabItem("Test5", canvas.NewCircle(theme.BackgroundColor()))) + tabs.Append(container.NewTabItem("Test3", canvas.NewCircle(theme.Color(theme.ColorNameBackground)))) + tabs.Append(container.NewTabItem("Test4", canvas.NewCircle(theme.Color(theme.ColorNameBackground)))) + tabs.Append(container.NewTabItem("Test5", canvas.NewCircle(theme.Color(theme.ColorNameBackground)))) assert.Equal(t, 4, len(tabs.Items)) assert.Equal(t, "Test3", tabs.Items[1].Text) assert.Equal(t, "Test4", tabs.Items[2].Text) @@ -159,73 +159,73 @@ func TestAppTabs_Layout(t *testing.T) { }{ { name: "top: tab with icon and text", - item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationTop, want: "apptabs/desktop/layout_top_icon_and_text.xml", }, { name: "top: tab with text only", - item: container.NewTabItem("Text2", canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItem("Text2", canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationTop, want: "apptabs/desktop/layout_top_text.xml", }, { name: "top: tab with icon only", - item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationTop, want: "apptabs/desktop/layout_top_icon.xml", }, { name: "bottom: tab with icon and text", - item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationBottom, want: "apptabs/desktop/layout_bottom_icon_and_text.xml", }, { name: "bottom: tab with text only", - item: container.NewTabItem("Text2", canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItem("Text2", canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationBottom, want: "apptabs/desktop/layout_bottom_text.xml", }, { name: "bottom: tab with icon only", - item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationBottom, want: "apptabs/desktop/layout_bottom_icon.xml", }, { name: "leading: tab with icon and text", - item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationLeading, want: "apptabs/desktop/layout_leading_icon_and_text.xml", }, { name: "leading: tab with text only", - item: container.NewTabItem("Text2", canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItem("Text2", canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationLeading, want: "apptabs/desktop/layout_leading_text.xml", }, { name: "leading: tab with icon only", - item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationLeading, want: "apptabs/desktop/layout_leading_icon.xml", }, { name: "trailing: tab with icon and text", - item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationTrailing, want: "apptabs/desktop/layout_trailing_icon_and_text.xml", }, { name: "trailing: tab with text only", - item: container.NewTabItem("Text2", canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItem("Text2", canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationTrailing, want: "apptabs/desktop/layout_trailing_text.xml", }, { name: "trailing: tab with icon only", - item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationTrailing, want: "apptabs/desktop/layout_trailing_icon.xml", }, diff --git a/container/apptabs_extend_test.go b/container/apptabs_extend_test.go index 1f53648823..19b99a9569 100644 --- a/container/apptabs_extend_test.go +++ b/container/apptabs_extend_test.go @@ -35,26 +35,26 @@ func TestAppTabs_Extended_Tapped(t *testing.T) { tab1 := r.bar.Objects[0].(*fyne.Container).Objects[0].(*tabButton) tab2 := r.bar.Objects[0].(*fyne.Container).Objects[1].(*tabButton) require.Equal(t, 0, tabs.SelectedIndex()) - require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.Color(theme.ColorNamePrimary), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) tab2.Tapped(&fyne.PointEvent{}) assert.Equal(t, 1, tabs.SelectedIndex()) - require.Equal(t, theme.ForegroundColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) - require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.Color(theme.ColorNameForeground), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.Color(theme.ColorNamePrimary), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) assert.False(t, tabs.Items[0].Content.Visible()) assert.True(t, tabs.Items[1].Content.Visible()) tab2.Tapped(&fyne.PointEvent{}) assert.Equal(t, 1, tabs.SelectedIndex()) - require.Equal(t, theme.ForegroundColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) - require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.Color(theme.ColorNameForeground), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.Color(theme.ColorNamePrimary), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) assert.False(t, tabs.Items[0].Content.Visible()) assert.True(t, tabs.Items[1].Content.Visible()) tab1.Tapped(&fyne.PointEvent{}) assert.Equal(t, 0, tabs.SelectedIndex()) - require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) - require.Equal(t, theme.ForegroundColor(), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.Color(theme.ColorNamePrimary), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.Color(theme.ColorNameForeground), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) assert.True(t, tabs.Items[0].Content.Visible()) assert.False(t, tabs.Items[1].Content.Visible()) } diff --git a/container/doctabs.go b/container/doctabs.go index 32c26c6cb5..6981800461 100644 --- a/container/doctabs.go +++ b/container/doctabs.go @@ -59,8 +59,8 @@ func (t *DocTabs) CreateRenderer() fyne.WidgetRenderer { r := &docTabsRenderer{ baseTabsRenderer: baseTabsRenderer{ bar: &fyne.Container{}, - divider: canvas.NewRectangle(theme.ShadowColor()), - indicator: canvas.NewRectangle(theme.PrimaryColor()), + divider: canvas.NewRectangle(theme.Color(theme.ColorNameShadow)), + indicator: canvas.NewRectangle(theme.Color(theme.ColorNamePrimary)), }, docTabs: t, scroller: NewScroll(&fyne.Container{}), diff --git a/container/doctabs_desktop_test.go b/container/doctabs_desktop_test.go index b81786cebe..88e6c6ee12 100644 --- a/container/doctabs_desktop_test.go +++ b/container/doctabs_desktop_test.go @@ -138,9 +138,9 @@ func TestDocTabs_DynamicTabs(t *testing.T) { assert.Equal(t, "Test2", tabs.Items[0].Text) test.AssertRendersToMarkup(t, "doctabs/desktop/dynamic_appended_and_removed.xml", c) - tabs.Append(container.NewTabItem("Test3", canvas.NewCircle(theme.BackgroundColor()))) - tabs.Append(container.NewTabItem("Test4", canvas.NewCircle(theme.BackgroundColor()))) - tabs.Append(container.NewTabItem("Test5", canvas.NewCircle(theme.BackgroundColor()))) + tabs.Append(container.NewTabItem("Test3", canvas.NewCircle(theme.Color(theme.ColorNameBackground)))) + tabs.Append(container.NewTabItem("Test4", canvas.NewCircle(theme.Color(theme.ColorNameBackground)))) + tabs.Append(container.NewTabItem("Test5", canvas.NewCircle(theme.Color(theme.ColorNameBackground)))) assert.Equal(t, 4, len(tabs.Items)) assert.Equal(t, "Test3", tabs.Items[1].Text) assert.Equal(t, "Test4", tabs.Items[2].Text) @@ -211,73 +211,73 @@ func TestDocTabs_Layout(t *testing.T) { }{ { name: "top: tab with icon and text", - item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationTop, want: "doctabs/desktop/layout_top_icon_and_text.xml", }, { name: "top: tab with text only", - item: container.NewTabItem("Text2", canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItem("Text2", canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationTop, want: "doctabs/desktop/layout_top_text.xml", }, { name: "top: tab with icon only", - item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationTop, want: "doctabs/desktop/layout_top_icon.xml", }, { name: "bottom: tab with icon and text", - item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationBottom, want: "doctabs/desktop/layout_bottom_icon_and_text.xml", }, { name: "bottom: tab with text only", - item: container.NewTabItem("Text2", canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItem("Text2", canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationBottom, want: "doctabs/desktop/layout_bottom_text.xml", }, { name: "bottom: tab with icon only", - item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationBottom, want: "doctabs/desktop/layout_bottom_icon.xml", }, { name: "leading: tab with icon and text", - item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationLeading, want: "doctabs/desktop/layout_leading_icon_and_text.xml", }, { name: "leading: tab with text only", - item: container.NewTabItem("Text2", canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItem("Text2", canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationLeading, want: "doctabs/desktop/layout_leading_text.xml", }, { name: "leading: tab with icon only", - item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationLeading, want: "doctabs/desktop/layout_leading_icon.xml", }, { name: "trailing: tab with icon and text", - item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("Text1", theme.CancelIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationTrailing, want: "doctabs/desktop/layout_trailing_icon_and_text.xml", }, { name: "trailing: tab with text only", - item: container.NewTabItem("Text2", canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItem("Text2", canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationTrailing, want: "doctabs/desktop/layout_trailing_text.xml", }, { name: "trailing: tab with icon only", - item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.BackgroundColor())), + item: container.NewTabItemWithIcon("", theme.InfoIcon(), canvas.NewCircle(theme.Color(theme.ColorNameBackground))), location: container.TabLocationTrailing, want: "doctabs/desktop/layout_trailing_icon.xml", }, diff --git a/container/doctabs_extend_test.go b/container/doctabs_extend_test.go index 00eb83d9e0..5fdaadfedc 100644 --- a/container/doctabs_extend_test.go +++ b/container/doctabs_extend_test.go @@ -36,26 +36,26 @@ func TestDocTabs_Extended_Tapped(t *testing.T) { tab1 := buttons[0].(*tabButton) tab2 := buttons[1].(*tabButton) require.Equal(t, 0, tabs.SelectedIndex()) - require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.Color(theme.ColorNamePrimary), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) tab2.Tapped(&fyne.PointEvent{}) assert.Equal(t, 1, tabs.SelectedIndex()) - require.Equal(t, theme.ForegroundColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) - require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.Color(theme.ColorNameForeground), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.Color(theme.ColorNamePrimary), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) assert.False(t, tabs.Items[0].Content.Visible()) assert.True(t, tabs.Items[1].Content.Visible()) tab2.Tapped(&fyne.PointEvent{}) assert.Equal(t, 1, tabs.SelectedIndex()) - require.Equal(t, theme.ForegroundColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) - require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.Color(theme.ColorNameForeground), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.Color(theme.ColorNamePrimary), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) assert.False(t, tabs.Items[0].Content.Visible()) assert.True(t, tabs.Items[1].Content.Visible()) tab1.Tapped(&fyne.PointEvent{}) assert.Equal(t, 0, tabs.SelectedIndex()) - require.Equal(t, theme.PrimaryColor(), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) - require.Equal(t, theme.ForegroundColor(), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.Color(theme.ColorNamePrimary), test.TempWidgetRenderer(t, tab1).(*tabButtonRenderer).label.Color) + require.Equal(t, theme.Color(theme.ColorNameForeground), test.TempWidgetRenderer(t, tab2).(*tabButtonRenderer).label.Color) assert.True(t, tabs.Items[0].Content.Visible()) assert.False(t, tabs.Items[1].Content.Visible()) } diff --git a/container/innerwindow.go b/container/innerwindow.go index 2c8d010c10..0597adbf29 100644 --- a/container/innerwindow.go +++ b/container/innerwindow.go @@ -78,8 +78,8 @@ func (w *InnerWindow) CreateRenderer() fyne.WidgetRenderer { title.Truncation = fyne.TextTruncateEllipsis bar := NewBorder(nil, nil, buttons, icon, title) - bg := canvas.NewRectangle(theme.OverlayBackgroundColor()) - contentBG := canvas.NewRectangle(theme.BackgroundColor()) + bg := canvas.NewRectangle(theme.Color(theme.ColorNameOverlayBackground)) + contentBG := canvas.NewRectangle(theme.Color(theme.ColorNameBackground)) corner := newDraggableCorner(w) objects := []fyne.CanvasObject{bg, contentBG, bar, w.content, corner} @@ -154,9 +154,9 @@ func (i *innerWindowRenderer) MinSize() fyne.Size { } func (i *innerWindowRenderer) Refresh() { - i.bg.FillColor = theme.OverlayBackgroundColor() + i.bg.FillColor = theme.Color(theme.ColorNameOverlayBackground) i.bg.Refresh() - i.contentBG.FillColor = theme.BackgroundColor() + i.contentBG.FillColor = theme.Color(theme.ColorNameBackground) i.contentBG.Refresh() i.bar.Refresh() diff --git a/container/split.go b/container/split.go index 158cef328d..5290de5e2c 100644 --- a/container/split.go +++ b/container/split.go @@ -234,8 +234,8 @@ func newDivider(split *Split) *divider { // CreateRenderer is a private method to Fyne which links this widget to its renderer func (d *divider) CreateRenderer() fyne.WidgetRenderer { d.ExtendBaseWidget(d) - background := canvas.NewRectangle(theme.ShadowColor()) - foreground := canvas.NewRectangle(theme.ForegroundColor()) + background := canvas.NewRectangle(theme.Color(theme.ColorNameShadow)) + foreground := canvas.NewRectangle(theme.Color(theme.ColorNameForeground)) return ÷rRenderer{ divider: d, background: background, @@ -342,12 +342,12 @@ func (r *dividerRenderer) Objects() []fyne.CanvasObject { func (r *dividerRenderer) Refresh() { if r.divider.hovered { - r.background.FillColor = theme.HoverColor() + r.background.FillColor = theme.Color(theme.ColorNameHover) } else { - r.background.FillColor = theme.ShadowColor() + r.background.FillColor = theme.Color(theme.ColorNameShadow) } r.background.Refresh() - r.foreground.FillColor = theme.ForegroundColor() + r.foreground.FillColor = theme.Color(theme.ColorNameForeground) r.foreground.Refresh() r.Layout(r.divider.Size()) } diff --git a/container/tabs.go b/container/tabs.go index cc20f99fc4..c8747e49ce 100644 --- a/container/tabs.go +++ b/container/tabs.go @@ -304,8 +304,8 @@ func (r *baseTabsRenderer) applyTheme(t baseTabs) { if r.action != nil { r.action.SetIcon(moreIcon(t)) } - r.divider.FillColor = theme.ShadowColor() - r.indicator.FillColor = theme.PrimaryColor() + r.divider.FillColor = theme.Color(theme.ColorNameShadow) + r.indicator.FillColor = theme.Color(theme.ColorNamePrimary) r.indicator.CornerRadius = theme.SelectionRadiusSize() for _, tab := range r.tabs.items() { @@ -425,7 +425,7 @@ func (r *baseTabsRenderer) moveIndicator(pos fyne.Position, siz fyne.Size, anima r.sizeAnimation = nil } - r.indicator.FillColor = theme.PrimaryColor() + r.indicator.FillColor = theme.Color(theme.ColorNamePrimary) if r.indicator.Position().IsZero() { r.indicator.Move(pos) r.indicator.Resize(siz) @@ -507,7 +507,7 @@ type tabButton struct { func (b *tabButton) CreateRenderer() fyne.WidgetRenderer { b.ExtendBaseWidget(b) - background := canvas.NewRectangle(theme.HoverColor()) + background := canvas.NewRectangle(theme.Color(theme.ColorNameHover)) background.CornerRadius = theme.SelectionRadiusSize() background.Hide() icon := canvas.NewImageFromResource(b.icon) @@ -515,7 +515,7 @@ func (b *tabButton) CreateRenderer() fyne.WidgetRenderer { icon.Hide() } - label := canvas.NewText(b.text, theme.ForegroundColor()) + label := canvas.NewText(b.text, theme.Color(theme.ColorNameForeground)) label.TextStyle.Bold = true close := &tabCloseButton{ @@ -658,7 +658,7 @@ func (r *tabButtonRenderer) Objects() []fyne.CanvasObject { func (r *tabButtonRenderer) Refresh() { if r.button.hovered && !r.button.Disabled() { - r.background.FillColor = theme.HoverColor() + r.background.FillColor = theme.Color(theme.ColorNameHover) r.background.CornerRadius = theme.SelectionRadiusSize() r.background.Show() } else { @@ -670,12 +670,12 @@ func (r *tabButtonRenderer) Refresh() { r.label.Alignment = r.button.textAlignment if !r.button.Disabled() { if r.button.importance == widget.HighImportance { - r.label.Color = theme.PrimaryColor() + r.label.Color = theme.Color(theme.ColorNamePrimary) } else { - r.label.Color = theme.ForegroundColor() + r.label.Color = theme.Color(theme.ColorNameForeground) } } else { - r.label.Color = theme.DisabledColor() + r.label.Color = theme.Color(theme.ColorNameDisabled) } r.label.TextSize = theme.TextSize() if r.button.text == "" { @@ -742,7 +742,7 @@ type tabCloseButton struct { func (b *tabCloseButton) CreateRenderer() fyne.WidgetRenderer { b.ExtendBaseWidget(b) - background := canvas.NewRectangle(theme.HoverColor()) + background := canvas.NewRectangle(theme.Color(theme.ColorNameHover)) background.CornerRadius = theme.SelectionRadiusSize() background.Hide() icon := canvas.NewImageFromResource(theme.CancelIcon()) @@ -804,7 +804,7 @@ func (r *tabCloseButtonRenderer) Objects() []fyne.CanvasObject { func (r *tabCloseButtonRenderer) Refresh() { if r.button.hovered { - r.background.FillColor = theme.HoverColor() + r.background.FillColor = theme.Color(theme.ColorNameHover) r.background.CornerRadius = theme.SelectionRadiusSize() r.background.Show() } else { diff --git a/dialog/base.go b/dialog/base.go index 012a48f223..3105d36ba8 100644 --- a/dialog/base.go +++ b/dialog/base.go @@ -162,7 +162,7 @@ func newThemedBackground() *themedBackground { func (t *themedBackground) CreateRenderer() fyne.WidgetRenderer { t.ExtendBaseWidget(t) - rect := canvas.NewRectangle(theme.OverlayBackgroundColor()) + rect := canvas.NewRectangle(theme.Color(theme.ColorNameOverlayBackground)) return &themedBackgroundRenderer{rect, []fyne.CanvasObject{rect}} } @@ -187,7 +187,7 @@ func (renderer *themedBackgroundRenderer) Objects() []fyne.CanvasObject { } func (renderer *themedBackgroundRenderer) Refresh() { - r, g, b, _ := col.ToNRGBA(theme.OverlayBackgroundColor()) + r, g, b, _ := col.ToNRGBA(theme.Color(theme.ColorNameOverlayBackground)) bg := &color.NRGBA{R: uint8(r), G: uint8(g), B: uint8(b), A: 230} renderer.rect.FillColor = bg } diff --git a/dialog/color.go b/dialog/color.go index bb01af98b7..50a4dfcef1 100644 --- a/dialog/color.go +++ b/dialog/color.go @@ -44,7 +44,7 @@ type ColorPickerDialog struct { func NewColorPicker(title, message string, callback func(c color.Color), parent fyne.Window) *ColorPickerDialog { return &ColorPickerDialog{ dialog: newDialog(title, message, theme.ColorPaletteIcon(), nil /*cancel?*/, parent), - color: theme.PrimaryColor(), + color: theme.Color(theme.ColorNamePrimary), callback: callback, } } @@ -84,8 +84,8 @@ func (p *ColorPickerDialog) Show() { func (p *ColorPickerDialog) createSimplePickers() (contents []fyne.CanvasObject) { contents = append(contents, newColorBasicPicker(p.selectColor), newColorGreyscalePicker(p.selectColor)) if recent := newColorRecentPicker(p.selectColor); len(recent.(*fyne.Container).Objects) > 0 { - // Add divider and recents if there are any - contents = append(contents, canvas.NewLine(theme.ShadowColor()), recent) + // Add divider and recents if there are any, + contents = append(contents, canvas.NewLine(theme.Color(theme.ColorNameShadow)), recent) } return } diff --git a/dialog/color_button.go b/dialog/color_button.go index ad9b72ddef..e75e6e5f32 100644 --- a/dialog/color_button.go +++ b/dialog/color_button.go @@ -103,7 +103,7 @@ func (r *colorButtonRenderer) MinSize() fyne.Size { func (r *colorButtonRenderer) Refresh() { if r.button.hovered { - r.rectangle.StrokeColor = theme.HoverColor() + r.rectangle.StrokeColor = theme.Color(theme.ColorNameHover) r.rectangle.StrokeWidth = theme.Padding() } else { r.rectangle.StrokeWidth = 0 diff --git a/dialog/color_button_test.go b/dialog/color_button_test.go index 356421440f..15966569f3 100644 --- a/dialog/color_button_test.go +++ b/dialog/color_button_test.go @@ -18,10 +18,10 @@ func Test_colorButton_Layout(t *testing.T) { hovered bool }{ "primary": { - color: theme.PrimaryColor(), + color: theme.Color(theme.ColorNamePrimary), }, "primary_hovered": { - color: theme.PrimaryColor(), + color: theme.Color(theme.ColorNamePrimary), hovered: true, }, } { diff --git a/dialog/color_picker_test.go b/dialog/color_picker_test.go index 6d87b9e7e1..ebe692add5 100644 --- a/dialog/color_picker_test.go +++ b/dialog/color_picker_test.go @@ -48,7 +48,7 @@ func Test_colorRecentPicker_Layout(t *testing.T) { func Test_colorAdvancedPicker_Layout(t *testing.T) { test.NewTempApp(t) - color := newColorAdvancedPicker(theme.PrimaryColor(), nil) + color := newColorAdvancedPicker(theme.Color(theme.ColorNamePrimary), nil) color.Refresh() diff --git a/dialog/color_wheel.go b/dialog/color_wheel.go index 8e4f5e9f52..1157b1fa2c 100644 --- a/dialog/color_wheel.go +++ b/dialog/color_wheel.go @@ -200,9 +200,9 @@ func (r *colorWheelRenderer) Refresh() { } else { r.Layout(s) } - r.x.StrokeColor = theme.ForegroundColor() + r.x.StrokeColor = theme.Color(theme.ColorNameForeground) r.x.Refresh() - r.y.StrokeColor = theme.ForegroundColor() + r.y.StrokeColor = theme.Color(theme.ColorNameForeground) r.y.Refresh() r.raster.Refresh() r.background.Refresh() diff --git a/internal/driver/common/canvas_test.go b/internal/driver/common/canvas_test.go index e9398c56fb..578eb5a641 100644 --- a/internal/driver/common/canvas_test.go +++ b/internal/driver/common/canvas_test.go @@ -6,12 +6,13 @@ import ( "image/color" "testing" + "github.com/stretchr/testify/assert" + "fyne.io/fyne/v2" "fyne.io/fyne/v2/canvas" "fyne.io/fyne/v2/container" "fyne.io/fyne/v2/test" "fyne.io/fyne/v2/theme" - "github.com/stretchr/testify/assert" ) func TestCanvas_walkTree(t *testing.T) { @@ -35,7 +36,7 @@ func TestCanvas_walkTree(t *testing.T) { tree := &renderCacheTree{root: &RenderCacheNode{obj: content}} c := &Canvas{} c.Initialize(nil, func() {}) - c.SetContentTreeAndFocusMgr(&canvas.Rectangle{FillColor: theme.BackgroundColor()}) + c.SetContentTreeAndFocusMgr(&canvas.Rectangle{FillColor: theme.Color(theme.ColorNameBackground)}) type nodeInfo struct { obj fyne.CanvasObject diff --git a/internal/driver/glfw/canvas.go b/internal/driver/glfw/canvas.go index ec9c1ae655..62583fc886 100644 --- a/internal/driver/glfw/canvas.go +++ b/internal/driver/glfw/canvas.go @@ -340,6 +340,6 @@ func (c *glCanvas) applyThemeOutOfTreeObjects() { func newCanvas() *glCanvas { c := &glCanvas{scale: 1.0, texScale: 1.0, padded: true} c.Initialize(c, c.overlayChanged) - c.setContent(&canvas.Rectangle{FillColor: theme.BackgroundColor()}) + c.setContent(&canvas.Rectangle{FillColor: theme.Color(theme.ColorNameBackground)}) return c } diff --git a/internal/driver/glfw/menu_bar.go b/internal/driver/glfw/menu_bar.go index 2c5cb9714f..9d3b6f223f 100644 --- a/internal/driver/glfw/menu_bar.go +++ b/internal/driver/glfw/menu_bar.go @@ -39,7 +39,7 @@ func NewMenuBar(mainMenu *fyne.MainMenu, canvas fyne.Canvas) *MenuBar { // Implements: fyne.Widget func (b *MenuBar) CreateRenderer() fyne.WidgetRenderer { cont := container.NewHBox(b.Items...) - background := canvas.NewRectangle(theme.BackgroundColor()) + background := canvas.NewRectangle(theme.Color(theme.ColorNameBackground)) underlay := &menuBarUnderlay{action: b.deactivate} underlay.ExtendBaseWidget(underlay) objects := []fyne.CanvasObject{underlay, background, cont} @@ -158,7 +158,7 @@ func (r *menuBarRenderer) MinSize() fyne.Size { func (r *menuBarRenderer) Refresh() { r.Layout(r.b.Size()) - r.background.FillColor = theme.BackgroundColor() + r.background.FillColor = theme.Color(theme.ColorNameBackground) r.background.Refresh() r.ShadowingRenderer.RefreshShadow() canvas.Refresh(r.b) diff --git a/internal/driver/glfw/menu_bar_item.go b/internal/driver/glfw/menu_bar_item.go index bfc8ad5042..172b9da7a0 100644 --- a/internal/driver/glfw/menu_bar_item.go +++ b/internal/driver/glfw/menu_bar_item.go @@ -38,10 +38,10 @@ func (i *menuBarItem) Child() *publicWidget.Menu { // // Implements: fyne.Widget func (i *menuBarItem) CreateRenderer() fyne.WidgetRenderer { - background := canvas.NewRectangle(theme.HoverColor()) + background := canvas.NewRectangle(theme.Color(theme.ColorNameHover)) background.CornerRadius = theme.SelectionRadiusSize() background.Hide() - text := canvas.NewText(i.Menu.Label, theme.ForegroundColor()) + text := canvas.NewText(i.Menu.Label, theme.Color(theme.ColorNameForeground)) objects := []fyne.CanvasObject{background, text} return &menuBarItemRenderer{ @@ -149,7 +149,7 @@ func (r *menuBarItemRenderer) Layout(size fyne.Size) { padding := r.padding() r.text.TextSize = theme.TextSize() - r.text.Color = theme.ForegroundColor() + r.text.Color = theme.Color(theme.ColorNameForeground) r.text.Resize(r.text.MinSize()) r.text.Move(fyne.NewPos(padding.Width/2, padding.Height/2)) @@ -163,10 +163,10 @@ func (r *menuBarItemRenderer) MinSize() fyne.Size { func (r *menuBarItemRenderer) Refresh() { r.background.CornerRadius = theme.SelectionRadiusSize() if r.i.active && r.i.Parent.active { - r.background.FillColor = theme.FocusColor() + r.background.FillColor = theme.Color(theme.ColorNameFocus) r.background.Show() } else if r.i.hovered && !r.i.Parent.active { - r.background.FillColor = theme.HoverColor() + r.background.FillColor = theme.Color(theme.ColorNameHover) r.background.Show() } else { r.background.Hide() diff --git a/internal/driver/mobile/driver.go b/internal/driver/mobile/driver.go index 9d8e5c3c75..017730b89c 100644 --- a/internal/driver/mobile/driver.go +++ b/internal/driver/mobile/driver.go @@ -73,7 +73,7 @@ func (d *driver) CreateWindow(title string) fyne.Window { ret := &window{title: title, canvas: c, isChild: len(d.windows) > 0} ret.InitEventQueue() go ret.RunEventQueue() - c.setContent(&fynecanvas.Rectangle{FillColor: theme.BackgroundColor()}) + c.setContent(&fynecanvas.Rectangle{FillColor: theme.Color(theme.ColorNameBackground)}) c.SetPainter(pgl.NewPainter(c, ret)) d.windows = append(d.windows, ret) return ret @@ -307,7 +307,7 @@ func (d *driver) paintWindow(window fyne.Window, size fyne.Size) { clips := &internal.ClipStack{} c := window.Canvas().(*canvas) - r, g, b, a := theme.BackgroundColor().RGBA() + r, g, b, a := theme.Color(theme.ColorNameBackground).RGBA() max16bit := float32(255 * 255) d.glctx.ClearColor(float32(r)/max16bit, float32(g)/max16bit, float32(b)/max16bit, float32(a)/max16bit) d.glctx.Clear(gl.ColorBufferBit) diff --git a/internal/driver/mobile/menu.go b/internal/driver/mobile/menu.go index 3ca0b604d1..cc446c94ce 100644 --- a/internal/driver/mobile/menu.go +++ b/internal/driver/mobile/menu.go @@ -59,8 +59,8 @@ func (c *canvas) showMenu(menu *fyne.MainMenu) { panel = container.NewPadded(panel) } - bg := fynecanvas.NewRectangle(theme.BackgroundColor()) - shadow := fynecanvas.NewHorizontalGradient(theme.ShadowColor(), color.Transparent) + bg := fynecanvas.NewRectangle(theme.Color(theme.ColorNameBackground)) + shadow := fynecanvas.NewHorizontalGradient(theme.Color(theme.ColorNameShadow), color.Transparent) safePos, safeSize := c.InteractiveArea() bg.Move(safePos) @@ -102,7 +102,7 @@ type menuLabelRenderer struct { } func (m *menuLabelRenderer) BackgroundColor() color.Color { - return theme.BackgroundColor() + return theme.Color(theme.ColorNameBackground) } func (m *menuLabelRenderer) Destroy() { diff --git a/internal/driver/mobile/menu_test.go b/internal/driver/mobile/menu_test.go index 3b2527b98d..c37108c48f 100644 --- a/internal/driver/mobile/menu_test.go +++ b/internal/driver/mobile/menu_test.go @@ -16,7 +16,7 @@ import ( func TestMobileCanvas_DismissBar(t *testing.T) { c := newCanvas(fyne.CurrentDevice()).(*canvas) - c.SetContent(fynecanvas.NewRectangle(theme.BackgroundColor())) + c.SetContent(fynecanvas.NewRectangle(theme.Color(theme.ColorNameBackground))) menu := fyne.NewMainMenu( fyne.NewMenu("Test")) c.showMenu(menu) @@ -32,7 +32,7 @@ func TestMobileCanvas_DismissBar(t *testing.T) { func TestMobileCanvas_DismissMenu(t *testing.T) { c := newCanvas(fyne.CurrentDevice()).(*canvas) c.padded = false - c.SetContent(fynecanvas.NewRectangle(theme.BackgroundColor())) + c.SetContent(fynecanvas.NewRectangle(theme.Color(theme.ColorNameBackground))) menu := fyne.NewMainMenu( fyne.NewMenu("Test", fyne.NewMenuItem("TapMe", func() {}))) c.showMenu(menu) diff --git a/internal/driver/mobile/menubutton.go b/internal/driver/mobile/menubutton.go index 2eb8ec9101..923f76eddf 100644 --- a/internal/driver/mobile/menubutton.go +++ b/internal/driver/mobile/menubutton.go @@ -22,7 +22,7 @@ func (w *window) newMenuButton(menu *fyne.MainMenu) *menuButton { func (m *menuButton) CreateRenderer() fyne.WidgetRenderer { return &menuButtonRenderer{btn: widget.NewButtonWithIcon("", theme.MenuIcon(), func() { m.win.canvas.showMenu(m.menu) - }), bg: fynecanvas.NewRectangle(theme.BackgroundColor())} + }), bg: fynecanvas.NewRectangle(theme.Color(theme.ColorNameBackground))} } type menuButtonRenderer struct { @@ -48,5 +48,5 @@ func (m *menuButtonRenderer) Objects() []fyne.CanvasObject { } func (m *menuButtonRenderer) Refresh() { - m.bg.FillColor = theme.BackgroundColor() + m.bg.FillColor = theme.Color(theme.ColorNameBackground) } diff --git a/internal/painter/gl/painter.go b/internal/painter/gl/painter.go index 314fa6442e..39619e9db8 100644 --- a/internal/painter/gl/painter.go +++ b/internal/painter/gl/painter.go @@ -78,7 +78,7 @@ type painter struct { var _ Painter = (*painter)(nil) func (p *painter) Clear() { - r, g, b, a := theme.BackgroundColor().RGBA() + r, g, b, a := theme.Color(theme.ColorNameBackground).RGBA() p.ctx.ClearColor(float32(r)/max16bit, float32(g)/max16bit, float32(b)/max16bit, float32(a)/max16bit) p.ctx.Clear(bitColorBuffer | bitDepthBuffer) p.logError() diff --git a/internal/painter/gl/texture.go b/internal/painter/gl/texture.go index 5989dcd2aa..f864e00f20 100644 --- a/internal/painter/gl/texture.go +++ b/internal/painter/gl/texture.go @@ -145,7 +145,7 @@ func (p *painter) newGlTextTexture(obj fyne.CanvasObject) Texture { text := obj.(*canvas.Text) color := text.Color if color == nil { - color = theme.ForegroundColor() + color = theme.Color(theme.ColorNameForeground) } bounds := text.MinSize() diff --git a/internal/painter/software/draw.go b/internal/painter/software/draw.go index 9b246177b3..bd81c0b50a 100644 --- a/internal/painter/software/draw.go +++ b/internal/painter/software/draw.go @@ -139,7 +139,7 @@ func drawText(c fyne.Canvas, text *canvas.Text, pos fyne.Position, base *image.N color := text.Color if color == nil { - color = theme.ForegroundColor() + color = theme.Color(theme.ColorNameForeground) } face := painter.CachedFontFace(text.TextStyle, text.FontSource, text) diff --git a/internal/painter/software/painter_test.go b/internal/painter/software/painter_test.go index dccbecad5d..57eb1f5c4d 100644 --- a/internal/painter/software/painter_test.go +++ b/internal/painter/software/painter_test.go @@ -352,7 +352,7 @@ func TestPainter_paintText_clipped(t *testing.T) { func TestPainter_paintText_boldItalicClip(t *testing.T) { test.ApplyTheme(t, test.Theme()) - text := canvas.NewText("Dd", theme.ForegroundColor()) + text := canvas.NewText("Dd", theme.Color(theme.ColorNameForeground)) text.TextStyle.Bold = true text.TextStyle.Italic = true text.TextSize = 42 @@ -367,7 +367,7 @@ func TestPainter_paintText_boldItalicClip(t *testing.T) { func TestPainter_paintText_scale2(t *testing.T) { test.ApplyTheme(t, test.Theme()) - text := canvas.NewText("scale2", theme.ForegroundColor()) + text := canvas.NewText("scale2", theme.Color(theme.ColorNameForeground)) text.TextSize = 18 c := test.NewCanvas() c.SetPadded(false) diff --git a/internal/widget/scroller.go b/internal/widget/scroller.go index fafd478697..e7a79951d0 100644 --- a/internal/widget/scroller.go +++ b/internal/widget/scroller.go @@ -50,7 +50,7 @@ func (r *scrollBarRenderer) MinSize() fyne.Size { } func (r *scrollBarRenderer) Refresh() { - r.background.FillColor = theme.ScrollBarColor() + r.background.FillColor = theme.Color(theme.ColorNameScrollBar) r.background.Refresh() } @@ -67,7 +67,7 @@ type scrollBar struct { } func (b *scrollBar) CreateRenderer() fyne.WidgetRenderer { - background := canvas.NewRectangle(theme.ScrollBarColor()) + background := canvas.NewRectangle(theme.Color(theme.ColorNameScrollBar)) r := &scrollBarRenderer{ scrollBar: b, background: background, diff --git a/internal/widget/shadow.go b/internal/widget/shadow.go index 86ba4f3620..509cef55f9 100644 --- a/internal/widget/shadow.go +++ b/internal/widget/shadow.go @@ -117,34 +117,34 @@ func (r *shadowRenderer) Refresh() { func (r *shadowRenderer) createShadows() { switch r.s.typ { case ShadowLeft: - r.l = canvas.NewHorizontalGradient(color.Transparent, theme.ShadowColor()) + r.l = canvas.NewHorizontalGradient(color.Transparent, theme.Color(theme.ColorNameShadow)) r.SetObjects([]fyne.CanvasObject{r.l}) case ShadowRight: - r.r = canvas.NewHorizontalGradient(theme.ShadowColor(), color.Transparent) + r.r = canvas.NewHorizontalGradient(theme.Color(theme.ColorNameShadow), color.Transparent) r.SetObjects([]fyne.CanvasObject{r.r}) case ShadowBottom: - r.b = canvas.NewVerticalGradient(theme.ShadowColor(), color.Transparent) + r.b = canvas.NewVerticalGradient(theme.Color(theme.ColorNameShadow), color.Transparent) r.SetObjects([]fyne.CanvasObject{r.b}) case ShadowTop: - r.t = canvas.NewVerticalGradient(color.Transparent, theme.ShadowColor()) + r.t = canvas.NewVerticalGradient(color.Transparent, theme.Color(theme.ColorNameShadow)) r.SetObjects([]fyne.CanvasObject{r.t}) case ShadowAround: - r.tl = canvas.NewRadialGradient(theme.ShadowColor(), color.Transparent) + r.tl = canvas.NewRadialGradient(theme.Color(theme.ColorNameShadow), color.Transparent) r.tl.CenterOffsetX = 0.5 r.tl.CenterOffsetY = 0.5 - r.t = canvas.NewVerticalGradient(color.Transparent, theme.ShadowColor()) - r.tr = canvas.NewRadialGradient(theme.ShadowColor(), color.Transparent) + r.t = canvas.NewVerticalGradient(color.Transparent, theme.Color(theme.ColorNameShadow)) + r.tr = canvas.NewRadialGradient(theme.Color(theme.ColorNameShadow), color.Transparent) r.tr.CenterOffsetX = -0.5 r.tr.CenterOffsetY = 0.5 - r.r = canvas.NewHorizontalGradient(theme.ShadowColor(), color.Transparent) - r.br = canvas.NewRadialGradient(theme.ShadowColor(), color.Transparent) + r.r = canvas.NewHorizontalGradient(theme.Color(theme.ColorNameShadow), color.Transparent) + r.br = canvas.NewRadialGradient(theme.Color(theme.ColorNameShadow), color.Transparent) r.br.CenterOffsetX = -0.5 r.br.CenterOffsetY = -0.5 - r.b = canvas.NewVerticalGradient(theme.ShadowColor(), color.Transparent) - r.bl = canvas.NewRadialGradient(theme.ShadowColor(), color.Transparent) + r.b = canvas.NewVerticalGradient(theme.Color(theme.ColorNameShadow), color.Transparent) + r.bl = canvas.NewRadialGradient(theme.Color(theme.ColorNameShadow), color.Transparent) r.bl.CenterOffsetX = 0.5 r.bl.CenterOffsetY = -0.5 - r.l = canvas.NewHorizontalGradient(color.Transparent, theme.ShadowColor()) + r.l = canvas.NewHorizontalGradient(color.Transparent, theme.Color(theme.ColorNameShadow)) r.SetObjects([]fyne.CanvasObject{r.tl, r.t, r.tr, r.r, r.br, r.b, r.bl, r.l}) } } @@ -166,7 +166,7 @@ func updateShadowEnd(g *canvas.LinearGradient) { return } - g.EndColor = theme.ShadowColor() + g.EndColor = theme.Color(theme.ColorNameShadow) g.Refresh() } @@ -175,7 +175,7 @@ func updateShadowRadial(g *canvas.RadialGradient) { return } - g.StartColor = theme.ShadowColor() + g.StartColor = theme.Color(theme.ColorNameShadow) g.Refresh() } @@ -184,6 +184,6 @@ func updateShadowStart(g *canvas.LinearGradient) { return } - g.StartColor = theme.ShadowColor() + g.StartColor = theme.Color(theme.ColorNameShadow) g.Refresh() } diff --git a/test/canvas.go b/test/canvas.go index d4c7c07458..193f3ef0d1 100644 --- a/test/canvas.go +++ b/test/canvas.go @@ -93,7 +93,7 @@ func (c *canvas) Capture() image.Image { bounds := image.Rect(0, 0, scale.ToScreenCoordinate(c, size.Width), scale.ToScreenCoordinate(c, size.Height)) img := image.NewNRGBA(bounds) if !c.transparent { - draw.Draw(img, bounds, image.NewUniform(theme.BackgroundColor()), image.Point{}, draw.Src) + draw.Draw(img, bounds, image.NewUniform(theme.Color(theme.ColorNameBackground)), image.Point{}, draw.Src) } if c.painter != nil { diff --git a/test/canvas_test.go b/test/canvas_test.go index c232c609e5..84d9d34a55 100644 --- a/test/canvas_test.go +++ b/test/canvas_test.go @@ -18,7 +18,7 @@ func Test_canvas_Capture(t *testing.T) { assert.True(t, img.Bounds().Size().X > 0) assert.True(t, img.Bounds().Size().Y > 0) - r1, g1, b1, a1 := theme.BackgroundColor().RGBA() + r1, g1, b1, a1 := theme.Color(theme.ColorNameBackground).RGBA() r2, g2, b2, a2 := img.At(1, 1).RGBA() assert.Equal(t, r1, r2) assert.Equal(t, g1, g2) diff --git a/test/markup_renderer.go b/test/markup_renderer.go index d3da0c163d..882380651b 100644 --- a/test/markup_renderer.go +++ b/test/markup_renderer.go @@ -360,7 +360,7 @@ func (r *markupRenderer) writeTag(name string, isEmpty bool, attrs map[string]*s } func (r *markupRenderer) writeText(t *fynecanvas.Text, attrs map[string]*string) { - r.setColorAttrWithDefault(attrs, "color", t.Color, theme.ForegroundColor()) + r.setColorAttrWithDefault(attrs, "color", t.Color, theme.Color(theme.ColorNameForeground)) r.setAlignmentAttr(attrs, "alignment", t.Alignment) r.setSizeAttrWithDefault(attrs, "textSize", t.TextSize, theme.TextSize()) r.setBoolAttr(attrs, "bold", t.TextStyle.Bold) @@ -386,32 +386,32 @@ func nrgbaColor(c color.Color) color.NRGBA { func knownColor(c color.Color) string { return map[color.Color]string{ - nrgbaColor(theme.BackgroundColor()): "background", - nrgbaColor(theme.ButtonColor()): "button", - nrgbaColor(theme.DisabledButtonColor()): "disabled button", - nrgbaColor(theme.DisabledColor()): "disabled", - nrgbaColor(theme.ErrorColor()): "error", - nrgbaColor(theme.FocusColor()): "focus", - nrgbaColor(theme.ForegroundColor()): "foreground", + nrgbaColor(theme.Color(theme.ColorNameBackground)): "background", + nrgbaColor(theme.Color(theme.ColorNameButton)): "button", + nrgbaColor(theme.Color(theme.ColorNameDisabledButton)): "disabled button", + nrgbaColor(theme.Color(theme.ColorNameDisabled)): "disabled", + nrgbaColor(theme.Color(theme.ColorNameError)): "error", + nrgbaColor(theme.Color(theme.ColorNameFocus)): "focus", + nrgbaColor(theme.Color(theme.ColorNameForeground)): "foreground", nrgbaColor(theme.Color(theme.ColorNameForegroundOnError)): "foregroundOnError", nrgbaColor(theme.Color(theme.ColorNameForegroundOnPrimary)): "foregroundOnPrimary", nrgbaColor(theme.Color(theme.ColorNameForegroundOnSuccess)): "foregroundOnSuccess", nrgbaColor(theme.Color(theme.ColorNameForegroundOnWarning)): "foregroundOnWarning", nrgbaColor(theme.Color(theme.ColorNameHeaderBackground)): "headerBackground", - nrgbaColor(theme.HoverColor()): "hover", + nrgbaColor(theme.Color(theme.ColorNameHover)): "hover", nrgbaColor(theme.Color(theme.ColorNameHyperlink)): "hyperlink", - nrgbaColor(theme.InputBackgroundColor()): "inputBackground", - nrgbaColor(theme.InputBorderColor()): "inputBorder", - nrgbaColor(theme.MenuBackgroundColor()): "menuBackground", - nrgbaColor(theme.OverlayBackgroundColor()): "overlayBackground", - nrgbaColor(theme.PlaceHolderColor()): "placeholder", + nrgbaColor(theme.Color(theme.ColorNameInputBackground)): "inputBackground", + nrgbaColor(theme.Color(theme.ColorNameInputBorder)): "inputBorder", + nrgbaColor(theme.Color(theme.ColorNameMenuBackground)): "menuBackground", + nrgbaColor(theme.Color(theme.ColorNameOverlayBackground)): "overlayBackground", + nrgbaColor(theme.Color(theme.ColorNamePlaceHolder)): "placeholder", nrgbaColor(theme.Color(theme.ColorNamePressed)): "pressed", - nrgbaColor(theme.PrimaryColor()): "primary", - nrgbaColor(theme.ScrollBarColor()): "scrollbar", - nrgbaColor(theme.SelectionColor()): "selection", + nrgbaColor(theme.Color(theme.ColorNamePrimary)): "primary", + nrgbaColor(theme.Color(theme.ColorNameScrollBar)): "scrollbar", + nrgbaColor(theme.Color(theme.ColorNameSelection)): "selection", nrgbaColor(theme.Color(theme.ColorNameSeparator)): "separator", nrgbaColor(theme.Color(theme.ColorNameSuccess)): "success", - nrgbaColor(theme.ShadowColor()): "shadow", + nrgbaColor(theme.Color(theme.ColorNameShadow)): "shadow", nrgbaColor(theme.Color(theme.ColorNameWarning)): "warning", }[nrgbaColor(c)] } diff --git a/test/markup_renderer_test.go b/test/markup_renderer_test.go index bce4c61405..d2f3ae91e0 100644 --- a/test/markup_renderer_test.go +++ b/test/markup_renderer_test.go @@ -41,7 +41,7 @@ func Test_snapshot(t *testing.T) { "\n", }, "circle with theme color": { // we won’t test _all_ valid values … it’s not that important - content: fynecanvas.NewCircle(theme.ScrollBarColor()), + content: fynecanvas.NewCircle(theme.Color(theme.ColorNameScrollBar)), want: "\n" + "\t\n" + "\t\t\n" + @@ -52,7 +52,7 @@ func Test_snapshot(t *testing.T) { content: func() fyne.CanvasObject { c := fynecanvas.NewCircle(color.NRGBA{R: 200, G: 100, B: 0, A: 50}) c.StrokeWidth = 3 - c.StrokeColor = theme.BackgroundColor() + c.StrokeColor = theme.Color(theme.ColorNameBackground) return c }(), size: fyne.NewSize(42, 42), @@ -205,7 +205,7 @@ func Test_snapshot(t *testing.T) { "\n", }, "line with theme color": { // we won’t test _all_ valid values … it’s not that important - content: fynecanvas.NewLine(theme.ShadowColor()), + content: fynecanvas.NewLine(theme.Color(theme.ColorNameShadow)), want: "\n" + "\t\n" + "\t\t\n" + @@ -227,7 +227,7 @@ func Test_snapshot(t *testing.T) { "\n", }, "linear gradient": { - content: fynecanvas.NewLinearGradient(color.NRGBA{R: 1, G: 2, B: 3, A: 4}, theme.DisabledColor(), 13.25), + content: fynecanvas.NewLinearGradient(color.NRGBA{R: 1, G: 2, B: 3, A: 4}, theme.Color(theme.ColorNameDisabled), 13.25), pos: fyne.NewPos(6, 13), size: fyne.NewSize(50, 10), want: "\n" + @@ -237,7 +237,7 @@ func Test_snapshot(t *testing.T) { "\n", }, "radial gradient": { - content: fynecanvas.NewRadialGradient(color.NRGBA{R: 1, G: 2, B: 3, A: 4}, theme.DisabledColor()), + content: fynecanvas.NewRadialGradient(color.NRGBA{R: 1, G: 2, B: 3, A: 4}, theme.Color(theme.ColorNameDisabled)), want: "\n" + "\t\n" + "\t\t\n" + @@ -246,7 +246,7 @@ func Test_snapshot(t *testing.T) { }, "radial gradient with offset": { content: func() fyne.CanvasObject { - g := fynecanvas.NewRadialGradient(color.NRGBA{R: 1, G: 2, B: 3, A: 4}, theme.DisabledColor()) + g := fynecanvas.NewRadialGradient(color.NRGBA{R: 1, G: 2, B: 3, A: 4}, theme.Color(theme.ColorNameDisabled)) g.CenterOffsetX = 1.5 g.CenterOffsetY = -13.7 return g @@ -276,7 +276,7 @@ func Test_snapshot(t *testing.T) { "\n", }, "rectangle with theme color": { // we won’t test _all_ valid values … it’s not that important - content: fynecanvas.NewRectangle(theme.HoverColor()), + content: fynecanvas.NewRectangle(theme.Color(theme.ColorNameHover)), want: "\n" + "\t\n" + "\t\t\n" + @@ -287,7 +287,7 @@ func Test_snapshot(t *testing.T) { content: func() fyne.CanvasObject { r := fynecanvas.NewRectangle(color.NRGBA{R: 200, G: 100, B: 0, A: 50}) r.StrokeWidth = 6.375 - r.StrokeColor = theme.PlaceHolderColor() + r.StrokeColor = theme.Color(theme.ColorNamePlaceHolder) return r }(), size: fyne.NewSize(42, 42), @@ -309,7 +309,7 @@ func Test_snapshot(t *testing.T) { "\n", }, "text with theme color": { - content: fynecanvas.NewText("bar", theme.ForegroundColor()), + content: fynecanvas.NewText("bar", theme.Color(theme.ColorNameForeground)), want: "\n" + "\t\n" + "\t\tbar\n" + @@ -318,7 +318,7 @@ func Test_snapshot(t *testing.T) { }, "text with alignment center": { content: func() fyne.CanvasObject { - t := fynecanvas.NewText("bar", theme.ForegroundColor()) + t := fynecanvas.NewText("bar", theme.Color(theme.ColorNameForeground)) t.Alignment = fyne.TextAlignCenter return t }(), @@ -330,7 +330,7 @@ func Test_snapshot(t *testing.T) { }, "text with alignment trailing": { content: func() fyne.CanvasObject { - txt := fynecanvas.NewText("bar", theme.ForegroundColor()) + txt := fynecanvas.NewText("bar", theme.Color(theme.ColorNameForeground)) txt.Alignment = fyne.TextAlignTrailing return txt }(), @@ -342,7 +342,7 @@ func Test_snapshot(t *testing.T) { }, "text with size": { content: func() fyne.CanvasObject { - txt := fynecanvas.NewText("big", theme.ForegroundColor()) + txt := fynecanvas.NewText("big", theme.Color(theme.ColorNameForeground)) txt.TextSize = 42 return txt }(), @@ -354,7 +354,7 @@ func Test_snapshot(t *testing.T) { }, "text bold": { content: func() fyne.CanvasObject { - txt := fynecanvas.NewText("bold", theme.ForegroundColor()) + txt := fynecanvas.NewText("bold", theme.Color(theme.ColorNameForeground)) txt.TextStyle.Bold = true return txt }(), @@ -366,7 +366,7 @@ func Test_snapshot(t *testing.T) { }, "text italic": { content: func() fyne.CanvasObject { - txt := fynecanvas.NewText("italic", theme.ForegroundColor()) + txt := fynecanvas.NewText("italic", theme.Color(theme.ColorNameForeground)) txt.TextStyle.Italic = true return txt }(), @@ -378,7 +378,7 @@ func Test_snapshot(t *testing.T) { }, "text monospace": { content: func() fyne.CanvasObject { - txt := fynecanvas.NewText("mono", theme.ForegroundColor()) + txt := fynecanvas.NewText("mono", theme.Color(theme.ColorNameForeground)) txt.TextStyle.Monospace = true return txt }(), diff --git a/widget/button_internal_test.go b/widget/button_internal_test.go index ba86b6411c..6c00cb25d0 100644 --- a/widget/button_internal_test.go +++ b/widget/button_internal_test.go @@ -38,7 +38,7 @@ func TestButton_DisabledColor(t *testing.T) { button.Disable() render.applyTheme() - assert.Equal(t, theme.DisabledButtonColor(), render.background.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameDisabledButton), render.background.FillColor) } func TestButton_Hover_Math(t *testing.T) { @@ -58,12 +58,12 @@ func TestButton_Hover_Math(t *testing.T) { // We're going to call ToNRGBA instead (which returns 8-bit components), use the unpremultiplied over operator, // store the result in an NRGBA, then convert what buttonColor() returns to an nrgba and compare. - bg := theme.ButtonColor() + bg := theme.Color(theme.ColorNameButton) if render.button.Importance == HighImportance { - bg = theme.PrimaryColor() + bg = theme.Color(theme.ColorNamePrimary) } dstR, dstG, dstB, dstA := col.ToNRGBA(bg) - srcR, srcG, srcB, srcA := col.ToNRGBA(theme.HoverColor()) + srcR, srcG, srcB, srcA := col.ToNRGBA(theme.Color(theme.ColorNameHover)) srcAlpha := float32(srcA) / 0xFF dstAlpha := float32(dstA) / 0xFF @@ -144,19 +144,19 @@ func TestButton_Focus(t *testing.T) { }) render := test.TempWidgetRenderer(t, button).(*buttonRenderer) render.applyTheme() - assert.Equal(t, theme.ButtonColor(), render.background.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameButton), render.background.FillColor) assert.Equal(t, false, tapped) button.FocusGained() render.Refresh() // force update without waiting - assert.Equal(t, blendColor(theme.ButtonColor(), theme.FocusColor()), render.background.FillColor) + assert.Equal(t, blendColor(theme.Color(theme.ColorNameButton), theme.Color(theme.ColorNameFocus)), render.background.FillColor) button.TypedKey(&fyne.KeyEvent{Name: fyne.KeySpace}) assert.Equal(t, true, tapped) button.FocusLost() render.applyTheme() - assert.Equal(t, theme.ButtonColor(), render.background.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameButton), render.background.FillColor) } func TestButtonRenderer_Layout(t *testing.T) { diff --git a/widget/check_internal_test.go b/widget/check_internal_test.go index 49014b0fd7..7b18b835be 100644 --- a/widget/check_internal_test.go +++ b/widget/check_internal_test.go @@ -143,7 +143,7 @@ func TestCheck_Focused(t *testing.T) { assert.False(t, check.focused) } else { assert.True(t, check.focused) - assert.Equal(t, theme.FocusColor(), render.focusIndicator.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameFocus), render.focusIndicator.FillColor) } check.Disable() @@ -176,12 +176,12 @@ func TestCheck_Hovered(t *testing.T) { check.MouseIn(&desktop.MouseEvent{}) assert.True(t, check.hovered) - assert.Equal(t, theme.HoverColor(), render.focusIndicator.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameHover), render.focusIndicator.FillColor) test.Tap(check) assert.True(t, check.hovered) if !fyne.CurrentDevice().IsMobile() { - assert.Equal(t, theme.FocusColor(), render.focusIndicator.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameFocus), render.focusIndicator.FillColor) } check.Disable() @@ -192,9 +192,9 @@ func TestCheck_Hovered(t *testing.T) { check.Enable() assert.True(t, check.hovered) if fyne.CurrentDevice().IsMobile() { - assert.Equal(t, theme.HoverColor(), render.focusIndicator.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameHover), render.focusIndicator.FillColor) } else { - assert.Equal(t, theme.FocusColor(), render.focusIndicator.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameFocus), render.focusIndicator.FillColor) } check.MouseOut() @@ -202,7 +202,7 @@ func TestCheck_Hovered(t *testing.T) { if fyne.CurrentDevice().IsMobile() { assert.Equal(t, color.Transparent, render.focusIndicator.FillColor) } else { - assert.Equal(t, theme.FocusColor(), render.focusIndicator.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameFocus), render.focusIndicator.FillColor) } check.FocusLost() diff --git a/widget/entry_cursor_anim.go b/widget/entry_cursor_anim.go index 3380ea10e5..252d7b28b0 100644 --- a/widget/entry_cursor_anim.go +++ b/widget/entry_cursor_anim.go @@ -33,8 +33,8 @@ func newEntryCursorAnimation(cursor *canvas.Rectangle) *entryCursorAnimation { // creates fyne animation func (a *entryCursorAnimation) createAnim(inverted bool) *fyne.Animation { - cursorOpaque := theme.PrimaryColor() - ri, gi, bi, ai := col.ToNRGBA(theme.PrimaryColor()) + cursorOpaque := theme.Color(theme.ColorNamePrimary) + ri, gi, bi, ai := col.ToNRGBA(cursorOpaque) r := uint8(ri >> 8) g := uint8(gi >> 8) b := uint8(bi >> 8) diff --git a/widget/entry_cursor_anim_test.go b/widget/entry_cursor_anim_test.go index 587f2d4b2f..3c7009d298 100644 --- a/widget/entry_cursor_anim_test.go +++ b/widget/entry_cursor_anim_test.go @@ -6,16 +6,17 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + "fyne.io/fyne/v2/canvas" col "fyne.io/fyne/v2/internal/color" _ "fyne.io/fyne/v2/test" "fyne.io/fyne/v2/theme" - "github.com/stretchr/testify/assert" ) func TestEntryCursorAnim(t *testing.T) { - cursorOpaque := theme.PrimaryColor() - r, g, b, _ := col.ToNRGBA(theme.PrimaryColor()) + cursorOpaque := theme.Color(theme.ColorNamePrimary) + r, g, b, _ := col.ToNRGBA(cursorOpaque) cursorDim := color.NRGBA{R: uint8(r), G: uint8(g), B: uint8(b), A: 0x16} alphaEquals := func(color1, color2 color.Color) bool { diff --git a/widget/gridwrap.go b/widget/gridwrap.go index d80f14e639..858d483fe0 100644 --- a/widget/gridwrap.go +++ b/widget/gridwrap.go @@ -411,7 +411,7 @@ func newGridWrapItem(child fyne.CanvasObject, tapped func()) *gridWrapItem { func (gw *gridWrapItem) CreateRenderer() fyne.WidgetRenderer { gw.ExtendBaseWidget(gw) - gw.background = canvas.NewRectangle(theme.HoverColor()) + gw.background = canvas.NewRectangle(theme.Color(theme.ColorNameHover)) gw.background.CornerRadius = theme.SelectionRadiusSize() gw.background.Hide() @@ -475,10 +475,10 @@ func (gw *gridWrapItemRenderer) Layout(size fyne.Size) { func (gw *gridWrapItemRenderer) Refresh() { gw.item.background.CornerRadius = theme.SelectionRadiusSize() if gw.item.selected { - gw.item.background.FillColor = theme.SelectionColor() + gw.item.background.FillColor = theme.Color(theme.ColorNameSelection) gw.item.background.Show() } else if gw.item.hovered { - gw.item.background.FillColor = theme.HoverColor() + gw.item.background.FillColor = theme.Color(theme.ColorNameHover) gw.item.background.Show() } else { gw.item.background.Hide() diff --git a/widget/label_test.go b/widget/label_test.go index 38bd510aeb..860fed9cad 100644 --- a/widget/label_test.go +++ b/widget/label_test.go @@ -160,9 +160,9 @@ func TestLabel_ApplyTheme(t *testing.T) { rich := test.TempWidgetRenderer(t, text).Objects()[0].(*RichText) render := test.TempWidgetRenderer(t, rich).(*textRenderer) - assert.Equal(t, theme.ForegroundColor(), render.Objects()[0].(*canvas.Text).Color) + assert.Equal(t, theme.Color(theme.ColorNameForeground), render.Objects()[0].(*canvas.Text).Color) text.Show() - assert.Equal(t, theme.ForegroundColor(), render.Objects()[0].(*canvas.Text).Color) + assert.Equal(t, theme.Color(theme.ColorNameForeground), render.Objects()[0].(*canvas.Text).Color) } func TestLabel_CreateRendererDoesNotAffectSize(t *testing.T) { diff --git a/widget/list.go b/widget/list.go index dffa53dc1a..e103d3c07d 100644 --- a/widget/list.go +++ b/widget/list.go @@ -509,7 +509,7 @@ func newListItem(child fyne.CanvasObject, tapped func()) *listItem { func (li *listItem) CreateRenderer() fyne.WidgetRenderer { li.ExtendBaseWidget(li) - li.background = canvas.NewRectangle(theme.HoverColor()) + li.background = canvas.NewRectangle(theme.Color(theme.ColorNameHover)) li.background.CornerRadius = theme.SelectionRadiusSize() li.background.Hide() @@ -573,10 +573,10 @@ func (li *listItemRenderer) Layout(size fyne.Size) { func (li *listItemRenderer) Refresh() { li.item.background.CornerRadius = theme.SelectionRadiusSize() if li.item.selected { - li.item.background.FillColor = theme.SelectionColor() + li.item.background.FillColor = theme.Color(theme.ColorNameSelection) li.item.background.Show() } else if li.item.hovered { - li.item.background.FillColor = theme.HoverColor() + li.item.background.FillColor = theme.Color(theme.ColorNameHover) li.item.background.Show() } else { li.item.background.Hide() diff --git a/widget/list_test.go b/widget/list_test.go index a4a1a0ee4b..2dcb4b72a5 100644 --- a/widget/list_test.go +++ b/widget/list_test.go @@ -179,7 +179,7 @@ func TestList_Hover(t *testing.T) { for i := 0; i < 2; i++ { assert.False(t, children[i].(*listItem).background.Visible()) children[i].(*listItem).MouseIn(&desktop.MouseEvent{}) - assert.Equal(t, children[i].(*listItem).background.FillColor, theme.HoverColor()) + assert.Equal(t, children[i].(*listItem).background.FillColor, theme.Color(theme.ColorNameHover)) children[i].(*listItem).MouseOut() assert.False(t, children[i].(*listItem).background.Visible()) } @@ -265,12 +265,12 @@ func TestList_Selection(t *testing.T) { assert.False(t, children[0].(*listItem).background.Visible()) children[0].(*listItem).Tapped(&fyne.PointEvent{}) - assert.Equal(t, children[0].(*listItem).background.FillColor, theme.SelectionColor()) + assert.Equal(t, children[0].(*listItem).background.FillColor, theme.Color(theme.ColorNameSelection)) assert.True(t, children[0].(*listItem).background.Visible()) assert.Equal(t, 1, len(list.selected)) assert.Equal(t, 0, list.selected[0]) children[1].(*listItem).Tapped(&fyne.PointEvent{}) - assert.Equal(t, children[1].(*listItem).background.FillColor, theme.SelectionColor()) + assert.Equal(t, children[1].(*listItem).background.FillColor, theme.Color(theme.ColorNameSelection)) assert.True(t, children[1].(*listItem).background.Visible()) assert.Equal(t, 1, len(list.selected)) assert.Equal(t, 1, list.selected[0]) @@ -296,13 +296,13 @@ func TestList_Select(t *testing.T) { assert.Equal(t, 988, int(list.offsetY)) lo := list.scroller.Content.(*fyne.Container).Layout.(*listLayout) visible50, _ := lo.searchVisible(lo.visible, 50) - assert.Equal(t, visible50.background.FillColor, theme.SelectionColor()) + assert.Equal(t, visible50.background.FillColor, theme.Color(theme.ColorNameSelection)) assert.True(t, visible50.background.Visible()) list.Select(5) assert.Equal(t, 195, int(list.offsetY)) visible5, _ := lo.searchVisible(lo.visible, 5) - assert.Equal(t, visible5.background.FillColor, theme.SelectionColor()) + assert.Equal(t, visible5.background.FillColor, theme.Color(theme.ColorNameSelection)) assert.True(t, visible5.background.Visible()) list.Select(6) @@ -310,7 +310,7 @@ func TestList_Select(t *testing.T) { visible5, _ = lo.searchVisible(lo.visible, 5) visible6, _ := lo.searchVisible(lo.visible, 6) assert.False(t, visible5.background.Visible()) - assert.Equal(t, visible6.background.FillColor, theme.SelectionColor()) + assert.Equal(t, visible6.background.FillColor, theme.Color(theme.ColorNameSelection)) assert.True(t, visible6.background.Visible()) } @@ -323,7 +323,7 @@ func TestList_Unselect(t *testing.T) { list.Select(10) children := list.scroller.Content.(*fyne.Container).Layout.(*listLayout).children - assert.Equal(t, children[10].(*listItem).background.FillColor, theme.SelectionColor()) + assert.Equal(t, children[10].(*listItem).background.FillColor, theme.Color(theme.ColorNameSelection)) assert.True(t, children[10].(*listItem).background.Visible()) list.Unselect(10) diff --git a/widget/menu_internal_desktop_test.go b/widget/menu_internal_desktop_test.go index 051aa419d8..3323bda743 100644 --- a/widget/menu_internal_desktop_test.go +++ b/widget/menu_internal_desktop_test.go @@ -46,7 +46,7 @@ func TestMenu_ItemHovered(t *testing.T) { r1 := cache.Renderer(mi).(*menuItemRenderer) assert.False(t, r1.background.Visible()) mi.MouseIn(nil) - assert.Equal(t, theme.FocusColor(), r1.background.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameFocus), r1.background.FillColor) assert.True(t, r1.background.Visible()) mi.MouseOut() assert.False(t, r1.background.Visible()) diff --git a/widget/menu_item_test.go b/widget/menu_item_test.go index fac1a0007b..920b779167 100644 --- a/widget/menu_item_test.go +++ b/widget/menu_item_test.go @@ -17,5 +17,5 @@ func TestMenuItem_Disabled(t *testing.T) { w := newMenuItem(i, NewMenu(m)) r := cache.Renderer(w) - assert.Equal(t, theme.DisabledColor(), r.(*menuItemRenderer).text.Color) + assert.Equal(t, theme.Color(theme.ColorNameDisabled), r.(*menuItemRenderer).text.Color) } diff --git a/widget/pool_test.go b/widget/pool_test.go index 8c21470de2..f6032a6238 100644 --- a/widget/pool_test.go +++ b/widget/pool_test.go @@ -16,15 +16,15 @@ func TestSyncPool(t *testing.T) { }) t.Run("Single", func(t *testing.T) { pool := &syncPool{} - rect := canvas.NewRectangle(theme.PrimaryColor()) + rect := canvas.NewRectangle(theme.Color(theme.ColorNamePrimary)) pool.Release(rect) assert.Equal(t, rect, pool.Obtain()) assert.Nil(t, pool.Obtain()) }) t.Run("Multiple", func(t *testing.T) { pool := &syncPool{} - rect := canvas.NewRectangle(theme.PrimaryColor()) - circle := canvas.NewCircle(theme.PrimaryColor()) + rect := canvas.NewRectangle(theme.Color(theme.ColorNamePrimary)) + circle := canvas.NewCircle(theme.Color(theme.ColorNamePrimary)) pool.Release(rect) pool.Release(circle) a := pool.Obtain() diff --git a/widget/popup_test.go b/widget/popup_test.go index 183a23a022..fc3c247544 100644 --- a/widget/popup_test.go +++ b/widget/popup_test.go @@ -319,7 +319,7 @@ func TestPopUp_Layout(t *testing.T) { if bg, ok := r.Objects()[1].(*canvas.Rectangle); assert.True(t, ok, "a background rectangle is rendered before the content") { assert.Equal(t, size, bg.Size()) assert.Equal(t, pos, bg.Position()) - assert.Equal(t, theme.OverlayBackgroundColor(), bg.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameOverlayBackground), bg.FillColor) } assert.Equal(t, r.Objects()[2], content) } diff --git a/widget/radio_group_extended_test.go b/widget/radio_group_extended_test.go index 0e6a788597..edd13ea2fb 100644 --- a/widget/radio_group_extended_test.go +++ b/widget/radio_group_extended_test.go @@ -152,7 +152,7 @@ func TestRadioGroup_Extended_Hovered(t *testing.T) { }, }) assert.True(t, item1.hovered) - assert.Equal(t, theme.HoverColor(), render1.focusIndicator.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameHover), render1.focusIndicator.FillColor) assert.Equal(t, color.Transparent, render2.focusIndicator.FillColor) item1.MouseOut() diff --git a/widget/radio_group_internal_test.go b/widget/radio_group_internal_test.go index 940833a818..392c19f63b 100644 --- a/widget/radio_group_internal_test.go +++ b/widget/radio_group_internal_test.go @@ -257,7 +257,7 @@ func TestRadioGroup_Hovered(t *testing.T) { }, }) assert.True(t, item1.hovered) - assert.Equal(t, theme.HoverColor(), render1.focusIndicator.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameHover), render1.focusIndicator.FillColor) assert.Equal(t, color.Transparent, render2.focusIndicator.FillColor) item1.MouseOut() diff --git a/widget/richtext_test.go b/widget/richtext_test.go index 0b4d9fca97..bbb8b84aed 100644 --- a/widget/richtext_test.go +++ b/widget/richtext_test.go @@ -356,7 +356,7 @@ func TestText_Multiline(t *testing.T) { func TestText_Color(t *testing.T) { text := NewRichText(trailingBoldErrorSegment()) - assert.Equal(t, theme.ErrorColor(), richTextRenderTexts(text)[0].Color) + assert.Equal(t, theme.Color(theme.ColorNameError), richTextRenderTexts(text)[0].Color) } func TestTextRenderer_ApplyTheme(t *testing.T) { diff --git a/widget/table.go b/widget/table.go index 6a4d341092..38ebcc9881 100644 --- a/widget/table.go +++ b/widget/table.go @@ -224,7 +224,7 @@ func (t *Table) FocusGained() { // Implements: fyne.Focusable func (t *Table) FocusLost() { t.focused = false - t.Refresh() //Item(t.currentFocus) + t.Refresh() // Item(t.currentFocus) } func (t *Table) MouseIn(ev *desktop.MouseEvent) { @@ -1153,15 +1153,15 @@ func newTableCells(t *Table) *tableCells { } func (c *tableCells) CreateRenderer() fyne.WidgetRenderer { - marker := canvas.NewRectangle(theme.SelectionColor()) + marker := canvas.NewRectangle(theme.Color(theme.ColorNameSelection)) marker.CornerRadius = theme.SelectionRadiusSize() - hover := canvas.NewRectangle(theme.HoverColor()) + hover := canvas.NewRectangle(theme.Color(theme.ColorNameHover)) hover.CornerRadius = theme.SelectionRadiusSize() r := &tableCellsRenderer{cells: c, pool: &syncPool{}, headerPool: &syncPool{}, visible: make(map[TableCellID]fyne.CanvasObject), headers: make(map[TableCellID]fyne.CanvasObject), - headRowBG: canvas.NewRectangle(theme.HeaderBackgroundColor()), headColBG: canvas.NewRectangle(theme.HeaderBackgroundColor()), - headRowStickyBG: canvas.NewRectangle(theme.HeaderBackgroundColor()), headColStickyBG: canvas.NewRectangle(theme.HeaderBackgroundColor()), + headRowBG: canvas.NewRectangle(theme.Color(theme.ColorNameHeaderBackground)), headColBG: canvas.NewRectangle(theme.Color(theme.ColorNameHeaderBackground)), + headRowStickyBG: canvas.NewRectangle(theme.Color(theme.ColorNameHeaderBackground)), headColStickyBG: canvas.NewRectangle(theme.Color(theme.ColorNameHeaderBackground)), marker: marker, hover: hover} c.t.moveCallback = r.moveIndicators @@ -1386,10 +1386,10 @@ func (r *tableCellsRenderer) refreshForID(toDraw TableCellID) { } r.moveIndicators() - r.marker.FillColor = theme.SelectionColor() + r.marker.FillColor = theme.Color(theme.ColorNameSelection) r.marker.CornerRadius = theme.SelectionRadiusSize() r.marker.Refresh() - r.hover.FillColor = theme.HoverColor() + r.hover.FillColor = theme.Color(theme.ColorNameHover) r.hover.CornerRadius = theme.SelectionRadiusSize() r.hover.Refresh() } @@ -1672,17 +1672,17 @@ func (r *tableCellsRenderer) refreshHeaders(visibleRowHeights, visibleColWidths r.cells.t.left.Content.Refresh() r.headColBG.Hidden = !r.cells.t.ShowHeaderColumn - r.headColBG.FillColor = theme.HeaderBackgroundColor() + r.headColBG.FillColor = theme.Color(theme.ColorNameHeaderBackground) r.headColBG.Resize(fyne.NewSize(colWidth, r.cells.t.Size().Height)) r.headColStickyBG.Hidden = !r.cells.t.ShowHeaderColumn - r.headColStickyBG.FillColor = theme.HeaderBackgroundColor() + r.headColStickyBG.FillColor = theme.Color(theme.ColorNameHeaderBackground) r.headColStickyBG.Resize(fyne.NewSize(colWidth, r.cells.t.stuckHeight+rowHeight)) r.headRowBG.Hidden = !r.cells.t.ShowHeaderRow - r.headRowBG.FillColor = theme.HeaderBackgroundColor() + r.headRowBG.FillColor = theme.Color(theme.ColorNameHeaderBackground) r.headRowBG.Resize(fyne.NewSize(r.cells.t.Size().Width, rowHeight)) r.headRowStickyBG.Hidden = !r.cells.t.ShowHeaderRow - r.headRowStickyBG.FillColor = theme.HeaderBackgroundColor() + r.headRowStickyBG.FillColor = theme.Color(theme.ColorNameHeaderBackground) r.headRowStickyBG.Resize(fyne.NewSize(r.cells.t.stuckWidth+colWidth, rowHeight)) r.cells.t.corner.Content.(*fyne.Container).Objects = corner r.cells.t.corner.Content.Refresh() diff --git a/widget/textgrid_test.go b/widget/textgrid_test.go index 9d37aa287b..98331e3b02 100644 --- a/widget/textgrid_test.go +++ b/widget/textgrid_test.go @@ -259,11 +259,11 @@ func assertGridStyle(t *testing.T, g *TextGrid, content string, expectedStyles m bg, fg := rendererCell(renderer, y, x) if r == ' ' { - assert.Equal(t, theme.ForegroundColor(), fg.Color) + assert.Equal(t, theme.Color(theme.ColorNameForeground), fg.Color) assert.Equal(t, color.Transparent, bg.FillColor) } else if expected != nil { if expected.TextColor() == nil { - assert.Equal(t, theme.ForegroundColor(), fg.Color) + assert.Equal(t, theme.Color(theme.ColorNameForeground), fg.Color) } else { assert.Equal(t, expected.TextColor(), fg.Color) } diff --git a/widget/tree.go b/widget/tree.go index 83a6a6b0ce..f8fe931ed8 100644 --- a/widget/tree.go +++ b/widget/tree.go @@ -187,7 +187,7 @@ func (t *Tree) FocusGained() { // Implements: fyne.Focusable func (t *Tree) FocusLost() { t.focused = false - t.Refresh() //Item(t.currentFocus) + t.Refresh() // Item(t.currentFocus) } // MinSize returns the size that this widget should not shrink below. @@ -846,7 +846,7 @@ func (n *treeNode) Content() fyne.CanvasObject { } func (n *treeNode) CreateRenderer() fyne.WidgetRenderer { - background := canvas.NewRectangle(theme.HoverColor()) + background := canvas.NewRectangle(theme.Color(theme.ColorNameHover)) background.CornerRadius = theme.SelectionRadiusSize() background.Hide() return &treeNodeRenderer{ @@ -966,10 +966,10 @@ func (r *treeNodeRenderer) partialRefresh() { } r.background.CornerRadius = theme.SelectionRadiusSize() if len(r.treeNode.tree.selected) > 0 && r.treeNode.uid == r.treeNode.tree.selected[0] { - r.background.FillColor = theme.SelectionColor() + r.background.FillColor = theme.Color(theme.ColorNameSelection) r.background.Show() } else if r.treeNode.hovered || (r.treeNode.tree.focused && r.treeNode.tree.currentFocus == r.treeNode.uid) { - r.background.FillColor = theme.HoverColor() + r.background.FillColor = theme.Color(theme.ColorNameHover) r.background.Show() } else { r.background.Hide() diff --git a/widget/tree_internal_test.go b/widget/tree_internal_test.go index 3a2ca484e3..aec6af998e 100644 --- a/widget/tree_internal_test.go +++ b/widget/tree_internal_test.go @@ -897,13 +897,13 @@ func TestTreeNodeRenderer_BackgroundColor(t *testing.T) { t.Run("Branch", func(t *testing.T) { a := getBranch(t, tree, "A") ar := test.TempWidgetRenderer(t, a).(*treeNodeRenderer) - assert.Equal(t, theme.HoverColor(), ar.background.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameHover), ar.background.FillColor) assert.False(t, ar.background.Visible()) }) t.Run("Leaf", func(t *testing.T) { b := getLeaf(t, tree, "B") br := test.TempWidgetRenderer(t, b).(*treeNodeRenderer) - assert.Equal(t, theme.HoverColor(), br.background.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameHover), br.background.FillColor) assert.False(t, br.background.Visible()) }) } @@ -918,20 +918,20 @@ func TestTreeNodeRenderer_BackgroundColor_Hovered(t *testing.T) { a := getBranch(t, tree, "A") ar := test.TempWidgetRenderer(t, a).(*treeNodeRenderer) a.MouseIn(&desktop.MouseEvent{}) - assert.Equal(t, theme.HoverColor(), ar.background.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameHover), ar.background.FillColor) assert.True(t, ar.background.Visible()) a.MouseOut() - assert.Equal(t, theme.HoverColor(), ar.background.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameHover), ar.background.FillColor) assert.False(t, ar.background.Visible()) }) t.Run("Leaf", func(t *testing.T) { b := getLeaf(t, tree, "B") br := test.TempWidgetRenderer(t, b).(*treeNodeRenderer) b.MouseIn(&desktop.MouseEvent{}) - assert.Equal(t, theme.HoverColor(), br.background.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameHover), br.background.FillColor) assert.True(t, br.background.Visible()) b.MouseOut() - assert.Equal(t, theme.HoverColor(), br.background.FillColor) + assert.Equal(t, theme.Color(theme.ColorNameHover), br.background.FillColor) assert.False(t, br.background.Visible()) }) }