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.

141 lines
3.6KB

  1. #include "app/RackScrollWidget.hpp"
  2. #include "app/Scene.hpp"
  3. #include "window.hpp"
  4. #include "app.hpp"
  5. #include "settings.hpp"
  6. namespace rack {
  7. namespace app {
  8. RackScrollWidget::RackScrollWidget() {
  9. zoomWidget = new widget::ZoomWidget;
  10. container->addChild(zoomWidget);
  11. rackWidget = new RackWidget;
  12. rackWidget->box.size = RACK_OFFSET.mult(2);
  13. zoomWidget->addChild(rackWidget);
  14. reset();
  15. }
  16. void RackScrollWidget::step() {
  17. // Clamp zoom
  18. settings::zoom = math::clamp(settings::zoom, 0.25f, 2.f);
  19. // Round zoom to nearest percent
  20. float zoom = std::round(settings::zoom / 0.01) * 0.01;
  21. if (zoom != zoomWidget->zoom) {
  22. // Set offset based on zoomPos
  23. offset = offset.plus(zoomPos).div(zoomWidget->zoom).mult(zoom).minus(zoomPos);
  24. // Set zoom
  25. zoomWidget->setZoom(zoom);
  26. }
  27. zoomPos = box.size.div(2);
  28. // Set zoomWidget box to module bounding box
  29. math::Rect moduleBox = rackWidget->moduleContainer->getChildrenBoundingBox();
  30. if (!moduleBox.size.isFinite())
  31. moduleBox = math::Rect(RACK_OFFSET, math::Vec(0, 0));
  32. zoomWidget->box.pos = moduleBox.pos.mult(zoom);
  33. zoomWidget->box.size = moduleBox.size.mult(zoom);
  34. // Expand to moduleBox
  35. math::Rect viewportBox = moduleBox.grow(RACK_GRID_SIZE.mult(math::Vec(50, 2)));
  36. viewportBox.pos = viewportBox.pos.mult(zoom);
  37. viewportBox.size = viewportBox.size.mult(zoom);
  38. // Expand to viewport size
  39. math::Vec s = box.size.minus(viewportBox.size).max(math::Vec());
  40. viewportBox.pos = viewportBox.pos.minus(s.div(2));
  41. viewportBox.size = viewportBox.size.plus(s);
  42. // Reposition widgets
  43. zoomWidget->box = viewportBox;
  44. rackWidget->box.pos = zoomWidget->box.pos.div(zoom).neg();
  45. // Scroll rack if dragging cable near the edge of the screen
  46. math::Vec pos = APP->window->mousePos;
  47. math::Rect viewport = getViewport(box.zeroPos());
  48. if (rackWidget->incompleteCable) {
  49. float margin = 20.0;
  50. float speed = 15.0;
  51. if (pos.x <= viewport.pos.x + margin)
  52. offset.x -= speed;
  53. if (pos.x >= viewport.pos.x + viewport.size.x - margin)
  54. offset.x += speed;
  55. if (pos.y <= viewport.pos.y + margin)
  56. offset.y -= speed;
  57. if (pos.y >= viewport.pos.y + viewport.size.y - margin)
  58. offset.y += speed;
  59. }
  60. ScrollWidget::step();
  61. }
  62. void RackScrollWidget::draw(const DrawArgs &args) {
  63. // DEBUG("%f %f %f %f", RECT_ARGS(args.clipBox));
  64. ScrollWidget::draw(args);
  65. }
  66. void RackScrollWidget::onHoverKey(const event::HoverKey &e) {
  67. ScrollWidget::onHoverKey(e);
  68. if (e.isConsumed())
  69. return;
  70. // Scroll with arrow keys
  71. float arrowSpeed = 30.0;
  72. if ((e.mods & RACK_MOD_MASK) == (RACK_MOD_CTRL |GLFW_MOD_SHIFT))
  73. arrowSpeed /= 16.0;
  74. else if ((e.mods & RACK_MOD_MASK) == RACK_MOD_CTRL)
  75. arrowSpeed *= 4.0;
  76. else if ((e.mods & RACK_MOD_MASK) == GLFW_MOD_SHIFT)
  77. arrowSpeed /= 4.0;
  78. if (e.action == RACK_HELD) {
  79. switch (e.key) {
  80. case GLFW_KEY_LEFT: {
  81. offset.x -= arrowSpeed;
  82. e.consume(this);
  83. } break;
  84. case GLFW_KEY_RIGHT: {
  85. offset.x += arrowSpeed;
  86. e.consume(this);
  87. } break;
  88. case GLFW_KEY_UP: {
  89. offset.y -= arrowSpeed;
  90. e.consume(this);
  91. } break;
  92. case GLFW_KEY_DOWN: {
  93. offset.y += arrowSpeed;
  94. e.consume(this);
  95. } break;
  96. }
  97. }
  98. }
  99. void RackScrollWidget::onHoverScroll(const event::HoverScroll &e) {
  100. if ((APP->window->getMods() & RACK_MOD_MASK) == RACK_MOD_CTRL) {
  101. // Increase zoom
  102. float zoomDelta = e.scrollDelta.y / 50 / 4;
  103. if (settings::invertZoom)
  104. zoomDelta *= -1;
  105. settings::zoom *= std::pow(2, zoomDelta);
  106. zoomPos = e.pos;
  107. e.consume(this);
  108. return;
  109. }
  110. ScrollWidget::onHoverScroll(e);
  111. }
  112. void RackScrollWidget::reset() {
  113. offset = RACK_OFFSET.mult(zoomWidget->zoom);
  114. offset = offset.minus(math::Vec(30, 30));
  115. }
  116. } // namespace app
  117. } // namespace rack