mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2025-06-25 09:01:11 +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() {
|
||||
auto screen = ScreenInteractive::TerminalOutput();
|
||||
int counter = 0;
|
||||
|
||||
screen.onSelectionModified([&]{
|
||||
counter++;
|
||||
});
|
||||
int selectionChangeCounter = 0;
|
||||
std::string selection = "";
|
||||
|
||||
auto quit = Button("Quit", screen.ExitLoopClosure());
|
||||
|
||||
// The components:
|
||||
auto renderer = Renderer(quit, [&] {
|
||||
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({
|
||||
LoremIpsum(),
|
||||
separator(),
|
||||
@ -75,5 +73,10 @@ int main() {
|
||||
});
|
||||
});
|
||||
|
||||
screen.onSelectionModified([&] {
|
||||
selectionChangeCounter++;
|
||||
selection = screen.GetSelectedContent(renderer);
|
||||
});
|
||||
|
||||
screen.Loop(renderer);
|
||||
}
|
||||
|
@ -69,8 +69,7 @@ class ScreenInteractive : public Screen {
|
||||
void ForceHandleCtrlZ(bool force);
|
||||
|
||||
// Selection API.
|
||||
// TODO: Implement somethings here.
|
||||
std::string GetSelectedContent(void);
|
||||
std::string GetSelectedContent(Component component);
|
||||
void onSelectionModified(std::function<void(void)> callback);
|
||||
|
||||
private:
|
||||
|
@ -48,6 +48,8 @@ class Node {
|
||||
// Step 4: Draw this element.
|
||||
virtual void Render(Screen& screen);
|
||||
|
||||
virtual std::string GetSelectedContent(Selection& selection);
|
||||
|
||||
// Layout may not resolve within a single iteration for some elements. This
|
||||
// allows them to request additionnal iterations. This signal must be
|
||||
// forwarded to children at least once.
|
||||
@ -66,6 +68,7 @@ class Node {
|
||||
void Render(Screen& screen, const Element& element);
|
||||
void Render(Screen& screen, Node* node);
|
||||
void Render(Screen& screen, Node* node, Selection& selection);
|
||||
std::string GetNodeSelectedContent(Screen& screen, Node* node, Selection& selection);
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
|
@ -577,9 +577,12 @@ void ScreenInteractive::ForceHandleCtrlZ(bool force) {
|
||||
}
|
||||
|
||||
/// @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
|
||||
|
@ -57,6 +57,17 @@ void Node::Check(Status* status) {
|
||||
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.
|
||||
/// @ingroup dom
|
||||
void Render(Screen& screen, const Element& element) {
|
||||
@ -105,4 +116,35 @@ void Render(Screen& screen, Node* node, Selection& selection) {
|
||||
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
|
||||
|
@ -44,6 +44,7 @@ class Text : public Node {
|
||||
void Render(Screen& screen) override {
|
||||
int x = box_.x_min;
|
||||
const int y = box_.y_min;
|
||||
|
||||
if (y > box_.y_max) {
|
||||
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:
|
||||
std::string text_;
|
||||
bool has_selection = false;
|
||||
|
Loading…
Reference in New Issue
Block a user