fyne-io / fyne

Cross platform GUI toolkit in Go inspired by Material Design
https://fyne.io/
Other
24.64k stars 1.37k forks source link

Objects added to a container that is part of a theme override don't get the overridden theme #4982

Open dweymouth opened 2 months ago

dweymouth commented 2 months ago

Checklist

Describe the bug

Objects that are added to containers that are part of a theme override after it has already been set up do not get the overridden theme. Including after refreshing the parent container.

How to reproduce

Run the example code and hit the "add child" button which puts a new button into the container. It has the app theme, not the overridden one. Hit the refresh button to refresh the whole window content. The added button(s) still have the app theme rather than the overridden one.

Expected behavior - container.Add should automatically ensure the contents have the correct theme. So should container.Refresh in the case of manually manipulating container.Objects.

Screenshots

No response

Example code

package main

import (
    "image/color"
    "strconv"

    "fyne.io/fyne/v2"
    "fyne.io/fyne/v2/app"
    "fyne.io/fyne/v2/container"
    "fyne.io/fyne/v2/theme"
    "fyne.io/fyne/v2/widget"
)

type customTheme struct {
}

var _ fyne.Theme = (*customTheme)(nil)

func (*customTheme) Color(name fyne.ThemeColorName, variant fyne.ThemeVariant) color.Color {
    if name == theme.ColorNameButton {
        return color.RGBA{R: 200, G: 10, B: 10, A: 255}
    }
    return fyne.CurrentApp().Settings().Theme().Color(name, variant)
}

func (*customTheme) Font(name fyne.TextStyle) fyne.Resource {
    return fyne.CurrentApp().Settings().Theme().Font(name)
}

func (*customTheme) Size(name fyne.ThemeSizeName) float32 {
    return fyne.CurrentApp().Settings().Theme().Size(name)
}

func (*customTheme) Icon(name fyne.ThemeIconName) fyne.Resource {
    return fyne.CurrentApp().Settings().Theme().Icon(name)
}

func main() {
    btnNumber := 0
    newButton := func() fyne.CanvasObject {
        btnNumber++
        return widget.NewButton(strconv.Itoa(btnNumber), nil)
    }
    app := app.New()
    newBtnsHbox := container.NewHBox(newButton())
    var content fyne.CanvasObject
    content = container.NewVBox(
        container.NewHBox(
            widget.NewButton("add child", func() {
                newBtnsHbox.Add(newButton())
            }),
            widget.NewButton("refresh", func() {
                content.Refresh()
            }),
        ),
        newBtnsHbox,
    )
    ovr := container.NewThemeOverride(content, &customTheme{})
    window := app.NewWindow("Hello!")
    window.SetContent(ovr)
    window.ShowAndRun()
}

Fyne version

develop

Go compiler version

n/a

Operating system and version

all

Additional Information

No response

dweymouth commented 2 months ago

Note that refreshing the theme override container instead of the child container where the button was added works. This is a bit confusing and we should document it, but not release blocking IMO