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.

160 lines
4.1KB

  1. #pragma once
  2. #include <vector>
  3. #include <set>
  4. #include <common.hpp>
  5. #include <math.hpp>
  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 "⌘"
  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. /** A key action state representing the the key is (still) being held.
  25. */
  26. #define RACK_HELD 3
  27. namespace rack {
  28. namespace widget {
  29. struct Widget;
  30. /** A per-event state shared and writable by all widgets that recursively handle an event. */
  31. struct EventContext {
  32. /** Whether the event should continue recursing to children Widgets. */
  33. bool propagating = true;
  34. /** Whether the event has been consumed by an event handler and no more handlers should consume the event. */
  35. bool consumed = false;
  36. /** The widget that responded to the event. */
  37. Widget* target = NULL;
  38. };
  39. /** Base class for all events. */
  40. struct BaseEvent {
  41. EventContext* context = NULL;
  42. /** Prevents the event from being handled by more Widgets.
  43. */
  44. void stopPropagating() const {
  45. if (!context)
  46. return;
  47. context->propagating = false;
  48. }
  49. bool isPropagating() const {
  50. if (!context)
  51. return true;
  52. return context->propagating;
  53. }
  54. /** Tells the event handler that a particular Widget consumed the event.
  55. You usually want to stop propagation as well, so call consume() instead.
  56. */
  57. void setTarget(Widget* w) const {
  58. if (!context)
  59. return;
  60. context->target = w;
  61. }
  62. Widget* getTarget() const {
  63. if (!context)
  64. return NULL;
  65. return context->target;
  66. }
  67. /** Sets the target Widget and stops propagating.
  68. A NULL Widget may be passed to consume but not set a target.
  69. */
  70. void consume(Widget* w) const {
  71. if (!context)
  72. return;
  73. context->propagating = false;
  74. context->consumed = true;
  75. context->target = w;
  76. }
  77. void unconsume() const {
  78. if (!context)
  79. return;
  80. context->consumed = false;
  81. }
  82. bool isConsumed() const {
  83. if (!context)
  84. return false;
  85. return context->consumed;
  86. }
  87. };
  88. struct EventState {
  89. Widget* rootWidget = NULL;
  90. /** State widgets
  91. Don't set these directly unless you know what you're doing. Use the set*() methods instead.
  92. */
  93. Widget* hoveredWidget = NULL;
  94. Widget* draggedWidget = NULL;
  95. int dragButton = 0;
  96. Widget* dragHoveredWidget = NULL;
  97. Widget* selectedWidget = NULL;
  98. /** For double-clicking */
  99. double lastClickTime = -INFINITY;
  100. Widget* lastClickedWidget = NULL;
  101. std::set<int> heldKeys;
  102. Widget* getRootWidget() {
  103. return rootWidget;
  104. }
  105. Widget* getHoveredWidget() {
  106. return hoveredWidget;
  107. }
  108. Widget* getDraggedWidget() {
  109. return draggedWidget;
  110. }
  111. Widget* getDragHoveredWidget() {
  112. return dragHoveredWidget;
  113. }
  114. Widget* getSelectedWidget() {
  115. return selectedWidget;
  116. }
  117. void setHoveredWidget(Widget* w);
  118. void setDraggedWidget(Widget* w, int button);
  119. void setDragHoveredWidget(Widget* w);
  120. void setSelectedWidget(Widget* w);
  121. DEPRECATED void setHovered(Widget* w) {setHoveredWidget(w);}
  122. DEPRECATED void setDragged(Widget* w, int button) {setDraggedWidget(w, button);}
  123. DEPRECATED void setDragHovered(Widget* w) {setDragHoveredWidget(w);}
  124. DEPRECATED void setSelected(Widget* w) {setSelectedWidget(w);}
  125. /** Prepares a widget for deletion */
  126. void finalizeWidget(Widget* w);
  127. bool handleButton(math::Vec pos, int button, int action, int mods);
  128. bool handleHover(math::Vec pos, math::Vec mouseDelta);
  129. bool handleLeave();
  130. bool handleScroll(math::Vec pos, math::Vec scrollDelta);
  131. bool handleText(math::Vec pos, int codepoint);
  132. bool handleKey(math::Vec pos, int key, int scancode, int action, int mods);
  133. bool handleDrop(math::Vec pos, const std::vector<std::string>& paths);
  134. bool handleDirty();
  135. };
  136. } // namespace widget
  137. } // namespace rack