| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- package internal
- import (
- "sync"
- "fyne.io/fyne/v2"
- "fyne.io/fyne/v2/internal/app"
- "fyne.io/fyne/v2/internal/widget"
- )
- // OverlayStack implements fyne.OverlayStack
- type OverlayStack struct {
- OnChange func()
- Canvas fyne.Canvas
- focusManagers []*app.FocusManager
- overlays []fyne.CanvasObject
- propertyLock sync.RWMutex
- }
- var _ fyne.OverlayStack = (*OverlayStack)(nil)
- // Add puts an overlay on the stack.
- //
- // Implements: fyne.OverlayStack
- func (s *OverlayStack) Add(overlay fyne.CanvasObject) {
- if overlay == nil {
- return
- }
- if s.OnChange != nil {
- defer s.OnChange()
- }
- s.propertyLock.Lock()
- defer s.propertyLock.Unlock()
- s.overlays = append(s.overlays, overlay)
- // TODO this should probably apply to all once #707 is addressed
- if _, ok := overlay.(*widget.OverlayContainer); ok {
- safePos, safeSize := s.Canvas.InteractiveArea()
- overlay.Resize(safeSize)
- overlay.Move(safePos)
- }
- s.focusManagers = append(s.focusManagers, app.NewFocusManager(overlay))
- }
- // List returns all overlays on the stack from bottom to top.
- //
- // Implements: fyne.OverlayStack
- func (s *OverlayStack) List() []fyne.CanvasObject {
- s.propertyLock.RLock()
- defer s.propertyLock.RUnlock()
- return s.overlays
- }
- // ListFocusManagers returns all focus managers on the stack from bottom to top.
- func (s *OverlayStack) ListFocusManagers() []*app.FocusManager {
- s.propertyLock.RLock()
- defer s.propertyLock.RUnlock()
- return s.focusManagers
- }
- // Remove deletes an overlay and all overlays above it from the stack.
- //
- // Implements: fyne.OverlayStack
- func (s *OverlayStack) Remove(overlay fyne.CanvasObject) {
- if s.OnChange != nil {
- defer s.OnChange()
- }
- s.propertyLock.Lock()
- defer s.propertyLock.Unlock()
- overlayIdx := -1
- for i, o := range s.overlays {
- if o == overlay {
- overlayIdx = i
- break
- }
- }
- if overlayIdx == -1 {
- return
- }
- // set removed elements in backing array to nil to release memory references
- for i := overlayIdx; i < len(s.overlays); i++ {
- s.overlays[i] = nil
- s.focusManagers[i] = nil
- }
- s.overlays = s.overlays[:overlayIdx]
- s.focusManagers = s.focusManagers[:overlayIdx]
- }
- // Top returns the top-most overlay of the stack.
- //
- // Implements: fyne.OverlayStack
- func (s *OverlayStack) Top() fyne.CanvasObject {
- s.propertyLock.RLock()
- defer s.propertyLock.RUnlock()
- if len(s.overlays) == 0 {
- return nil
- }
- return s.overlays[len(s.overlays)-1]
- }
- // TopFocusManager returns the app.FocusManager assigned to the top-most overlay of the stack.
- func (s *OverlayStack) TopFocusManager() *app.FocusManager {
- s.propertyLock.RLock()
- defer s.propertyLock.RUnlock()
- return s.topFocusManager()
- }
- func (s *OverlayStack) topFocusManager() *app.FocusManager {
- var fm *app.FocusManager
- if len(s.focusManagers) > 0 {
- fm = s.focusManagers[len(s.focusManagers)-1]
- }
- return fm
- }
|