FTXUI  0.8.1
C++ functional terminal UI.
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 
15 namespace ftxui {
16 
17 template <class T>
18 class 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 /// ```
122 template <class T>
123 Component 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 
127 template Component Slider(ConstStringRef label,
128  int* value,
129  int min,
130  int max,
131  int increment);
132 
133 template Component Slider(ConstStringRef label,
134  float* value,
135  float min,
136  float max,
137  float increment);
138 
139 template Component Slider(ConstStringRef label,
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.
ftxui::xflex
Element xflex(Element)
Expand/Minimize if possible/needed on the X axis.
Definition: flex.cpp:125
ftxui::Mouse::Released
@ Released
Definition: mouse.hpp:19
screen_interactive.hpp
ftxui
Definition: captured_mouse.hpp:6
ftxui::Component
std::shared_ptr< ComponentBase > Component
Definition: component_base.hpp:17
ftxui::vcenter
Element vcenter(Element)
Center an element vertically.
Definition: composite_decorator.cpp:20
event.hpp
ftxui::color
Decorator color(Color)
Decorate using a foreground color.
Definition: color.cpp:86
ftxui::Event::ArrowLeft
static const Event ArrowLeft
Definition: event.hpp:35
ftxui::Event::Character
static Event Character(std::string)
Definition: event.cpp:10
ftxui::reflect
Decorator reflect(Box &box)
Definition: reflect.cpp:38
box.hpp
ftxui::hbox
Element hbox(Elements)
A container displaying elements horizontally one by one.
Definition: hbox.cpp:75
ref.hpp
elements.hpp
captured_mouse.hpp
component.hpp
ftxui::ComponentBase::Focused
bool Focused() const
Returns if the elements if focused by the user. True when the ComponentBase is focused by the user....
Definition: component.cpp:132
ftxui::underlined
Element underlined(Element)
Make the underlined element to be underlined.
Definition: underlined.cpp:28
ftxui::gauge
Element gauge(float ratio)
Draw a high definition progress bar.
Definition: gauge.cpp:75
ftxui::Slider
Component Slider(ConstStringRef label, T *value, T min, T max, T increment)
An horizontal slider.
Definition: slider.cpp:123
ftxui::ComponentBase::CaptureMouse
CapturedMouse CaptureMouse(const Event &event)
Take the CapturedMouse if available. There is only one component of them. It represents a component t...
Definition: component.cpp:166
component_base.hpp
ftxui::Element
std::shared_ptr< Node > Element
Definition: elements.hpp:15
ftxui::Terminal::Color
Color
Definition: terminal.hpp:13
ftxui::Mouse::Pressed
@ Pressed
Definition: mouse.hpp:20
ftxui::Color::GrayLight
@ GrayLight
Definition: color.hpp:47
color.hpp
ftxui::CapturedMouse
std::unique_ptr< CapturedMouseInterface > CapturedMouse
Definition: captured_mouse.hpp:11
mouse.hpp
ftxui::ComponentBase::TakeFocus
void TakeFocus()
Configure all the ancestors to give focus to this component.
Definition: component.cpp:154
ftxui::dim
Element dim(Element)
Use a light font, for elements with less emphasis.
Definition: dim.cpp:28
ftxui::Render
void Render(Screen &screen, const Element &node)
Display an element on a ftxui::Screen.
Definition: node.cpp:34
ftxui::ConstStringRef
An adapter. Own or reference a constant string. For convenience, this class convert multiple immutabl...
Definition: ref.hpp:76
ftxui::Event::ArrowRight
static const Event ArrowRight
Definition: event.hpp:36
ftxui::ComponentBase::OnEvent
virtual bool OnEvent(Event)
Called in response to an event.
Definition: component.cpp:95
ftxui::Mouse::Left
@ Left
Definition: mouse.hpp:10
ftxui::text
Element text(std::wstring text)
Display a piece of unicode text.
Definition: text.cpp:106