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.

63 lines
1.6KB

  1. #include <app/RailWidget.hpp>
  2. #include <context.hpp>
  3. #include <asset.hpp>
  4. #include <widget/SvgWidget.hpp>
  5. #include <widget/FramebufferWidget.hpp>
  6. namespace rack {
  7. namespace app {
  8. struct RailWidget::Internal {
  9. widget::FramebufferWidget* railFb;
  10. widget::SvgWidget* railSw;
  11. };
  12. RailWidget::RailWidget() {
  13. internal = new Internal;
  14. internal->railFb = new widget::FramebufferWidget;
  15. // The rail renders fine without oversampling, and it would be too expensive anyway.
  16. internal->railFb->oversample = 1.0;
  17. // Don't redraw when the world offset of the rail FramebufferWidget changes its fractional value.
  18. internal->railFb->dirtyOnSubpixelChange = false;
  19. addChild(internal->railFb);
  20. internal->railSw = new widget::SvgWidget;
  21. internal->railSw->setSvg(window::Svg::load(asset::system("res/ComponentLibrary/Rail.svg")));
  22. internal->railFb->addChild(internal->railSw);
  23. }
  24. RailWidget::~RailWidget() {
  25. delete internal;
  26. }
  27. void RailWidget::draw(const DrawArgs& args) {
  28. if (!internal->railSw->svg)
  29. return;
  30. math::Vec tileSize = internal->railSw->svg->getSize().div(RACK_GRID_SIZE).round().mult(RACK_GRID_SIZE);
  31. if (tileSize.area() == 0.f)
  32. return;
  33. math::Vec min = args.clipBox.getTopLeft().div(tileSize).floor().mult(tileSize);
  34. math::Vec max = args.clipBox.getBottomRight().div(tileSize).ceil().mult(tileSize);
  35. // Draw the same FramebufferWidget repeatedly as a tile
  36. math::Vec p;
  37. for (p.y = min.y; p.y < max.y; p.y += tileSize.y) {
  38. for (p.x = min.x; p.x < max.x; p.x += tileSize.x) {
  39. internal->railFb->box.pos = p;
  40. Widget::drawChild(internal->railFb, args);
  41. }
  42. }
  43. }
  44. } // namespace app
  45. } // namespace rack