simple_grid_layout.cc 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/bubble/simple_grid_layout.h"
  5. #include "ui/views/view.h"
  6. namespace ash {
  7. SimpleGridLayout::SimpleGridLayout(int column_count,
  8. int column_spacing,
  9. int row_spacing)
  10. : column_count_(column_count),
  11. column_spacing_(column_spacing),
  12. row_spacing_(row_spacing) {}
  13. SimpleGridLayout::~SimpleGridLayout() = default;
  14. views::ProposedLayout SimpleGridLayout::CalculateProposedLayout(
  15. const views::SizeBounds& size_bounds) const {
  16. views::ProposedLayout proposed_layout;
  17. if (size_bounds.is_fully_bounded()) {
  18. proposed_layout.host_size =
  19. gfx::Size(size_bounds.width().value(), size_bounds.height().value());
  20. } else {
  21. proposed_layout.host_size = CalculatePreferredSize();
  22. }
  23. gfx::Size size = GetChildPreferredSize();
  24. int row = 0;
  25. int col = 0;
  26. for (auto* child : host_view()->children()) {
  27. if (!IsChildIncludedInLayout(child))
  28. continue;
  29. int x = col * (column_spacing_ + size.width());
  30. int y = row * (row_spacing_ + size.height());
  31. proposed_layout.child_layouts.push_back(
  32. views::ChildLayout{child,
  33. child->GetVisible(),
  34. gfx::Rect(x, y, size.width(), size.height()),
  35. {size.width(), size.height()}});
  36. ++col;
  37. if (col % column_count_ == 0) {
  38. ++row;
  39. col = 0;
  40. }
  41. }
  42. return proposed_layout;
  43. }
  44. void SimpleGridLayout::OnLayoutChanged() {
  45. LayoutManagerBase::OnLayoutChanged();
  46. cached_child_preferred_size_.reset();
  47. host_view()->SetPreferredSize(CalculatePreferredSize());
  48. }
  49. gfx::Size SimpleGridLayout::GetChildPreferredSize() const {
  50. if (cached_child_preferred_size_)
  51. return *cached_child_preferred_size_;
  52. if (!host_view()->children().size())
  53. return gfx::Size();
  54. cached_child_preferred_size_ = host_view()->children()[0]->GetPreferredSize();
  55. return *cached_child_preferred_size_;
  56. }
  57. gfx::Size SimpleGridLayout::CalculatePreferredSize() const {
  58. int total_children = 0;
  59. for (auto* child : host_view()->children()) {
  60. if (IsChildIncludedInLayout(child))
  61. ++total_children;
  62. }
  63. // Equivalent to `ceil(children().size() / column_count_)`.
  64. int number_of_rows = (total_children + column_count_ - 1) / column_count_;
  65. if (!number_of_rows)
  66. return gfx::Size();
  67. // `SimpleGridLayout` assumes all children have identical sizes.
  68. int child_height = GetChildPreferredSize().height();
  69. int child_width = GetChildPreferredSize().width();
  70. int height = (number_of_rows * (row_spacing_ + child_height)) - row_spacing_;
  71. int width =
  72. (column_count_ * (child_width + column_spacing_)) - column_spacing_;
  73. return gfx::Size(width, height);
  74. }
  75. } // namespace ash