26std::string PasswordField(
size_t size) {
28 out.reserve(2 *
size);
36class InputBase :
public ComponentBase {
38 InputBase(StringRef content,
39 ConstStringRef placeholder,
40 Ref<InputOption> option)
41 : content_(std::move(content)),
42 placeholder_(std::move(placeholder)),
43 option_(std::move(option)) {}
45 int cursor_position_internal_ = 0;
46 int& cursor_position() {
47 int& opt = option_->cursor_position();
51 return cursor_position_internal_;
56 std::string password_content;
57 if (option_->password()) {
58 password_content = PasswordField(content_->size());
60 std::string& content = option_->password() ? password_content : *content_;
64 cursor_position() = std::max(0, std::min<int>(
size, cursor_position()));
66 bool is_focused = Focused();
70 bool hovered = hovered_;
73 decorator = decorator |
focus;
75 if (hovered || is_focused) {
78 return text(*placeholder_) | decorator |
reflect(box_);
86 return text(content) | main_decorator |
reflect(box_);
90 int index_before_cursor =
GlyphPosition(content, cursor_position());
91 int index_after_cursor =
GlyphPosition(content, 1, index_before_cursor);
92 std::string part_before_cursor = content.substr(0, index_before_cursor);
93 std::string part_at_cursor =
" ";
94 if (cursor_position() <
size) {
95 part_at_cursor = content.substr(index_before_cursor,
96 index_after_cursor - index_before_cursor);
98 std::string part_after_cursor = content.substr(index_after_cursor);
99 auto focused = (is_focused || hovered_) ?
focus :
select;
101 text(part_before_cursor),
103 text(part_after_cursor),
108 bool OnEvent(Event event)
override {
110 std::max(0, std::min<int>((
int)content_->size(), cursor_position()));
112 if (event.is_mouse()) {
113 return OnMouseEvent(event);
120 if (cursor_position() == 0) {
123 size_t start =
GlyphPosition(*content_, cursor_position() - 1);
125 content_->erase(start, end - start);
127 option_->on_change();
133 if (cursor_position() ==
int(content_->size())) {
137 size_t end =
GlyphPosition(*content_, cursor_position() + 1);
138 content_->erase(start, end - start);
139 option_->on_change();
159 cursor_position() < (
int)content_->size()) {
165 cursor_position() = 0;
175 if (event.is_character()) {
177 content_->insert(start, event.character());
179 option_->on_change();
186 bool OnMouseEvent(Event event) {
188 box_.Contain(event.mouse().x, event.mouse().y) && CaptureMouse(event);
199 if (content_->empty()) {
204 int original_glyph = cursor_position();
205 original_glyph =
util::clamp(original_glyph, 0,
int(mapping.size()));
206 size_t original_cell = 0;
207 for (
size_t i = 0; i < mapping.size(); i++) {
208 if (mapping[i] == original_glyph) {
209 original_cell = (int)i;
213 if (mapping[original_cell] != original_glyph) {
214 original_cell = mapping.size();
216 int target_cell = int(original_cell) +
event.mouse().x - cursor_box_.x_min;
217 int target_glyph = target_cell < (int)mapping.size() ? mapping[target_cell]
218 : (int)mapping.size();
220 if (cursor_position() != target_glyph) {
221 cursor_position() = target_glyph;
222 option_->on_change();
227 bool Focusable() const final {
return true; }
229 bool hovered_ =
false;
231 ConstStringRef placeholder_;
235 Ref<InputOption> option_;
An adapter. Own or reference a constant string. For convenience, this class convert multiple immutabl...
An adapter. Own or reference an mutable object.
An adapter. Own or reference a constant string. For convenience, this class convert multiple mutable ...
constexpr const T & clamp(const T &v, const T &lo, const T &hi)
std::function< Element(Element)> Decorator
Element flex(Element)
Make a child element to expand proportionnally to the space left in a container.
std::shared_ptr< T > Make(Args &&... args)
std::shared_ptr< Node > Element
Component Input(StringRef content, ConstStringRef placeholder, Ref< InputOption > option={})
An input box for editing text.
Element bold(Element)
Use a bold font, for elements with more emphasis.
Element hbox(Elements)
A container displaying elements horizontally one by one.
Element inverted(Element)
Add a filter that will invert the foreground and the background colors.
Element text(std::wstring text)
Display a piece of unicode text.
int GlyphPosition(const std::string &input, size_t glyph_index, size_t start=0)
std::vector< int > CellToGlyphIndex(const std::string &input)
int GlyphCount(const std::string &input)
Decorator reflect(Box &box)
Element dim(Element)
Use a light font, for elements with less emphasis.
Element frame(Element)
Allow an element to be displayed inside a 'virtual' area. It size can be larger than its container....
void Render(Screen &screen, const Element &element)
Display an element on a ftxui::Screen.
Decorator size(Direction, Constraint, int value)
Apply a constraint on the size of an element.
std::shared_ptr< ComponentBase > Component
static const Event Custom
static const Event Backspace
static const Event Return
static const Event ArrowLeft
static const Event Delete
static const Event ArrowRight