FTXUI  0.8.1
C++ functional terminal UI.
checkbox.cpp
Go to the documentation of this file.
1 #include <functional> // for function
2 #include <memory> // for shared_ptr
3 #include <utility> // for move
4 
5 #include "ftxui/component/captured_mouse.hpp" // for CapturedMouse
6 #include "ftxui/component/component.hpp" // for Make, Component, Checkbox
7 #include "ftxui/component/component_base.hpp" // for ComponentBase
8 #include "ftxui/component/component_options.hpp" // for CheckboxOption
9 #include "ftxui/component/event.hpp" // for Event, Event::Return
10 #include "ftxui/component/mouse.hpp" // for Mouse, Mouse::Left, Mouse::Pressed
11 #include "ftxui/dom/elements.hpp" // for operator|, text, Element, hbox, reflect, focus, nothing, select
12 #include "ftxui/screen/box.hpp" // for Box
13 #include "ftxui/util/ref.hpp" // for Ref, ConstStringRef
14 
15 namespace ftxui {
16 
17 namespace {
18 class CheckboxBase : public ComponentBase {
19  public:
20  CheckboxBase(ConstStringRef label, bool* state, Ref<CheckboxOption> option)
21  : label_(label), state_(state), option_(std::move(option)) {
22 #if defined(FTXUI_MICROSOFT_TERMINAL_FALLBACK)
23  // Microsoft terminal do not use fonts able to render properly the default
24  // radiobox glyph.
25  if (option_->style_checked == "▣ ")
26  option_->style_checked = "[X]";
27  if (option_->style_unchecked == "☐ ")
28  option_->style_unchecked = "[ ]";
29 #endif
30  }
31 
32  private:
33  // Component implementation.
34  Element Render() override {
35  bool is_focused = Focused();
36  bool is_active = Active();
37  auto style = is_focused ? (hovered_ ? option_->style_selected_focused
38  : option_->style_selected)
39  : (hovered_ ? option_->style_focused
40  : option_->style_normal);
41  auto focus_management = is_focused ? focus : is_active ? select : nothing;
42  return hbox(text(*state_ ? option_->style_checked
43  : option_->style_unchecked),
44  text(*label_) | style | focus_management) |
45  reflect(box_);
46  }
47 
48  bool OnEvent(Event event) override {
49  if (event.is_mouse())
50  return OnMouseEvent(event);
51 
52  hovered_ = false;
53  if (event == Event::Character(' ') || event == Event::Return) {
54  *state_ = !*state_;
55  option_->on_change();
56  return true;
57  }
58  return false;
59  }
60 
61  bool OnMouseEvent(Event event) {
62  hovered_ = box_.Contain(event.mouse().x, event.mouse().y);
63 
64  if (!CaptureMouse(event))
65  return false;
66 
67  if (!hovered_)
68  return false;
69 
70  if (event.mouse().button == Mouse::Left &&
71  event.mouse().motion == Mouse::Pressed) {
72  *state_ = !*state_;
73  option_->on_change();
74  return true;
75  }
76 
77  return false;
78  }
79 
80  bool Focusable() const final { return true; }
81 
82  ConstStringRef label_;
83  bool* const state_;
84  bool hovered_ = false;
85  Ref<CheckboxOption> option_;
86  Box box_;
87 };
88 } // namespace
89 
90 /// @brief Draw checkable element.
91 /// @param label The label of the checkbox.
92 /// @param checked Whether the checkbox is checked or not.
93 /// @param option Additional optional parameters.
94 /// @ingroup component
95 /// @see CheckboxBase
96 ///
97 /// ### Example
98 ///
99 /// ```cpp
100 /// auto screen = ScreenInteractive::FitComponent();
101 /// std::string label = "Make a sandwidth";
102 /// bool checked = false;
103 /// Component checkbox = Checkbox(&label, &checked);
104 /// screen.Loop(checkbox)
105 /// ```
106 ///
107 /// ### Output
108 ///
109 /// ```bash
110 /// ☐ Make a sandwitch
111 /// ```
113  bool* checked,
114  Ref<CheckboxOption> option) {
115  return Make<CheckboxBase>(label, checked, std::move(option));
116 }
117 
118 } // namespace ftxui
119 
120 // Copyright 2020 Arthur Sonzogni. All rights reserved.
121 // Use of this source code is governed by the MIT license that can be found in
122 // the LICENSE file.
ftxui::focus
Element focus(Element)
Definition: frame.cpp:79
ftxui
Definition: captured_mouse.hpp:6
ftxui::Component
std::shared_ptr< ComponentBase > Component
Definition: component_base.hpp:17
ftxui::nothing
Element nothing(Element element)
A decoration doing absolutely nothing.
Definition: util.cpp:25
event.hpp
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
ftxui::select
Element select(Element)
Definition: frame.cpp:38
elements.hpp
captured_mouse.hpp
component.hpp
ftxui::Event::Return
static const Event Return
Definition: event.hpp:43
ftxui::Checkbox
Component Checkbox(ConstStringRef label, bool *checked, Ref< CheckboxOption > option={})
Draw checkable element.
Definition: checkbox.cpp:112
component_base.hpp
ftxui::Element
std::shared_ptr< Node > Element
Definition: elements.hpp:15
ftxui::Ref
An adapter. Own or reference an mutable object.
Definition: ref.hpp:27
ftxui::Mouse::Pressed
@ Pressed
Definition: mouse.hpp:20
mouse.hpp
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
component_options.hpp
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