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.

367 lines
8.2KB

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