diff --git a/CMakeLists.txt b/CMakeLists.txt index e8fb578..d8f9d4f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -78,7 +78,6 @@ add_library(component STATIC include/ftxui/component/component_base.hpp include/ftxui/component/container.hpp include/ftxui/component/event.hpp - include/ftxui/component/input.hpp include/ftxui/component/menu.hpp include/ftxui/component/mouse.hpp include/ftxui/component/radiobox.hpp diff --git a/examples/component/homescreen.cpp b/examples/component/homescreen.cpp index 8a604b6..a05d30c 100644 --- a/examples/component/homescreen.cpp +++ b/examples/component/homescreen.cpp @@ -12,7 +12,6 @@ #include "ftxui/component/component.hpp" // for Checkbox, Renderer, Horizontal, Vertical, Input, Menu, Radiobox, Tab, Toggle #include "ftxui/component/component_base.hpp" // for ComponentBase #include "ftxui/component/event.hpp" // for Event, Event::Custom -#include "ftxui/component/input.hpp" // for InputBase #include "ftxui/component/screen_interactive.hpp" // for Component, ScreenInteractive #include "ftxui/dom/elements.hpp" // for text, operator|, color, bgcolor, Element, filler, size, vbox, flex, hbox, graph, separator, EQUAL, WIDTH, hcenter, bold, border, window, HEIGHT, Elements, hflow, flex_grow, frame, gauge, LESS_THAN, spinner, dim, GREATER_THAN #include "ftxui/screen/color.hpp" // for Color, Color::BlueLight, Color::RedLight, Color::Black, Color::Blue, Color::Cyan, Color::CyanLight, Color::GrayDark, Color::GrayLight, Color::Green, Color::GreenLight, Color::Magenta, Color::MagentaLight, Color::Red, Color::White, Color::Yellow, Color::YellowLight, Color::Default diff --git a/include/ftxui/component/component.hpp b/include/ftxui/component/component.hpp index 06faecb..c202280 100644 --- a/include/ftxui/component/component.hpp +++ b/include/ftxui/component/component.hpp @@ -26,22 +26,22 @@ std::shared_ptr Make(Args&&... args) { Component Button(ConstStringRef label, std::function on_click, - ConstRef = {}); + Ref = {}); Component Checkbox(ConstStringRef label, bool* checked, - ConstRef option = {}); + Ref option = {}); Component Input(StringRef content, ConstStringRef placeholder, - ConstRef option = {}); + Ref option = {}); Component Menu(const std::vector* entries, int* selected_, - ConstRef = {}); + Ref = {}); Component Radiobox(const std::vector* entries, int* selected_, - ConstRef option = {}); + Ref option = {}); Component Toggle(const std::vector* entries, int* selected, - ConstRef option = {}); + Ref option = {}); template // T = {int, float, long} Component Slider(StringRef label, T* value, T min, T max, T increment); Component Renderer(Component child, std::function); diff --git a/include/ftxui/component/component_options.hpp b/include/ftxui/component/component_options.hpp index 3fdf0bf..d9d0a5a 100644 --- a/include/ftxui/component/component_options.hpp +++ b/include/ftxui/component/component_options.hpp @@ -2,6 +2,7 @@ #define FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP #include +#include namespace ftxui { @@ -42,6 +43,8 @@ struct InputOption { std::function on_change = [] {}; /// Called when the user presses enter. std::function on_enter = [] {}; + + Ref cursor_position = 0; }; /// @brief Option for the Radiobox component. diff --git a/include/ftxui/component/input.hpp b/include/ftxui/component/input.hpp deleted file mode 100644 index efa9e0c..0000000 --- a/include/ftxui/component/input.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef FTXUI_COMPONENT_INPUT_H_ -#define FTXUI_COMPONENT_INPUT_H_ - -#include // for function -#include // for wstring - -#include "ftxui/component/component.hpp" // for Component -#include "ftxui/component/component_base.hpp" // for ComponentBase -#include "ftxui/dom/elements.hpp" // for Element -#include "ftxui/screen/box.hpp" // for Box -#include "ftxui/screen/string.hpp" // for ConstStringRef, StringRef - -namespace ftxui { -struct Event; - -/// @brief An input box. The user can type text into it. -/// @ingroup component. -class InputBase : public ComponentBase { - public: - // Access this interface from a Component - static InputBase* From(Component component); - - // Constructor. - InputBase(StringRef content, - ConstStringRef placeholder, - ConstRef option = {}); - ~InputBase() override = default; - - // State. - int cursor_position = 0; - - // Component implementation. - Element Render() override; - bool OnEvent(Event) override; - - private: - StringRef content_; - ConstStringRef placeholder_; - - bool OnMouseEvent(Event); - Box input_box_; - Box cursor_box_; - ConstRef option_; -}; - -} // namespace ftxui - -#endif /* end of include guard: FTXUI_COMPONENT_INPUT_H_ */ - -// Copyright 2020 Arthur Sonzogni. All rights reserved. -// Use of this source code is governed by the MIT license that can be found in -// the LICENSE file. diff --git a/include/ftxui/component/menu.hpp b/include/ftxui/component/menu.hpp index cb16314..0b56f05 100644 --- a/include/ftxui/component/menu.hpp +++ b/include/ftxui/component/menu.hpp @@ -24,7 +24,7 @@ class MenuBase : public ComponentBase { // Constructor. MenuBase(const std::vector* entries, int* selected_, - ConstRef option = {}); + Ref option = {}); ~MenuBase() override = default; // State. @@ -37,7 +37,7 @@ class MenuBase : public ComponentBase { protected: const std::vector* const entries_; int* selected_ = 0; - ConstRef option_; + Ref option_; bool OnMouseEvent(Event); diff --git a/include/ftxui/component/radiobox.hpp b/include/ftxui/component/radiobox.hpp index 82850e2..181fc91 100644 --- a/include/ftxui/component/radiobox.hpp +++ b/include/ftxui/component/radiobox.hpp @@ -24,7 +24,7 @@ class RadioboxBase : public ComponentBase { // Constructor. RadioboxBase(const std::vector* entries, int* selected, - ConstRef option = {}); + Ref option = {}); ~RadioboxBase() override = default; int focused = 0; @@ -40,7 +40,7 @@ class RadioboxBase : public ComponentBase { bool OnMouseEvent(Event event); int cursor_position = 0; std::vector boxes_; - ConstRef option_; + Ref option_; }; } // namespace ftxui diff --git a/include/ftxui/component/toggle.hpp b/include/ftxui/component/toggle.hpp index e54faa0..d5530da 100644 --- a/include/ftxui/component/toggle.hpp +++ b/include/ftxui/component/toggle.hpp @@ -23,7 +23,7 @@ class ToggleBase : public ComponentBase { // Constructor. ToggleBase(const std::vector* entries, int* selected, - ConstRef option = {}); + Ref option = {}); ~ToggleBase() override = default; // State. @@ -39,7 +39,7 @@ class ToggleBase : public ComponentBase { bool OnMouseEvent(Event event); std::vector boxes_; - ConstRef option_; + Ref option_; }; } // namespace ftxui diff --git a/include/ftxui/util/ref.hpp b/include/ftxui/util/ref.hpp index 68b2738..513a66e 100644 --- a/include/ftxui/util/ref.hpp +++ b/include/ftxui/util/ref.hpp @@ -6,7 +6,7 @@ namespace ftxui { -/// @brief An adapter. Own or reference a constant object. +/// @brief An adapter. Own or reference an immutable object. template class ConstRef { public: @@ -14,6 +14,7 @@ class ConstRef { ConstRef(T t) : owned_(t) {} ConstRef(const T* t) : address_(t) {} const T& operator*() { return address_ ? *address_ : owned_; } + const T& operator()() { return address_ ? *address_ : owned_; } const T* operator->() { return address_ ? address_ : &owned_; } private: @@ -21,6 +22,22 @@ class ConstRef { const T* address_ = nullptr; }; +/// @brief An adapter. Own or reference an mutable object. +template +class Ref{ + public: + Ref() {} + Ref(T t) : owned_(t) {} + Ref(T* t) : address_(t) {} + T& operator*() { return address_ ? *address_ : owned_; } + T& operator()() { return address_ ? *address_ : owned_; } + T* operator->() { return address_ ? address_ : &owned_; } + + private: + T owned_; + T* address_ = nullptr; +}; + /// @brief An adapter. Own or reference a constant string. For convenience, this /// class convert multiple mutable string toward a shared representation. class StringRef { diff --git a/src/ftxui/component/button.cpp b/src/ftxui/component/button.cpp index bfe3ca9..3c81b20 100644 --- a/src/ftxui/component/button.cpp +++ b/src/ftxui/component/button.cpp @@ -16,7 +16,7 @@ class ButtonBase : public ComponentBase { public: ButtonBase(ConstStringRef label, std::function on_click, - ConstRef option) + Ref option) : label_(label), on_click_(on_click), option_(std::move(option)) {} ~ButtonBase() override = default; @@ -55,7 +55,7 @@ class ButtonBase : public ComponentBase { ConstStringRef label_; std::function on_click_; Box box_; - ConstRef option_; + Ref option_; }; } // namespace @@ -84,7 +84,7 @@ class ButtonBase : public ComponentBase { /// ``` Component Button(ConstStringRef label, std::function on_click, - ConstRef option) { + Ref option) { return Make(label, std::move(on_click), std::move(option)); } diff --git a/src/ftxui/component/checkbox.cpp b/src/ftxui/component/checkbox.cpp index 2cdc787..b241974 100644 --- a/src/ftxui/component/checkbox.cpp +++ b/src/ftxui/component/checkbox.cpp @@ -25,7 +25,7 @@ class CheckboxBase : public ComponentBase { public: CheckboxBase(ConstStringRef label, bool* state, - ConstRef option) + Ref option) : label_(label), state_(state), option_(std::move(option)) { #if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK) // Microsoft terminal do not use fonts able to render properly the default @@ -84,7 +84,7 @@ class CheckboxBase : public ComponentBase { ConstStringRef label_; bool* const state_; Box box_; - ConstRef option_; + Ref option_; }; } // namespace @@ -111,7 +111,7 @@ class CheckboxBase : public ComponentBase { /// ``` Component Checkbox(ConstStringRef label, bool* checked, - ConstRef option) { + Ref option) { return Make(label, checked, std::move(option)); } diff --git a/src/ftxui/component/input.cpp b/src/ftxui/component/input.cpp index e419f36..5897a5e 100644 --- a/src/ftxui/component/input.cpp +++ b/src/ftxui/component/input.cpp @@ -3,13 +3,166 @@ #include // for wstring, allocator, basic_string #include "ftxui/component/captured_mouse.hpp" // for CapturedMouse +#include "ftxui/component/component.hpp" // for Component +#include "ftxui/component/component_base.hpp" // for Component #include "ftxui/component/event.hpp" // for Event, Event::ArrowLeft, Event::ArrowRight, Event::Backspace, Event::Custom, Event::Delete, Event::End, Event::Home, Event::Return -#include "ftxui/component/input.hpp" #include "ftxui/component/mouse.hpp" // for Mouse, Mouse::Left, Mouse::Pressed #include "ftxui/component/screen_interactive.hpp" // for Component +#include "ftxui/util/ref.hpp" // for Component namespace ftxui { +/// @brief An input box. The user can type text into it. +/// @ingroup component. +class InputBase : public ComponentBase { + public: + InputBase(StringRef content, + ConstStringRef placeholder, + Ref option) + : content_(content), placeholder_(placeholder), option_(option) {} + ~InputBase() override = default; + + int& cursor_position() { return *(option_->cursor_position); } + + // Component implementation: + Element Render() override { + cursor_position() = + std::max(0, std::min(content_->size(), cursor_position())); + auto main_decorator = flex | size(HEIGHT, EQUAL, 1); + bool is_focused = Focused(); + + // placeholder. + if (content_->size() == 0) { + if (is_focused) + return text(*placeholder_) | focus | dim | inverted | main_decorator | + reflect(input_box_); + else + return text(*placeholder_) | dim | main_decorator | reflect(input_box_); + } + + // Not focused. + if (!is_focused) + return text(*content_) | main_decorator | reflect(input_box_); + + std::wstring part_before_cursor = content_->substr(0, cursor_position()); + std::wstring part_at_cursor = cursor_position() < (int)content_->size() + ? content_->substr(cursor_position(), 1) + : L" "; + std::wstring part_after_cursor = + cursor_position() < (int)content_->size() - 1 + ? content_->substr(cursor_position() + 1) + : L""; + auto focused = is_focused ? focus : select; + + // clang-format off + return + hbox( + text(part_before_cursor), + text(part_at_cursor) | underlined | focused | reflect(cursor_box_), + text(part_after_cursor) + ) | flex | inverted | frame | main_decorator | reflect(input_box_); + // clang-format on + } + + bool OnEvent(Event event) override { + cursor_position() = + std::max(0, std::min(content_->size(), cursor_position())); + + if (event.is_mouse()) + return OnMouseEvent(event); + + std::wstring c; + + // Backspace. + if (event == Event::Backspace) { + if (cursor_position() == 0) + return false; + content_->erase(cursor_position() - 1, 1); + cursor_position()--; + option_->on_change(); + return true; + } + + // Delete + if (event == Event::Delete) { + if (cursor_position() == int(content_->size())) + return false; + content_->erase(cursor_position(), 1); + option_->on_change(); + return true; + } + + // Enter. + if (event == Event::Return) { + option_->on_enter(); + return true; + } + + if (event == Event::Custom) { + return false; + } + + if (event == Event::ArrowLeft && cursor_position() > 0) { + cursor_position()--; + return true; + } + + if (event == Event::ArrowRight && + cursor_position() < (int)content_->size()) { + cursor_position()++; + return true; + } + + if (event == Event::Home) { + cursor_position() = 0; + return true; + } + + if (event == Event::End) { + cursor_position() = (int)content_->size(); + return true; + } + + // Content + if (event.is_character()) { + content_->insert(cursor_position(), 1, event.character()); + cursor_position()++; + option_->on_change(); + return true; + } + return false; + } + + private: + bool OnMouseEvent(Event event) { + if (!CaptureMouse(event)) + return false; + if (!input_box_.Contain(event.mouse().x, event.mouse().y)) + return false; + + TakeFocus(); + + if (event.mouse().button == Mouse::Left && + event.mouse().motion == Mouse::Pressed) { + int new_cursor_position = + cursor_position() + event.mouse().x - cursor_box_.x_min; + new_cursor_position = + std::max(0, std::min(content_->size(), new_cursor_position)); + if (cursor_position() != new_cursor_position) { + cursor_position() = new_cursor_position; + option_->on_change(); + } + } + return true; + } + StringRef content_; + ConstStringRef placeholder_; + + Box input_box_; + Box cursor_box_; + Ref option_; +}; + /// @brief An input box for editing text. /// @param content The editable content. /// @param placeholder The text displayed when content is still empty. @@ -33,149 +186,10 @@ namespace ftxui { /// ``` Component Input(StringRef content, ConstStringRef placeholder, - ConstRef option) { + Ref option) { return Make(content, placeholder, std::move(option)); } -// static -InputBase* InputBase::From(Component component) { - return static_cast(component.get()); -} - -InputBase::InputBase(StringRef content, - ConstStringRef placeholder, - ConstRef option) - : content_(content), placeholder_(placeholder), option_(option) {} - -// Component implementation. -Element InputBase::Render() { - cursor_position = - std::max(0, std::min(content_->size(), cursor_position)); - auto main_decorator = flex | size(HEIGHT, EQUAL, 1); - bool is_focused = Focused(); - - // placeholder. - if (content_->size() == 0) { - if (is_focused) - return text(*placeholder_) | focus | dim | inverted | main_decorator | - reflect(input_box_); - else - return text(*placeholder_) | dim | main_decorator | reflect(input_box_); - } - - // Not focused. - if (!is_focused) - return text(*content_) | main_decorator | reflect(input_box_); - - std::wstring part_before_cursor = content_->substr(0, cursor_position); - std::wstring part_at_cursor = cursor_position < (int)content_->size() - ? content_->substr(cursor_position, 1) - : L" "; - std::wstring part_after_cursor = cursor_position < (int)content_->size() - 1 - ? content_->substr(cursor_position + 1) - : L""; - auto focused = is_focused ? focus : select; - - // clang-format off - return - hbox( - text(part_before_cursor), - text(part_at_cursor) | underlined | focused | reflect(cursor_box_), - text(part_after_cursor) - ) | flex | inverted | frame | main_decorator | reflect(input_box_); - // clang-format on -} - -bool InputBase::OnEvent(Event event) { - cursor_position = - std::max(0, std::min(content_->size(), cursor_position)); - - if (event.is_mouse()) - return OnMouseEvent(event); - - std::wstring c; - - // Backspace. - if (event == Event::Backspace) { - if (cursor_position == 0) - return false; - content_->erase(cursor_position - 1, 1); - cursor_position--; - option_->on_change(); - return true; - } - - // Delete - if (event == Event::Delete) { - if (cursor_position == int(content_->size())) - return false; - content_->erase(cursor_position, 1); - option_->on_change(); - return true; - } - - // Enter. - if (event == Event::Return) { - option_->on_enter(); - return true; - } - - if (event == Event::Custom) { - return false; - } - - if (event == Event::ArrowLeft && cursor_position > 0) { - cursor_position--; - return true; - } - - if (event == Event::ArrowRight && cursor_position < (int)content_->size()) { - cursor_position++; - return true; - } - - if (event == Event::Home) { - cursor_position = 0; - return true; - } - - if (event == Event::End) { - cursor_position = (int)content_->size(); - return true; - } - - // Content - if (event.is_character()) { - content_->insert(cursor_position, 1, event.character()); - cursor_position++; - option_->on_change(); - return true; - } - return false; -} - -bool InputBase::OnMouseEvent(Event event) { - if (!CaptureMouse(event)) - return false; - if (!input_box_.Contain(event.mouse().x, event.mouse().y)) - return false; - - TakeFocus(); - - if (event.mouse().button == Mouse::Left && - event.mouse().motion == Mouse::Pressed) { - int new_cursor_position = - cursor_position + event.mouse().x - cursor_box_.x_min; - new_cursor_position = - std::max(0, std::min(content_->size(), new_cursor_position)); - if (cursor_position != new_cursor_position) { - cursor_position = new_cursor_position; - option_->on_change(); - } - } - return true; -} - } // namespace ftxui // Copyright 2020 Arthur Sonzogni. All rights reserved. diff --git a/src/ftxui/component/input_test.cpp b/src/ftxui/component/input_test.cpp index be98285..490228f 100644 --- a/src/ftxui/component/input_test.cpp +++ b/src/ftxui/component/input_test.cpp @@ -4,68 +4,72 @@ #include // for wstring, allocator #include "ftxui/component/captured_mouse.hpp" // for ftxui +#include "ftxui/component/component.hpp" +#include "ftxui/component/component_options.hpp" #include "ftxui/component/event.hpp" // for Event, Event::ArrowLeft, Event::ArrowRight, Event::Backspace, Event::Delete, Event::End, Event::Home -#include "ftxui/component/input.hpp" -#include "gtest/gtest_pred_impl.h" // for Test, EXPECT_EQ, TEST +#include "gtest/gtest_pred_impl.h" // for Test, EXPECT_EQ, TEST using namespace ftxui; TEST(InputTest, Init) { std::wstring content; std::wstring placeholder; - Component input = Input(&content, &placeholder); + auto option = InputOption(); + Component input = Input(&content, &placeholder, &option); - EXPECT_EQ(InputBase::From(input)->cursor_position, 0); + EXPECT_EQ(option.cursor_position(), 0); } TEST(InputTest, Type) { std::wstring content; std::wstring placeholder; - Component input = Input(&content, &placeholder); + auto option = InputOption(); + Component input = Input(&content, &placeholder, &option); input->OnEvent(Event::Character('a')); EXPECT_EQ(content, L"a"); - EXPECT_EQ(InputBase::From(input)->cursor_position, 1u); + EXPECT_EQ(option.cursor_position(), 1u); input->OnEvent(Event::Character('b')); EXPECT_EQ(content, L"ab"); - EXPECT_EQ(InputBase::From(input)->cursor_position, 2u); + EXPECT_EQ(option.cursor_position(), 2u); } TEST(InputTest, Arrow) { std::wstring content; std::wstring placeholder; - Component input = Input(&content, &placeholder); + auto option = InputOption(); + auto input = Input(&content, &placeholder, &option); input->OnEvent(Event::Character('a')); input->OnEvent(Event::Character('b')); input->OnEvent(Event::Character('c')); - EXPECT_EQ(InputBase::From(input)->cursor_position, 3u); + EXPECT_EQ(option.cursor_position(), 3u); input->OnEvent(Event::ArrowLeft); - EXPECT_EQ(InputBase::From(input)->cursor_position, 2u); + EXPECT_EQ(option.cursor_position(), 2u); input->OnEvent(Event::ArrowLeft); - EXPECT_EQ(InputBase::From(input)->cursor_position, 1u); + EXPECT_EQ(option.cursor_position(), 1u); input->OnEvent(Event::ArrowLeft); - EXPECT_EQ(InputBase::From(input)->cursor_position, 0u); + EXPECT_EQ(option.cursor_position(), 0u); input->OnEvent(Event::ArrowLeft); - EXPECT_EQ(InputBase::From(input)->cursor_position, 0u); + EXPECT_EQ(option.cursor_position(), 0u); input->OnEvent(Event::ArrowRight); - EXPECT_EQ(InputBase::From(input)->cursor_position, 1u); + EXPECT_EQ(option.cursor_position(), 1u); input->OnEvent(Event::ArrowRight); - EXPECT_EQ(InputBase::From(input)->cursor_position, 2u); + EXPECT_EQ(option.cursor_position(), 2u); input->OnEvent(Event::ArrowRight); - EXPECT_EQ(InputBase::From(input)->cursor_position, 3u); + EXPECT_EQ(option.cursor_position(), 3u); input->OnEvent(Event::ArrowRight); - EXPECT_EQ(InputBase::From(input)->cursor_position, 3u); + EXPECT_EQ(option.cursor_position(), 3u); } TEST(InputTest, Insert) { @@ -97,16 +101,17 @@ TEST(InputTest, Insert) { TEST(InputTest, Home) { std::wstring content; std::wstring placeholder; - Component input = Input(&content, &placeholder); + auto option = InputOption(); + auto input = Input(&content, &placeholder, &option); input->OnEvent(Event::Character('a')); input->OnEvent(Event::Character('b')); input->OnEvent(Event::Character('c')); EXPECT_EQ(content, L"abc"); - EXPECT_EQ(InputBase::From(input)->cursor_position, 3u); + EXPECT_EQ(option.cursor_position(), 3u); input->OnEvent(Event::Home); - EXPECT_EQ(InputBase::From(input)->cursor_position, 0u); + EXPECT_EQ(option.cursor_position(), 0u); input->OnEvent(Event::Character('-')); EXPECT_EQ(content, L"-abc"); @@ -115,7 +120,8 @@ TEST(InputTest, Home) { TEST(InputTest, End) { std::wstring content; std::wstring placeholder; - Component input = Input(&content, &placeholder); + auto option = InputOption(); + auto input = Input(&content, &placeholder, &option); input->OnEvent(Event::Character('a')); input->OnEvent(Event::Character('b')); @@ -124,15 +130,16 @@ TEST(InputTest, End) { input->OnEvent(Event::ArrowLeft); input->OnEvent(Event::ArrowLeft); - EXPECT_EQ(InputBase::From(input)->cursor_position, 1u); + EXPECT_EQ(option.cursor_position(), 1u); input->OnEvent(Event::End); - EXPECT_EQ(InputBase::From(input)->cursor_position, 3u); + EXPECT_EQ(option.cursor_position(), 3u); } TEST(InputTest, Delete) { std::wstring content; std::wstring placeholder; - Component input = Input(&content, &placeholder); + auto option = InputOption(); + auto input = Input(&content, &placeholder, &option); input->OnEvent(Event::Character('a')); input->OnEvent(Event::Character('b')); @@ -140,21 +147,22 @@ TEST(InputTest, Delete) { input->OnEvent(Event::ArrowLeft); EXPECT_EQ(content, L"abc"); - EXPECT_EQ(InputBase::From(input)->cursor_position, 2u); + EXPECT_EQ(option.cursor_position(), 2u); input->OnEvent(Event::Delete); EXPECT_EQ(content, L"ab"); - EXPECT_EQ(InputBase::From(input)->cursor_position, 2u); + EXPECT_EQ(option.cursor_position(), 2u); input->OnEvent(Event::Delete); EXPECT_EQ(content, L"ab"); - EXPECT_EQ(InputBase::From(input)->cursor_position, 2u); + EXPECT_EQ(option.cursor_position(), 2u); } TEST(InputTest, Backspace) { std::wstring content; std::wstring placeholder; - Component input = Input(&content, &placeholder); + auto option = InputOption(); + auto input = Input(&content, &placeholder, &option); input->OnEvent(Event::Character('a')); input->OnEvent(Event::Character('b')); @@ -162,19 +170,19 @@ TEST(InputTest, Backspace) { input->OnEvent(Event::ArrowLeft); EXPECT_EQ(content, L"abc"); - EXPECT_EQ(InputBase::From(input)->cursor_position, 2u); + EXPECT_EQ(option.cursor_position(), 2u); input->OnEvent(Event::Backspace); EXPECT_EQ(content, L"ac"); - EXPECT_EQ(InputBase::From(input)->cursor_position, 1u); + EXPECT_EQ(option.cursor_position(), 1u); input->OnEvent(Event::Backspace); EXPECT_EQ(content, L"c"); - EXPECT_EQ(InputBase::From(input)->cursor_position, 0u); + EXPECT_EQ(option.cursor_position(), 0u); input->OnEvent(Event::Backspace); EXPECT_EQ(content, L"c"); - EXPECT_EQ(InputBase::From(input)->cursor_position, 0u); + EXPECT_EQ(option.cursor_position(), 0u); } // Copyright 2021 Arthur Sonzogni. All rights reserved. diff --git a/src/ftxui/component/menu.cpp b/src/ftxui/component/menu.cpp index 6af46df..0ff6b54 100644 --- a/src/ftxui/component/menu.cpp +++ b/src/ftxui/component/menu.cpp @@ -40,7 +40,7 @@ namespace ftxui { /// ``` Component Menu(const std::vector* entries, int* selected, - ConstRef option) { + Ref option) { return Make(entries, selected, std::move(option)); } @@ -51,7 +51,7 @@ MenuBase* MenuBase::From(Component component) { MenuBase::MenuBase(const std::vector* entries, int* selected, - ConstRef option) + Ref option) : entries_(entries), selected_(selected), option_(option) {} Element MenuBase::Render() { diff --git a/src/ftxui/component/radiobox.cpp b/src/ftxui/component/radiobox.cpp index cce7c1c..81a3f84 100644 --- a/src/ftxui/component/radiobox.cpp +++ b/src/ftxui/component/radiobox.cpp @@ -41,7 +41,7 @@ namespace ftxui { /// ``` Component Radiobox(const std::vector* entries, int* selected, - ConstRef option) { + Ref option) { return Make(entries, selected, std::move(option)); } @@ -52,7 +52,7 @@ RadioboxBase* RadioboxBase::From(Component component) { RadioboxBase::RadioboxBase(const std::vector* entries, int* selected, - ConstRef option) + Ref option) : entries_(entries), selected_(selected), option_(std::move(option)) { #if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK) // Microsoft terminal do not use fonts able to render properly the default diff --git a/src/ftxui/component/toggle.cpp b/src/ftxui/component/toggle.cpp index 0eb36c0..4d55128 100644 --- a/src/ftxui/component/toggle.cpp +++ b/src/ftxui/component/toggle.cpp @@ -12,7 +12,7 @@ namespace ftxui { Component Toggle(const std::vector* entries, int* selected, - ConstRef option) { + Ref option) { return Make(entries, selected, std::move(option)); } @@ -23,7 +23,7 @@ ToggleBase* ToggleBase::From(Component component) { ToggleBase::ToggleBase(const std::vector* entries, int* selected, - ConstRef option) + Ref option) : entries_(entries), selected_(selected), option_(std::move(option)) {} Element ToggleBase::Render() {