BuGUI
BUtton Grid User Interface
Loading...
Searching...
No Matches
color_converter.hpp
1#pragma once
2#include "color.hpp"
3#include "palette.hpp"
4#include <bugui/concepts/color.hpp>
5
6#include <cstdint>
7#include <limits>
8
9namespace bugui
10{
13template <typename Value_t>
15{
16 using color_value_t = Value_t;
17
19 virtual void set(const color& color) = 0;
20
23 bool operator== (const color& other) const
24 {
25 return other == original;
26 }
27
28 bool operator!= (const base_converter<Value_t>& other) const
29 {
30 return other != original;
31 }
32
34 Value_t get() const { return value; }
37 { return original.get_state(); }
38
41 virtual void clear() = 0;
44 virtual bool is_clear() = 0;
45
46protected:
47 Value_t value{};
48 color original{};
49};
50
53template <typename T, typename Value_t = uint8_t>
55struct color_converter
56 : base_converter<Value_t>
57{
58 color_converter() = default;
59 color_converter(const color& color) { set(color); };
60 ~color_converter() = default;
61
62 void set(const color& color) override
63 {
64 if (this->original == color) return;
65
66 this->original = color;
67 auto c{this->original.get()};
68
69 float factor{static_cast<float>(c[3] / 255)};
70 uint8_t r = c[0] * factor;
71 uint8_t g = c[1] * factor;
72 uint8_t b = c[2] * factor;
73 int min_d{std::numeric_limits<int>::max()};
74
75 // adapted from
76 // github.com/ArthurSonzogni/FTXUI/blob/main/src/ftxui/screen/color.cpp
77 // line 114
78 for (const auto& [rgb, val] : palette<T>::value)
79 {
80 auto dr{r - rgb[0]};
81 auto dg{g - rgb[1]};
82 auto db{b - rgb[2]};
83 auto d = dr*dr + dg*dg + db*db;
84 if (d < min_d)
85 {
86 min_d = d;
87 this->value = val;
88 }
89 }
90 }
91
92 void clear() override
93 {
94 this->value = clear_value;
95 this->original.clear();
96 }
97
98 bool is_clear() override
99 {
100 return this->original.is_clear()
101 && this->value == clear_value;
102 }
103
104 static const Value_t clear_value;
105};
106
107template <typename T, typename Value_t>
108 requires (has_color_palette<T> && integral_no_bool<Value_t>)
109inline const Value_t color_converter<T, Value_t>::clear_value
110 {color_converter<T, Value_t>({0, 0, 0}).get()};
111
113template <typename T>
114 requires (!has_color_palette<T>)
115struct color_converter<T, color::rgba>
116 : base_converter<color::rgba>
117{
118 void set(const color& color) override
119 {
120 original = color;
121 value = original.get();
122 }
123
124 void clear() override
125 {
126 value[0] = 0;
127 value[1] = 0;
128 value[2] = 0;
129 value[3] = 255;
130 original.clear();
131 }
132
133 bool is_clear() override
134 {
135 return original.is_clear()
136 && value[0] == 0
137 && value[1] == 0
138 && value[2] == 0
139 && value[3] == 255;
140 }
141
142 static const color::rgba clear_value;
143};
144
145template <typename T>
146 requires (!has_color_palette<T>)
147inline const color::rgba color_converter<T, color::rgba>
148 ::clear_value{0, 0, 0};
149
152template <typename T>
153 requires (!has_color_palette<T>)
154struct color_converter<T, uint8_t>
155 : base_converter<uint8_t>
156{
157 void set(const color& color) override
158 {
159 if (original == color) return;
160
161 original = color;
162 auto c{original.get()};
163
164 float factor{static_cast<float>(c[3] / 255)};
165 uint8_t r = c[0] * factor;
166 uint8_t g = c[1] * factor;
167 uint8_t b = c[2] * factor;
168
169 // according to
170 // goodcalculators.com/rgb-to-grayscale-conversion-calculator
171 value = 0.299 * r + 0.587 * g + 0.114 * b;
172 }
173
174 void clear() override
175 {
176 value = clear_value;
177 original.clear();
178 }
179
180 bool is_clear() override
181 {
182 return original.is_clear()
183 && value == clear_value;
184 }
185
186 static const uint8_t clear_value;
187};
188
189template <typename T>
190 requires (!has_color_palette<T>)
191inline const uint8_t color_converter<T, uint8_t>::clear_value
192 {color_converter<T, uint8_t>({0, 0, 0}).get()};
193
194} // namespace bugui
Definition color.hpp:17
Definition common.hpp:22
Provides base functionalities for converting color objects to devices specific colour values.
Definition color_converter.hpp:15
color::states get_state() const
Retrives the current state.
Definition color_converter.hpp:36
virtual bool is_clear()=0
Checks that the original and device specific colour are set to their initial value.
Value_t get() const
Retrives the main device specific colour value.
Definition color_converter.hpp:34
bool operator==(const color &other) const
Determines equality between the original color and another.
Definition color_converter.hpp:23
virtual void clear()=0
Resets the original and the device specific colour to their initial value.
virtual void set(const color &color)=0
Sets the original color.
void clear() override
Resets the original and the device specific colour to their initial value.
Definition color_converter.hpp:124
void set(const color &color) override
Sets the original color.
Definition color_converter.hpp:118
bool is_clear() override
Checks that the original and device specific colour are set to their initial value.
Definition color_converter.hpp:133
void clear() override
Resets the original and the device specific colour to their initial value.
Definition color_converter.hpp:174
bool is_clear() override
Checks that the original and device specific colour are set to their initial value.
Definition color_converter.hpp:180
void set(const color &color) override
Sets the original color.
Definition color_converter.hpp:157
void clear() override
Resets the original and the device specific colour to their initial value.
Definition color_converter.hpp:92
bool is_clear() override
Checks that the original and device specific colour are set to their initial value.
Definition color_converter.hpp:98
void set(const color &color) override
Sets the original color.
Definition color_converter.hpp:62
Generic colour class holding RGBA coloour values. The blinking and pulsing states indicate discrete o...
Definition color.hpp:14
states
Definition color.hpp:18
rgba get() const noexcept
Retrieves the primary colour as rgba values.
Definition color.hpp:53