Add options for checkbox.

This commit is contained in:
ArthurSonzogni 2021-07-07 22:37:50 +02:00 committed by Arthur Sonzogni
parent 359100ca73
commit 2b7daf061f
4 changed files with 36 additions and 24 deletions

View File

@ -22,18 +22,11 @@ class CheckboxBase : public ComponentBase {
static CheckboxBase* From(Component component);
// Constructor.
CheckboxBase(ConstStringRef label, bool* state);
CheckboxBase(ConstStringRef label,
bool* state,
ConstRef<CheckboxOption> option = {});
~CheckboxBase() override = default;
std::wstring checked = L""; /// Prefix for a "checked" state.
std::wstring unchecked = L""; /// Prefix for a "unchecked" state.
Decorator focused_style = inverted; /// Decorator used when focused.
Decorator unfocused_style = nothing; /// Decorator used when unfocused.
/// Called when the user change the state of the CheckboxBase.
std::function<void()> on_change = []() {};
// Component implementation.
Element Render() override;
bool OnEvent(Event) override;
@ -43,8 +36,8 @@ class CheckboxBase : public ComponentBase {
ConstStringRef label_;
bool* const state_;
int cursor_position = 0;
Box box_;
ConstRef<CheckboxOption> option_;
};
} // namespace ftxui

View File

@ -27,7 +27,9 @@ std::shared_ptr<T> Make(Args&&... args) {
Component Button(ConstStringRef label,
std::function<void()> on_click,
ConstRef<ButtonOption> = {});
Component Checkbox(ConstStringRef label, bool* checked);
Component Checkbox(ConstStringRef label,
bool* checked,
ConstRef<CheckboxOption> option = {});
Component Input(StringRef content, ConstStringRef placeholder);
Component Menu(const std::vector<std::wstring>* entries,
int* selected_,

View File

@ -1,6 +1,8 @@
#ifndef FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP
#define FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP
#include <ftxui/dom/elements.hpp>
namespace ftxui {
struct MenuOption {
@ -18,6 +20,17 @@ struct ButtonOption {
bool border = true;
};
struct CheckboxOption {
std::wstring checked = L""; /// Prefix for a "checked" state.
std::wstring unchecked = L""; /// Prefix for a "unchecked" state.
Decorator focused_style = inverted; /// Decorator used when focused.
Decorator unfocused_style = nothing; /// Decorator used when unfocused.
/// Called when the user change the state.
std::function<void()> on_change = []() {};
};
}; // namespace ftxui
#endif /* end of include guard: FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP */

View File

@ -30,8 +30,10 @@ namespace ftxui {
/// ```bash
/// ☐ Make a sandwitch
/// ```
Component Checkbox(ConstStringRef label, bool* checked) {
return Make<CheckboxBase>(label, checked);
Component Checkbox(ConstStringRef label,
bool* checked,
ConstRef<CheckboxOption> option) {
return Make<CheckboxBase>(label, checked, std::move(option));
}
// static
@ -39,23 +41,25 @@ CheckboxBase* CheckboxBase::From(Component component) {
return static_cast<CheckboxBase*>(component.get());
}
CheckboxBase::CheckboxBase(ConstStringRef label, bool* state)
: label_(label), state_(state) {
CheckboxBase::CheckboxBase(ConstStringRef label,
bool* state,
ConstRef<CheckboxOption> option)
: label_(label), state_(state), option_(std::move(option)) {
#if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK)
// Microsoft terminal do not use fonts able to render properly the default
// radiobox glyph.
if (checked == L"")
checked = L"[X]";
if (unchecked == L"")
unchecked = L"[ ]";
if (option->checked == L"")
option->checked = L"[X]";
if (option->unchecked == L"")
option->unchecked = L"[ ]";
#endif
}
Element CheckboxBase::Render() {
bool is_focused = Focused();
auto style = is_focused ? focused_style : unfocused_style;
auto style = is_focused ? option_->focused_style : option_->unfocused_style;
auto focus_management = is_focused ? focus : *state_ ? select : nothing;
return hbox(text(*state_ ? checked : unchecked),
return hbox(text(*state_ ? option_->checked : option_->unchecked),
text(*label_) | style | focus_management) |
reflect(box_);
}
@ -66,7 +70,7 @@ bool CheckboxBase::OnEvent(Event event) {
if (event == Event::Character(' ') || event == Event::Return) {
*state_ = !*state_;
on_change();
option_->on_change();
return true;
}
return false;
@ -83,7 +87,7 @@ bool CheckboxBase::OnMouseEvent(Event event) {
if (event.mouse().button == Mouse::Left &&
event.mouse().motion == Mouse::Pressed) {
*state_ = !*state_;
on_change();
option_->on_change();
return true;
}