FTXUI/include/ftxui/component/component_options.hpp

298 lines
10 KiB
C++
Raw Normal View History

2023-08-19 19:56:36 +08:00
// 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.
#ifndef FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP
#define FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP
2022-03-14 01:51:46 +08:00
#include <chrono> // for milliseconds
2022-05-08 14:44:38 +08:00
#include <ftxui/component/animation.hpp> // for Duration, QuadraticInOut, Function
#include <ftxui/dom/direction.hpp> // for Direction, Direction::Left, Direction::Right, Direction::Down
#include <ftxui/dom/elements.hpp> // for Element, separator
2023-05-02 19:32:37 +08:00
#include <ftxui/util/ref.hpp> // for Ref, ConstRef, StringRef
#include <functional> // for function
#include <string> // for string
#include "ftxui/component/component_base.hpp" // for Component
2022-03-14 01:51:46 +08:00
#include "ftxui/screen/color.hpp" // for Color, Color::GrayDark, Color::White
2021-07-08 04:37:50 +08:00
namespace ftxui {
2022-03-14 01:51:46 +08:00
/// @brief arguments for |ButtonOption::transform|, |CheckboxOption::transform|,
/// |Radiobox::transform|, |MenuEntryOption::transform|,
/// |MenuOption::transform|.
struct EntryState {
std::string label; ///< The label to display.
bool state; ///< The state of the button/checkbox/radiobox
bool active; ///< Whether the entry is the active one.
bool focused; ///< Whether the entry is one focused by the user.
int index; ///< Index of the entry when applicable or -1.
2022-03-14 01:51:46 +08:00
};
2022-03-14 01:51:46 +08:00
struct UnderlineOption {
bool enabled = false;
2021-07-10 18:59:36 +08:00
2022-03-14 01:51:46 +08:00
Color color_active = Color::White;
Color color_inactive = Color::GrayDark;
animation::easing::Function leader_function =
animation::easing::QuadraticInOut;
animation::easing::Function follower_function =
animation::easing::QuadraticInOut;
animation::Duration leader_duration = std::chrono::milliseconds(250);
animation::Duration leader_delay = std::chrono::milliseconds(0);
animation::Duration follower_duration = std::chrono::milliseconds(250);
animation::Duration follower_delay = std::chrono::milliseconds(0);
void SetAnimation(animation::Duration d, animation::easing::Function f);
void SetAnimationDuration(animation::Duration d);
void SetAnimationFunction(animation::easing::Function f);
void SetAnimationFunction(animation::easing::Function f_leader,
animation::easing::Function f_follower);
};
/// @brief Option about a potentially animated color.
/// @ingroup component
struct AnimatedColorOption {
void Set(
Color inactive,
Color active,
animation::Duration duration = std::chrono::milliseconds(250),
animation::easing::Function function = animation::easing::QuadraticInOut);
bool enabled = false;
Color inactive;
Color active;
animation::Duration duration = std::chrono::milliseconds(250);
animation::easing::Function function = animation::easing::QuadraticInOut;
};
struct AnimatedColorsOption {
AnimatedColorOption background;
AnimatedColorOption foreground;
};
/// @brief Option for the MenuEntry component.
/// @ingroup component
struct MenuEntryOption {
ConstStringRef label = "MenuEntry";
2022-03-31 08:17:43 +08:00
std::function<Element(const EntryState& state)> transform;
2022-03-14 01:51:46 +08:00
AnimatedColorsOption animated_colors;
};
2022-03-14 01:51:46 +08:00
/// @brief Option for the Menu component.
/// @ingroup component
struct MenuOption {
// Standard constructors:
static MenuOption Horizontal();
static MenuOption HorizontalAnimated();
static MenuOption Vertical();
static MenuOption VerticalAnimated();
static MenuOption Toggle();
ConstStringListRef entries; ///> The list of entries.
Ref<int> selected = 0; ///> The index of the selected entry.
2022-03-14 01:51:46 +08:00
// Style:
UnderlineOption underline;
MenuEntryOption entries_option;
Direction direction = Direction::Down;
2022-03-14 01:51:46 +08:00
std::function<Element()> elements_prefix;
std::function<Element()> elements_infix;
std::function<Element()> elements_postfix;
// Observers:
2022-08-24 18:00:54 +08:00
std::function<void()> on_change; ///> Called when the selected entry changes.
2022-03-14 01:51:46 +08:00
std::function<void()> on_enter; ///> Called when the user presses enter.
Ref<int> focused_entry = 0;
};
/// @brief Option for the AnimatedButton component.
2021-07-10 20:23:46 +08:00
/// @ingroup component
2021-07-08 04:23:07 +08:00
struct ButtonOption {
2022-03-14 01:51:46 +08:00
// Standard constructors:
static ButtonOption Ascii();
static ButtonOption Simple();
static ButtonOption Border();
static ButtonOption Animated();
static ButtonOption Animated(Color color);
static ButtonOption Animated(Color background, Color foreground);
static ButtonOption Animated(Color background,
Color foreground,
Color background_active,
Color foreground_active);
ConstStringRef label = "Button";
std::function<void()> on_click = [] {};
2022-03-14 01:51:46 +08:00
// Style:
2022-03-31 08:17:43 +08:00
std::function<Element(const EntryState&)> transform;
2022-03-14 01:51:46 +08:00
AnimatedColorsOption animated_colors;
2021-07-08 04:23:07 +08:00
};
2021-07-10 17:50:17 +08:00
/// @brief Option for the Checkbox component.
2021-07-10 20:23:46 +08:00
/// @ingroup component
2021-07-08 04:37:50 +08:00
struct CheckboxOption {
2022-03-14 01:51:46 +08:00
// Standard constructors:
static CheckboxOption Simple();
ConstStringRef label = "Checkbox";
Ref<bool> checked = false;
2022-03-14 01:51:46 +08:00
// Style:
2022-03-31 08:17:43 +08:00
std::function<Element(const EntryState&)> transform;
2021-07-08 04:37:50 +08:00
2022-03-14 01:51:46 +08:00
// Observer:
2021-07-08 04:37:50 +08:00
/// Called when the user change the state.
2022-03-14 01:51:46 +08:00
std::function<void()> on_change = [] {};
2021-07-08 04:37:50 +08:00
};
2023-05-02 19:32:37 +08:00
/// @brief Used to define style for the Input component.
struct InputState {
Element element;
bool hovered; ///< Whether the input is hovered by the mouse.
bool focused; ///< Whether the input is focused by the user.
bool is_placeholder; ///< Whether the input is empty and displaying the
///< placeholder.
2023-05-02 19:32:37 +08:00
};
2021-07-10 17:50:17 +08:00
/// @brief Option for the Input component.
2021-07-10 20:23:46 +08:00
/// @ingroup component
2021-07-08 06:01:42 +08:00
struct InputOption {
2023-05-02 19:32:37 +08:00
// A set of predefined styles:
/// @brief Create the default input style:
static InputOption Default();
/// @brief A white on black style with high margins:
static InputOption Spacious();
/// The content of the input.
StringRef content = "";
2023-05-02 19:32:37 +08:00
/// The content of the input when it's empty.
StringRef placeholder = "";
// Style:
std::function<Element(InputState)> transform;
Ref<bool> password = false; ///< Obscure the input content using '*'.
Ref<bool> multiline = true; ///< Whether the input can be multiline.
Ref<bool> insert = true; ///< Insert or overtype character mode.
2023-05-02 19:32:37 +08:00
2021-07-10 17:50:17 +08:00
/// Called when the content changes.
2021-07-08 06:01:42 +08:00
std::function<void()> on_change = [] {};
2021-07-10 17:50:17 +08:00
/// Called when the user presses enter.
2021-07-08 06:01:42 +08:00
std::function<void()> on_enter = [] {};
2021-07-10 18:29:39 +08:00
2023-05-02 19:32:37 +08:00
// The char position of the cursor:
Ref<int> cursor_position = 0;
2021-07-08 06:01:42 +08:00
};
2021-07-10 17:50:17 +08:00
/// @brief Option for the Radiobox component.
2021-07-10 20:23:46 +08:00
/// @ingroup component
2021-07-10 16:50:25 +08:00
struct RadioboxOption {
2022-03-14 01:51:46 +08:00
// Standard constructors:
static RadioboxOption Simple();
2021-07-10 16:50:25 +08:00
// Content:
ConstStringListRef entries;
Ref<int> selected = 0;
2022-03-14 01:51:46 +08:00
// Style:
2022-03-31 08:17:43 +08:00
std::function<Element(const EntryState&)> transform;
2021-07-10 17:03:01 +08:00
2022-03-14 01:51:46 +08:00
// Observers:
2021-07-10 17:50:17 +08:00
/// Called when the selected entry changes.
std::function<void()> on_change = [] {};
2021-07-10 19:15:28 +08:00
Ref<int> focused_entry = 0;
2021-07-10 17:03:01 +08:00
};
struct ResizableSplitOption {
Component main;
Component back;
Ref<Direction> direction = Direction::Left;
Ref<int> main_size =
(direction() == Direction::Left || direction() == Direction::Right) ? 20
: 10;
std::function<Element()> separator_func = [] { return ::ftxui::separator(); };
};
// @brief Option for the `Slider` component.
// @ingroup component
template <typename T>
struct SliderOption {
Ref<T> value;
ConstRef<T> min = T(0);
ConstRef<T> max = T(100);
ConstRef<T> increment = (max() - min()) / 20;
Direction direction = Direction::Right;
Color color_active = Color::White;
Color color_inactive = Color::GrayDark;
};
// @brief Option for the `SliderWithCallback` component.
// @ingroup component
template <typename T>
struct SliderWithCallbackOption {
std::function<void(T)> callback;
Ref<T> value;
ConstRef<T> min = T(0);
ConstRef<T> max = T(100);
ConstRef<T> increment = (max() - min()) / 20;
Direction direction = Direction::Right;
Color color_active = Color::White;
Color color_inactive = Color::GrayDark;
};
// Parameter pack used by `WindowOptions::render`.
struct WindowRenderState {
Element inner; ///< The element wrapped inside this window.
const std::string& title; ///< The title of the window.
bool active = false; ///< Whether the window is the active one.
bool drag = false; ///< Whether the window is being dragged.
bool resize = false; ///< Whether the window is being resized.
bool hover_left = false; ///< Whether the resizeable left side is hovered.
bool hover_right = false; ///< Whether the resizeable right side is hovered.
bool hover_top = false; ///< Whether the resizeable top side is hovered.
bool hover_down = false; ///< Whether the resizeable down side is hovered.
};
// @brief Option for the `Window` component.
// @ingroup component
struct WindowOptions {
Component inner; ///< The component wrapped by this window.
ConstStringRef title = ""; ///< The title displayed by this window.
Ref<int> left = 0; ///< The left side position of the window.
Ref<int> top = 0; ///< The top side position of the window.
Ref<int> width = 20; ///< The width of the window.
Ref<int> height = 10; ///< The height of the window.
Ref<bool> resize_left = true; ///< Can the left side be resized?
Ref<bool> resize_right = true; ///< Can the right side be resized?
Ref<bool> resize_top = true; ///< Can the top side be resized?
Ref<bool> resize_down = true; ///< Can the down side be resized?
/// An optional function to customize how the window looks like:
std::function<Element(const WindowRenderState&)> render;
};
/// @brief Option for the Dropdown component.
/// @ingroup component
/// A dropdown menu is a checkbox opening/closing a radiobox.
struct DropdownOption {
/// Whether the dropdown is open or closed:
Ref<bool> open = false;
// The options for the checkbox:
CheckboxOption checkbox;
// The options for the radiobox:
RadioboxOption radiobox;
// The transformation function:
std::function<Element(bool open, Element checkbox, Element radiobox)>
transform;
};
2021-07-10 20:23:46 +08:00
} // namespace ftxui
#endif /* end of include guard: FTXUI_COMPONENT_COMPONENT_OPTIONS_HPP */