Feature: Dropdown options with callback

This commit is contained in:
James Parker 2024-03-14 11:29:34 +00:00
parent ce5ac6b12f
commit dda2896700
4 changed files with 43 additions and 12 deletions

View File

@ -30,12 +30,12 @@ int main() {
auto layout = Container::Vertical({ auto layout = Container::Vertical({
Container::Horizontal({ Container::Horizontal({
Dropdown(&entries, &selected_1), Dropdown(&entries, &selected_1, { .on_change = [&] { selected_3 = selected_1; } } ), // Keep in sync with selected_3.
Dropdown(&entries, &selected_2), Dropdown(&entries, &selected_2),
}), }),
Container::Horizontal({ Container::Horizontal({
Dropdown(&entries, &selected_3), Dropdown(&entries, &selected_3, { .border = false }),
Dropdown(&entries, &selected_4), Dropdown(&entries, &selected_4, { .border = false }),
}), }),
}); });

View File

@ -74,7 +74,7 @@ Component Radiobox(ConstStringListRef entries,
int* selected_, int* selected_,
RadioboxOption options = {}); RadioboxOption options = {});
Component Dropdown(ConstStringListRef entries, int* selected); Component Dropdown(ConstStringListRef entries, int* selected, DropdownOption options = {});
Component Toggle(ConstStringListRef entries, int* selected); Component Toggle(ConstStringListRef entries, int* selected);
// General slider constructor: // General slider constructor:

View File

@ -148,6 +148,17 @@ struct CheckboxOption {
std::function<void()> on_change = [] {}; std::function<void()> on_change = [] {};
}; };
/// @brief Option for the Dropdown component.
/// @ingroup component
struct DropdownOption {
bool border = true;
// Observer:
/// Called when the user change the state.
std::function<void()> on_change = [] {};
};
/// @brief Used to define style for the Input component. /// @brief Used to define style for the Input component.
struct InputState { struct InputState {
Element element; Element element;

View File

@ -19,10 +19,10 @@ namespace ftxui {
/// @ingroup component /// @ingroup component
/// @param entries The list of entries to display. /// @param entries The list of entries to display.
/// @param selected The index of the selected entry. /// @param selected The index of the selected entry.
Component Dropdown(ConstStringListRef entries, int* selected) { Component Dropdown(ConstStringListRef entries, int* selected, DropdownOption option) {
class Impl : public ComponentBase { class Impl : public ComponentBase {
public: public:
Impl(ConstStringListRef entries, int* selected) Impl(ConstStringListRef entries, int* selected, DropdownOption dropDownOption)
: entries_(entries), selected_(selected) { : entries_(entries), selected_(selected) {
CheckboxOption option; CheckboxOption option;
option.transform = [](const EntryState& s) { option.transform = [](const EntryState& s) {
@ -37,12 +37,18 @@ Component Dropdown(ConstStringListRef entries, int* selected) {
return hbox({prefix, t}); return hbox({prefix, t});
}; };
checkbox_ = Checkbox(&title_, &show_, option); checkbox_ = Checkbox(&title_, &show_, option);
radiobox_ = Radiobox(entries_, selected_);
RadioboxOption radioboxOption;
radioboxOption.on_change = dropDownOption.on_change;
radiobox_ = Radiobox(entries_, selected_, radioboxOption);
Add(Container::Vertical({ Add(Container::Vertical({
checkbox_, checkbox_,
Maybe(radiobox_, &show_), Maybe(radiobox_, &show_),
})); }));
border_ = dropDownOption.border;
} }
Element Render() override { Element Render() override {
@ -50,17 +56,30 @@ Component Dropdown(ConstStringListRef entries, int* selected) {
title_ = entries_[static_cast<size_t>(*selected_)]; title_ = entries_[static_cast<size_t>(*selected_)];
if (show_) { if (show_) {
const int max_height = 12; const int max_height = 12;
return vbox({ auto element = vbox({
checkbox_->Render(), checkbox_->Render(),
separator(), separator(),
radiobox_->Render() | vscroll_indicator | frame | radiobox_->Render() | vscroll_indicator | frame |
size(HEIGHT, LESS_THAN, max_height), size(HEIGHT, LESS_THAN, max_height),
}) | });
border;
if (border_)
{
element |= border;
}
return element;
}
auto element = checkbox_->Render();
if (border_)
{
element |= border;
} }
return vbox({ return vbox({
checkbox_->Render() | border, element,
filler(), filler(),
}); });
} }
@ -86,13 +105,14 @@ Component Dropdown(ConstStringListRef entries, int* selected) {
private: private:
ConstStringListRef entries_; ConstStringListRef entries_;
bool show_ = false; bool show_ = false;
bool border_ = true;
int* selected_; int* selected_;
std::string title_; std::string title_;
Component checkbox_; Component checkbox_;
Component radiobox_; Component radiobox_;
}; };
return Make<Impl>(entries, selected); return Make<Impl>(entries, selected, option);
} }
} // namespace ftxui } // namespace ftxui