FTXUI 6.1.9
C++ functional terminal UI.
Loading...
Searching...
No Matches
box_helper.cpp
Go to the documentation of this file.
1// Copyright 2021 Arthur Sonzogni. 版權所有。
2// 本原始碼的使用受 MIT 授權條款約束,詳情請參閱
3// LICENSE 檔案。
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<int64_t>(value) * static_cast<int64_t>(numerator) /
16 std::max(static_cast<int64_t>(denominator), static_cast<int64_t>(1));
17}
18
19// 當允許的尺寸大於請求的尺寸時呼叫。這會
20// 將額外空間按相對比例分配給彈性元素。
21void ComputeGrow(std::vector<Element>* elements,
22 int extra_space,
23 int flex_grow_sum) {
24 for (Element& element : *elements) {
25 const int added_space =
26 SafeRatio(extra_space, element.flex_grow, flex_grow_sum);
27 extra_space -= added_space;
28 flex_grow_sum -= element.flex_grow;
29 element.size = element.min_size + added_space;
30 }
31}
32
33// 當允許的尺寸小於請求的尺寸時呼叫,且
34// 可縮小元素可以吸收(負數)額外空間。這會將
35// 額外空間分配給這些元素。
36void ComputeShrinkEasy(std::vector<Element>* elements,
37 int extra_space,
38 int flex_shrink_sum) {
39 for (Element& element : *elements) {
40 const int added_space = SafeRatio(
41 extra_space, element.min_size * element.flex_shrink, flex_shrink_sum);
42 extra_space -= added_space;
43 flex_shrink_sum -= element.flex_shrink * element.min_size;
44 element.size = element.min_size + added_space;
45 }
46}
47
48// 當允許的尺寸小於請求的尺寸時呼叫,且
49// 可縮小元素無法吸收(負數)額外空間。這會將
50// 零分配給可縮小元素,並將剩餘的(負數)
51// 額外空間分配給其他不可縮小元素。
52void ComputeShrinkHard(std::vector<Element>* elements,
53 int extra_space,
54 int size) {
55 for (Element& element : *elements) {
56 if (element.flex_shrink != 0) {
57 element.size = 0;
58 continue;
59 }
60
61 const int added_space = SafeRatio(extra_space, element.min_size, size);
62
63 extra_space -= added_space;
64 size -= element.min_size;
65
66 element.size = element.min_size + added_space;
67 }
68}
69
70} // namespace
71
72void Compute(std::vector<Element>* elements, int target_size) {
73 int size = 0;
74 int flex_grow_sum = 0;
75 int flex_shrink_sum = 0;
76 int flex_shrink_size = 0;
77
78 for (auto& element : *elements) {
79 flex_grow_sum += element.flex_grow;
80 flex_shrink_sum += element.min_size * element.flex_shrink;
81 if (element.flex_shrink != 0) {
82 flex_shrink_size += element.min_size;
83 }
84 size += element.min_size;
85 }
86
87 const int extra_space = target_size - size;
88 if (extra_space >= 0) {
89 ComputeGrow(elements, extra_space, flex_grow_sum);
90 } else if (flex_shrink_size + extra_space >= 0) {
91 ComputeShrinkEasy(elements, extra_space, flex_shrink_sum);
92
93 } else {
94 ComputeShrinkHard(elements, extra_space + flex_shrink_size,
95 size - flex_shrink_size);
96 }
97}
98
99} // namespace ftxui::box_helper
Decorator size(WidthOrHeight, Constraint, int value)
限制元素的大小。
void Compute(std::vector< Element > *elements, int target_size)