94 lines
1.9 KiB
Go
94 lines
1.9 KiB
Go
package cache
|
|
|
|
import (
|
|
"strconv"
|
|
"sync/atomic"
|
|
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/internal/async"
|
|
)
|
|
|
|
var (
|
|
overrides async.Map[fyne.CanvasObject, *overrideScope]
|
|
overrideCount atomic.Uint32
|
|
)
|
|
|
|
type overrideScope struct {
|
|
th fyne.Theme
|
|
cacheID string
|
|
}
|
|
|
|
// OverrideTheme allows an app to specify that a single object should use a different theme to the app.
|
|
// This should be used sparingly to avoid a jarring user experience.
|
|
// If the object is a container it will theme the children, if it is a canvas primitive it will do nothing.
|
|
//
|
|
// Since: 2.5
|
|
func OverrideTheme(o fyne.CanvasObject, th fyne.Theme) {
|
|
id := overrideCount.Add(1)
|
|
s := &overrideScope{th: th, cacheID: strconv.Itoa(int(id))}
|
|
overrideTheme(o, s)
|
|
}
|
|
|
|
func OverrideThemeMatchingScope(o, parent fyne.CanvasObject) bool {
|
|
scope, ok := overrides.Load(parent)
|
|
if !ok { // not overridden in parent
|
|
return false
|
|
}
|
|
|
|
overrideTheme(o, scope)
|
|
return true
|
|
}
|
|
|
|
func WidgetScopeID(o fyne.CanvasObject) string {
|
|
scope, ok := overrides.Load(o)
|
|
if !ok {
|
|
return ""
|
|
}
|
|
|
|
return scope.cacheID
|
|
}
|
|
|
|
func WidgetTheme(o fyne.CanvasObject) fyne.Theme {
|
|
scope, ok := overrides.Load(o)
|
|
if !ok {
|
|
return nil
|
|
}
|
|
|
|
return scope.th
|
|
}
|
|
|
|
func overrideContainer(c *fyne.Container, s *overrideScope) {
|
|
for _, o := range c.Objects {
|
|
overrideTheme(o, s)
|
|
}
|
|
}
|
|
|
|
func overrideTheme(o fyne.CanvasObject, s *overrideScope) {
|
|
if _, ok := o.(interface{ SetDeviceIsMobile(bool) }); ok { // ThemeOverride without the import loop
|
|
return // do not apply this theme over a new scope
|
|
}
|
|
|
|
switch c := o.(type) {
|
|
case fyne.Widget:
|
|
overrideWidget(c, s)
|
|
case *fyne.Container:
|
|
overrideContainer(c, s)
|
|
default:
|
|
overrides.Store(c, s)
|
|
}
|
|
}
|
|
|
|
func overrideWidget(w fyne.Widget, s *overrideScope) {
|
|
ResetThemeCaches()
|
|
overrides.Store(w, s)
|
|
|
|
r := Renderer(w)
|
|
if r == nil {
|
|
return
|
|
}
|
|
|
|
for _, o := range r.Objects() {
|
|
overrideTheme(o, s)
|
|
}
|
|
}
|