diff --git a/action.go b/action.go index 202dfeb0..7e409a27 100644 --- a/action.go +++ b/action.go @@ -28,6 +28,7 @@ type Action struct { enabledConditionChangedHandle int visibleCondition Condition visibleConditionChangedHandle int + refCount int enabled bool visible bool checkable bool @@ -50,6 +51,23 @@ func NewAction() *Action { return a } +func (a *Action) addRef() { + a.refCount++ +} + +func (a *Action) release() { + a.refCount-- + + if a.refCount == 0 { + a.SetEnabledCondition(nil) + a.SetVisibleCondition(nil) + + if a.menu != nil { + a.menu.actions.Clear() + } + } +} + func (a *Action) Checkable() bool { return a.checkable } diff --git a/actionlist.go b/actionlist.go index 80efaa63..e92c5500 100644 --- a/actionlist.go +++ b/actionlist.go @@ -16,6 +16,10 @@ type ActionList struct { } func newActionList(observer actionListObserver) *ActionList { + if observer == nil { + panic("observer == nil") + } + return &ActionList{observer: observer} } @@ -32,11 +36,12 @@ func (l *ActionList) At(index int) *Action { } func (l *ActionList) Clear() error { - observer := l.observer - if observer != nil { - if err := observer.onClearingActions(); err != nil { - return err - } + if err := l.observer.onClearingActions(); err != nil { + return err + } + + for _, a := range l.actions { + a.release() } l.actions = l.actions[:0] @@ -78,15 +83,14 @@ func (l *ActionList) Insert(index int, action *Action) error { copy(l.actions[index+1:], l.actions[index:]) l.actions[index] = action - observer := l.observer - if observer != nil { - if err := observer.onInsertedAction(action); err != nil { - l.actions = append(l.actions[:index], l.actions[index+1:]...) + if err := l.observer.onInsertedAction(action); err != nil { + l.actions = append(l.actions[:index], l.actions[index+1:]...) - return err - } + return err } + action.addRef() + return nil } @@ -115,16 +119,15 @@ func (l *ActionList) Remove(action *Action) error { } func (l *ActionList) RemoveAt(index int) error { - observer := l.observer - if observer != nil { - action := l.actions[index] - if action.Visible() { - if err := observer.onRemovingAction(action); err != nil { - return err - } + action := l.actions[index] + if action.Visible() { + if err := l.observer.onRemovingAction(action); err != nil { + return err } } + action.release() + l.actions = append(l.actions[:index], l.actions[index+1:]...) return nil