File: stack_layout.cc

package info (click to toggle)
chromium 138.0.7204.183-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 6,071,908 kB
  • sloc: cpp: 34,937,088; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,953; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,806; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (114 lines) | stat: -rw-r--r-- 3,780 bytes parent folder | download | duplicates (6)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
// Copyright 2019 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ash/assistant/ui/base/stack_layout.h"

#include <algorithm>
#include <numeric>

#include "ui/views/view.h"

namespace ash {

StackLayout::StackLayout() = default;

StackLayout::~StackLayout() = default;

bool StackLayout::OnViewRemoved(views::View* host, views::View* view) {
  DCHECK(view);
  respect_dimension_map_.erase(view);
  vertical_alignment_map_.erase(view);
  return views::LayoutManagerBase::OnViewRemoved(host, view);
}

gfx::Size StackLayout::GetPreferredSize(const views::View* host) const {
  return GetPreferredSize(host, {});
}

gfx::Size StackLayout::GetPreferredSize(
    const views::View* host,
    const views::SizeBounds& available_size) const {
  return std::transform_reduce(
      host->children().cbegin(), host->children().cend(), gfx::Size(),
      [](gfx::Size a, const gfx::Size b) {
        a.SetToMax(b);
        return a;
      },
      [&available_size](const views::View* v) {
        return v->GetPreferredSize(available_size);
      });
}

int StackLayout::GetPreferredHeightForWidth(const views::View* host,
                                            int width) const {
  const auto& children = host->children();
  if (children.empty())
    return 0;
  std::vector<int> heights(children.size());
  std::ranges::transform(
      children, heights.begin(),
      [width](const views::View* v) { return v->GetHeightForWidth(width); });
  return *std::max_element(heights.cbegin(), heights.cend());
}

views::ProposedLayout StackLayout::CalculateProposedLayout(
    const views::SizeBounds& size_bounds) const {
  const int host_width =
      size_bounds.width().is_bounded() ? size_bounds.width().value() : 0;
  const int host_height =
      size_bounds.height().is_bounded() ? size_bounds.height().value() : 0;
  views::ProposedLayout layouts;

  for (views::View* child : host_view()->children()) {
    if (!IsChildIncludedInLayout(child)) {
      continue;
    }
    int child_width = host_width;
    int child_height = host_height;

    int child_x = 0;
    uint32_t dimension = static_cast<uint32_t>(RespectDimension::kAll);

    if (auto iter = respect_dimension_map_.find(child);
        iter != respect_dimension_map_.end()) {
      dimension = static_cast<uint32_t>(iter->second);
    }

    if (dimension & static_cast<uint32_t>(RespectDimension::kWidth)) {
      child_width = std::min(child->GetPreferredSize().width(), host_width);
      child_x = (host_width - child_width) / 2;
    }

    if (dimension & static_cast<uint32_t>(RespectDimension::kHeight))
      child_height = child->GetHeightForWidth(child_width);

    int child_y = 0;
    auto iter = vertical_alignment_map_.find(child);
    if (iter != vertical_alignment_map_.end()) {
      VerticalAlignment vertical_alignment = iter->second;
      if (vertical_alignment == VerticalAlignment::kCenter)
        child_y = std::max(0, (host_height - child_height) / 2);
    }

    layouts.child_layouts.emplace_back(
        child, child->GetVisible(),
        gfx::Rect(child_x, child_y, child_width, child_height), size_bounds);
  }
  layouts.host_size = gfx::Size(host_width, host_height);
  return layouts;
}

void StackLayout::SetRespectDimensionForView(views::View* view,
                                             RespectDimension dimension) {
  CHECK(host_view() && view->parent() == host_view());
  respect_dimension_map_[view] = dimension;
}

void StackLayout::SetVerticalAlignmentForView(views::View* view,
                                              VerticalAlignment alignment) {
  CHECK(host_view() && view->parent() == host_view());
  vertical_alignment_map_[view] = alignment;
}

}  // namespace ash