mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2025-09-15 23:48:15 +08:00
Feature: Selection
Add support for selection content in the dom.
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse
|
||||
#include "ftxui/component/event.hpp" // for Event
|
||||
#include "ftxui/component/task.hpp" // for Task, Closure
|
||||
#include "ftxui/dom/selection.hpp" // for SelectionOption
|
||||
#include "ftxui/screen/screen.hpp" // for Screen
|
||||
|
||||
namespace ftxui {
|
||||
@@ -68,6 +69,10 @@ class ScreenInteractive : public Screen {
|
||||
void ForceHandleCtrlC(bool force);
|
||||
void ForceHandleCtrlZ(bool force);
|
||||
|
||||
// Selection API.
|
||||
std::string GetSelection();
|
||||
void SelectionChange(std::function<void()> callback);
|
||||
|
||||
private:
|
||||
void ExitNow();
|
||||
|
||||
@@ -82,6 +87,8 @@ class ScreenInteractive : public Screen {
|
||||
void RunOnceBlocking(Component component);
|
||||
|
||||
void HandleTask(Component component, Task& task);
|
||||
bool HandleSelection(bool handled, Event event);
|
||||
void RefreshSelection();
|
||||
void Draw(Component component);
|
||||
void ResetCursorPosition();
|
||||
|
||||
@@ -129,6 +136,22 @@ class ScreenInteractive : public Screen {
|
||||
// The style of the cursor to restore on exit.
|
||||
int cursor_reset_shape_ = 1;
|
||||
|
||||
// Selection API:
|
||||
CapturedMouse selection_pending_;
|
||||
struct SelectionData {
|
||||
int start_x = -1;
|
||||
int start_y = -1;
|
||||
int end_x = -2;
|
||||
int end_y = -2;
|
||||
bool empty = true;
|
||||
bool operator==(const SelectionData& other) const;
|
||||
bool operator!=(const SelectionData& other) const;
|
||||
};
|
||||
SelectionData selection_data_;
|
||||
SelectionData selection_data_previous_;
|
||||
std::unique_ptr<Selection> selection_;
|
||||
std::function<void()> selection_on_change_;
|
||||
|
||||
friend class Loop;
|
||||
|
||||
public:
|
||||
|
@@ -113,6 +113,11 @@ Decorator focusPositionRelative(float x, float y);
|
||||
Element automerge(Element child);
|
||||
Decorator hyperlink(std::string link);
|
||||
Element hyperlink(std::string link, Element child);
|
||||
Element selectionStyleReset(Element);
|
||||
Decorator selectionColor(Color foreground);
|
||||
Decorator selectionBackgroundColor(Color foreground);
|
||||
Decorator selectionForegroundColor(Color foreground);
|
||||
Decorator selectionStyle(std::function<void(Pixel&)> style);
|
||||
|
||||
// --- Layout is
|
||||
// Horizontal, Vertical or stacked set of elements.
|
||||
|
@@ -8,6 +8,7 @@
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/dom/requirement.hpp" // for Requirement
|
||||
#include "ftxui/dom/selection.hpp" // for Selection
|
||||
#include "ftxui/screen/box.hpp" // for Box
|
||||
#include "ftxui/screen/screen.hpp"
|
||||
|
||||
@@ -40,9 +41,15 @@ class Node {
|
||||
// Propagated from Parents to Children.
|
||||
virtual void SetBox(Box box);
|
||||
|
||||
// Step 3: Draw this element.
|
||||
// Step 3: (optional) Selection
|
||||
// Propagated from Parents to Children.
|
||||
virtual void Select(Selection& selection);
|
||||
|
||||
// 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.
|
||||
@@ -60,6 +67,10 @@ 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
|
||||
|
||||
|
50
include/ftxui/dom/selection.hpp
Normal file
50
include/ftxui/dom/selection.hpp
Normal file
@@ -0,0 +1,50 @@
|
||||
// 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.
|
||||
|
||||
#ifndef FTXUI_DOM_SELECTION_HPP
|
||||
#define FTXUI_DOM_SELECTION_HPP
|
||||
|
||||
#include <functional>
|
||||
|
||||
#include <sstream>
|
||||
#include "ftxui/screen/box.hpp" // for Box
|
||||
#include "ftxui/screen/pixel.hpp" // for Pixel
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
/// @brief Represent a selection in the terminal.
|
||||
class Selection {
|
||||
public:
|
||||
Selection(); // Empty selection.
|
||||
Selection(int start_x, int start_y, int end_x, int end_y);
|
||||
|
||||
const Box& GetBox() const;
|
||||
|
||||
Selection SaturateHorizontal(Box box);
|
||||
Selection SaturateVertical(Box box);
|
||||
bool IsEmpty() const { return empty_; }
|
||||
|
||||
void AddPart(const std::string& part, int y, int left, int right);
|
||||
std::string GetParts() { return parts_.str(); }
|
||||
|
||||
private:
|
||||
Selection(int start_x, int start_y, int end_x, int end_y, Selection* parent);
|
||||
|
||||
Selection* const parent_ = this;
|
||||
const bool empty_ = true;
|
||||
const int start_x_ = 0;
|
||||
const int start_y_ = 0;
|
||||
const int end_x_ = 0;
|
||||
const int end_y_ = 0;
|
||||
const Box box_ = {};
|
||||
std::stringstream parts_;
|
||||
|
||||
// The position of the last inserted part.
|
||||
int x_ = 0;
|
||||
int y_ = 0;
|
||||
};
|
||||
|
||||
} // namespace ftxui
|
||||
|
||||
#endif /* end of include guard: FTXUI_DOM_SELECTION_HPP */
|
@@ -4,12 +4,14 @@
|
||||
#ifndef FTXUI_SCREEN_SCREEN_HPP
|
||||
#define FTXUI_SCREEN_SCREEN_HPP
|
||||
|
||||
#include <cstdint> // for uint8_t
|
||||
#include <string> // for string, basic_string, allocator
|
||||
#include <vector> // for vector
|
||||
#include <cstdint> // for uint8_t
|
||||
#include <functional> // for function
|
||||
#include <string> // for string, basic_string, allocator
|
||||
#include <vector> // for vector
|
||||
|
||||
#include "ftxui/screen/image.hpp" // for Pixel, Image
|
||||
#include "ftxui/screen/terminal.hpp" // for Dimensions
|
||||
#include "ftxui/util/autoreset.hpp" // for AutoReset
|
||||
|
||||
namespace ftxui {
|
||||
|
||||
@@ -67,9 +69,18 @@ class Screen : public Image {
|
||||
uint8_t RegisterHyperlink(const std::string& link);
|
||||
const std::string& Hyperlink(uint8_t id) const;
|
||||
|
||||
using SelectionStyle = std::function<void(Pixel&)>;
|
||||
const SelectionStyle& GetSelectionStyle() const;
|
||||
void SetSelectionStyle(SelectionStyle decorator);
|
||||
|
||||
protected:
|
||||
Cursor cursor_;
|
||||
std::vector<std::string> hyperlinks_ = {""};
|
||||
|
||||
// The current selection style. This is overridden by various dom elements.
|
||||
SelectionStyle selection_style_ = [](Pixel& pixel) {
|
||||
pixel.inverted ^= true;
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace ftxui
|
||||
|
Reference in New Issue
Block a user