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.

77 lines
1.6KB

  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<window::Svg> svg) {
  16. if (svg == sw->svg)
  17. return;
  18. sw->setSvg(svg);
  19. tw->box.size = sw->box.size;
  20. fb->box.size = sw->box.size;
  21. box.size = sw->box.size;
  22. shadow->box.size = sw->box.size;
  23. // Move shadow downward by 10%
  24. shadow->box.pos = math::Vec(0, sw->box.size.y * 0.10);
  25. // shadow->box = shadow->box.grow(math::Vec(2, 2));
  26. fb->setDirty();
  27. // Dispatch ChangeEvent
  28. ChangeEvent eChange;
  29. onChange(eChange);
  30. }
  31. void SvgKnob::onChange(const ChangeEvent& e) {
  32. // Re-transform the widget::TransformWidget
  33. engine::ParamQuantity* pq = getParamQuantity();
  34. if (pq) {
  35. float value = pq->getValue();
  36. float angle;
  37. if (!pq->isBounded()) {
  38. // Number of rotations equals value for unbounded range
  39. angle = value * (2 * M_PI);
  40. }
  41. else if (pq->getRange() == 0.f) {
  42. // Center angle for zero range
  43. angle = (minAngle + maxAngle) / 2.f;
  44. }
  45. else {
  46. // Proportional angle for finite range
  47. angle = math::rescale(value, pq->getMinValue(), pq->getMaxValue(), minAngle, maxAngle);
  48. }
  49. angle = std::fmod(angle, 2 * M_PI);
  50. tw->identity();
  51. // Rotate SVG
  52. math::Vec center = sw->box.getCenter();
  53. tw->translate(center);
  54. tw->rotate(angle);
  55. tw->translate(center.neg());
  56. fb->setDirty();
  57. }
  58. Knob::onChange(e);
  59. }
  60. } // namespace app
  61. } // namespace rack