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.

366 lines
8.4KB

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