FTXUI/src/ftxui/component/dropdown.cpp

96 lines
2.9 KiB
C++
Raw Normal View History

#include <cstddef> // for size_t
2022-03-31 08:17:43 +08:00
#include <functional> // for function
#include <memory> // for __shared_ptr_access, allocator, shared_ptr
2022-03-31 08:17:43 +08:00
#include <string> // for string
#include "ftxui/component/component.hpp" // for Maybe, Checkbox, Make, Radiobox, Vertical, Dropdown
#include "ftxui/component/component_base.hpp" // for Component, ComponentBase
2022-03-31 08:17:43 +08:00
#include "ftxui/component/component_options.hpp" // for CheckboxOption, EntryState
#include "ftxui/dom/elements.hpp" // for operator|, Element, border, filler, operator|=, separator, size, text, vbox, frame, vscroll_indicator, hbox, HEIGHT, LESS_THAN, bold, inverted
#include "ftxui/screen/util.hpp" // for clamp
#include "ftxui/util/ref.hpp" // for ConstStringListRef
namespace ftxui {
Component Dropdown(ConstStringListRef entries, int* selected) {
class Impl : public ComponentBase {
public:
Impl(ConstStringListRef entries, int* selected)
2022-03-31 08:17:43 +08:00
: entries_(entries), selected_(selected) {
CheckboxOption option;
2022-03-31 08:17:43 +08:00
option.transform = [](const EntryState& s) {
auto prefix = text(s.state ? "" : ""); // NOLINT
2022-03-14 01:51:46 +08:00
auto t = text(s.label);
2022-03-31 08:17:43 +08:00
if (s.active) {
2022-03-14 01:51:46 +08:00
t |= bold;
2022-03-31 08:17:43 +08:00
}
if (s.focused) {
2022-03-14 01:51:46 +08:00
t |= inverted;
2022-03-31 08:17:43 +08:00
}
2022-03-14 01:51:46 +08:00
return hbox({prefix, t});
};
checkbox_ = Checkbox(&title_, &show_, option);
radiobox_ = Radiobox(entries_, selected_);
Add(Container::Vertical({
checkbox_,
Maybe(radiobox_, &show_),
}));
}
Element Render() override {
*selected_ = util::clamp(*selected_, 0, int(entries_.size()) - 1);
title_ = entries_[static_cast<size_t>(*selected_)];
if (show_) {
2022-03-31 08:17:43 +08:00
const int max_height = 12;
return vbox({
checkbox_->Render(),
separator(),
radiobox_->Render() | vscroll_indicator | frame |
2022-03-31 08:17:43 +08:00
size(HEIGHT, LESS_THAN, max_height),
}) |
border;
}
return vbox({
checkbox_->Render() | border,
filler(),
});
}
// Switch focus in between the checkbox and the radiobox when selecting it.
bool OnEvent(ftxui::Event event) override {
const bool show_old = show_;
const int selected_old = *selected_;
const bool handled = ComponentBase::OnEvent(event);
if (!show_old && show_) {
radiobox_->TakeFocus();
}
if (selected_old != *selected_) {
checkbox_->TakeFocus();
show_ = false;
}
return handled;
}
private:
ConstStringListRef entries_;
bool show_ = false;
int* selected_;
std::string title_;
Component checkbox_;
Component radiobox_;
};
2022-03-31 08:17:43 +08:00
return Make<Impl>(entries, selected);
}
} // namespace ftxui
// Copyright 2021 Arthur Sonzogni. All rights reserved.
// Use of this source code is governed by the MIT license that can be found in
// the LICENSE file.