action.go 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. // Copyright 2010 The Walk Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // +build windows
  5. package walk
  6. type actionChangedHandler interface {
  7. onActionChanged(action *Action) error
  8. onActionVisibleChanged(action *Action) error
  9. }
  10. var (
  11. // ISSUE: When pressing enter resp. escape,
  12. // WM_COMMAND with wParam=1 resp. 2 is sent.
  13. // Maybe there is more to consider.
  14. nextActionId uint16 = 3
  15. actionsById = make(map[uint16]*Action)
  16. shortcut2Action = make(map[Shortcut]*Action)
  17. )
  18. type Action struct {
  19. menu *Menu
  20. triggeredPublisher EventPublisher
  21. changedHandlers []actionChangedHandler
  22. text string
  23. toolTip string
  24. image *Bitmap
  25. enabledCondition Condition
  26. enabledConditionChangedHandle int
  27. visibleCondition Condition
  28. visibleConditionChangedHandle int
  29. refCount int
  30. shortcut Shortcut
  31. enabled bool
  32. visible bool
  33. checkable bool
  34. checked bool
  35. exclusive bool
  36. id uint16
  37. }
  38. func NewAction() *Action {
  39. a := &Action{
  40. enabled: true,
  41. id: nextActionId,
  42. visible: true,
  43. }
  44. actionsById[a.id] = a
  45. nextActionId++
  46. return a
  47. }
  48. func NewMenuAction(menu *Menu) *Action {
  49. a := NewAction()
  50. a.menu = menu
  51. return a
  52. }
  53. func NewSeparatorAction() *Action {
  54. return &Action{
  55. enabled: true,
  56. visible: true,
  57. }
  58. }
  59. func (a *Action) addRef() {
  60. a.refCount++
  61. }
  62. func (a *Action) release() {
  63. a.refCount--
  64. if a.refCount == 0 {
  65. a.SetEnabledCondition(nil)
  66. a.SetVisibleCondition(nil)
  67. if a.menu != nil {
  68. a.menu.actions.Clear()
  69. a.menu.Dispose()
  70. }
  71. delete(actionsById, a.id)
  72. delete(shortcut2Action, a.shortcut)
  73. }
  74. }
  75. func (a *Action) Checkable() bool {
  76. return a.checkable
  77. }
  78. func (a *Action) SetCheckable(value bool) (err error) {
  79. if value != a.checkable {
  80. old := a.checkable
  81. a.checkable = value
  82. if err = a.raiseChanged(); err != nil {
  83. a.checkable = old
  84. a.raiseChanged()
  85. }
  86. }
  87. return
  88. }
  89. func (a *Action) Checked() bool {
  90. return a.checked
  91. }
  92. func (a *Action) SetChecked(value bool) (err error) {
  93. if value != a.checked {
  94. old := a.checked
  95. a.checked = value
  96. if err = a.raiseChanged(); err != nil {
  97. a.checked = old
  98. a.raiseChanged()
  99. }
  100. }
  101. return
  102. }
  103. func (a *Action) Enabled() bool {
  104. if a.enabledCondition != nil {
  105. return a.enabledCondition.Satisfied()
  106. }
  107. return a.enabled
  108. }
  109. func (a *Action) SetEnabled(value bool) (err error) {
  110. if a.enabledCondition != nil {
  111. return newError("EnabledCondition != nil")
  112. }
  113. if value != a.enabled {
  114. old := a.enabled
  115. a.enabled = value
  116. if err = a.raiseChanged(); err != nil {
  117. a.enabled = old
  118. a.raiseChanged()
  119. }
  120. }
  121. return
  122. }
  123. func (a *Action) EnabledCondition() Condition {
  124. return a.enabledCondition
  125. }
  126. func (a *Action) SetEnabledCondition(c Condition) {
  127. if a.enabledCondition != nil {
  128. a.enabledCondition.Changed().Detach(a.enabledConditionChangedHandle)
  129. }
  130. a.enabledCondition = c
  131. if c != nil {
  132. a.enabled = c.Satisfied()
  133. a.enabledConditionChangedHandle = c.Changed().Attach(func() {
  134. if a.enabled != c.Satisfied() {
  135. a.enabled = !a.enabled
  136. a.raiseChanged()
  137. }
  138. })
  139. }
  140. a.raiseChanged()
  141. }
  142. func (a *Action) Exclusive() bool {
  143. return a.exclusive
  144. }
  145. func (a *Action) SetExclusive(value bool) (err error) {
  146. if value != a.exclusive {
  147. old := a.exclusive
  148. a.exclusive = value
  149. if err = a.raiseChanged(); err != nil {
  150. a.exclusive = old
  151. a.raiseChanged()
  152. }
  153. }
  154. return
  155. }
  156. func (a *Action) Image() *Bitmap {
  157. return a.image
  158. }
  159. func (a *Action) SetImage(value *Bitmap) (err error) {
  160. if value != a.image {
  161. old := a.image
  162. a.image = value
  163. if err = a.raiseChanged(); err != nil {
  164. a.image = old
  165. a.raiseChanged()
  166. }
  167. }
  168. return
  169. }
  170. func (a *Action) Shortcut() Shortcut {
  171. return a.shortcut
  172. }
  173. func (a *Action) SetShortcut(shortcut Shortcut) (err error) {
  174. if shortcut != a.shortcut {
  175. old := a.shortcut
  176. a.shortcut = shortcut
  177. defer func() {
  178. if err != nil {
  179. a.shortcut = old
  180. }
  181. }()
  182. if err = a.raiseChanged(); err != nil {
  183. a.shortcut = old
  184. a.raiseChanged()
  185. } else {
  186. if shortcut.Key == 0 {
  187. delete(shortcut2Action, old)
  188. } else {
  189. shortcut2Action[shortcut] = a
  190. }
  191. }
  192. }
  193. return
  194. }
  195. func (a *Action) Text() string {
  196. return a.text
  197. }
  198. func (a *Action) SetText(value string) (err error) {
  199. if value != a.text {
  200. old := a.text
  201. a.text = value
  202. if err = a.raiseChanged(); err != nil {
  203. a.text = old
  204. a.raiseChanged()
  205. }
  206. }
  207. return
  208. }
  209. func (a *Action) IsSeparator() bool {
  210. return a.id == 0 || a.text == "-"
  211. }
  212. func (a *Action) ToolTip() string {
  213. return a.toolTip
  214. }
  215. func (a *Action) SetToolTip(value string) (err error) {
  216. if value != a.toolTip {
  217. old := a.toolTip
  218. a.toolTip = value
  219. if err = a.raiseChanged(); err != nil {
  220. a.toolTip = old
  221. a.raiseChanged()
  222. }
  223. }
  224. return
  225. }
  226. func (a *Action) Visible() bool {
  227. if a.visibleCondition != nil {
  228. return a.visibleCondition.Satisfied()
  229. }
  230. return a.visible
  231. }
  232. func (a *Action) SetVisible(value bool) (err error) {
  233. if a.visibleCondition != nil {
  234. return newError("VisibleCondition != nil")
  235. }
  236. if value != a.visible {
  237. old := a.visible
  238. a.visible = value
  239. if err = a.raiseVisibleChanged(); err != nil {
  240. a.visible = old
  241. a.raiseVisibleChanged()
  242. }
  243. }
  244. return
  245. }
  246. func (a *Action) VisibleCondition() Condition {
  247. return a.visibleCondition
  248. }
  249. func (a *Action) SetVisibleCondition(c Condition) {
  250. if a.visibleCondition != nil {
  251. a.visibleCondition.Changed().Detach(a.visibleConditionChangedHandle)
  252. }
  253. a.visibleCondition = c
  254. if c != nil {
  255. a.visible = c.Satisfied()
  256. a.visibleConditionChangedHandle = c.Changed().Attach(func() {
  257. if a.visible != c.Satisfied() {
  258. a.visible = !a.visible
  259. a.raiseVisibleChanged()
  260. }
  261. })
  262. }
  263. a.raiseChanged()
  264. }
  265. func (a *Action) Triggered() *Event {
  266. return a.triggeredPublisher.Event()
  267. }
  268. func (a *Action) raiseTriggered() {
  269. a.triggeredPublisher.Publish()
  270. }
  271. func (a *Action) addChangedHandler(handler actionChangedHandler) {
  272. a.changedHandlers = append(a.changedHandlers, handler)
  273. }
  274. func (a *Action) removeChangedHandler(handler actionChangedHandler) {
  275. for i, h := range a.changedHandlers {
  276. if h == handler {
  277. a.changedHandlers = append(a.changedHandlers[:i], a.changedHandlers[i+1:]...)
  278. break
  279. }
  280. }
  281. }
  282. func (a *Action) raiseChanged() error {
  283. for _, handler := range a.changedHandlers {
  284. if err := handler.onActionChanged(a); err != nil {
  285. return err
  286. }
  287. }
  288. return nil
  289. }
  290. func (a *Action) raiseVisibleChanged() error {
  291. for _, handler := range a.changedHandlers {
  292. if err := handler.onActionVisibleChanged(a); err != nil {
  293. return err
  294. }
  295. }
  296. return nil
  297. }