Loading...
Searching...
No Matches
selection.cpp
Go to the documentation of this file.
// Copyright 2024 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.
#include "ftxui/dom/selection.hpp" // for Selection
#include <algorithm> // for max, min
#include <string> // for string
#include <tuple> // for ignore
#include "ftxui/dom/node_decorator.hpp" // for NodeDecorator
namespace ftxui {
namespace {
class Unselectable : public NodeDecorator {
public:
using NodeDecorator::NodeDecorator;
void Select(Selection& ignored) override {
std::ignore = ignored;
// Overwrite the select method to do nothing.
}
};
} // namespace
/// @brief Create an empty selection.
Selection::Selection() = default;
/// @brief Create a selection.
/// @param start_x The x coordinate of the start of the selection.
/// @param start_y The y coordinate of the start of the selection.
/// @param end_x The x coordinate of the end of the selection.
/// @param end_y The y coordinate of the end of the selection.
Selection::Selection(int start_x, int start_y, int end_x, int end_y)
: start_x_(start_x),
start_y_(start_y),
end_x_(end_x),
end_y_(end_y),
box_{
std::min(start_x, end_x),
std::max(start_x, end_x),
std::min(start_y, end_y),
std::max(start_y, end_y),
},
empty_(false) {}
Selection::Selection(int start_x,
int start_y,
int end_x,
int end_y,
Selection* parent)
: start_x_(start_x),
start_y_(start_y),
end_x_(end_x),
end_y_(end_y),
box_{
std::min(start_x, end_x),
std::max(start_x, end_x),
std::min(start_y, end_y),
std::max(start_y, end_y),
},
parent_(parent),
empty_(false) {}
/// @brief Get the box of the selection.
/// @return The box of the selection.
const Box& Selection::GetBox() const {
return box_;
}
/// @brief Saturate the selection to be inside the box.
/// This is called by `hbox` to propagate the selection to its children.
/// @param box The box to saturate the selection in.
/// @return The saturated selection.
Selection Selection::SaturateHorizontal(Box box) {
int start_x = start_x_;
int start_y = start_y_;
int end_x = end_x_;
int end_y = end_y_;
const bool start_outside = !box.Contain(start_x, start_y);
const bool end_outside = !box.Contain(end_x, end_y);
const bool properly_ordered =
start_y < end_y || (start_y == end_y && start_x <= end_x);
if (properly_ordered) {
if (start_outside) {
start_x = box.x_min;
start_y = box.y_min;
}
if (end_outside) {
end_x = box.x_max;
end_y = box.y_max;
}
} else {
if (start_outside) {
start_x = box.x_max;
start_y = box.y_max;
}
if (end_outside) {
end_x = box.x_min;
end_y = box.y_min;
}
}
return {
start_x, start_y, end_x, end_y, parent_,
};
}
/// @brief Saturate the selection to be inside the box.
/// This is called by `vbox` to propagate the selection to its children.
/// @param box The box to saturate the selection in.
/// @return The saturated selection.
Selection Selection::SaturateVertical(Box box) {
int start_x = start_x_;
int start_y = start_y_;
int end_x = end_x_;
int end_y = end_y_;
const bool start_outside = !box.Contain(start_x, start_y);
const bool end_outside = !box.Contain(end_x, end_y);
const bool properly_ordered =
start_y < end_y || (start_y == end_y && start_x <= end_x);
if (properly_ordered) {
if (start_outside) {
start_x = box.x_min;
start_y = box.y_min;
}
if (end_outside) {
end_x = box.x_max;
end_y = box.y_max;
}
} else {
if (start_outside) {
start_x = box.x_max;
start_y = box.y_max;
}
if (end_outside) {
end_x = box.x_min;
end_y = box.y_min;
}
}
return {start_x, start_y, end_x, end_y, parent_};
}
void Selection::AddPart(const std::string& part, int y, int left, int right) {
if (parent_ != this) {
parent_->AddPart(part, y, left, right);
return;
}
[&] {
if (parts_.str().empty()) {
parts_ << part;
return;
}
if (y_ != y) {
parts_ << '\n' << part;
return;
}
if (x_ == left + 1) {
parts_ << part;
return;
}
parts_ << part;
}();
y_ = y;
x_ = right;
}
} // namespace ftxui
ftxui::NodeDecorator
Definition node_decorator.hpp:16
ftxui::NodeDecorator::NodeDecorator
NodeDecorator(Element child)
Definition node_decorator.hpp:18
ftxui::Selection
Represent a selection in the terminal.
Definition selection.hpp:17
ftxui::Selection::GetBox
const Box & GetBox() const
Get the box of the selection.
Definition selection.cpp:67
ftxui::Selection::AddPart
void AddPart(const std::string &part, int y, int left, int right)
Definition 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 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 selection.cpp:75
ftxui
Definition animation.hpp:10
node_decorator.hpp
selection.hpp
ftxui::Box
Definition box.hpp:9
ftxui::Box::Contain
bool Contain(int x, int y) const
Definition box.cpp:46
ftxui::Box::x_max
int x_max
Definition box.hpp:11
ftxui::Box::y_min
int y_min
Definition box.hpp:12
ftxui::Box::y_max
int y_max
Definition box.hpp:13
ftxui::Box::x_min
int x_min
Definition box.hpp:10