2021-08-06 14:22:56 +02:00
|
|
|
#ifndef BWIDGETS_COLOR_HPP
|
|
|
|
#define BWIDGETS_COLOR_HPP
|
|
|
|
|
2021-08-12 15:22:58 +02:00
|
|
|
#include <cmath>
|
2021-08-06 14:22:56 +02:00
|
|
|
#include <cstdint>
|
|
|
|
#include <functional>
|
|
|
|
|
|
|
|
#include <SDL2/SDL_assert.h>
|
|
|
|
#include <SDL2/SDL_pixels.h>
|
|
|
|
|
|
|
|
#include <basic_widgets/core/type/concepts.hpp>
|
|
|
|
|
|
|
|
namespace bwidgets
|
|
|
|
{
|
|
|
|
class Color final
|
|
|
|
{
|
|
|
|
public:
|
2021-08-14 09:17:51 +02:00
|
|
|
[[nodiscard]] auto& operator()() noexcept
|
2021-08-06 14:22:56 +02:00
|
|
|
{
|
|
|
|
return sdl_type;
|
|
|
|
}
|
|
|
|
|
2021-08-14 09:17:51 +02:00
|
|
|
[[nodiscard]] const auto& operator()() const noexcept
|
2021-08-06 14:22:56 +02:00
|
|
|
{
|
|
|
|
return sdl_type;
|
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool _operate_on_alpha;
|
|
|
|
bool _operate_on_colors;
|
|
|
|
|
|
|
|
template<Numeric N>
|
2021-08-14 09:17:51 +02:00
|
|
|
auto _operate(N operand,
|
2021-08-12 16:10:49 +02:00
|
|
|
const std::function<N(N, N)>& operator_) const noexcept
|
2021-08-06 14:22:56 +02:00
|
|
|
{
|
|
|
|
Color c(sdl_type, _operate_on_alpha, _operate_on_colors);
|
|
|
|
if (_operate_on_alpha) {
|
|
|
|
auto a = std::round(operator_(c().a, operand));
|
|
|
|
SDL_assert_release(a == (uint8_t)a); // NOLINT
|
|
|
|
c().a = (uint8_t)a;
|
|
|
|
}
|
|
|
|
if (_operate_on_colors) {
|
|
|
|
auto r = std::round(operator_(c().r, operand));
|
|
|
|
auto g = std::round(operator_(c().g, operand));
|
|
|
|
auto b = std::round(operator_(c().b, operand));
|
|
|
|
// NOLINTNEXTLINE
|
|
|
|
SDL_assert_release(r == (uint8_t)r && g == (uint8_t)g
|
|
|
|
&& b == (uint8_t)b);
|
|
|
|
c().r = (uint8_t)r;
|
|
|
|
c().g = (uint8_t)g;
|
|
|
|
c().b = (uint8_t)b;
|
|
|
|
}
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
|
|
|
public:
|
|
|
|
SDL_Color sdl_type;
|
|
|
|
|
2021-08-14 09:17:51 +02:00
|
|
|
Color(uint8_t r, uint8_t g, uint8_t b, uint8_t a,
|
2021-08-06 14:22:56 +02:00
|
|
|
bool op_on_alpha = false, bool op_on_colors = true) noexcept
|
|
|
|
: _operate_on_alpha(op_on_alpha),
|
|
|
|
_operate_on_colors(op_on_colors),
|
|
|
|
sdl_type({r, g, b, a})
|
|
|
|
{}
|
|
|
|
inline Color(const SDL_Color& c = {}, bool op_on_alpha = false,
|
|
|
|
bool op_on_colors = true) noexcept
|
|
|
|
: _operate_on_alpha(op_on_alpha), _operate_on_colors(op_on_colors), sdl_type(c)
|
|
|
|
{}
|
2021-08-14 09:17:51 +02:00
|
|
|
Color(const Color&) noexcept = default;
|
|
|
|
Color(Color&&) noexcept = default;
|
2021-08-12 15:29:25 +02:00
|
|
|
~Color() = default;
|
2021-08-06 14:22:56 +02:00
|
|
|
|
2021-08-14 09:17:51 +02:00
|
|
|
[[nodiscard]] auto alpha() const noexcept -> Color
|
2021-08-06 14:22:56 +02:00
|
|
|
{
|
|
|
|
return {sdl_type, _operate_on_colors, true};
|
|
|
|
}
|
|
|
|
|
2021-08-14 09:17:51 +02:00
|
|
|
[[nodiscard]] auto colors() const noexcept -> Color
|
2021-08-06 14:22:56 +02:00
|
|
|
{
|
|
|
|
return {sdl_type, true, _operate_on_alpha};
|
|
|
|
}
|
|
|
|
|
|
|
|
template<Numeric N>
|
2021-08-14 09:17:51 +02:00
|
|
|
[[nodiscard]] auto operator+(const N& operand) const noexcept
|
2021-08-06 14:22:56 +02:00
|
|
|
{
|
|
|
|
return _operate(operand, [](const N& a, const N& b) { return a + b; });
|
|
|
|
}
|
|
|
|
|
|
|
|
template<Numeric N>
|
2021-08-14 09:17:51 +02:00
|
|
|
[[nodiscard]] auto operator-(const N& operand) const noexcept
|
2021-08-06 14:22:56 +02:00
|
|
|
{
|
|
|
|
return _operate(operand, [](const N& a, const N& b) { return a - b; });
|
|
|
|
}
|
|
|
|
|
|
|
|
template<Numeric N>
|
2021-08-14 09:17:51 +02:00
|
|
|
[[nodiscard]] auto operator*(const N& operand) const noexcept
|
2021-08-06 14:22:56 +02:00
|
|
|
{
|
|
|
|
return _operate(operand, [](const N& a, const N& b) { return a * b; });
|
|
|
|
}
|
|
|
|
|
|
|
|
template<Numeric N>
|
2021-08-14 09:17:51 +02:00
|
|
|
[[nodiscard]] auto operator/(const N& operand) const noexcept
|
2021-08-06 14:22:56 +02:00
|
|
|
{
|
2021-08-12 16:09:26 +02:00
|
|
|
SDL_assert_release(operand != 0); // NOLINT
|
2021-08-06 14:22:56 +02:00
|
|
|
return _operate<N>(operand, [](const N& a, const N& b) { return a / b; });
|
|
|
|
}
|
|
|
|
|
2021-08-14 09:17:51 +02:00
|
|
|
auto operator=(const Color& c) noexcept -> Color& = default;
|
|
|
|
auto operator=(Color&&) noexcept -> Color& = default;
|
2021-08-06 14:22:56 +02:00
|
|
|
|
2021-08-14 09:17:51 +02:00
|
|
|
auto& operator=(const SDL_Color& c) noexcept
|
2021-08-06 14:22:56 +02:00
|
|
|
{
|
|
|
|
sdl_type = c;
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2021-08-14 09:17:51 +02:00
|
|
|
[[nodiscard]] auto operator==(const Color& other) const noexcept
|
2021-08-06 14:22:56 +02:00
|
|
|
{
|
|
|
|
return (_operate_on_colors && sdl_type.r == other().r
|
|
|
|
&& sdl_type.g == other().g && sdl_type.b == other().b)
|
|
|
|
|| (_operate_on_alpha && sdl_type.a == other().a);
|
|
|
|
}
|
|
|
|
|
2021-08-14 09:17:51 +02:00
|
|
|
[[nodiscard]] auto operator!=(const Color& other) const noexcept
|
2021-08-06 14:22:56 +02:00
|
|
|
{
|
|
|
|
return (sdl_type.r != other().r || sdl_type.g != other().g
|
|
|
|
|| sdl_type.b != other().b)
|
|
|
|
&& ((_operate_on_alpha && sdl_type.a != other().a)
|
|
|
|
|| !_operate_on_alpha);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
#endif
|