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.

151 lines
3.9KB

  1. #pragma once
  2. #include "widgets.hpp"
  3. class ButtonCell
  4. {
  5. public:
  6. friend class WaveformSelector;
  7. ButtonCell(const ButtonCell&) = delete;
  8. ButtonCell& operator = (const ButtonCell&) = delete;
  9. ButtonCell(float x) : value(x) {}
  10. void loadSVG(const char* res, const char* resOn);
  11. const float value;
  12. rack::Rect box;
  13. void dump(const char*);
  14. private:
  15. SVGWidget svg;
  16. SVGWidget svgOn;
  17. };
  18. inline void ButtonCell::loadSVG(const char* res, const char* resOn)
  19. {
  20. svg.setSVG(SVG::load (assetPlugin(plugin, res)));
  21. svgOn.setSVG(SVG::load (assetPlugin(plugin, resOn)));
  22. this->box.size = svg.box.size;
  23. }
  24. inline void ButtonCell::dump(const char* label)
  25. {
  26. printf("cell(%.2f) {%s} box size=%f, %f po %f, %f\n",
  27. value,
  28. label,
  29. box.size.x,
  30. box.size.y,
  31. box.pos.x,
  32. box.pos.y);
  33. }
  34. using CellPtr = std::shared_ptr<ButtonCell>;
  35. struct WaveformSelector : ParamWidget
  36. {
  37. WaveformSelector();
  38. void draw(NVGcontext *vg) override;
  39. ~WaveformSelector() override;
  40. std::vector< std::vector< CellPtr>> svgs;
  41. void addSvg(int row, const char* res, const char* resOn);
  42. void drawSVG(NVGcontext *vg, SVGWidget&, float x, float y);
  43. void onMouseDown( EventMouseDown &e ) override;
  44. CellPtr hitTest(float x, float y);
  45. //
  46. float nextValue = 0;
  47. };
  48. CellPtr WaveformSelector::hitTest(float x, float y)
  49. {
  50. const Vec pos(x, y);
  51. for (auto& r : svgs) {
  52. for (auto& s : r) {
  53. if (s->box.contains(pos)) {
  54. return s;
  55. }
  56. }
  57. }
  58. return nullptr;
  59. }
  60. inline void WaveformSelector::addSvg(int row, const char* res, const char* resOn)
  61. {
  62. if ((int)svgs.size() < row+1) {
  63. svgs.resize(row+1);
  64. }
  65. // make a new cell, put the SVGs in it
  66. CellPtr cell = std::make_shared<ButtonCell>(nextValue++);
  67. cell->loadSVG(res, resOn);
  68. svgs[row].push_back(cell);
  69. // now set the box for cell
  70. float y = 0;
  71. if (row > 0) {
  72. // if we are going in the second row, y = height of first
  73. assert(!svgs[row-1].empty());
  74. CellPtr otherCell = svgs[row-1][0];
  75. y = otherCell->box.pos.y + otherCell->box.size.y;
  76. }
  77. cell->box.pos.y = y;
  78. const int cellsInRow = (int) svgs[row].size();
  79. if (cellsInRow == 1) {
  80. cell->box.pos.x = 0;
  81. } else {
  82. cell->box.pos.x =
  83. svgs[row][cellsInRow-2]->box.pos.x +
  84. svgs[row][cellsInRow-2]->box.size.x;
  85. }
  86. }
  87. inline WaveformSelector::WaveformSelector()
  88. {
  89. addSvg(0, "res/waveforms-6-08.svg","res/waveforms-6-07.svg");
  90. addSvg(0, "res/waveforms-6-06.svg","res/waveforms-6-05.svg");
  91. addSvg(0, "res/waveforms-6-02.svg","res/waveforms-6-01.svg");
  92. addSvg(1, "res/waveforms-6-04.svg","res/waveforms-6-03.svg");
  93. addSvg(1, "res/waveforms-6-12.svg","res/waveforms-6-11.svg");
  94. addSvg(1, "res/waveforms-6-10.svg","res/waveforms-6-09.svg");
  95. }
  96. inline WaveformSelector::~WaveformSelector()
  97. {
  98. }
  99. inline void WaveformSelector::drawSVG(NVGcontext *vg, SVGWidget& svg, float x, float y)
  100. {
  101. nvgSave(vg);
  102. float transform[6];
  103. nvgTransformIdentity(transform);
  104. nvgTransformTranslate(transform, x, y);
  105. nvgTransform(vg, transform[0], transform[1], transform[2], transform[3], transform[4], transform[5]);
  106. svg.draw(vg);
  107. nvgRestore(vg);
  108. }
  109. void inline WaveformSelector::draw(NVGcontext *vg)
  110. {
  111. for (auto& r : svgs) {
  112. for (auto& s : r) {
  113. const bool on = (this->value == s->value);
  114. drawSVG(vg, on ? s->svgOn : s->svg, s->box.pos.x, s->box.pos.y);
  115. }
  116. }
  117. }
  118. inline void WaveformSelector::onMouseDown( EventMouseDown &e )
  119. {
  120. e.consumed = false;
  121. CellPtr hit = hitTest(e.pos.x, e.pos.y);
  122. if (hit) {
  123. e.consumed = true;
  124. if (hit->value == this->value) {
  125. printf("value same\n"); fflush(stdout);
  126. return;
  127. }
  128. setValue(hit->value);
  129. }
  130. }