FTXUI 6.1.9 C++ functional terminal UI.

Loading...
Searching...
No Matches
src/ftxui/dom/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
12 namespace ftxui {
13
14 namespace {
15 class Unselectable : public NodeDecorator {
16 public:
17 using NodeDecorator::NodeDecorator;
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.
27 Selection::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.
34 Selection::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
47 Selection::Selection(int start_x,
48 int start_y,
49 int end_x,
50 int end_y,
51 Selection* parent)
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.
67 const 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.
75 Selection Selection::SaturateHorizontal(Box box) {
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.
113 Selection Selection::SaturateVertical(Box box) {
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
146 void 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
ftxui::NodeDecorator::NodeDecorator
NodeDecorator(Element child)
Definition node_decorator.hpp:18
ftxui::Selection::GetBox
const Box & GetBox() const
Get the box of the selection.
Definition src/ftxui/dom/selection.cpp:67
ftxui::Selection::AddPart
void AddPart(const std::string &part, int y, int left, int right)
Definition src/ftxui/dom/selection.cpp:146
ftxui::Selection::SaturateVertical
Selection SaturateVertical(Box box)
Saturate the selection to be inside the box. This is called by vbox to propagate the selection to its...
Definition src/ftxui/dom/selection.cpp:113
ftxui::Selection::Selection
Selection()
Create an empty selection.
ftxui::Selection::SaturateHorizontal
Selection SaturateHorizontal(Box box)
Saturate the selection to be inside the box. This is called by hbox to propagate the selection to its...
Definition src/ftxui/dom/selection.cpp:75
ftxui::Selection
Represents a selection in a terminal user interface.
Definition selection.hpp:22
ftxui::Box::Contain
bool Contain(int x, int y) const
Definition box.cpp:42
ftxui::Box::x_max
int x_max
Definition box.hpp:18
ftxui::Box::y_min
int y_min
Definition box.hpp:19
ftxui::Box::y_max
int y_max
Definition box.hpp:20
ftxui::Box::x_min
int x_min
Definition box.hpp:17
ftxui::Box
Box is a structure that represents a rectangular area in a 2D space.
Definition box.hpp:16
ftxui
The FTXUI ftxui:: namespace.
Definition animation.hpp:10
node_decorator.hpp
left
std::uint8_t left
Definition screen.cpp:129
right
std::uint8_t right
Definition screen.cpp:131
selection.hpp