32std::vector<std::string>
Split(
const std::string& input) {
33 std::vector<std::string>
output;
34 std::stringstream
ss(input);
36 while (std::getline(
ss, line)) {
39 if (input.back() ==
'\n') {
94class InputBase :
public ComponentBase,
public InputOption {
110 if (content->empty()) {
124 const std::vector<std::string>
lines =
Split(*content);
126 cursor_position() =
util::clamp(cursor_position(), 0, (
int)content->size());
131 for (
const auto& line :
lines) {
145 for (
size_t i = 0;
i <
lines.size(); ++
i) {
146 const std::string& line =
lines[
i];
171 auto element =
hbox({
188 Element Text(
const std::string& input) {
194 out.reserve(10 + input.size() * 3 / 2);
195 for (
size_t i = 0;
i < input.size(); ++
i) {
202 if (cursor_position() == 0) {
206 const size_t end = cursor_position();
208 cursor_position() =
start;
213 if (cursor_position() == (
int)content->size()) {
216 const size_t start = cursor_position();
217 const size_t end =
GlyphNext(content(), cursor_position());
223 if (cursor_position() == 0) {
227 cursor_position() =
GlyphPrevious(content(), cursor_position());
232 if (cursor_position() == (
int)content->size()) {
236 cursor_position() =
GlyphNext(content(), cursor_position());
241 size_t iter = cursor_position();
248 if (content()[
iter] ==
'\n') {
259 if (cursor_position() == (
int)content().
size() ||
260 content()[cursor_position()] ==
'\n') {
265 cursor_position() =
GlyphNext(content(), cursor_position());
270 if (cursor_position() == 0) {
278 if (cursor_position() == 0) {
287 cursor_position() =
GlyphPrevious(content(), cursor_position());
289 if (cursor_position() == 0) {
304 if (cursor_position() == (
int)content->size()) {
312 if (content()[cursor_position()] ==
'\n') {
315 cursor_position() =
GlyphNext(content(), cursor_position());
316 if (cursor_position() == (
int)content().
size()) {
320 cursor_position() =
GlyphNext(content(), cursor_position());
327 cursor_position() = 0;
332 cursor_position() = content->size();
345 content->insert(cursor_position(), character);
346 cursor_position() += character.size();
352 bool OnEvent(Event
event)
override {
353 cursor_position() =
util::clamp(cursor_position(), 0, (
int)content->size());
358 if (
event.is_character()) {
361 if (
event.is_mouse()) {
399 if (cursor_position() == 0) {
404 while (cursor_position()) {
412 while (cursor_position()) {
423 if (cursor_position() == (
int)content().
size()) {
428 while (cursor_position() < (
int)content().
size()) {
429 cursor_position() =
GlyphNext(content(), cursor_position());
435 while (cursor_position() < (
int)content().
size()) {
440 cursor_position() =
next;
447 hovered_ = box_.Contain(
event.mouse().x,
461 if (content->empty()) {
462 cursor_position() = 0;
467 std::vector<std::string>
lines =
Split(*content);
470 for (
const auto& line :
lines) {
499 cursor_position() = 0;
501 cursor_position() +=
lines[
i].size() + 1;
505 cursor_position() =
GlyphNext(content(), cursor_position());
514 bool hovered_ =
false;
574 option.content = std::move(content);
600 option.content = std::move(content);
601 option.placeholder = std::move(placeholder);
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)
size_t GlyphNext(const std::string &input, size_t start)
Element focusCursorBarBlinking(Element)
Same as focus, but set the cursor shape to be a blinking bar.
Element xflex(Element)
Expand/Minimize if possible/needed on the X axis.
WordBreakProperty CodepointToWordBreakProperty(uint32_t codepoint)
Decorator size(WidthOrHeight, Constraint, int value)
Apply a constraint on the size of an element.
std::shared_ptr< Node > Element
std::shared_ptr< ComponentBase > Component
int string_width(const std::string &)
Element hbox(Elements)
A container displaying elements horizontally one by one.
Element text(std::wstring text)
Display a piece of unicode text.
std::vector< Element > Elements
Component Input(InputOption options={})
An input box for editing text.
bool EatCodePoint(const std::string &input, size_t start, size_t *end, uint32_t *ucs)
Element select(Element)
Set the child to be the one selected among its siblings.
Element focus(Element)
Set the child to be the one in focus globally.
Component Slider(SliderOption< T > options)
A slider in any direction.
Decorator reflect(Box &box)
bool IsFullWidth(uint32_t ucs)
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.
size_t GlyphPrevious(const std::string &input, size_t start)
Element vbox(Elements)
A container displaying elements vertically one by one.
static const Event ArrowLeftCtrl
static const Event Backspace
static const Event ArrowUp
static const Event ArrowDown
static const Event Return
static const Event ArrowLeft
static const Event Delete
static const Event ArrowRightCtrl
static const Event ArrowRight