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.

86 lines
2.1KB

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