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.

318 lines
6.7KB

  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) setHovered(NULL);
  92. if (draggedWidget == w) setDragged(NULL, 0);
  93. if (dragHoveredWidget == w) setDragHovered(NULL);
  94. if (selectedWidget == w) setSelected(NULL);
  95. if (lastClickedWidget == w) lastClickedWidget = NULL;
  96. }
  97. bool State::handleButton(math::Vec pos, int button, int action, int mods) {
  98. // Button
  99. Context cButton;
  100. Button eButton;
  101. eButton.context = &cButton;
  102. eButton.pos = pos;
  103. eButton.button = button;
  104. eButton.action = action;
  105. eButton.mods = mods;
  106. rootWidget->onButton(eButton);
  107. widget::Widget *clickedWidget = cButton.target;
  108. if (action == GLFW_PRESS) {
  109. setDragged(clickedWidget, button);
  110. }
  111. if (action == GLFW_RELEASE) {
  112. setDragHovered(NULL);
  113. if (clickedWidget && draggedWidget) {
  114. // DragDrop
  115. DragDrop eDragDrop;
  116. eDragDrop.button = dragButton;
  117. eDragDrop.origin = draggedWidget;
  118. clickedWidget->onDragDrop(eDragDrop);
  119. }
  120. setDragged(NULL, 0);
  121. }
  122. if (button == GLFW_MOUSE_BUTTON_LEFT) {
  123. if (action == GLFW_PRESS) {
  124. setSelected(clickedWidget);
  125. }
  126. if (action == GLFW_PRESS) {
  127. const double doubleClickDuration = 0.3;
  128. double clickTime = glfwGetTime();
  129. if (clickedWidget
  130. && clickTime - lastClickTime <= doubleClickDuration
  131. && lastClickedWidget == clickedWidget) {
  132. // DoubleClick
  133. DoubleClick eDoubleClick;
  134. clickedWidget->onDoubleClick(eDoubleClick);
  135. // Reset double click
  136. lastClickTime = -INFINITY;
  137. lastClickedWidget = NULL;
  138. }
  139. else {
  140. lastClickTime = clickTime;
  141. lastClickedWidget = clickedWidget;
  142. }
  143. }
  144. }
  145. return !!clickedWidget;
  146. }
  147. bool State::handleHover(math::Vec pos, math::Vec mouseDelta) {
  148. // Fake a key RACK_HELD event for each held key
  149. int mods = APP->window->getMods();
  150. for (int key : heldKeys) {
  151. int scancode = glfwGetKeyScancode(key);
  152. handleKey(pos, key, scancode, RACK_HELD, mods);
  153. }
  154. if (draggedWidget) {
  155. // DragMove
  156. DragMove eDragMove;
  157. eDragMove.button = dragButton;
  158. eDragMove.mouseDelta = mouseDelta;
  159. draggedWidget->onDragMove(eDragMove);
  160. // DragHover
  161. Context cDragHover;
  162. DragHover eDragHover;
  163. eDragHover.context = &cDragHover;
  164. eDragHover.button = dragButton;
  165. eDragHover.pos = pos;
  166. eDragHover.mouseDelta = mouseDelta;
  167. eDragHover.origin = draggedWidget;
  168. rootWidget->onDragHover(eDragHover);
  169. setDragHovered(cDragHover.target);
  170. if (cDragHover.target)
  171. return true;
  172. }
  173. // Hover
  174. Context cHover;
  175. Hover eHover;
  176. eHover.context = &cHover;
  177. eHover.pos = pos;
  178. eHover.mouseDelta = mouseDelta;
  179. rootWidget->onHover(eHover);
  180. setHovered(cHover.target);
  181. return !!cHover.target;
  182. }
  183. bool State::handleLeave() {
  184. heldKeys.clear();
  185. setDragHovered(NULL);
  186. setHovered(NULL);
  187. return true;
  188. }
  189. bool State::handleScroll(math::Vec pos, math::Vec scrollDelta) {
  190. // HoverScroll
  191. Context cHoverScroll;
  192. HoverScroll eHoverScroll;
  193. eHoverScroll.context = &cHoverScroll;
  194. eHoverScroll.pos = pos;
  195. eHoverScroll.scrollDelta = scrollDelta;
  196. rootWidget->onHoverScroll(eHoverScroll);
  197. return !!cHoverScroll.target;
  198. }
  199. bool State::handleDrop(math::Vec pos, const std::vector<std::string> &paths) {
  200. // PathDrop
  201. Context cPathDrop;
  202. PathDrop ePathDrop(paths);
  203. ePathDrop.context = &cPathDrop;
  204. ePathDrop.pos = pos;
  205. rootWidget->onPathDrop(ePathDrop);
  206. return !!cPathDrop.target;
  207. }
  208. bool State::handleText(math::Vec pos, int codepoint) {
  209. if (selectedWidget) {
  210. // SelectText
  211. Context cSelectText;
  212. SelectText eSelectText;
  213. eSelectText.context = &cSelectText;
  214. eSelectText.codepoint = codepoint;
  215. selectedWidget->onSelectText(eSelectText);
  216. if (cSelectText.target)
  217. return true;
  218. }
  219. // HoverText
  220. Context cHoverText;
  221. HoverText eHoverText;
  222. eHoverText.context = &cHoverText;
  223. eHoverText.pos = pos;
  224. eHoverText.codepoint = codepoint;
  225. rootWidget->onHoverText(eHoverText);
  226. return !!cHoverText.target;
  227. }
  228. bool State::handleKey(math::Vec pos, int key, int scancode, int action, int mods) {
  229. // Update heldKey state
  230. if (action == GLFW_PRESS) {
  231. heldKeys.insert(key);
  232. }
  233. else if (action == GLFW_RELEASE) {
  234. auto it = heldKeys.find(key);
  235. if (it != heldKeys.end())
  236. heldKeys.erase(it);
  237. }
  238. if (selectedWidget) {
  239. // SelectKey
  240. Context cSelectKey;
  241. SelectKey eSelectKey;
  242. eSelectKey.context = &cSelectKey;
  243. eSelectKey.key = key;
  244. eSelectKey.scancode = scancode;
  245. eSelectKey.action = action;
  246. eSelectKey.mods = mods;
  247. selectedWidget->onSelectKey(eSelectKey);
  248. if (cSelectKey.target)
  249. return true;
  250. }
  251. // HoverKey
  252. Context cHoverKey;
  253. HoverKey eHoverKey;
  254. eHoverKey.context = &cHoverKey;
  255. eHoverKey.pos = pos;
  256. eHoverKey.key = key;
  257. eHoverKey.scancode = scancode;
  258. eHoverKey.action = action;
  259. eHoverKey.mods = mods;
  260. rootWidget->onHoverKey(eHoverKey);
  261. return !!cHoverKey.target;
  262. }
  263. bool State::handleZoom() {
  264. // Zoom
  265. Context cZoom;
  266. Zoom eZoom;
  267. eZoom.context = &cZoom;
  268. rootWidget->onZoom(eZoom);
  269. return true;
  270. }
  271. } // namespace event
  272. } // namespace rack