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.

179 lines
4.8KB

  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. struct Widget;
  32. /** Returns the name of a GLFW key macro.
  33. Printable keys return the key string such as "Q", "=", "\t", etc.
  34. Letters are capitalized.
  35. Does not remap keys based on keyboard layout, so GLFW_KEY_Q always returns "Q".
  36. GLFW_KEY_SPACE returns "Space" translated to the current language.
  37. Non-printable characters return the name of the key in the current language.
  38. Key 0 returns "".
  39. */
  40. std::string getKeyName(int key);
  41. /** Returns the name of a key command/chord/combo.
  42. For example, getKeyCommandName(GLFW_KEY_Q, GLFW_MOD_CONTROL) == "Ctrl+Q" translated to the current language.
  43. */
  44. std::string getKeyCommandName(int key, int mods = 0);
  45. /** A per-event state shared and writable by all widgets that recursively handle an event. */
  46. struct EventContext {
  47. /** Whether the event should continue recursing to children Widgets. */
  48. bool propagating = true;
  49. /** Whether the event has been consumed by an event handler and no more handlers should consume the event. */
  50. bool consumed = false;
  51. /** The widget that responded to the event. */
  52. Widget* target = NULL;
  53. };
  54. /** Base class for all events. */
  55. struct BaseEvent {
  56. EventContext* context = NULL;
  57. /** Prevents the event from being handled by more Widgets.
  58. */
  59. void stopPropagating() const {
  60. if (!context)
  61. return;
  62. context->propagating = false;
  63. }
  64. bool isPropagating() const {
  65. if (!context)
  66. return true;
  67. return context->propagating;
  68. }
  69. /** Tells the event handler that a particular Widget consumed the event.
  70. You usually want to stop propagation as well, so call consume() instead.
  71. */
  72. void setTarget(Widget* w) const {
  73. if (!context)
  74. return;
  75. context->target = w;
  76. }
  77. Widget* getTarget() const {
  78. if (!context)
  79. return NULL;
  80. return context->target;
  81. }
  82. /** Sets the target Widget and stops propagating.
  83. A NULL Widget may be passed to consume but not set a target.
  84. */
  85. void consume(Widget* w) const {
  86. if (!context)
  87. return;
  88. context->propagating = false;
  89. context->consumed = true;
  90. context->target = w;
  91. }
  92. void unconsume() const {
  93. if (!context)
  94. return;
  95. context->consumed = false;
  96. }
  97. bool isConsumed() const {
  98. if (!context)
  99. return false;
  100. return context->consumed;
  101. }
  102. };
  103. struct EventState {
  104. Widget* rootWidget = NULL;
  105. /** State widgets
  106. Don't set these directly unless you know what you're doing. Use the set*() methods instead.
  107. */
  108. Widget* hoveredWidget = NULL;
  109. Widget* draggedWidget = NULL;
  110. int dragButton = 0;
  111. Widget* dragHoveredWidget = NULL;
  112. Widget* selectedWidget = NULL;
  113. /** For double-clicking */
  114. double lastClickTime = -INFINITY;
  115. Widget* lastClickedWidget = NULL;
  116. std::set<int> heldKeys;
  117. Widget* getRootWidget() {
  118. return rootWidget;
  119. }
  120. Widget* getHoveredWidget() {
  121. return hoveredWidget;
  122. }
  123. Widget* getDraggedWidget() {
  124. return draggedWidget;
  125. }
  126. Widget* getDragHoveredWidget() {
  127. return dragHoveredWidget;
  128. }
  129. Widget* getSelectedWidget() {
  130. return selectedWidget;
  131. }
  132. void setHoveredWidget(Widget* w);
  133. void setDraggedWidget(Widget* w, int button);
  134. void setDragHoveredWidget(Widget* w);
  135. void setSelectedWidget(Widget* w);
  136. DEPRECATED void setHovered(Widget* w) {setHoveredWidget(w);}
  137. DEPRECATED void setDragged(Widget* w, int button) {setDraggedWidget(w, button);}
  138. DEPRECATED void setDragHovered(Widget* w) {setDragHoveredWidget(w);}
  139. DEPRECATED void setSelected(Widget* w) {setSelectedWidget(w);}
  140. /** Prepares a widget for deletion */
  141. void finalizeWidget(Widget* w);
  142. bool handleButton(math::Vec pos, int button, int action, int mods);
  143. bool handleHover(math::Vec pos, math::Vec mouseDelta);
  144. bool handleLeave();
  145. bool handleScroll(math::Vec pos, math::Vec scrollDelta);
  146. bool handleText(math::Vec pos, uint32_t codepoint);
  147. bool handleKey(math::Vec pos, int key, int scancode, int action, int mods);
  148. bool handleDrop(math::Vec pos, const std::vector<std::string>& paths);
  149. bool handleDirty();
  150. };
  151. } // namespace widget
  152. } // namespace rack