erm/vendor/github.com/lxn/walk/action.go
2021-07-30 23:29:20 +01:00

479 lines
8.5 KiB
Go

// Copyright 2010 The Walk Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// +build windows
package walk
type actionChangedHandler interface {
onActionChanged(action *Action) error
onActionVisibleChanged(action *Action) error
}
var (
// ISSUE: When pressing enter resp. escape,
// WM_COMMAND with wParam=1 resp. 2 is sent.
// Maybe there is more to consider.
nextActionId uint16 = 3
actionsById = make(map[uint16]*Action)
shortcut2Action = make(map[Shortcut]*Action)
)
type Action struct {
menu *Menu
triggeredPublisher EventPublisher
changedHandlers []actionChangedHandler
text string
toolTip string
image Image
checkedCondition Condition
checkedConditionChangedHandle int
defaultCondition Condition
defaultConditionChangedHandle int
enabledCondition Condition
enabledConditionChangedHandle int
visibleCondition Condition
visibleConditionChangedHandle int
refCount int
shortcut Shortcut
enabled bool
visible bool
checkable bool
checked bool
defawlt bool
exclusive bool
id uint16
}
func NewAction() *Action {
a := &Action{
enabled: true,
id: nextActionId,
visible: true,
}
actionsById[a.id] = a
nextActionId++
return a
}
func NewMenuAction(menu *Menu) *Action {
a := NewAction()
a.menu = menu
return a
}
func NewSeparatorAction() *Action {
return &Action{
enabled: true,
visible: true,
}
}
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()
a.menu.Dispose()
}
delete(actionsById, a.id)
delete(shortcut2Action, a.shortcut)
}
}
func (a *Action) Checkable() bool {
return a.checkable
}
func (a *Action) SetCheckable(value bool) (err error) {
if value != a.checkable {
old := a.checkable
a.checkable = value
if err = a.raiseChanged(); err != nil {
a.checkable = old
a.raiseChanged()
}
}
return
}
func (a *Action) Checked() bool {
return a.checked
}
func (a *Action) SetChecked(value bool) (err error) {
if a.checkedCondition != nil {
if bp, ok := a.checkedCondition.(*boolProperty); ok {
if err := bp.Set(value); err != nil {
return err
}
} else {
return newError("CheckedCondition != nil")
}
}
if value != a.checked {
old := a.checked
a.checked = value
if err = a.raiseChanged(); err != nil {
a.checked = old
a.raiseChanged()
}
}
return
}
func (a *Action) CheckedCondition() Condition {
return a.checkedCondition
}
func (a *Action) SetCheckedCondition(c Condition) {
if a.checkedCondition != nil {
a.checkedCondition.Changed().Detach(a.checkedConditionChangedHandle)
}
a.checkedCondition = c
if c != nil {
a.checked = c.Satisfied()
a.checkedConditionChangedHandle = c.Changed().Attach(func() {
if a.checked != c.Satisfied() {
a.checked = !a.checked
a.raiseChanged()
}
})
}
a.raiseChanged()
}
func (a *Action) Default() bool {
return a.defawlt
}
func (a *Action) SetDefault(value bool) (err error) {
if a.defaultCondition != nil {
if bp, ok := a.defaultCondition.(*boolProperty); ok {
if err := bp.Set(value); err != nil {
return err
}
} else {
return newError("DefaultCondition != nil")
}
}
if value != a.defawlt {
old := a.defawlt
a.defawlt = value
if err = a.raiseChanged(); err != nil {
a.defawlt = old
a.raiseChanged()
}
}
return
}
func (a *Action) DefaultCondition() Condition {
return a.defaultCondition
}
func (a *Action) SetDefaultCondition(c Condition) {
if a.defaultCondition != nil {
a.defaultCondition.Changed().Detach(a.defaultConditionChangedHandle)
}
a.defaultCondition = c
if c != nil {
a.defawlt = c.Satisfied()
a.defaultConditionChangedHandle = c.Changed().Attach(func() {
if a.defawlt != c.Satisfied() {
a.defawlt = !a.defawlt
a.raiseChanged()
}
})
}
a.raiseChanged()
}
func (a *Action) Enabled() bool {
return a.enabled
}
func (a *Action) SetEnabled(value bool) (err error) {
if a.enabledCondition != nil {
return newError("EnabledCondition != nil")
}
if value != a.enabled {
old := a.enabled
a.enabled = value
if err = a.raiseChanged(); err != nil {
a.enabled = old
a.raiseChanged()
}
}
return
}
func (a *Action) EnabledCondition() Condition {
return a.enabledCondition
}
func (a *Action) SetEnabledCondition(c Condition) {
if a.enabledCondition != nil {
a.enabledCondition.Changed().Detach(a.enabledConditionChangedHandle)
}
a.enabledCondition = c
if c != nil {
a.enabled = c.Satisfied()
a.enabledConditionChangedHandle = c.Changed().Attach(func() {
if a.enabled != c.Satisfied() {
a.enabled = !a.enabled
a.raiseChanged()
}
})
}
a.raiseChanged()
}
func (a *Action) Exclusive() bool {
return a.exclusive
}
func (a *Action) SetExclusive(value bool) (err error) {
if value != a.exclusive {
old := a.exclusive
a.exclusive = value
if err = a.raiseChanged(); err != nil {
a.exclusive = old
a.raiseChanged()
}
}
return
}
func (a *Action) Image() Image {
return a.image
}
func (a *Action) SetImage(value Image) (err error) {
if value != a.image {
old := a.image
a.image = value
if err = a.raiseChanged(); err != nil {
a.image = old
a.raiseChanged()
}
}
return
}
func (a *Action) Shortcut() Shortcut {
return a.shortcut
}
func (a *Action) SetShortcut(shortcut Shortcut) (err error) {
if shortcut != a.shortcut {
old := a.shortcut
a.shortcut = shortcut
defer func() {
if err != nil {
a.shortcut = old
}
}()
if err = a.raiseChanged(); err != nil {
a.shortcut = old
a.raiseChanged()
} else {
if shortcut.Key == 0 {
delete(shortcut2Action, old)
} else {
shortcut2Action[shortcut] = a
}
}
}
return
}
func (a *Action) Text() string {
return a.text
}
func (a *Action) SetText(value string) (err error) {
if value != a.text {
old := a.text
a.text = value
if err = a.raiseChanged(); err != nil {
a.text = old
a.raiseChanged()
}
}
return
}
func (a *Action) IsSeparator() bool {
return a.id == 0 || a.text == "-"
}
func (a *Action) ToolTip() string {
return a.toolTip
}
func (a *Action) SetToolTip(value string) (err error) {
if value != a.toolTip {
old := a.toolTip
a.toolTip = value
if err = a.raiseChanged(); err != nil {
a.toolTip = old
a.raiseChanged()
}
}
return
}
func (a *Action) Visible() bool {
return a.visible
}
func (a *Action) SetVisible(value bool) (err error) {
if a.visibleCondition != nil {
return newError("VisibleCondition != nil")
}
if value != a.visible {
old := a.visible
a.visible = value
if err = a.raiseVisibleChanged(); err != nil {
a.visible = old
a.raiseVisibleChanged()
}
}
return
}
func (a *Action) VisibleCondition() Condition {
return a.visibleCondition
}
func (a *Action) SetVisibleCondition(c Condition) {
if a.visibleCondition != nil {
a.visibleCondition.Changed().Detach(a.visibleConditionChangedHandle)
}
a.visibleCondition = c
if c != nil {
a.visible = c.Satisfied()
a.visibleConditionChangedHandle = c.Changed().Attach(func() {
if a.visible != c.Satisfied() {
a.visible = !a.visible
a.raiseVisibleChanged()
}
})
}
a.raiseChanged()
}
func (a *Action) Triggered() *Event {
return a.triggeredPublisher.Event()
}
func (a *Action) raiseTriggered() {
if a.Checkable() {
a.SetChecked(!a.Checked())
}
a.triggeredPublisher.Publish()
}
func (a *Action) addChangedHandler(handler actionChangedHandler) {
a.changedHandlers = append(a.changedHandlers, handler)
}
func (a *Action) removeChangedHandler(handler actionChangedHandler) {
for i, h := range a.changedHandlers {
if h == handler {
a.changedHandlers = append(a.changedHandlers[:i], a.changedHandlers[i+1:]...)
break
}
}
}
func (a *Action) raiseChanged() error {
for _, handler := range a.changedHandlers {
if err := handler.onActionChanged(a); err != nil {
return err
}
}
return nil
}
func (a *Action) raiseVisibleChanged() error {
for _, handler := range a.changedHandlers {
if err := handler.onActionVisibleChanged(a); err != nil {
return err
}
}
return nil
}