FTXUI  3.0.0
C++ functional terminal UI.
Loading...
Searching...
No Matches
slider.cpp
Go to the documentation of this file.
1#include <string> // for allocator
2#include <utility> // for move
3
4#include "ftxui/component/captured_mouse.hpp" // for CapturedMouse
5#include "ftxui/component/component.hpp" // for Make, Slider
6#include "ftxui/component/component_base.hpp" // for ComponentBase
7#include "ftxui/component/event.hpp" // for Event, Event::ArrowLeft, Event::ArrowRight
8#include "ftxui/component/mouse.hpp" // for Mouse, Mouse::Left, Mouse::Pressed, Mouse::Released
9#include "ftxui/component/screen_interactive.hpp" // for Component
10#include "ftxui/dom/elements.hpp" // for operator|, text, Element, reflect, xflex, gauge, hbox, underlined, color, dim, vcenter
11#include "ftxui/screen/box.hpp" // for Box
12#include "ftxui/screen/color.hpp" // for Color, Color::GrayDark, Color::GrayLight
13#include "ftxui/util/ref.hpp" // for StringRef
14
15namespace ftxui {
16
17template <class T>
18class SliderBase : public ComponentBase {
19 public:
20 SliderBase(ConstStringRef label, T* value, T min, T max, T increment)
21 : label_(std::move(label)),
22 value_(value),
23 min_(min),
24 max_(max),
25 increment_(increment) {}
26
27 Element Render() override {
28 auto gauge_color =
29 Focused() ? color(Color::GrayLight) : color(Color::GrayDark);
30 float percent = float(*value_ - min_) / float(max_ - min_);
31 return hbox({
32 text(*label_) | dim | vcenter,
33 hbox({
34 text("["),
35 gauge(percent) | underlined | xflex | reflect(gauge_box_),
36 text("]"),
37 }) | xflex,
38 }) |
39 gauge_color | xflex | reflect(box_);
40 }
41
42 bool OnEvent(Event event) final {
43 if (event.is_mouse()) {
44 return OnMouseEvent(event);
45 }
46
47 if (event == Event::ArrowLeft || event == Event::Character('h')) {
48 *value_ -= increment_;
49 *value_ = std::max(*value_, min_);
50 return true;
51 }
52
53 if (event == Event::ArrowRight || event == Event::Character('l')) {
54 *value_ += increment_;
55 *value_ = std::min(*value_, max_);
56 return true;
57 }
58
59 return ComponentBase::OnEvent(event);
60 }
61
62 bool OnMouseEvent(Event event) {
63 if (captured_mouse_ && event.mouse().motion == Mouse::Released) {
64 captured_mouse_ = nullptr;
65 return true;
66 }
67
68 if (box_.Contain(event.mouse().x, event.mouse().y) && CaptureMouse(event)) {
69 TakeFocus();
70 }
71
72 if (event.mouse().button == Mouse::Left &&
73 event.mouse().motion == Mouse::Pressed &&
74 gauge_box_.Contain(event.mouse().x, event.mouse().y) &&
75 !captured_mouse_) {
76 captured_mouse_ = CaptureMouse(event);
77 }
78
79 if (captured_mouse_) {
80 *value_ = min_ + (event.mouse().x - gauge_box_.x_min) * (max_ - min_) /
81 (gauge_box_.x_max - gauge_box_.x_min);
82 *value_ = std::max(min_, std::min(max_, *value_));
83 return true;
84 }
85 return false;
86 }
87
88 bool Focusable() const final { return true; }
89
90 private:
91 ConstStringRef label_;
92 T* value_;
93 T min_;
94 T max_;
95 T increment_ = 1;
96 Box box_;
97 Box gauge_box_;
98 CapturedMouse captured_mouse_;
99};
100
101/// @brief An horizontal slider.
102/// @param label The name of the slider.
103/// @param value The current value of the slider.
104/// @param min The minimum value.
105/// @param max The maximum value.
106/// @param increment The increment when used by the cursor.
107/// @ingroup component
108///
109/// ### Example
110///
111/// ```cpp
112/// auto screen = ScreenInteractive::TerminalOutput();
113/// int value = 50;
114/// auto slider = Slider("Value:", &value, 0, 100, 1);
115/// screen.Loop(slider);
116/// ```
117///
118/// ### Output
119///
120/// ```bash
121/// Value:[██████████████████████████ ]
122/// ```
123template <class T>
124Component Slider(ConstStringRef label, T* value, T min, T max, T increment) {
125 return Make<SliderBase<T>>(std::move(label), value, min, max, increment);
126}
127
129 int* value,
130 int min,
131 int max,
132 int increment);
133
135 float* value,
136 float min,
137 float max,
138 float increment);
139
141 long* value,
142 long min,
143 long max,
144 long increment);
145
146} // namespace ftxui
147
148// Copyright 2020 Arthur Sonzogni. All rights reserved.
149// Use of this source code is governed by the MIT license that can be found in
150// the LICENSE file.
bool Focused() const
Returns if the elements if focused by the user. True when the ComponentBase is focused by the user....
CapturedMouse CaptureMouse(const Event &event)
Take the CapturedMouse if available. There is only one component of them. It represents a component t...
void TakeFocus()
Configure all the ancestors to give focus to this component.
virtual bool OnEvent(Event)
Called in response to an event.
An adapter. Own or reference a constant string. For convenience, this class convert multiple immutabl...
Definition ref.hpp:60
Element xflex(Element)
Expand/Minimize if possible/needed on the X axis.
Definition flex.cpp:126
std::unique_ptr< CapturedMouseInterface > CapturedMouse
std::shared_ptr< T > Make(Args &&... args)
Definition component.hpp:25
std::shared_ptr< Node > Element
Definition elements.hpp:18
Element hbox(Elements)
A container displaying elements horizontally one by one.
Definition hbox.cpp:76
Element underlined(Element)
Make the underlined element to be underlined.
Element text(std::wstring text)
Display a piece of unicode text.
Definition text.cpp:111
Decorator reflect(Box &box)
Definition reflect.cpp:39
Element dim(Element)
Use a light font, for elements with less emphasis.
Definition dim.cpp:28
Component Slider(ConstStringRef label, T *value, T min, T max, T increment)
An horizontal slider.
Definition slider.cpp:124
Element vcenter(Element)
Center an element vertically.
Element gauge(float progress)
Draw a high definition progress bar.
Definition gauge.cpp:286
std::shared_ptr< ComponentBase > Component
Decorator color(Color)
Decorate using a foreground color.
Definition color.cpp:86
bool Contain(int x, int y) const
Definition box.cpp:20
int x_max
Definition box.hpp:8
int x_min
Definition box.hpp:7
static const Event ArrowLeft
Definition event.hpp:36
static const Event ArrowRight
Definition event.hpp:37