Dropdown: Fix title not updated. (#851)

A bug was introduced by:
https://github.com/ArthurSonzogni/FTXUI/pull/826

The checkbox label wasn't updated.

Bug:https://github.com/ArthurSonzogni/FTXUI/issues/861
This commit is contained in:
Arthur Sonzogni 2024-05-15 18:23:59 +02:00 committed by GitHub
parent af49b57e60
commit ecacb22d37
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 160 additions and 24 deletions

View File

@ -44,6 +44,9 @@ current (development)
### Screen ### Screen
- Feature: Add `Box::IsEmpty()`. - Feature: Add `Box::IsEmpty()`.
### Util
- Feature: Support arbitrary `Adapter` for `ConstStringListRef`. See #843.
### Build ### Build
- Support for cmake's "unity/jumbo" builds. Fixed by @ClausKlein. - Support for cmake's "unity/jumbo" builds. Fixed by @ClausKlein.

View File

@ -18,6 +18,7 @@ add_executable(ftxui-tests
src/ftxui/component/menu_test.cpp src/ftxui/component/menu_test.cpp
src/ftxui/component/modal_test.cpp src/ftxui/component/modal_test.cpp
src/ftxui/component/radiobox_test.cpp src/ftxui/component/radiobox_test.cpp
src/ftxui/util/ref_test.cpp
src/ftxui/component/receiver_test.cpp src/ftxui/component/receiver_test.cpp
src/ftxui/component/resizable_split_test.cpp src/ftxui/component/resizable_split_test.cpp
src/ftxui/component/screen_interactive_test.cpp src/ftxui/component/screen_interactive_test.cpp

View File

@ -5,8 +5,10 @@
#define FTXUI_UTIL_REF_HPP #define FTXUI_UTIL_REF_HPP
#include <ftxui/screen/string.hpp> #include <ftxui/screen/string.hpp>
#include <memory>
#include <string> #include <string>
#include <variant> #include <variant>
#include <vector>
namespace ftxui { namespace ftxui {
@ -104,42 +106,109 @@ class ConstStringRef : public ConstRef<std::string> {
}; };
/// @brief An adapter. Reference a list of strings. /// @brief An adapter. Reference a list of strings.
///
/// Supported input:
/// - `std::vector<std::string>`
/// - `std::vector<std::string>*`
/// - `std::vector<std::wstring>*`
/// - `Adapter*`
/// - `std::unique_ptr<Adapter>`
class ConstStringListRef { class ConstStringListRef {
public: public:
// Bring your own adapter:
class Adapter {
public:
Adapter() = default;
Adapter(const Adapter&) = default;
Adapter& operator=(const Adapter&) = default;
Adapter(Adapter&&) = default;
Adapter& operator=(Adapter&&) = default;
virtual ~Adapter() = default;
virtual size_t size() const = 0;
virtual std::string operator[](size_t i) const = 0;
};
using Variant = std::variant<const std::vector<std::string>, //
const std::vector<std::string>*, //
const std::vector<std::wstring>*, //
Adapter*, //
std::unique_ptr<Adapter> //
>;
ConstStringListRef() = default; ConstStringListRef() = default;
~ConstStringListRef() = default; ~ConstStringListRef() = default;
ConstStringListRef(ConstStringListRef&&) = delete; ConstStringListRef& operator=(const ConstStringListRef&) = default;
ConstStringListRef& operator=(ConstStringListRef&&) = delete; ConstStringListRef& operator=(ConstStringListRef&&) = default;
ConstStringListRef(const std::vector<std::string>* ref) // NOLINT ConstStringListRef(ConstStringListRef&&) = default;
: ref_(ref) {} ConstStringListRef(const ConstStringListRef&) = default;
ConstStringListRef(const std::vector<std::wstring>* ref) // NOLINT
: ref_wide_(ref) {} ConstStringListRef(std::vector<std::string> value) // NOLINT
ConstStringListRef(const ConstStringListRef& other) = default; {
ConstStringListRef& operator=(const ConstStringListRef& other) = default; variant_ = std::make_shared<Variant>(value);
}
ConstStringListRef(const std::vector<std::string>* value) // NOLINT
{
variant_ = std::make_shared<Variant>(value);
}
ConstStringListRef(const std::vector<std::wstring>* value) // NOLINT
{
variant_ = std::make_shared<Variant>(value);
}
ConstStringListRef(Adapter* adapter) // NOLINT
{
variant_ = std::make_shared<Variant>(adapter);
}
template <typename AdapterType>
ConstStringListRef(std::unique_ptr<AdapterType> adapter) // NOLINT
{
variant_ = std::make_shared<Variant>(
static_cast<std::unique_ptr<Adapter>>(std::move(adapter)));
}
size_t size() const { size_t size() const {
if (ref_) { return variant_ ? std::visit(SizeVisitor(), *variant_) : 0;
return ref_->size();
}
if (ref_wide_) {
return ref_wide_->size();
}
return 0;
} }
std::string operator[](size_t i) const { std::string operator[](size_t i) const {
if (ref_) { return variant_ ? std::visit(IndexedGetter(i), *variant_) : "";
return (*ref_)[i];
}
if (ref_wide_) {
return to_string((*ref_wide_)[i]);
}
return "";
} }
private: private:
const std::vector<std::string>* ref_ = nullptr; struct SizeVisitor {
const std::vector<std::wstring>* ref_wide_ = nullptr; size_t operator()(const std::vector<std::string>& v) const {
return v.size();
}
size_t operator()(const std::vector<std::string>* v) const {
return v->size();
}
size_t operator()(const std::vector<std::wstring>* v) const {
return v->size();
}
size_t operator()(const Adapter* v) const { return v->size(); }
size_t operator()(const std::unique_ptr<Adapter>& v) const {
return v->size();
}
};
struct IndexedGetter {
IndexedGetter(size_t index) // NOLINT
: index_(index) {}
size_t index_;
std::string operator()(const std::vector<std::string>& v) const {
return v[index_];
}
std::string operator()(const std::vector<std::string>* v) const {
return (*v)[index_];
}
std::string operator()(const std::vector<std::wstring>* v) const {
return to_string((*v)[index_]);
}
std::string operator()(const Adapter* v) const { return (*v)[index_]; }
std::string operator()(const std::unique_ptr<Adapter>& v) const {
return (*v)[index_];
}
};
std::shared_ptr<Variant> variant_;
}; };
} // namespace ftxui } // namespace ftxui

View File

@ -0,0 +1,63 @@
#include "ftxui/util/ref.hpp"
#include <gtest/gtest.h>
#include "ftxui/component/component.hpp"
namespace ftxui {
namespace {
class Adapter : public ConstStringListRef::Adapter {
public:
Adapter(std::vector<std::string>& entries) : entries(entries) {}
size_t size() const override { return entries.size() * 2; }
std::string operator[](size_t index) const override {
return entries[index / 2];
}
std::vector<std::string>& entries;
};
} // namespace
TEST(ConstStringListRef, Copy) {
std::vector<std::string> entries = {
"entry 1",
"entry 2",
"entry 3",
};
int selected = 0;
auto menu = Menu(entries, &selected);
}
TEST(ConstStringListRef, Ref) {
std::vector<std::string> entries = {
"entry 1",
"entry 2",
"entry 3",
};
int selected = 0;
auto menu = Menu(&entries, &selected);
}
TEST(ConstStringListRef, Adapter) {
std::vector<std::string> entries = {
"entry 1",
"entry 2",
"entry 3",
};
int selected = 0;
Adapter a(entries);
auto menu = Menu(&a, &selected);
}
TEST(ConstStringListRef, UniquePtrAdapter) {
std::vector<std::string> entries = {
"entry 1",
"entry 2",
"entry 3",
};
int selected = 0;
auto a = std::make_unique<Adapter>(entries);
auto menu = Menu(std::move(a), &selected);
}
} // namespace ftxui