FTXUI  6.0.2
C++ functional terminal UI.
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
selection.cpp
Go to the documentation of this file.
1// Copyright 2024 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.
4
5#include "ftxui/dom/selection.hpp" // for Selection
6#include <algorithm> // for max, min
7#include <string> // for string
8#include <tuple> // for ignore
9
10#include "ftxui/dom/node_decorator.hpp" // for NodeDecorator
11
12namespace ftxui {
13
14namespace {
15class Unselectable : public NodeDecorator {
16 public:
18
19 void Select(Selection& ignored) override {
20 std::ignore = ignored;
21 // Overwrite the select method to do nothing.
22 }
23};
24} // namespace
25
26/// @brief Create an empty selection.
27Selection::Selection() = default;
28
29/// @brief Create a selection.
30/// @param start_x The x coordinate of the start of the selection.
31/// @param start_y The y coordinate of the start of the selection.
32/// @param end_x The x coordinate of the end of the selection.
33/// @param end_y The y coordinate of the end of the selection.
34Selection::Selection(int start_x, int start_y, int end_x, int end_y)
35 : start_x_(start_x),
36 start_y_(start_y),
37 end_x_(end_x),
38 end_y_(end_y),
39 box_{
40 std::min(start_x, end_x),
41 std::max(start_x, end_x),
42 std::min(start_y, end_y),
43 std::max(start_y, end_y),
44 },
45 empty_(false) {}
46
47Selection::Selection(int start_x,
48 int start_y,
49 int end_x,
50 int end_y,
52 : start_x_(start_x),
53 start_y_(start_y),
54 end_x_(end_x),
55 end_y_(end_y),
56 box_{
57 std::min(start_x, end_x),
58 std::max(start_x, end_x),
59 std::min(start_y, end_y),
60 std::max(start_y, end_y),
61 },
62 parent_(parent),
63 empty_(false) {}
64
65/// @brief Get the box of the selection.
66/// @return The box of the selection.
67const Box& Selection::GetBox() const {
68 return box_;
69}
70
71/// @brief Saturate the selection to be inside the box.
72/// This is called by `hbox` to propagate the selection to its children.
73/// @param box The box to saturate the selection in.
74/// @return The saturated selection.
76 int start_x = start_x_;
77 int start_y = start_y_;
78 int end_x = end_x_;
79 int end_y = end_y_;
80
81 const bool start_outside = !box.Contain(start_x, start_y);
82 const bool end_outside = !box.Contain(end_x, end_y);
83 const bool properly_ordered =
84 start_y < end_y || (start_y == end_y && start_x <= end_x);
85 if (properly_ordered) {
86 if (start_outside) {
87 start_x = box.x_min;
88 start_y = box.y_min;
89 }
90 if (end_outside) {
91 end_x = box.x_max;
92 end_y = box.y_max;
93 }
94 } else {
95 if (start_outside) {
96 start_x = box.x_max;
97 start_y = box.y_max;
98 }
99 if (end_outside) {
100 end_x = box.x_min;
101 end_y = box.y_min;
102 }
103 }
104 return {
105 start_x, start_y, end_x, end_y, parent_,
106 };
107}
108
109/// @brief Saturate the selection to be inside the box.
110/// This is called by `vbox` to propagate the selection to its children.
111/// @param box The box to saturate the selection in.
112/// @return The saturated selection.
114 int start_x = start_x_;
115 int start_y = start_y_;
116 int end_x = end_x_;
117 int end_y = end_y_;
118
119 const bool start_outside = !box.Contain(start_x, start_y);
120 const bool end_outside = !box.Contain(end_x, end_y);
121 const bool properly_ordered =
122 start_y < end_y || (start_y == end_y && start_x <= end_x);
123
124 if (properly_ordered) {
125 if (start_outside) {
126 start_x = box.x_min;
127 start_y = box.y_min;
128 }
129 if (end_outside) {
130 end_x = box.x_max;
131 end_y = box.y_max;
132 }
133 } else {
134 if (start_outside) {
135 start_x = box.x_max;
136 start_y = box.y_max;
137 }
138 if (end_outside) {
139 end_x = box.x_min;
140 end_y = box.y_min;
141 }
142 }
143 return {start_x, start_y, end_x, end_y, parent_};
144}
145
146void Selection::AddPart(const std::string& part, int y, int left, int right) {
147 if (parent_ != this) {
148 parent_->AddPart(part, y, left, right);
149 return;
150 }
151 [&] {
152 if (parts_.str().empty()) {
153 parts_ << part;
154 return;
155 }
156
157 if (y_ != y) {
158 parts_ << '\n' << part;
159 return;
160 }
161
162 if (x_ == left + 1) {
163 parts_ << part;
164 return;
165 }
166
167 parts_ << part;
168 }();
169 y_ = y;
170 x_ = right;
171}
172
173} // namespace ftxui
NodeDecorator(Element child)
Represent a selection in the terminal.
Definition selection.hpp:17
const Box & GetBox() const
Get the box of the selection.
Definition selection.cpp:67
void AddPart(const std::string &part, int y, int left, int right)
Selection SaturateVertical(Box box)
Saturate the selection to be inside the box. This is called by vbox to propagate the selection to its...
Selection()
Create an empty selection.
Selection SaturateHorizontal(Box box)
Saturate the selection to be inside the box. This is called by hbox to propagate the selection to its...
Definition selection.cpp:75
std::shared_ptr< T > Make(Args &&... args)
Definition component.hpp:26
bool Contain(int x, int y) const
Definition box.cpp:46
int x_max
Definition box.hpp:11
int y_min
Definition box.hpp:12
int y_max
Definition box.hpp:13
int x_min
Definition box.hpp:10