TermOx
number_view.hpp
1 #ifndef TERMOX_WIDGET_WIDGETS_NUMBER_VIEW_HPP
2 #define TERMOX_WIDGET_WIDGETS_NUMBER_VIEW_HPP
3 #include <iomanip>
4 #include <ios>
5 #include <memory>
6 #include <sstream>
7 #include <type_traits>
8 #include <utility>
9 
10 #include <termox/widget/align.hpp>
11 #include <termox/widget/widgets/label.hpp>
12 
13 namespace ox {
14 
16 template <typename Number_t>
17 class Number_view : public HLabel {
18  static_assert(std::is_integral_v<Number_t> ||
19  std::is_floating_point_v<Number_t>);
20 
21  public:
22  struct Parameters {
23  Number_t initial = 0;
24  int precision = 2;
25  Align alignment = Align::Left;
26  };
27 
28  public:
30  Number_view(Number_t initial = 0,
31  int precision = 2,
32  Align alignment = Align::Left)
33  : HLabel{as_str(initial, precision), alignment},
34  value_{initial},
35  precision_{precision}
36  {}
37 
38  Number_view(Parameters parameters)
39  : Number_view{parameters.initial, parameters.precision,
40  parameters.alignment}
41  {}
42 
43  public:
45  void set_value(Number_t x)
46  {
47  value_ = x;
48  this->HLabel::set_text(as_str(value_, precision_));
49  }
50 
52  [[nodiscard]] auto value() const noexcept -> Number_t { return value_; }
53 
55  void set_precision(int x)
56  {
57  precision_ = x;
58  this->set_value(value_);
59  }
60 
62  [[nodiscard]] auto precision() const noexcept -> int { return precision_; }
63 
64  public:
65  using HLabel::alignment;
67 
68  private:
69  Number_t value_;
70  int precision_;
71 
72  private:
73  [[nodiscard]] static auto as_str(Number_t value, int precision)
74  -> std::string
75  {
76  if constexpr (std::is_floating_point_v<Number_t>) {
77  auto ss = std::stringstream{};
78  ss << std::fixed << std::setprecision(precision) << value;
79  return ss.str();
80  }
81  else
82  return std::to_string(value);
83  }
84 
85  private:
86  using HLabel::set_text;
87 };
88 
90 template <typename Number_t>
91 [[nodiscard]] auto number_view(Number_t initial = 0,
92  int precision = 2,
93  Align alignment = Align::Left)
94  -> std::unique_ptr<Number_view<Number_t>>
95 {
96  return std::make_unique<Number_view<Number_t>>(initial, precision,
97  alignment);
98 }
99 
101 template <typename Number_t>
102 [[nodiscard]] auto number_view(
103  typename Number_view<Number_t>::Parameters parameters)
104  -> std::unique_ptr<Number_view<Number_t>>
105 {
106  return std::make_unique<Number_view<Number_t>>(std::move(parameters));
107 }
108 
109 using Int_view = Number_view<int>;
110 
112 [[nodiscard]] inline auto int_view(int initial = 0,
113  int precision = 2,
114  Align alignment = Align::Left)
115  -> std::unique_ptr<Int_view>
116 {
117  return std::make_unique<Int_view>(initial, precision, alignment);
118 }
119 
121 [[nodiscard]] inline auto int_view(Int_view::Parameters parameters)
122  -> std::unique_ptr<Int_view>
123 {
124  return std::make_unique<Int_view>(std::move(parameters));
125 }
126 
127 using Unsigned_view = Number_view<unsigned int>;
128 
130 [[nodiscard]] inline auto unsigned_view(unsigned int initial = 0,
131  int precision = 2,
132  Align alignment = Align::Left)
133  -> std::unique_ptr<Unsigned_view>
134 {
135  return std::make_unique<Unsigned_view>(initial, precision, alignment);
136 }
137 
139 [[nodiscard]] inline auto unsigned_view(Unsigned_view::Parameters parameters)
140  -> std::unique_ptr<Unsigned_view>
141 {
142  return std::make_unique<Unsigned_view>(std::move(parameters));
143 }
144 
145 using Double_view = Number_view<double>;
146 
148 [[nodiscard]] inline auto double_view(double initial = 0,
149  int precision = 2,
150  Align alignment = Align::Left)
151  -> std::unique_ptr<Double_view>
152 {
153  return std::make_unique<Double_view>(initial, precision, alignment);
154 }
155 
157 [[nodiscard]] inline auto double_view(Double_view::Parameters parameters)
158  -> std::unique_ptr<Double_view>
159 {
160  return std::make_unique<Double_view>(std::move(parameters));
161 }
162 
163 using Float_view = Number_view<float>;
164 
166 [[nodiscard]] inline auto float_view(float initial = 0,
167  int precision = 2,
168  Align alignment = Align::Left)
169  -> std::unique_ptr<Float_view>
170 {
171  return std::make_unique<Float_view>(initial, precision, alignment);
172 }
173 
175 [[nodiscard]] inline auto float_view(Float_view::Parameters parameters)
176  -> std::unique_ptr<Float_view>
177 {
178  return std::make_unique<Float_view>(std::move(parameters));
179 }
180 
181 } // namespace ox
182 #endif // TERMOX_WIDGET_WIDGETS_NUMBER_VIEW_HPP
A single line of text with alignment, non-editable.
Definition: label.hpp:22
auto alignment() const noexcept -> Align
Return the Align given to set_alignment().
Definition: label.cpp:111
void set_alignment(Align x)
Set text alignment of Label and update display.
Definition: label.cpp:104
void set_text(Glyph_string text)
Set text contents of Label and update display.
Definition: label.cpp:81
Displays a number on a single horizontal line.
Definition: number_view.hpp:17
auto alignment() const noexcept -> Align
Return the Align given to set_alignment().
Definition: label.cpp:111
auto precision() const noexcept -> int
Return the current precision value.
Definition: number_view.hpp:62
Number_view(Number_t initial=0, int precision=2, Align alignment=Align::Left)
Precision is only used if Number_t is floating point.
Definition: number_view.hpp:30
void set_value(Number_t x)
Set a new value to display in the Number_view.
Definition: number_view.hpp:45
void set_precision(int x)
Set a new value for floating point precision to display.
Definition: number_view.hpp:55
auto value() const noexcept -> Number_t
Return the current value.
Definition: number_view.hpp:52
Definition: number_view.hpp:22