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({
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),
}),
Container::Horizontal({
Dropdown(&entries, &selected_3),
Dropdown(&entries, &selected_4),
Dropdown(&entries, &selected_3, { .border = false }),
Dropdown(&entries, &selected_4, { .border = false }),
}),
});

View File

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

View File

@ -148,6 +148,17 @@ struct CheckboxOption {
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.
struct InputState {
Element element;

View File

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