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.

event.hpp 10KB

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