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.

168 lines
4.2KB

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