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.

67 lines
1.5KB

  1. #include <app/SvgKnob.hpp>
  2. namespace rack {
  3. namespace app {
  4. SvgKnob::SvgKnob() {
  5. fb = new widget::FramebufferWidget;
  6. addChild(fb);
  7. shadow = new CircularShadow;
  8. fb->addChild(shadow);
  9. shadow->box.size = math::Vec();
  10. tw = new widget::TransformWidget;
  11. fb->addChild(tw);
  12. sw = new widget::SvgWidget;
  13. tw->addChild(sw);
  14. }
  15. void SvgKnob::setSvg(std::shared_ptr<Svg> svg) {
  16. sw->setSvg(svg);
  17. tw->box.size = sw->box.size;
  18. fb->box.size = sw->box.size;
  19. box.size = sw->box.size;
  20. shadow->box.size = sw->box.size;
  21. // Move shadow downward by 10%
  22. shadow->box.pos = math::Vec(0, sw->box.size.y * 0.10);
  23. // shadow->box = shadow->box.grow(math::Vec(2, 2));
  24. }
  25. void SvgKnob::onChange(const event::Change& e) {
  26. // Re-transform the widget::TransformWidget
  27. engine::ParamQuantity* pq = getParamQuantity();
  28. if (pq) {
  29. float value = pq->getSmoothValue();
  30. float angle;
  31. if (!pq->isBounded()) {
  32. // Number of rotations equals value for unbounded range
  33. angle = value * (2 * M_PI);
  34. }
  35. else if (pq->getRange() == 0.f) {
  36. // Center angle for zero range
  37. angle = (minAngle + maxAngle) / 2.f;
  38. }
  39. else {
  40. // Proportional angle for finite range
  41. angle = math::rescale(value, pq->getMinValue(), pq->getMaxValue(), minAngle, maxAngle);
  42. }
  43. angle = std::fmod(angle, 2 * M_PI);
  44. tw->identity();
  45. // Rotate SVG
  46. math::Vec center = sw->box.getCenter();
  47. tw->translate(center);
  48. tw->rotate(angle);
  49. tw->translate(center.neg());
  50. fb->dirty = true;
  51. }
  52. Knob::onChange(e);
  53. }
  54. } // namespace app
  55. } // namespace rack