FTXUI  5.0.0
C++ functional terminal UI.
checkbox.cpp
Go to the documentation of this file.
1 // Copyright 2020 Arthur Sonzogni. All rights reserved.
2 // Use of this source code is governed by the MIT license that can be found in
3 // the LICENSE file.
4 #include <functional> // for function
5 #include <utility> // for move
6 
7 #include "ftxui/component/captured_mouse.hpp" // for CapturedMouse
8 #include "ftxui/component/component.hpp" // for Make, Checkbox
9 #include "ftxui/component/component_base.hpp" // for Component, ComponentBase
10 #include "ftxui/component/component_options.hpp" // for CheckboxOption, EntryState
11 #include "ftxui/component/event.hpp" // for Event, Event::Return
12 #include "ftxui/component/mouse.hpp" // for Mouse, Mouse::Left, Mouse::Pressed
13 #include "ftxui/dom/elements.hpp" // for operator|, Element, reflect, focus, nothing, select
14 #include "ftxui/screen/box.hpp" // for Box
15 #include "ftxui/util/ref.hpp" // for Ref, ConstStringRef
16 
17 namespace ftxui {
18 
19 namespace {
20 class CheckboxBase : public ComponentBase, public CheckboxOption {
21  public:
22  explicit CheckboxBase(CheckboxOption option)
23  : CheckboxOption(std::move(option)) {}
24 
25  private:
26  // Component implementation.
27  Element Render() override {
28  const bool is_focused = Focused();
29  const bool is_active = Active();
30  auto focus_management = is_focused ? focus : is_active ? select : nothing;
31  auto entry_state = EntryState{
32  *label,
33  *checked,
34  is_active,
35  is_focused || hovered_,
36  };
37  auto element = (transform ? transform : CheckboxOption::Simple().transform)(
38  entry_state);
39  return element | focus_management | reflect(box_);
40  }
41 
42  bool OnEvent(Event event) override {
43  if (!CaptureMouse(event)) {
44  return false;
45  }
46 
47  if (event.is_mouse()) {
48  return OnMouseEvent(event);
49  }
50 
51  hovered_ = false;
52  if (event == Event::Character(' ') || event == Event::Return) {
53  *checked = !*checked;
54  on_change();
55  TakeFocus();
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 
68  if (!hovered_) {
69  return false;
70  }
71 
72  if (event.mouse().button == Mouse::Left &&
73  event.mouse().motion == Mouse::Pressed) {
74  *checked = !*checked;
75  on_change();
76  TakeFocus();
77  return true;
78  }
79 
80  return false;
81  }
82 
83  bool Focusable() const final { return true; }
84 
85  bool hovered_ = false;
86  Box box_;
87 };
88 } // namespace
89 
90 /// @brief Draw checkable element.
91 /// @param option Additional optional parameters.
92 /// @ingroup component
93 /// @see CheckboxBase
94 ///
95 /// ### Example
96 ///
97 /// ```cpp
98 /// auto screen = ScreenInteractive::FitComponent();
99 /// CheckboxOption option;
100 /// option.label = "Make a sandwidth";
101 /// option.checked = false;
102 /// Component checkbox = Checkbox(option);
103 /// screen.Loop(checkbox)
104 /// ```
105 ///
106 /// ### Output
107 ///
108 /// ```bash
109 /// ☐ Make a sandwitch
110 /// ```
111 // NOLINTNEXTLINE
113  return Make<CheckboxBase>(std::move(option));
114 }
115 
116 /// @brief Draw checkable element.
117 /// @param label The label of the checkbox.
118 /// @param checked Whether the checkbox is checked or not.
119 /// @param option Additional optional parameters.
120 /// @ingroup component
121 /// @see CheckboxBase
122 ///
123 /// ### Example
124 ///
125 /// ```cpp
126 /// auto screen = ScreenInteractive::FitComponent();
127 /// std::string label = "Make a sandwidth";
128 /// bool checked = false;
129 /// Component checkbox = Checkbox(&label, &checked);
130 /// screen.Loop(checkbox)
131 /// ```
132 ///
133 /// ### Output
134 ///
135 /// ```bash
136 /// ☐ Make a sandwitch
137 /// ```
138 // NOLINTNEXTLINE
139 Component Checkbox(ConstStringRef label, bool* checked, CheckboxOption option) {
140  option.label = label;
141  option.checked = checked;
142  return Make<CheckboxBase>(std::move(option));
143 }
144 
145 } // namespace ftxui
An adapter. Own or reference a constant string. For convenience, this class convert multiple immutabl...
Definition: ref.hpp:86
Element nothing(Element element)
A decoration doing absolutely nothing.
Definition: util.cpp:30
std::shared_ptr< Node > Element
Definition: elements.hpp:23
std::shared_ptr< ComponentBase > Component
Element select(Element)
Set the child to be the one selected among its siblings.
Definition: frame.cpp:150
Element focus(Element)
Set the child to be the one in focus globally.
Definition: frame.cpp:157
Decorator reflect(Box &box)
Definition: reflect.cpp:44
void Render(Screen &screen, const Element &element)
Display an element on a ftxui::Screen.
Definition: node.cpp:47
Component Checkbox(CheckboxOption options)
Draw checkable element.
Definition: checkbox.cpp:112
Option for the Checkbox component.
static CheckboxOption Simple()
Option for standard Checkbox.
std::function< Element(const EntryState &)> transform
static Event Character(std::string)
An event corresponding to a given typed character.
Definition: event.cpp:16
static const Event Return
Definition: event.hpp:53