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.

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