47FlexboxConfig Normalize(FlexboxConfig config) {
48 Normalize(config.direction);
49 Normalize(config.wrap);
50 Normalize(config.justify_content);
51 Normalize(config.align_content);
55class Flexbox :
public Node {
57 Flexbox(
Elements children, FlexboxConfig config)
58 : Node(std::move(children)),
61 requirement_.flex_grow_x = 1;
62 requirement_.flex_grow_y = 0;
64 if (IsColumnOriented()) {
65 std::swap(requirement_.flex_grow_x, requirement_.flex_grow_y);
69 bool IsColumnOriented()
const {
74 void Layout(flexbox_helper::Global& global,
75 bool compute_requirement =
false) {
76 global.blocks.reserve(children_.size());
77 for (
auto& child : children_) {
78 flexbox_helper::Block block;
79 block.min_size_x = child->requirement().min_x;
80 block.min_size_y = child->requirement().min_y;
81 if (!compute_requirement) {
82 block.flex_grow_x = child->requirement().flex_grow_x;
83 block.flex_grow_y = child->requirement().flex_grow_y;
84 block.flex_shrink_x = child->requirement().flex_shrink_x;
85 block.flex_shrink_y = child->requirement().flex_shrink_y;
87 global.blocks.push_back(block);
93 void ComputeRequirement()
override {
94 requirement_ = Requirement{};
95 for (
auto& child : children_) {
96 child->ComputeRequirement();
98 global_ = flexbox_helper::Global();
100 if (IsColumnOriented()) {
107 Layout(global_,
true);
115 box.x_min =
global_.blocks[0].x;
116 box.y_min =
global_.blocks[0].y;
119 for (
auto& b :
global_.blocks) {
120 box.x_min = std::min(box.x_min, b.x);
121 box.y_min = std::min(box.y_min, b.y);
122 box.x_max = std::max(box.x_max, b.x + b.dim_x);
123 box.y_max = std::max(box.y_max, b.y + b.dim_y);
125 requirement_.min_x = box.x_max - box.x_min;
126 requirement_.min_y = box.y_max - box.y_min;
129 for (
size_t i = 0; i < children_.size(); ++i) {
130 if (requirement_.focused.Prefer(children_[i]->requirement().focused)) {
131 requirement_.focused = children_[i]->requirement().focused;
134 requirement_.focused.box.Shift(b.x, b.y);
135 requirement_.focused.box =
141 void SetBox(Box box)
override {
144 const int asked_previous =
asked_;
145 asked_ = std::min(asked_, IsColumnOriented() ? box.y_max - box.y_min + 1
146 : box.x_max - box.x_min + 1);
149 flexbox_helper::Global global;
151 global.size_x = box.x_max - box.x_min + 1;
152 global.size_y = box.y_max - box.y_min + 1;
155 for (
size_t i = 0; i < children_.size(); ++i) {
156 auto& child = children_[i];
157 auto& b = global.blocks[i];
160 children_box.x_min = box.x_min + b.x;
161 children_box.y_min = box.y_min + b.y;
162 children_box.x_max = box.x_min + b.x + b.dim_x - 1;
163 children_box.y_max = box.y_min + b.y + b.dim_y - 1;
166 child->SetBox(intersection);
172 void Select(Selection& selection)
override {
179 Selection selection_lines = IsColumnOriented()
180 ? selection.SaturateVertical(box_)
181 : selection.SaturateHorizontal(box_);
184 for (
auto& line :
global_.lines) {
186 box.x_min = box_.x_min + line.x;
187 box.x_max = box_.x_min + line.x + line.dim_x - 1;
188 box.y_min = box_.y_min + line.y;
189 box.y_max = box_.y_min + line.y + line.dim_y - 1;
197 Selection selection_line = IsColumnOriented()
198 ? selection_lines.SaturateHorizontal(box)
199 : selection_lines.SaturateVertical(box);
201 for (
auto& block : line.blocks) {
203 children_[i]->Select(selection_line);
209 void Check(Status* status)
override {
210 for (
auto& child : children_) {
211 child->Check(status);
214 if (status->iteration == 0) {
251 return std::make_shared<Flexbox>(std::move(children), config);
285 return flexbox(std::move(children),
const FlexboxConfig config_
const FlexboxConfig config_normalized_
flexbox_helper::Global global_
@ FlexStart
アイテムは交差軸の開始位置に配置されます。
@ Column
フレックスアイテムは列に配置されます。
@ RowInversed
フレックスアイテムは行に配置されますが、逆順になります。
virtual void SetBox(Box box)
描画のために要素に位置と次元を割り当てます。
@ Wrap
フレックスアイテムは複数行に折り返されます。
@ FlexStart
アイテムはflexboxの方向の開始位置に揃えられます。
FlexboxConfigは、flexboxコンテナのレイアウトプロパティを定義する構成構造体です。
static auto Intersection(Box a, Box b) -> Box
void Compute(Global &global)
Element flexbox(Elements, FlexboxConfig config=FlexboxConfig())
行/列に要素を表示し、一杯になると次の列/行に折り返すことができるコンテナ。
std::shared_ptr< Node > Element
Element hflow(Elements)
要素を左から右へ行で表示するコンテナ。一杯になると、下の新しい行から開始します。
std::vector< Element > Elements
Element vflow(Elements)
要素を上から下へ行で表示するコンテナ。一杯になると、右側の新しい列から開始します。