123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386 |
- // 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 *Bitmap
- enabledCondition Condition
- enabledConditionChangedHandle int
- visibleCondition Condition
- visibleConditionChangedHandle int
- refCount int
- shortcut Shortcut
- enabled bool
- visible bool
- checkable bool
- checked 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 value != a.checked {
- old := a.checked
- a.checked = value
- if err = a.raiseChanged(); err != nil {
- a.checked = old
- a.raiseChanged()
- }
- }
- return
- }
- func (a *Action) Enabled() bool {
- if a.enabledCondition != nil {
- return a.enabledCondition.Satisfied()
- }
- 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() *Bitmap {
- return a.image
- }
- func (a *Action) SetImage(value *Bitmap) (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 {
- if a.visibleCondition != nil {
- return a.visibleCondition.Satisfied()
- }
- 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() {
- 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
- }
|