diff --git a/internal/driver/glfw/testdata/menu_bar_hovered_content.png b/internal/driver/glfw/testdata/menu_bar_hovered_content.png index 0569411355..fc5c0c3a9b 100644 Binary files a/internal/driver/glfw/testdata/menu_bar_hovered_content.png and b/internal/driver/glfw/testdata/menu_bar_hovered_content.png differ diff --git a/widget/button.go b/widget/button.go index 5c2ecbcc37..07e390287e 100644 --- a/widget/button.go +++ b/widget/button.go @@ -312,10 +312,25 @@ func (r *buttonRenderer) buttonColor() color.Color { switch { case r.button.Disabled(): return theme.DisabledButtonColor() + case r.button.hovered: + bg := theme.ButtonColor() + if r.button.Importance == HighImportance { + bg = theme.PrimaryColor() + } + + dstR, dstG, dstB, dstA := bg.RGBA() + srcR, srcG, srcB, srcA := theme.HoverColor().RGBA() + srcAlpha := float32(srcA) / 0xFFFF + dstAlpha := float32(dstA) / 0xFFFF + targetAlpha := 1 - srcAlpha*dstAlpha + + outAlpha := srcAlpha + targetAlpha + outR := (srcAlpha*float32(srcR) + targetAlpha*float32(dstR)) / outAlpha + outG := (srcAlpha*float32(srcG) + targetAlpha*float32(dstG)) / outAlpha + outB := (srcAlpha*float32(srcB) + targetAlpha*float32(dstB)) / outAlpha + return color.RGBA{R: uint8(uint32(outR) >> 8), G: uint8(uint32(outG) >> 8), B: uint8(uint32(outB) >> 8), A: uint8(outAlpha * 0xFF)} case r.button.Importance == HighImportance: return theme.PrimaryColor() - case r.button.hovered: - return theme.HoverColor() default: return theme.ButtonColor() } diff --git a/widget/button_test.go b/widget/button_test.go index d2818ffbf6..f9478dd361 100644 --- a/widget/button_test.go +++ b/widget/button_test.go @@ -121,6 +121,31 @@ func TestButton_Disabled(t *testing.T) { assert.False(t, button.Disabled()) } +func TestButton_Hover(t *testing.T) { + app := test.NewApp() + defer test.NewApp() + app.Settings().SetTheme(theme.LightTheme()) + + b := widget.NewButtonWithIcon("Test", theme.HomeIcon(), func() {}) + w := test.NewWindow(b) + defer w.Close() + + test.MoveMouse(w.Canvas(), fyne.NewPos(5, 5)) + test.AssertImageMatches(t, "button/hovered.png", w.Canvas().Capture()) + + b.Importance = widget.HighImportance + b.Refresh() + test.AssertImageMatches(t, "button/high_importance_hovered.png", w.Canvas().Capture()) + + test.MoveMouse(w.Canvas(), fyne.NewPos(0, 0)) + b.Refresh() + test.AssertImageMatches(t, "button/high_importance.png", w.Canvas().Capture()) + + b.Importance = widget.MediumImportance + b.Refresh() + test.AssertImageMatches(t, "button/initial.png", w.Canvas().Capture()) +} + func TestButton_Layout(t *testing.T) { test.NewApp() defer test.NewApp() diff --git a/widget/testdata/button/high_importance.png b/widget/testdata/button/high_importance.png new file mode 100644 index 0000000000..1339bd9cac Binary files /dev/null and b/widget/testdata/button/high_importance.png differ diff --git a/widget/testdata/button/high_importance_hovered.png b/widget/testdata/button/high_importance_hovered.png new file mode 100644 index 0000000000..ef5bf89f80 Binary files /dev/null and b/widget/testdata/button/high_importance_hovered.png differ diff --git a/widget/testdata/button/hovered.png b/widget/testdata/button/hovered.png new file mode 100644 index 0000000000..8a0effa81e Binary files /dev/null and b/widget/testdata/button/hovered.png differ