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