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.

129 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. APP->window->cursorUnlock();
  36. if (paramQuantity) {
  37. float newValue = paramQuantity->getSmoothValue();
  38. if (oldValue != newValue) {
  39. // Push ParamChange history action
  40. history::ParamChange *h = new history::ParamChange;
  41. h->name = "move knob";
  42. h->moduleId = paramQuantity->module->id;
  43. h->paramId = paramQuantity->paramId;
  44. h->oldValue = oldValue;
  45. h->newValue = newValue;
  46. APP->history->push(h);
  47. }
  48. else {
  49. // Call Action if knob was not changed
  50. event::Action eAction;
  51. onAction(eAction);
  52. }
  53. }
  54. }
  55. void Knob::onDragMove(const event::DragMove &e) {
  56. if (paramQuantity) {
  57. float range;
  58. if (paramQuantity->isBounded()) {
  59. range = paramQuantity->getRange();
  60. }
  61. else {
  62. // Continuous encoders scale as if their limits are +/-1
  63. range = 2.f;
  64. }
  65. float delta = (horizontal ? e.mouseDelta.x : -e.mouseDelta.y);
  66. delta *= KNOB_SENSITIVITY;
  67. delta *= speed;
  68. delta *= range;
  69. // Drag slower if mod is held
  70. int mods = APP->window->getMods();
  71. if ((mods & RACK_MOD_MASK) == RACK_MOD_CTRL) {
  72. delta /= 16.f;
  73. }
  74. // Drag even slower if mod+shift is held
  75. if ((mods & RACK_MOD_MASK) == (RACK_MOD_CTRL | GLFW_MOD_SHIFT)) {
  76. delta /= 256.f;
  77. }
  78. if (snap) {
  79. snapValue += delta;
  80. snapValue = math::clamp(snapValue, paramQuantity->getMinValue(), paramQuantity->getMaxValue());
  81. paramQuantity->setValue(std::round(snapValue));
  82. }
  83. else if (smooth) {
  84. paramQuantity->setSmoothValue(paramQuantity->getSmoothValue() + delta);
  85. }
  86. else {
  87. paramQuantity->setValue(paramQuantity->getValue() + delta);
  88. }
  89. }
  90. ParamWidget::onDragMove(e);
  91. }
  92. void Knob::reset() {
  93. if (paramQuantity && paramQuantity->isBounded()) {
  94. paramQuantity->reset();
  95. oldValue = snapValue = paramQuantity->getValue();
  96. }
  97. }
  98. void Knob::randomize() {
  99. if (paramQuantity && paramQuantity->isBounded()) {
  100. float value = math::rescale(random::uniform(), 0.f, 1.f, paramQuantity->getMinValue(), paramQuantity->getMaxValue());
  101. if (snap)
  102. value = std::round(value);
  103. paramQuantity->setValue(value);
  104. oldValue = snapValue = paramQuantity->getValue();
  105. }
  106. }
  107. } // namespace app
  108. } // namespace rack