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.

338 lines
7.1KB

  1. #include <event.hpp>
  2. #include <widget/Widget.hpp>
  3. #include <app.hpp>
  4. #include <window.hpp>
  5. namespace rack {
  6. namespace event {
  7. void State::setHovered(widget::Widget* w) {
  8. if (w == hoveredWidget)
  9. return;
  10. if (hoveredWidget) {
  11. // Leave
  12. Leave eLeave;
  13. hoveredWidget->onLeave(eLeave);
  14. hoveredWidget = NULL;
  15. }
  16. if (w) {
  17. // Enter
  18. Context cEnter;
  19. cEnter.target = w;
  20. Enter eEnter;
  21. eEnter.context = &cEnter;
  22. w->onEnter(eEnter);
  23. hoveredWidget = cEnter.target;
  24. }
  25. }
  26. void State::setDragged(widget::Widget* w, int button) {
  27. if (w == draggedWidget)
  28. return;
  29. if (draggedWidget) {
  30. // DragEnd
  31. DragEnd eDragEnd;
  32. eDragEnd.button = dragButton;
  33. draggedWidget->onDragEnd(eDragEnd);
  34. draggedWidget = NULL;
  35. }
  36. dragButton = button;
  37. if (w) {
  38. // DragStart
  39. Context cDragStart;
  40. cDragStart.target = w;
  41. DragStart eDragStart;
  42. eDragStart.context = &cDragStart;
  43. eDragStart.button = dragButton;
  44. w->onDragStart(eDragStart);
  45. draggedWidget = cDragStart.target;
  46. }
  47. }
  48. void State::setDragHovered(widget::Widget* w) {
  49. if (w == dragHoveredWidget)
  50. return;
  51. if (dragHoveredWidget) {
  52. // DragLeave
  53. DragLeave eDragLeave;
  54. eDragLeave.button = dragButton;
  55. eDragLeave.origin = draggedWidget;
  56. dragHoveredWidget->onDragLeave(eDragLeave);
  57. dragHoveredWidget = NULL;
  58. }
  59. if (w) {
  60. // DragEnter
  61. Context cDragEnter;
  62. cDragEnter.target = w;
  63. DragEnter eDragEnter;
  64. eDragEnter.context = &cDragEnter;
  65. eDragEnter.button = dragButton;
  66. eDragEnter.origin = draggedWidget;
  67. w->onDragEnter(eDragEnter);
  68. dragHoveredWidget = cDragEnter.target;
  69. }
  70. }
  71. void State::setSelected(widget::Widget* w) {
  72. if (w == selectedWidget)
  73. return;
  74. if (selectedWidget) {
  75. // Deselect
  76. Deselect eDeselect;
  77. selectedWidget->onDeselect(eDeselect);
  78. selectedWidget = NULL;
  79. }
  80. if (w) {
  81. // Select
  82. Context cSelect;
  83. cSelect.target = w;
  84. Select eSelect;
  85. eSelect.context = &cSelect;
  86. w->onSelect(eSelect);
  87. selectedWidget = cSelect.target;
  88. }
  89. }
  90. void State::finalizeWidget(widget::Widget* w) {
  91. if (hoveredWidget == w)
  92. setHovered(NULL);
  93. if (draggedWidget == w)
  94. setDragged(NULL, 0);
  95. if (dragHoveredWidget == w)
  96. setDragHovered(NULL);
  97. if (selectedWidget == w)
  98. setSelected(NULL);
  99. if (lastClickedWidget == w)
  100. lastClickedWidget = NULL;
  101. }
  102. bool State::handleButton(math::Vec pos, int button, int action, int mods) {
  103. bool cursorLocked = APP->window->isCursorLocked();
  104. widget::Widget* clickedWidget = NULL;
  105. if (!cursorLocked) {
  106. // Button
  107. Context cButton;
  108. Button eButton;
  109. eButton.context = &cButton;
  110. eButton.pos = pos;
  111. eButton.button = button;
  112. eButton.action = action;
  113. eButton.mods = mods;
  114. rootWidget->onButton(eButton);
  115. clickedWidget = cButton.target;
  116. }
  117. if (action == GLFW_PRESS) {
  118. setDragged(clickedWidget, button);
  119. }
  120. if (action == GLFW_RELEASE) {
  121. setDragHovered(NULL);
  122. if (clickedWidget && draggedWidget) {
  123. // DragDrop
  124. DragDrop eDragDrop;
  125. eDragDrop.button = dragButton;
  126. eDragDrop.origin = draggedWidget;
  127. clickedWidget->onDragDrop(eDragDrop);
  128. }
  129. setDragged(NULL, 0);
  130. }
  131. if (button == GLFW_MOUSE_BUTTON_LEFT) {
  132. if (action == GLFW_PRESS) {
  133. setSelected(clickedWidget);
  134. }
  135. if (action == GLFW_PRESS) {
  136. const double doubleClickDuration = 0.3;
  137. double clickTime = glfwGetTime();
  138. if (clickedWidget
  139. && clickTime - lastClickTime <= doubleClickDuration
  140. && lastClickedWidget == clickedWidget) {
  141. // DoubleClick
  142. DoubleClick eDoubleClick;
  143. clickedWidget->onDoubleClick(eDoubleClick);
  144. // Reset double click
  145. lastClickTime = -INFINITY;
  146. lastClickedWidget = NULL;
  147. }
  148. else {
  149. lastClickTime = clickTime;
  150. lastClickedWidget = clickedWidget;
  151. }
  152. }
  153. }
  154. return !!clickedWidget;
  155. }
  156. bool State::handleHover(math::Vec pos, math::Vec mouseDelta) {
  157. bool cursorLocked = APP->window->isCursorLocked();
  158. // Fake a key RACK_HELD event for each held key
  159. if (!cursorLocked) {
  160. int mods = APP->window->getMods();
  161. for (int key : heldKeys) {
  162. int scancode = glfwGetKeyScancode(key);
  163. handleKey(pos, key, scancode, RACK_HELD, mods);
  164. }
  165. }
  166. if (draggedWidget) {
  167. // DragMove
  168. DragMove eDragMove;
  169. eDragMove.button = dragButton;
  170. eDragMove.mouseDelta = mouseDelta;
  171. draggedWidget->onDragMove(eDragMove);
  172. if (!cursorLocked) {
  173. // DragHover
  174. Context cDragHover;
  175. DragHover eDragHover;
  176. eDragHover.context = &cDragHover;
  177. eDragHover.button = dragButton;
  178. eDragHover.pos = pos;
  179. eDragHover.mouseDelta = mouseDelta;
  180. eDragHover.origin = draggedWidget;
  181. rootWidget->onDragHover(eDragHover);
  182. setDragHovered(cDragHover.target);
  183. if (cDragHover.target)
  184. return true;
  185. }
  186. }
  187. if (!cursorLocked) {
  188. // Hover
  189. Context cHover;
  190. Hover eHover;
  191. eHover.context = &cHover;
  192. eHover.pos = pos;
  193. eHover.mouseDelta = mouseDelta;
  194. rootWidget->onHover(eHover);
  195. setHovered(cHover.target);
  196. return !!cHover.target;
  197. }
  198. return false;
  199. }
  200. bool State::handleLeave() {
  201. heldKeys.clear();
  202. // When leaving the window, don't un-hover widgets because the mouse might be dragging.
  203. // setDragHovered(NULL);
  204. // setHovered(NULL);
  205. return true;
  206. }
  207. bool State::handleScroll(math::Vec pos, math::Vec scrollDelta) {
  208. // HoverScroll
  209. Context cHoverScroll;
  210. HoverScroll eHoverScroll;
  211. eHoverScroll.context = &cHoverScroll;
  212. eHoverScroll.pos = pos;
  213. eHoverScroll.scrollDelta = scrollDelta;
  214. rootWidget->onHoverScroll(eHoverScroll);
  215. return !!cHoverScroll.target;
  216. }
  217. bool State::handleDrop(math::Vec pos, const std::vector<std::string>& paths) {
  218. // PathDrop
  219. Context cPathDrop;
  220. PathDrop ePathDrop(paths);
  221. ePathDrop.context = &cPathDrop;
  222. ePathDrop.pos = pos;
  223. rootWidget->onPathDrop(ePathDrop);
  224. return !!cPathDrop.target;
  225. }
  226. bool State::handleText(math::Vec pos, int codepoint) {
  227. if (selectedWidget) {
  228. // SelectText
  229. Context cSelectText;
  230. SelectText eSelectText;
  231. eSelectText.context = &cSelectText;
  232. eSelectText.codepoint = codepoint;
  233. selectedWidget->onSelectText(eSelectText);
  234. if (cSelectText.target)
  235. return true;
  236. }
  237. // HoverText
  238. Context cHoverText;
  239. HoverText eHoverText;
  240. eHoverText.context = &cHoverText;
  241. eHoverText.pos = pos;
  242. eHoverText.codepoint = codepoint;
  243. rootWidget->onHoverText(eHoverText);
  244. return !!cHoverText.target;
  245. }
  246. bool State::handleKey(math::Vec pos, int key, int scancode, int action, int mods) {
  247. // Update heldKey state
  248. if (action == GLFW_PRESS) {
  249. heldKeys.insert(key);
  250. }
  251. else if (action == GLFW_RELEASE) {
  252. auto it = heldKeys.find(key);
  253. if (it != heldKeys.end())
  254. heldKeys.erase(it);
  255. }
  256. if (selectedWidget) {
  257. // SelectKey
  258. Context cSelectKey;
  259. SelectKey eSelectKey;
  260. eSelectKey.context = &cSelectKey;
  261. eSelectKey.key = key;
  262. eSelectKey.scancode = scancode;
  263. eSelectKey.action = action;
  264. eSelectKey.mods = mods;
  265. selectedWidget->onSelectKey(eSelectKey);
  266. if (cSelectKey.target)
  267. return true;
  268. }
  269. // HoverKey
  270. Context cHoverKey;
  271. HoverKey eHoverKey;
  272. eHoverKey.context = &cHoverKey;
  273. eHoverKey.pos = pos;
  274. eHoverKey.key = key;
  275. eHoverKey.scancode = scancode;
  276. eHoverKey.action = action;
  277. eHoverKey.mods = mods;
  278. rootWidget->onHoverKey(eHoverKey);
  279. return !!cHoverKey.target;
  280. }
  281. bool State::handleZoom() {
  282. // Zoom
  283. Context cZoom;
  284. Zoom eZoom;
  285. eZoom.context = &cZoom;
  286. rootWidget->onZoom(eZoom);
  287. return true;
  288. }
  289. } // namespace event
  290. } // namespace rack