mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2025-06-25 17:11:13 +08:00
We can retrieve the content of the selection
This commit is contained in:
parent
dc70091203
commit
307d8b51bf
@ -27,18 +27,16 @@ Element LoremIpsum() {
|
|||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
auto screen = ScreenInteractive::TerminalOutput();
|
auto screen = ScreenInteractive::TerminalOutput();
|
||||||
int counter = 0;
|
int selectionChangeCounter = 0;
|
||||||
|
std::string selection = "";
|
||||||
screen.onSelectionModified([&]{
|
|
||||||
counter++;
|
|
||||||
});
|
|
||||||
|
|
||||||
auto quit = Button("Quit", screen.ExitLoopClosure());
|
auto quit = Button("Quit", screen.ExitLoopClosure());
|
||||||
|
|
||||||
// The components:
|
// The components:
|
||||||
auto renderer = Renderer(quit, [&] {
|
auto renderer = Renderer(quit, [&] {
|
||||||
return vbox({
|
return vbox({
|
||||||
text("Select: " + std::to_string(counter)),
|
text("Select changed: " + std::to_string(selectionChangeCounter) + " times"),
|
||||||
|
text("Currently selected: " + selection),
|
||||||
window(text("Horizontal split"), hbox({
|
window(text("Horizontal split"), hbox({
|
||||||
LoremIpsum(),
|
LoremIpsum(),
|
||||||
separator(),
|
separator(),
|
||||||
@ -75,5 +73,10 @@ int main() {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
screen.onSelectionModified([&] {
|
||||||
|
selectionChangeCounter++;
|
||||||
|
selection = screen.GetSelectedContent(renderer);
|
||||||
|
});
|
||||||
|
|
||||||
screen.Loop(renderer);
|
screen.Loop(renderer);
|
||||||
}
|
}
|
||||||
|
@ -69,8 +69,7 @@ class ScreenInteractive : public Screen {
|
|||||||
void ForceHandleCtrlZ(bool force);
|
void ForceHandleCtrlZ(bool force);
|
||||||
|
|
||||||
// Selection API.
|
// Selection API.
|
||||||
// TODO: Implement somethings here.
|
std::string GetSelectedContent(Component component);
|
||||||
std::string GetSelectedContent(void);
|
|
||||||
void onSelectionModified(std::function<void(void)> callback);
|
void onSelectionModified(std::function<void(void)> callback);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -48,6 +48,8 @@ class Node {
|
|||||||
// Step 4: Draw this element.
|
// Step 4: Draw this element.
|
||||||
virtual void Render(Screen& screen);
|
virtual void Render(Screen& screen);
|
||||||
|
|
||||||
|
virtual std::string GetSelectedContent(Selection& selection);
|
||||||
|
|
||||||
// Layout may not resolve within a single iteration for some elements. This
|
// Layout may not resolve within a single iteration for some elements. This
|
||||||
// allows them to request additionnal iterations. This signal must be
|
// allows them to request additionnal iterations. This signal must be
|
||||||
// forwarded to children at least once.
|
// forwarded to children at least once.
|
||||||
@ -66,6 +68,7 @@ class Node {
|
|||||||
void Render(Screen& screen, const Element& element);
|
void Render(Screen& screen, const Element& element);
|
||||||
void Render(Screen& screen, Node* node);
|
void Render(Screen& screen, Node* node);
|
||||||
void Render(Screen& screen, Node* node, Selection& selection);
|
void Render(Screen& screen, Node* node, Selection& selection);
|
||||||
|
std::string GetNodeSelectedContent(Screen& screen, Node* node, Selection& selection);
|
||||||
|
|
||||||
} // namespace ftxui
|
} // namespace ftxui
|
||||||
|
|
||||||
|
@ -577,9 +577,12 @@ void ScreenInteractive::ForceHandleCtrlZ(bool force) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Returns the content of the current selection
|
/// @brief Returns the content of the current selection
|
||||||
std::string ScreenInteractive::GetSelectedContent(void)
|
std::string ScreenInteractive::GetSelectedContent(Component component)
|
||||||
{
|
{
|
||||||
|
Selection selection(selection_start_x_, selection_start_y_, //
|
||||||
|
selection_end_x_, selection_end_y_);
|
||||||
|
|
||||||
|
return GetNodeSelectedContent(*this, component->Render().get(), selection);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// @brief Sets a callback on modifications of the selection
|
/// @brief Sets a callback on modifications of the selection
|
||||||
|
@ -57,6 +57,17 @@ void Node::Check(Status* status) {
|
|||||||
status->need_iteration |= (status->iteration == 0);
|
status->need_iteration |= (status->iteration == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Node::GetSelectedContent(Selection& selection) {
|
||||||
|
|
||||||
|
std::string content;
|
||||||
|
|
||||||
|
for (auto& child : children_) {
|
||||||
|
content += child->GetSelectedContent(selection);
|
||||||
|
}
|
||||||
|
|
||||||
|
return content;
|
||||||
|
}
|
||||||
|
|
||||||
/// @brief Display an element on a ftxui::Screen.
|
/// @brief Display an element on a ftxui::Screen.
|
||||||
/// @ingroup dom
|
/// @ingroup dom
|
||||||
void Render(Screen& screen, const Element& element) {
|
void Render(Screen& screen, const Element& element) {
|
||||||
@ -105,4 +116,35 @@ void Render(Screen& screen, Node* node, Selection& selection) {
|
|||||||
screen.ApplyShader();
|
screen.ApplyShader();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string GetNodeSelectedContent(Screen& screen, Node* node, Selection& selection) {
|
||||||
|
|
||||||
|
Box box;
|
||||||
|
box.x_min = 0;
|
||||||
|
box.y_min = 0;
|
||||||
|
box.x_max = screen.dimx() - 1;
|
||||||
|
box.y_max = screen.dimy() - 1;
|
||||||
|
|
||||||
|
Node::Status status;
|
||||||
|
node->Check(&status);
|
||||||
|
const int max_iterations = 20;
|
||||||
|
while (status.need_iteration && status.iteration < max_iterations) {
|
||||||
|
// Step 1: Find what dimension this elements wants to be.
|
||||||
|
node->ComputeRequirement();
|
||||||
|
|
||||||
|
// Step 2: Assign a dimension to the element.
|
||||||
|
node->SetBox(box);
|
||||||
|
|
||||||
|
// Check if the element needs another iteration of the layout algorithm.
|
||||||
|
status.need_iteration = false;
|
||||||
|
status.iteration++;
|
||||||
|
node->Check(&status);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Step 3: Selection
|
||||||
|
node->Select(selection);
|
||||||
|
|
||||||
|
// Step 4: get the selected content.
|
||||||
|
return node->GetSelectedContent(selection);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ftxui
|
} // namespace ftxui
|
||||||
|
@ -44,6 +44,7 @@ class Text : public Node {
|
|||||||
void Render(Screen& screen) override {
|
void Render(Screen& screen) override {
|
||||||
int x = box_.x_min;
|
int x = box_.x_min;
|
||||||
const int y = box_.y_min;
|
const int y = box_.y_min;
|
||||||
|
|
||||||
if (y > box_.y_max) {
|
if (y > box_.y_max) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -67,6 +68,29 @@ class Text : public Node {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string GetSelectedContent(Selection& selection) {
|
||||||
|
int x = box_.x_min;
|
||||||
|
std::string selected_text = "";
|
||||||
|
|
||||||
|
if (has_selection == false) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& cell : Utf8ToGlyphs(text_)) {
|
||||||
|
if (x > box_.x_max) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((x >= selection_start_) && (x <= selection_end_)) {
|
||||||
|
selected_text += cell;
|
||||||
|
}
|
||||||
|
|
||||||
|
++x;
|
||||||
|
}
|
||||||
|
|
||||||
|
return selected_text;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string text_;
|
std::string text_;
|
||||||
bool has_selection = false;
|
bool has_selection = false;
|
||||||
|
Loading…
Reference in New Issue
Block a user