75 lines
1.7 KiB
Go
75 lines
1.7 KiB
Go
package cache
|
|
|
|
import (
|
|
"fyne.io/fyne/v2"
|
|
"fyne.io/fyne/v2/internal/async"
|
|
)
|
|
|
|
var renderers async.Map[fyne.Widget, *rendererInfo]
|
|
|
|
type isBaseWidget interface {
|
|
ExtendBaseWidget(fyne.Widget)
|
|
super() fyne.Widget
|
|
}
|
|
|
|
// Renderer looks up the render implementation for a widget
|
|
// If one does not exist, it creates and caches a renderer for the widget.
|
|
func Renderer(wid fyne.Widget) fyne.WidgetRenderer {
|
|
renderer, ok := CachedRenderer(wid)
|
|
if !ok && wid != nil {
|
|
renderer = wid.CreateRenderer()
|
|
rinfo := &rendererInfo{renderer: renderer}
|
|
rinfo.setAlive()
|
|
renderers.Store(wid, rinfo)
|
|
}
|
|
|
|
return renderer
|
|
}
|
|
|
|
// CachedRenderer looks up the cached render implementation for a widget
|
|
// If a renderer does not exist in the cache, it returns nil, false.
|
|
func CachedRenderer(wid fyne.Widget) (fyne.WidgetRenderer, bool) {
|
|
if wid == nil {
|
|
return nil, false
|
|
}
|
|
|
|
if wd, ok := wid.(isBaseWidget); ok {
|
|
if wd.super() != nil {
|
|
wid = wd.super()
|
|
}
|
|
}
|
|
|
|
rinfo, ok := renderers.Load(wid)
|
|
if !ok {
|
|
return nil, false
|
|
}
|
|
|
|
rinfo.setAlive()
|
|
return rinfo.renderer, true
|
|
}
|
|
|
|
// DestroyRenderer frees a render implementation for a widget.
|
|
// This is typically for internal use only.
|
|
func DestroyRenderer(wid fyne.Widget) {
|
|
rinfo, ok := renderers.LoadAndDelete(wid)
|
|
if !ok {
|
|
return
|
|
}
|
|
if rinfo != nil {
|
|
rinfo.renderer.Destroy()
|
|
}
|
|
overrides.Delete(wid)
|
|
}
|
|
|
|
// IsRendered returns true of the widget currently has a renderer.
|
|
// One will be created the first time a widget is shown but may be removed after it is hidden.
|
|
func IsRendered(wid fyne.Widget) bool {
|
|
_, found := renderers.Load(wid)
|
|
return found
|
|
}
|
|
|
|
type rendererInfo struct {
|
|
expiringCache
|
|
renderer fyne.WidgetRenderer
|
|
}
|