mirror of
https://github.com/ArthurSonzogni/FTXUI.git
synced 2024-11-25 12:11:33 +08:00
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:
parent
af49b57e60
commit
ecacb22d37
@ -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.
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
63
src/ftxui/util/ref_test.cpp
Normal file
63
src/ftxui/util/ref_test.cpp
Normal 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
|
Loading…
Reference in New Issue
Block a user