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.

130 lines
2.9KB

  1. #include <app/Knob.hpp>
  2. #include <app.hpp>
  3. #include <app/Scene.hpp>
  4. #include <random.hpp>
  5. #include <history.hpp>
  6. namespace rack {
  7. namespace app {
  8. static const float KNOB_SENSITIVITY = 0.0015f;
  9. void Knob::onHover(const event::Hover& e) {
  10. math::Vec c = box.size.div(2);
  11. float dist = e.pos.minus(c).norm();
  12. if (dist <= c.x) {
  13. ParamWidget::onHover(e);
  14. }
  15. }
  16. void Knob::onButton(const event::Button& e) {
  17. math::Vec c = box.size.div(2);
  18. float dist = e.pos.minus(c).norm();
  19. if (dist <= c.x) {
  20. ParamWidget::onButton(e);
  21. }
  22. }
  23. void Knob::onDragStart(const event::DragStart& e) {
  24. if (e.button != GLFW_MOUSE_BUTTON_LEFT)
  25. return;
  26. if (paramQuantity) {
  27. oldValue = paramQuantity->getSmoothValue();
  28. if (snap) {
  29. snapValue = paramQuantity->getValue();
  30. }
  31. }
  32. APP->window->cursorLock();
  33. }
  34. void Knob::onDragEnd(const event::DragEnd& e) {
  35. if (e.button != GLFW_MOUSE_BUTTON_LEFT)
  36. return;
  37. APP->window->cursorUnlock();
  38. if (paramQuantity) {
  39. float newValue = paramQuantity->getSmoothValue();
  40. if (oldValue != newValue) {
  41. // Push ParamChange history action
  42. history::ParamChange* h = new history::ParamChange;
  43. h->name = "move knob";
  44. h->moduleId = paramQuantity->module->id;
  45. h->paramId = paramQuantity->paramId;
  46. h->oldValue = oldValue;
  47. h->newValue = newValue;
  48. APP->history->push(h);
  49. }
  50. }
  51. }
  52. void Knob::onDragMove(const event::DragMove& e) {
  53. if (e.button != GLFW_MOUSE_BUTTON_LEFT)
  54. return;
  55. if (paramQuantity) {
  56. float range;
  57. if (paramQuantity->isBounded()) {
  58. range = paramQuantity->getRange();
  59. }
  60. else {
  61. // Continuous encoders scale as if their limits are +/-1
  62. range = 2.f;
  63. }
  64. float delta = (horizontal ? e.mouseDelta.x : -e.mouseDelta.y);
  65. delta *= KNOB_SENSITIVITY;
  66. delta *= speed;
  67. delta *= range;
  68. // Drag slower if mod is held
  69. int mods = APP->window->getMods();
  70. if ((mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
  71. delta /= 16.f;
  72. }
  73. // Drag even slower if mod+shift is held
  74. if ((mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) {
  75. delta /= 256.f;
  76. }
  77. if (snap) {
  78. snapValue += delta;
  79. snapValue = math::clamp(snapValue, paramQuantity->getMinValue(), paramQuantity->getMaxValue());
  80. paramQuantity->setValue(std::round(snapValue));
  81. }
  82. else if (smooth) {
  83. paramQuantity->setSmoothValue(paramQuantity->getSmoothValue() + delta);
  84. }
  85. else {
  86. paramQuantity->setValue(paramQuantity->getValue() + delta);
  87. }
  88. }
  89. ParamWidget::onDragMove(e);
  90. }
  91. void Knob::reset() {
  92. if (paramQuantity && paramQuantity->isBounded()) {
  93. paramQuantity->reset();
  94. oldValue = snapValue = paramQuantity->getValue();
  95. }
  96. }
  97. void Knob::randomize() {
  98. if (paramQuantity && paramQuantity->isBounded()) {
  99. float value = math::rescale(random::uniform(), 0.f, 1.f, paramQuantity->getMinValue(), paramQuantity->getMaxValue());
  100. if (snap)
  101. value = std::round(value);
  102. paramQuantity->setValue(value);
  103. oldValue = snapValue = paramQuantity->getValue();
  104. }
  105. }
  106. } // namespace app
  107. } // namespace rack