FTXUI 7.0.3
C++ functional terminal UI.
Loading...
Searching...
No Matches
box_helper.cpp
Go to the documentation of this file.
1// Copyright 2021 Arthur Sonzogni. All rights reserved.
2// Use of this source code is governed by the MIT license that can be found in
3// the LICENSE file.
5
6#include <algorithm> // for max
7#include <cstdint>
8#include <vector> // for vector
9
11
12namespace {
13
14int SafeRatio(int value, int numerator, int denominator) {
15 return static_cast<int>(
16 static_cast<int64_t>(value) * static_cast<int64_t>(numerator) /
17 std::max(static_cast<int64_t>(denominator), static_cast<int64_t>(1)));
18}
19
20// 許可されたサイズが要求されたサイズより大きい場合に呼ばれる。これは
21// 余分なスペースを、相対的な比率でフレキシブルな要素へ分配する。
22void ComputeGrow(std::vector<Element>* elements,
23 int extra_space,
24 int flex_grow_sum) {
25 for (Element& element : *elements) {
26 const int added_space =
27 SafeRatio(extra_space, element.flex_grow, flex_grow_sum);
28 extra_space -= added_space;
29 flex_grow_sum -= element.flex_grow;
30 element.size = element.min_size + added_space;
31 }
32}
33
34// 許可されたサイズが要求されたサイズより小さく、縮小可能な要素が
35// (負の)余分なスペースを吸収できる場合に呼ばれる。これは余分なスペースを
36// それらの要素に分配する。
37void ComputeShrinkEasy(std::vector<Element>* elements,
38 int extra_space,
39 int flex_shrink_sum) {
40 for (Element& element : *elements) {
41 const int added_space = SafeRatio(
42 extra_space, element.min_size * element.flex_shrink, flex_shrink_sum);
43 extra_space -= added_space;
44 flex_shrink_sum -= element.flex_shrink * element.min_size;
45 element.size = element.min_size + added_space;
46 }
47}
48
49// 許可されたサイズが要求されたサイズより小さく、縮小可能な要素が
50// (負の)余分なスペースを吸収できない場合に呼ばれる。縮小可能な要素には
51// ゼロを割り当て、残りの(負の)余分なスペースを他の縮小不可能な要素に
52// 分配する。
53void ComputeShrinkHard(std::vector<Element>* elements,
54 int extra_space,
55 int size) {
56 for (Element& element : *elements) {
57 if (element.flex_shrink != 0) {
58 element.size = 0;
59 continue;
60 }
61
62 const int added_space = SafeRatio(extra_space, element.min_size, size);
63
64 extra_space -= added_space;
65 size -= element.min_size;
66
67 element.size = element.min_size + added_space;
68 }
69}
70
71} // namespace
72
73void Compute(std::vector<Element>* elements, int target_size) {
74 int size = 0;
75 int flex_grow_sum = 0;
76 int flex_shrink_sum = 0;
77 int flex_shrink_size = 0;
78
79 for (auto& element : *elements) {
80 flex_grow_sum += element.flex_grow;
81 flex_shrink_sum += element.min_size * element.flex_shrink;
82 if (element.flex_shrink != 0) {
83 flex_shrink_size += element.min_size;
84 }
85 size += element.min_size;
86 }
87
88 const int extra_space = target_size - size;
89 if (extra_space >= 0) {
90 ComputeGrow(elements, extra_space, flex_grow_sum);
91 } else if (flex_shrink_size + extra_space >= 0) {
92 ComputeShrinkEasy(elements, extra_space, flex_shrink_sum);
93
94 } else {
95 ComputeShrinkHard(elements, extra_space + flex_shrink_size,
96 size - flex_shrink_size);
97 }
98}
99
100} // namespace ftxui::box_helper
Decorator size(WidthOrHeight direction, Constraint constraint, int value)
要素のサイズに制約を適用する。
void Compute(std::vector< Element > *elements, int target_size)
const Element & element
Definition node.hpp:94
int value
Definition elements.hpp:192