FTXUI  0.10.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_(label),
22 value_(value),
23 min_(min),
24 max_(max),
25 increment_(increment) {}
26
27 Element Render() {
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 if (event == Event::ArrowLeft || event == Event::Character('h')) {
47 *value_ -= increment_;
48 *value_ = std::max(*value_, min_);
49 return true;
50 }
51
52 if (event == Event::ArrowRight || event == Event::Character('l')) {
53 *value_ += increment_;
54 *value_ = std::min(*value_, max_);
55 return true;
56 }
57
58 return ComponentBase::OnEvent(event);
59 }
60
61 bool OnMouseEvent(Event event) {
62 if (captured_mouse_ && event.mouse().motion == Mouse::Released) {
63 captured_mouse_ = nullptr;
64 return true;
65 }
66
67 if (box_.Contain(event.mouse().x, event.mouse().y) && CaptureMouse(event)) {
68 TakeFocus();
69 }
70
71 if (event.mouse().button == Mouse::Left &&
72 event.mouse().motion == Mouse::Pressed &&
73 gauge_box_.Contain(event.mouse().x, event.mouse().y) &&
74 !captured_mouse_) {
75 captured_mouse_ = CaptureMouse(event);
76 }
77
78 if (captured_mouse_) {
79 *value_ = min_ + (event.mouse().x - gauge_box_.x_min) * (max_ - min_) /
80 (gauge_box_.x_max - gauge_box_.x_min);
81 *value_ = std::max(min_, std::min(max_, *value_));
82 return true;
83 }
84 return false;
85 }
86
87 bool Focusable() const final { return true; }
88
89 private:
90 ConstStringRef label_;
91 T* value_;
92 T min_;
93 T max_;
94 T increment_ = 1;
95 Box box_;
96 Box gauge_box_;
97 CapturedMouse captured_mouse_;
98};
99
100/// @brief An horizontal slider.
101/// @param label The name of the slider.
102/// @param value The current value of the slider.
103/// @param min The minimum value.
104/// @param max The maximum value.
105/// @param increment The increment when used by the cursor.
106/// @ingroup component
107///
108/// ### Example
109///
110/// ```cpp
111/// auto screen = ScreenInteractive::TerminalOutput();
112/// int value = 50;
113/// auto slider = Slider("Value:", &value, 0, 100, 1);
114/// screen.Loop(slider);
115/// ```
116///
117/// ### Output
118///
119/// ```bash
120/// Value:[██████████████████████████ ]
121/// ```
122template <class T>
123Component Slider(ConstStringRef label, T* value, T min, T max, T increment) {
124 return Make<SliderBase<T>>(std::move(label), value, min, max, increment);
125}
126
128 int* value,
129 int min,
130 int max,
131 int increment);
132
134 float* value,
135 float min,
136 float max,
137 float increment);
138
140 long* value,
141 long min,
142 long max,
143 long increment);
144
145} // namespace ftxui
146
147// Copyright 2020 Arthur Sonzogni. All rights reserved.
148// Use of this source code is governed by the MIT license that can be found in
149// 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.
Definition component.cpp:95
An adapter. Own or reference a constant string. For convenience, this class convert multiple immutabl...
Definition ref.hpp:76
Element xflex(Element)
Expand/Minimize if possible/needed on the X axis.
Definition flex.cpp:125
std::unique_ptr< CapturedMouseInterface > CapturedMouse
std::shared_ptr< T > Make(Args &&... args)
Definition component.hpp:25
std::shared_ptr< Node > Element
Definition elements.hpp:15
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:106
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:123
Element vcenter(Element)
Center an element vertically.
Element gauge(float ratio)
Draw a high definition progress bar.
Definition gauge.cpp:75
std::shared_ptr< ComponentBase > Component
Decorator color(Color)
Decorate using a foreground color.
Definition color.cpp:86
int x_max
Definition box.hpp:8
bool Contain(int x, int y)
Definition box.cpp:20
int x_min
Definition box.hpp:7
static const Event ArrowLeft
Definition event.hpp:35
static const Event ArrowRight
Definition event.hpp:36