You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

362 lines
8.1KB

  1. #pragma once
  2. #include "common.hpp"
  3. #include "math.hpp"
  4. #include <vector>
  5. namespace rack {
  6. namespace widget {
  7. struct Widget;
  8. }
  9. /** Handles user interaction with Widget.
  10. */
  11. namespace event {
  12. /** A per-event state shared and writable by all widgets that recursively handle an event. */
  13. struct Context {
  14. /** Whether the event should continue recursing to children Widgets. */
  15. bool propagating = true;
  16. /** Whether the event has been consumed by an event handler and no more handlers should consume the event. */
  17. bool consumed = false;
  18. /** The widget that responded to the event. */
  19. widget::Widget *target = NULL;
  20. };
  21. /** Base class for all events. */
  22. struct Base {
  23. Context *context = NULL;
  24. /** Prevents the event from being handled by more Widgets.
  25. */
  26. void stopPropagating() const {
  27. if (!context) return;
  28. context->propagating = false;
  29. }
  30. bool isPropagating() const {
  31. if (!context) return true;
  32. return context->propagating;
  33. }
  34. /** Tells the event handler that a particular Widget consumed the event.
  35. You usually want to stop propagation as well, so call consume() instead.
  36. */
  37. void setTarget(widget::Widget *w) const {
  38. if (!context) return;
  39. context->target = w;
  40. }
  41. widget::Widget *getTarget() const {
  42. if (!context) return NULL;
  43. return context->target;
  44. }
  45. /** Sets the target Widget and stops propagating.
  46. A NULL Widget may be passed to consume but not set a target.
  47. */
  48. void consume(widget::Widget *w) const {
  49. if (!context) return;
  50. context->propagating = false;
  51. context->consumed = true;
  52. context->target = w;
  53. }
  54. bool isConsumed() const {
  55. if (!context) return false;
  56. return context->consumed;
  57. }
  58. };
  59. /** An event prototype with a vector position. */
  60. struct PositionBase {
  61. /** The pixel coordinate where the event occurred, relative to the Widget it is called on. */
  62. math::Vec pos;
  63. };
  64. /** An event prototype with a GLFW key. */
  65. struct KeyBase {
  66. /** GLFW_KEY_* */
  67. int key;
  68. /** GLFW_KEY_*. You should usually use `key` instead. */
  69. int scancode;
  70. /** GLFW_RELEASE, GLFW_PRESS, or GLFW_REPEAT */
  71. int action;
  72. /** GLFW_MOD_* */
  73. int mods;
  74. };
  75. /** An event prototype with a Unicode character. */
  76. struct TextBase {
  77. /** Unicode code point of the character */
  78. int codepoint;
  79. };
  80. /** Occurs every frame when the mouse is hovering over a Widget.
  81. Recurses.
  82. */
  83. struct Hover : Base, PositionBase {
  84. /** Change in mouse position since the last frame. Can be zero. */
  85. math::Vec mouseDelta;
  86. };
  87. /** Occurs each mouse button press or release.
  88. Recurses.
  89. */
  90. struct Button : Base, PositionBase {
  91. /** GLFW_MOUSE_BUTTON_LEFT, GLFW_MOUSE_BUTTON_RIGHT, GLFW_MOUSE_BUTTON_MIDDLE, etc. */
  92. int button;
  93. /** GLFW_PRESS or GLFW_RELEASE */
  94. int action;
  95. /** GLFW_MOD_* */
  96. int mods;
  97. };
  98. /** Occurs when the left mouse button is pressed a second time on the same Widget within a time duration.
  99. Must set the Button target to receive this event.
  100. */
  101. struct DoubleClick : Base {
  102. };
  103. /** Occurs when a key is pressed, released, or repeated while the mouse is hovering a Widget.
  104. Recurses.
  105. */
  106. struct HoverKey : Base, PositionBase, KeyBase {
  107. };
  108. /** Occurs when a character is typed while the mouse is hovering a Widget.
  109. Recurses.
  110. */
  111. struct HoverText : Base, PositionBase, TextBase {
  112. };
  113. /** Occurs when the mouse scroll wheel is moved while the mouse is hovering a Widget.
  114. Recurses.
  115. */
  116. struct HoverScroll : Base, PositionBase {
  117. /** Change of scroll wheel position. */
  118. math::Vec scrollDelta;
  119. };
  120. /** Occurs when a Widget begins consuming the Hover event.
  121. Must set the Hover target to receive this event.
  122. */
  123. struct Enter : Base {
  124. };
  125. /** Occurs when a different Widget is entered.
  126. Must set the Hover target to receive this event.
  127. */
  128. struct Leave : Base {
  129. };
  130. /** Occurs when a Widget begins consuming the Button press event for the left mouse button.
  131. Must set the Button target to receive this event.
  132. */
  133. struct Select : Base {
  134. };
  135. /** Occurs when a different Widget is selected.
  136. Must set the Button target to receive this event.
  137. */
  138. struct Deselect : Base {
  139. };
  140. /** Occurs when a key is pressed, released, or repeated while a Widget is selected.
  141. Must consume to prevent HoverKey from being triggered.
  142. */
  143. struct SelectKey : Base, KeyBase {
  144. };
  145. /** Occurs when text is typed while a Widget is selected.
  146. Must consume to prevent HoverKey from being triggered.
  147. */
  148. struct SelectText : Base, TextBase {
  149. };
  150. struct DragBase : Base {
  151. /** The mouse button held while dragging. */
  152. int button;
  153. };
  154. /** Occurs when a Widget begins being dragged.
  155. Must set the Button target to receive this event.
  156. */
  157. struct DragStart : DragBase {
  158. };
  159. /** Occurs when a Widget stops being dragged by releasing the mouse button.
  160. Must set the Button target to receive this event.
  161. */
  162. struct DragEnd : DragBase {
  163. };
  164. /** Occurs every frame on the dragged Widget.
  165. Must set the Button target to receive this event.
  166. */
  167. struct DragMove : DragBase {
  168. /** Change in mouse position since the last frame. Can be zero. */
  169. math::Vec mouseDelta;
  170. };
  171. /** Occurs every frame when the mouse is hovering over a Widget while another Widget (possibly the same one) is being dragged.
  172. Recurses.
  173. */
  174. struct DragHover : DragBase, PositionBase {
  175. /** The dragged widget */
  176. widget::Widget *origin = NULL;
  177. /** Change in mouse position since the last frame. Can be zero. */
  178. math::Vec mouseDelta;
  179. };
  180. /** Occurs when the mouse enters a Widget while dragging.
  181. Must set the DragHover target to receive this event.
  182. */
  183. struct DragEnter : DragBase {
  184. /** The dragged widget */
  185. widget::Widget *origin = NULL;
  186. };
  187. /** Occurs when the mouse leaves a Widget while dragging.
  188. Must set the DragHover target to receive this event.
  189. */
  190. struct DragLeave : DragBase {
  191. /** The dragged widget */
  192. widget::Widget *origin = NULL;
  193. };
  194. /** Occurs when the mouse button is released over a Widget while dragging.
  195. Must set the Button target to receive this event.
  196. */
  197. struct DragDrop : DragBase {
  198. /** The dragged widget */
  199. widget::Widget *origin = NULL;
  200. };
  201. /** Occurs when a selection of files from the operating system is dropped onto a Widget.
  202. Recurses.
  203. */
  204. struct PathDrop : Base, PositionBase {
  205. PathDrop(const std::vector<std::string> &paths) : paths(paths) {}
  206. /** List of file paths in the dropped selection */
  207. const std::vector<std::string> &paths;
  208. };
  209. /** Occurs after a certain action is triggered on a Widget.
  210. The concept of an "action" is defined by the type of Widget.
  211. */
  212. struct Action : Base {
  213. };
  214. /** Occurs after the value of a Widget changes.
  215. The concept of a "value" is defined by the type of Widget.
  216. */
  217. struct Change : Base {
  218. };
  219. /** Occurs after the zoom level of a Widget is changed.
  220. Recurses.
  221. */
  222. struct Zoom : Base {
  223. };
  224. /** Occurs after a Widget's position is set by Widget::setPosition().
  225. */
  226. struct Reposition : Base {
  227. };
  228. /** Occurs after a Widget's size is set by Widget::setSize().
  229. */
  230. struct Resize : Base {
  231. };
  232. /** Occurs after a Widget is added to a parent.
  233. */
  234. struct Add : Base {
  235. };
  236. /** Occurs before a Widget is removed from its parent.
  237. */
  238. struct Remove : Base {
  239. };
  240. /** Occurs after a Widget is shown with Widget::show().
  241. Recurses.
  242. */
  243. struct Show : Base {
  244. };
  245. /** Occurs after a Widget is hidden with Widget::hide().
  246. Recurses.
  247. */
  248. struct Hide : Base {
  249. };
  250. struct State {
  251. widget::Widget *rootWidget = NULL;
  252. /** State widgets
  253. Don't set these directly unless you know what you're doing. Use the set*() methods instead.
  254. */
  255. widget::Widget *hoveredWidget = NULL;
  256. widget::Widget *draggedWidget = NULL;
  257. int dragButton = 0;
  258. widget::Widget *dragHoveredWidget = NULL;
  259. widget::Widget *selectedWidget = NULL;
  260. /** For double-clicking */
  261. double lastClickTime = -INFINITY;
  262. widget::Widget *lastClickedWidget = NULL;
  263. void setHovered(widget::Widget *w);
  264. void setDragged(widget::Widget *w, int button);
  265. void setDragHovered(widget::Widget *w);
  266. void setSelected(widget::Widget *w);
  267. /** Prepares a widget for deletion */
  268. void finalizeWidget(widget::Widget *w);
  269. void handleButton(math::Vec pos, int button, int action, int mods);
  270. void handleHover(math::Vec pos, math::Vec mouseDelta);
  271. void handleLeave();
  272. void handleScroll(math::Vec pos, math::Vec scrollDelta);
  273. void handleText(math::Vec pos, int codepoint);
  274. void handleKey(math::Vec pos, int key, int scancode, int action, int mods);
  275. void handleDrop(math::Vec pos, const std::vector<std::string> &paths);
  276. void handleZoom();
  277. };
  278. } // namespace event
  279. } // namespace rack