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.

69 lines
1.6KB

  1. #include <ui/SequentialLayout.hpp>
  2. #include <vector>
  3. namespace rack {
  4. namespace ui {
  5. #define X(v) (orientation == HORIZONTAL_ORIENTATION ? (v).x : (v).y)
  6. #define Y(v) (orientation == HORIZONTAL_ORIENTATION ? (v).y : (v).x)
  7. void SequentialLayout::step() {
  8. Widget::step();
  9. // Sort widgets into rows (or columns if vertical)
  10. std::vector<std::vector<widget::Widget*>> rows;
  11. rows.resize(1);
  12. float rowWidth = 0.0;
  13. for (widget::Widget* child : children) {
  14. if (!child->visible)
  15. continue;
  16. // Should we wrap the widget now?
  17. if (!rows.back().empty() && rowWidth + X(child->box.size) >= X(box.size)) {
  18. rowWidth = 0.0;
  19. rows.resize(rows.size() + 1);
  20. }
  21. rows.back().push_back(child);
  22. rowWidth += X(child->box.size) + X(spacing);
  23. }
  24. // Position widgets
  25. math::Vec p;
  26. for (auto& row : rows) {
  27. // For center and right alignment, compute offset from the left margin
  28. float offset = 0.0;
  29. if (alignment != LEFT_ALIGNMENT) {
  30. float rowWidth = 0.0;
  31. for (widget::Widget* child : row) {
  32. rowWidth += X(child->box.size) + X(spacing);
  33. }
  34. rowWidth -= X(spacing);
  35. if (alignment == CENTER_ALIGNMENT)
  36. offset = (X(box.size) - rowWidth) / 2;
  37. else if (alignment == RIGHT_ALIGNMENT)
  38. offset = X(box.size) - rowWidth;
  39. }
  40. float maxHeight = 0.0;
  41. for (widget::Widget* child : row) {
  42. child->box.pos = p;
  43. X(child->box.pos) += offset;
  44. X(p) += X(child->box.size) + X(spacing);
  45. if (Y(child->box.size) > maxHeight)
  46. maxHeight = Y(child->box.size);
  47. }
  48. X(p) = 0.0;
  49. Y(p) += maxHeight + Y(spacing);
  50. }
  51. }
  52. } // namespace ui
  53. } // namespace rack