EventHandler.go 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. package giu
  2. var _ Disposable = &eventHandlerState{}
  3. type eventHandlerState struct {
  4. isActive bool
  5. }
  6. // Dispose implements Disposable interface.
  7. func (s *eventHandlerState) Dispose() {
  8. // noop
  9. }
  10. type mouseEvent struct {
  11. mouseButton MouseButton
  12. callback func()
  13. cond func(MouseButton) bool
  14. }
  15. type keyEvent struct {
  16. key Key
  17. callback func()
  18. cond func(Key) bool
  19. }
  20. var _ Widget = &EventHandler{}
  21. // EventHandler is a universal event handler for giu widgets.
  22. // put giu.Event()... after any widget to handle any event.
  23. type EventHandler struct {
  24. hover func()
  25. mouseEvents []mouseEvent
  26. keyEvents []keyEvent
  27. onActivate,
  28. onDeactivate,
  29. onActive func()
  30. }
  31. // Event adds a new event to widget above.
  32. func Event() *EventHandler {
  33. return &EventHandler{
  34. mouseEvents: make([]mouseEvent, 0),
  35. keyEvents: make([]keyEvent, 0),
  36. }
  37. }
  38. // OnHover sets callback when item gets hovered.
  39. func (eh *EventHandler) OnHover(onHover func()) *EventHandler {
  40. eh.hover = onHover
  41. return eh
  42. }
  43. // OnActive sets a callback when ite IS ACTIVE (not activated).
  44. func (eh *EventHandler) OnActive(cb func()) *EventHandler {
  45. eh.onActive = cb
  46. return eh
  47. }
  48. // OnActivate sets callback when item gets activated.
  49. func (eh *EventHandler) OnActivate(cb func()) *EventHandler {
  50. eh.onActivate = cb
  51. return eh
  52. }
  53. // OnDeactivate sets callback when item gets deactivated.
  54. func (eh *EventHandler) OnDeactivate(cb func()) *EventHandler {
  55. eh.onDeactivate = cb
  56. return eh
  57. }
  58. // Key events
  59. // OnKeyDown sets callback when key `key` is down.
  60. func (eh *EventHandler) OnKeyDown(key Key, cb func()) *EventHandler {
  61. eh.keyEvents = append(eh.keyEvents, keyEvent{key, cb, IsKeyDown})
  62. return eh
  63. }
  64. // OnKeyPressed sets callback when key `key` is pressed.
  65. func (eh *EventHandler) OnKeyPressed(key Key, cb func()) *EventHandler {
  66. eh.keyEvents = append(eh.keyEvents, keyEvent{key, cb, IsKeyPressed})
  67. return eh
  68. }
  69. // OnKeyReleased sets callback when key `key` is released.
  70. func (eh *EventHandler) OnKeyReleased(key Key, cb func()) *EventHandler {
  71. eh.keyEvents = append(eh.keyEvents, keyEvent{key, cb, IsKeyReleased})
  72. return eh
  73. }
  74. // Mouse events
  75. // OnClick sets callback when mouse button `mouseButton` is clicked.
  76. func (eh *EventHandler) OnClick(mouseButton MouseButton, callback func()) *EventHandler {
  77. eh.mouseEvents = append(eh.mouseEvents, mouseEvent{mouseButton, callback, IsMouseClicked})
  78. return eh
  79. }
  80. // OnDClick sets callback when mouse button `mouseButton` is double-clicked.
  81. func (eh *EventHandler) OnDClick(mouseButton MouseButton, callback func()) *EventHandler {
  82. eh.mouseEvents = append(eh.mouseEvents, mouseEvent{mouseButton, callback, IsMouseDoubleClicked})
  83. return eh
  84. }
  85. // OnMouseDown sets callback when mouse button `mouseButton` is down.
  86. func (eh *EventHandler) OnMouseDown(mouseButton MouseButton, callback func()) *EventHandler {
  87. eh.mouseEvents = append(eh.mouseEvents, mouseEvent{mouseButton, callback, IsMouseDown})
  88. return eh
  89. }
  90. // OnMouseReleased sets callback when mouse button `mouseButton` is released.
  91. func (eh *EventHandler) OnMouseReleased(mouseButton MouseButton, callback func()) *EventHandler {
  92. eh.mouseEvents = append(eh.mouseEvents, mouseEvent{mouseButton, callback, IsMouseReleased})
  93. return eh
  94. }
  95. // Build implements Widget interface
  96. // nolint:gocognit,gocyclo // will fix later
  97. func (eh *EventHandler) Build() {
  98. isActive := IsItemActive()
  99. if eh.onActivate != nil || eh.onDeactivate != nil {
  100. var state *eventHandlerState
  101. stateID := GenAutoID("eventHandlerState")
  102. if s := Context.GetState(stateID); s != nil {
  103. var isOk bool
  104. state, isOk = s.(*eventHandlerState)
  105. Assert(isOk, "EventHandler", "Build", "unexpected type of state received")
  106. } else {
  107. newState := &eventHandlerState{}
  108. Context.SetState(stateID, newState)
  109. state = newState
  110. }
  111. if eh.onActivate != nil && isActive && !state.isActive {
  112. state.isActive = true
  113. eh.onActivate()
  114. }
  115. if eh.onDeactivate != nil && !isActive && state.isActive {
  116. state.isActive = false
  117. eh.onDeactivate()
  118. }
  119. }
  120. if isActive && eh.onActive != nil {
  121. eh.onActive()
  122. }
  123. if !IsItemHovered() {
  124. return
  125. }
  126. if eh.hover != nil {
  127. eh.hover()
  128. }
  129. if len(eh.keyEvents) > 0 {
  130. for _, event := range eh.keyEvents {
  131. if event.callback != nil && event.cond(event.key) {
  132. event.callback()
  133. }
  134. }
  135. }
  136. if len(eh.mouseEvents) > 0 {
  137. for _, event := range eh.mouseEvents {
  138. if event.callback != nil && event.cond(event.mouseButton) {
  139. event.callback()
  140. }
  141. }
  142. }
  143. }