widget.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package cache
  2. import (
  3. "sync"
  4. "fyne.io/fyne/v2"
  5. )
  6. var renderersLock sync.RWMutex
  7. var renderers = map[fyne.Widget]*rendererInfo{}
  8. type isBaseWidget interface {
  9. ExtendBaseWidget(fyne.Widget)
  10. super() fyne.Widget
  11. }
  12. // Renderer looks up the render implementation for a widget
  13. func Renderer(wid fyne.Widget) fyne.WidgetRenderer {
  14. if wid == nil {
  15. return nil
  16. }
  17. if wd, ok := wid.(isBaseWidget); ok {
  18. if wd.super() != nil {
  19. wid = wd.super()
  20. }
  21. }
  22. renderersLock.RLock()
  23. rinfo, ok := renderers[wid]
  24. renderersLock.RUnlock()
  25. if !ok {
  26. rinfo = &rendererInfo{renderer: wid.CreateRenderer()}
  27. renderersLock.Lock()
  28. renderers[wid] = rinfo
  29. renderersLock.Unlock()
  30. }
  31. if rinfo == nil {
  32. return nil
  33. }
  34. rinfo.setAlive()
  35. return rinfo.renderer
  36. }
  37. // DestroyRenderer frees a render implementation for a widget.
  38. // This is typically for internal use only.
  39. func DestroyRenderer(wid fyne.Widget) {
  40. renderersLock.RLock()
  41. rinfo, ok := renderers[wid]
  42. renderersLock.RUnlock()
  43. if !ok {
  44. return
  45. }
  46. if rinfo != nil {
  47. rinfo.renderer.Destroy()
  48. }
  49. renderersLock.Lock()
  50. delete(renderers, wid)
  51. renderersLock.Unlock()
  52. }
  53. // IsRendered returns true of the widget currently has a renderer.
  54. // One will be created the first time a widget is shown but may be removed after it is hidden.
  55. func IsRendered(wid fyne.Widget) bool {
  56. renderersLock.RLock()
  57. _, found := renderers[wid]
  58. renderersLock.RUnlock()
  59. return found
  60. }
  61. type rendererInfo struct {
  62. expiringCache
  63. renderer fyne.WidgetRenderer
  64. }