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.

103 lines
1.8KB

  1. #include "widgets.hpp"
  2. #include "app.hpp"
  3. #include "event.hpp"
  4. #include <algorithm>
  5. namespace rack {
  6. Widget::~Widget() {
  7. // You should only delete orphaned widgets
  8. assert(!parent);
  9. event::gContext->finalizeWidget(this);
  10. clearChildren();
  11. }
  12. Rect Widget::getChildrenBoundingBox() {
  13. Rect bound;
  14. for (Widget *child : children) {
  15. if (child == children.front()) {
  16. bound = child->box;
  17. }
  18. else {
  19. bound = bound.expand(child->box);
  20. }
  21. }
  22. return bound;
  23. }
  24. Vec Widget::getRelativeOffset(Vec v, Widget *relative) {
  25. if (this == relative) {
  26. return v;
  27. }
  28. v = v.plus(box.pos);
  29. if (parent) {
  30. v = parent->getRelativeOffset(v, relative);
  31. }
  32. return v;
  33. }
  34. Rect Widget::getViewport(Rect r) {
  35. Rect bound;
  36. if (parent) {
  37. bound = parent->getViewport(box);
  38. }
  39. else {
  40. bound = box;
  41. }
  42. bound.pos = bound.pos.minus(box.pos);
  43. return r.clamp(bound);
  44. }
  45. void Widget::addChild(Widget *widget) {
  46. assert(!widget->parent);
  47. widget->parent = this;
  48. children.push_back(widget);
  49. }
  50. void Widget::removeChild(Widget *widget) {
  51. assert(widget->parent == this);
  52. auto it = std::find(children.begin(), children.end(), widget);
  53. assert(it != children.end());
  54. children.erase(it);
  55. widget->parent = NULL;
  56. }
  57. void Widget::clearChildren() {
  58. for (Widget *child : children) {
  59. child->parent = NULL;
  60. delete child;
  61. }
  62. children.clear();
  63. }
  64. void Widget::step() {
  65. for (auto it = children.begin(); it != children.end();) {
  66. Widget *child = *it;
  67. // Delete children if a delete is requested
  68. if (child->requestedDelete) {
  69. it = children.erase(it);
  70. child->parent = NULL;
  71. delete child;
  72. continue;
  73. }
  74. child->step();
  75. it++;
  76. }
  77. }
  78. void Widget::draw(NVGcontext *vg) {
  79. for (Widget *child : children) {
  80. if (!child->visible)
  81. continue;
  82. nvgSave(vg);
  83. nvgTranslate(vg, child->box.pos.x, child->box.pos.y);
  84. child->draw(vg);
  85. nvgRestore(vg);
  86. }
  87. }
  88. } // namespace rack