diff --git a/examples/arduino_nano/color/main.cpp b/examples/arduino_nano/color/main.cpp index c995306428..80d7cd9d52 100644 --- a/examples/arduino_nano/color/main.cpp +++ b/examples/arduino_nano/color/main.cpp @@ -64,11 +64,8 @@ class Sensorthread : public modm::pt::Protothread PT_WAIT_UNTIL(TCS3472_INT::read() == false); if (PT_CALL(sensor.readColor())) { - const auto color = data.getColor(); - MODM_LOG_INFO << "RGB: " << color; - modm::color::HsvT hsv; - color.toHsv(&hsv); - MODM_LOG_INFO << "\tHSV: " << hsv << modm::endl; + const auto rgb = data.getColor(); + MODM_LOG_INFO << "RGB: " << rgb << "\tHSV: " << modm::color::Hsv(rgb) << modm::endl; } } diff --git a/examples/avr/display/dogm128/benchmark/main.cpp b/examples/avr/display/dogm128/benchmark/main.cpp index 0c763947c4..b8989c1dbe 100644 --- a/examples/avr/display/dogm128/benchmark/main.cpp +++ b/examples/avr/display/dogm128/benchmark/main.cpp @@ -21,6 +21,7 @@ using namespace modm::platform; using namespace modm::literals; using namespace std::chrono_literals; +using namespace modm::color::html; namespace led @@ -161,7 +162,7 @@ main() while (!timer.execute()) { // rectangle in left side of screen - // TODO display.setColor(Color::black()); + // display.setColor(Black); display.drawRectangle(Point(0, 0), 62, 62); // rounded rectangle around text area @@ -176,14 +177,14 @@ main() display.drawCircle(Point(31, 31), 31); // clear previous spinner position - // TODO display.setColor(Color::white()); + // TODO display.setColor(White); display.fillRectangle(Point(87, 40), 16, 16); static uint8_t loops = 0; - // TODO display.setColor(Color::black()); + // TODO display.setColor(Black); drawSpinner(Point(95, 48), loops++); - // TODO display.setColor(Color::white()); + // TODO display.setColor(White); display.setCursor(Point(25, 40)); display << ++iter; display.update(); @@ -192,7 +193,7 @@ main() // print number of iterations in one second display.clear(); display.setCursor(Point(80, 10)); - // TODO display.setColor(Color::white()); + // display.setColor(White); display << "FPS=" << iter; } } diff --git a/examples/avr/display/dogm128/draw/main.cpp b/examples/avr/display/dogm128/draw/main.cpp index 236e4ae748..06fc5b20b1 100644 --- a/examples/avr/display/dogm128/draw/main.cpp +++ b/examples/avr/display/dogm128/draw/main.cpp @@ -17,6 +17,7 @@ using namespace modm::platform; using namespace modm::literals; +using namespace modm::color::html; namespace led @@ -71,11 +72,11 @@ main() display.fillRectangle(Point(10, 10), 20, 20); display.fillCircle(Point(45, 40), 23); - // TODO display.setColor(Color::white()); + // display.setColor(White); display.fillRectangle(Point(20, 20), 20, 20); display.fillCircle(Point(55, 50), 8); - // TODO display.setColor(Color::black()); + // display.setColor(Black); display.drawLine(Point(0, 0), Point(127, 63)); display.update(); diff --git a/examples/blue_pill_f103/graphics/main.cpp b/examples/blue_pill_f103/graphics/main.cpp index 4ca5c3c1f0..2a6f07531d 100644 --- a/examples/blue_pill_f103/graphics/main.cpp +++ b/examples/blue_pill_f103/graphics/main.cpp @@ -50,7 +50,8 @@ main() tft.initialize(); tft.enableBacklight(true); LedGreen::set(); - tft.setColor(modm::glcd::Color::black()); + tft.setColor(modm::color::html::Black); + int16_t w = tft.getWidth(); int16_t h = tft.getHeight(); tft.drawLine({0,0}, {w, h}); diff --git a/examples/nucleo_f446re/color/main.cpp b/examples/nucleo_f446re/color/main.cpp index e95d95847f..ac80a406ce 100644 --- a/examples/nucleo_f446re/color/main.cpp +++ b/examples/nucleo_f446re/color/main.cpp @@ -11,8 +11,8 @@ // ---------------------------------------------------------------------------- #include -#include #include +#include class ThreadOne : public modm::pt::Protothread { @@ -28,9 +28,7 @@ class ThreadOne : public modm::pt::Protothread while (true) { // we wait until the task started - if (PT_CALL(sensor.ping())) { - break; - } + if (PT_CALL(sensor.ping())) { break; } // otherwise, try again in 100ms timeout.restart(100ms); PT_WAIT_UNTIL(timeout.isExpired()); @@ -40,9 +38,7 @@ class ThreadOne : public modm::pt::Protothread while (true) { - if (PT_CALL(sensor.initialize())) { - break; - } + if (PT_CALL(sensor.initialize())) { break; } // otherwise, try again in 100ms timeout.restart(100ms); PT_WAIT_UNTIL(timeout.isExpired()); @@ -52,7 +48,8 @@ class ThreadOne : public modm::pt::Protothread while (true) { - if (PT_CALL(sensor.configure(sensor.Gain::X4, sensor.IntegrationTime::MSEC_101))) { + if (PT_CALL(sensor.configure(sensor.Gain::X4, sensor.IntegrationTime::MSEC_101))) + { break; } // otherwise, try again in 100ms @@ -66,11 +63,8 @@ class ThreadOne : public modm::pt::Protothread { if (PT_CALL(sensor.readColor())) { - const auto color = data.getColor(); - MODM_LOG_INFO << "RGB: " << color; - modm::color::HsvT hsv; - color.toHsv(&hsv); - MODM_LOG_INFO << "\tHSV: " << hsv << modm::endl; + const auto rgb = data.getColor(); + MODM_LOG_INFO << "RGB: " << rgb << "\tHSV: " << modm::color::Hsv(rgb) << modm::endl; } timeout.restart(500ms); PT_WAIT_UNTIL(timeout.isExpired()); diff --git a/examples/nucleo_l452re/graphics_touch/main.cpp b/examples/nucleo_l452re/graphics_touch/main.cpp index 162b074163..f71ed9b5d5 100644 --- a/examples/nucleo_l452re/graphics_touch/main.cpp +++ b/examples/nucleo_l452re/graphics_touch/main.cpp @@ -16,6 +16,7 @@ #include using namespace Board; +using namespace modm::color::html; namespace tft { @@ -86,12 +87,12 @@ main() LedGreen::set(); - tftController.setColor(modm::glcd::Color::black()); - tftController.setBackgroundColor(modm::glcd::Color::red()); + tftController.setColor(Black); + tftController.setBackgroundColor(Red); tftController.clear(); tftController.setFont(modm::font::ArcadeClassic); - tftController.setColor(modm::glcd::Color::white()); + tftController.setColor(White); tftController.setCursor(10,12); tftController << "(10,10)"; tftController.setCursor(150,202); @@ -101,7 +102,7 @@ main() tftController.drawLine(145, 200, 155, 200); tftController.drawLine(150, 195, 150, 205); - tftController.setColor(modm::glcd::Color::black()); + tftController.setColor(Black); tftController.setFont(modm::font::Ubuntu_36); int16_t X = 0; @@ -113,9 +114,9 @@ main() LedGreen::set(); std::tie(X, Y, Z) = RF_CALL_BLOCKING(touchController.getRawValues()); - tftController.setColor(modm::glcd::Color::red()); + tftController.setColor(Red); tftController.fillRectangle({30, 50}, 90, 115); - tftController.setColor(modm::glcd::Color::black()); + tftController.setColor(Black); tftController.setCursor(0, 50); tftController << "X=" << X; tftController.setCursor(0, 90); @@ -123,9 +124,9 @@ main() tftController.setCursor(0, 130); tftController << "Z=" << Z; - tftController.setColor(modm::glcd::Color::red()); + tftController.setColor(Red); tftController.fillRectangle({30, 220}, 120, 35); - tftController.setColor(modm::glcd::Color::black()); + tftController.setColor(Black); if(RF_CALL_BLOCKING(touchController.isTouched())) { std::tie(X, Y) = RF_CALL_BLOCKING(touchController.getTouchPosition()); tftController.setCursor(5, 220); diff --git a/examples/nucleo_l452re/lvgl/main.cpp b/examples/nucleo_l452re/lvgl/main.cpp index 8e70bb5574..4a4003da2b 100644 --- a/examples/nucleo_l452re/lvgl/main.cpp +++ b/examples/nucleo_l452re/lvgl/main.cpp @@ -83,7 +83,7 @@ void my_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * {area->x1, area->y1}, (area->x2 - area->x1 +1), (area->y2 - area->y1 + 1), - (modm::glcd::Color*)color_p); + (modm::color::Rgb565*)color_p); lv_disp_flush_ready(disp_drv); } diff --git a/examples/stm32_f4ve/gui/main.cpp b/examples/stm32_f4ve/gui/main.cpp index 45552f287c..29c27eecaa 100644 --- a/examples/stm32_f4ve/gui/main.cpp +++ b/examples/stm32_f4ve/gui/main.cpp @@ -26,10 +26,12 @@ #include + #include "touchscreen_calibrator.hpp" #include "images/bluetooth_12x16.hpp" +using namespace modm::color; // ---------------------------------------------------------------------------- @@ -166,13 +168,13 @@ initTouchscreen() static void drawCross(modm::ColorGraphicDisplay& display, modm::glcd::Point center) { - display.setColor(modm::glcd::Color::red()); + display.setColor(html::Red); display.drawLine(center.x - 15, center.y, center.x - 2, center.y); display.drawLine(center.x + 2, center.y, center.x + 15, center.y); display.drawLine(center.x, center.y - 15, center.x, center.y - 2); display.drawLine(center.x, center.y + 2, center.x, center.y + 15); - display.setColor(modm::glcd::Color::white()); + display.setColor(html::White); display.drawLine(center.x - 15, center.y + 15, center.x - 7, center.y + 15); display.drawLine(center.x - 15, center.y + 7, center.x - 15, center.y + 15); @@ -198,7 +200,7 @@ calibrateTouchscreen(modm::ColorGraphicDisplay& display, modm::glcd::Point *fixe { display.clear(); - display.setColor(modm::glcd::Color::yellow()); + display.setColor(modm::color::html::Yellow); display.setCursor(50, 5); display << "Touch crosshair to calibrate"; @@ -385,20 +387,18 @@ test_callback(const modm::gui::InputEvent& ev, modm::gui::Widget* w, void* data) Board::LedGreen2::toggle(); } - -modm::glcd::Color colors[modm::gui::Color::PALETTE_SIZE] { - modm::glcd::Color::black(), - modm::glcd::Color::white(), - modm::glcd::Color::gray(), - modm::glcd::Color::red(), - modm::glcd::Color::green(), - modm::glcd::Color::blue(), - modm::glcd::Color::blue(), // BORDER - modm::glcd::Color::red(), // TEXT - modm::glcd::Color::black(), // BACKGROUND - modm::glcd::Color::red(), // ACTIVATED - modm::glcd::Color::blue(), // DEACTIVATED - +modm::color::Rgb565 colors[modm::gui::Color::PALETTE_SIZE] { + html::Black, + html::White, + html::Gray, + html::Red, + html::Green, + html::Blue, + html::Blue, // BORDER + html::Red, // TEXT + html::Black, // BACKGROUND + html::Red, // ACTIVATED + html::Blue, // DEACTIVATED }; modm::gui::ColorPalette colorpalette{colors}; /* @@ -444,7 +444,7 @@ main() * manipulate the color palette */ - colorpalette.setColor(modm::gui::Color::TEXT, modm::glcd::Color::yellow()); + colorpalette.setColor(modm::gui::Color::TEXT, html::Yellow); /* diff --git a/examples/stm32f469_discovery/display/main.cpp b/examples/stm32f469_discovery/display/main.cpp index 12c4eeebcd..cfd578e0b1 100644 --- a/examples/stm32f469_discovery/display/main.cpp +++ b/examples/stm32f469_discovery/display/main.cpp @@ -42,7 +42,7 @@ main() } else { display.setCursor(rand() % 750, rand() % 460); display << "Hello World!"; - display.setColor(Color(uint16_t(rand()))); + display.setColor(uint16_t(rand())); } } diff --git a/examples/stm32f469_discovery/game_of_life/main.cpp b/examples/stm32f469_discovery/game_of_life/main.cpp index 2c1dc59b72..662edac1bb 100644 --- a/examples/stm32f469_discovery/game_of_life/main.cpp +++ b/examples/stm32f469_discovery/game_of_life/main.cpp @@ -72,7 +72,7 @@ uint16_t * displayBuffer; #define TRAIL_LENGTH ((1 << TRAIL_POWER) + 1) constexpr uint8_t alive = (1 << TRAIL_POWER); -#define COLOR_SHADE(red, green, blue, fraction) Color( \ +#define COLOR_SHADE(red, green, blue, fraction) modm::color::Rgb(\ uint8_t(uint32_t(red) * (fraction) / TRAIL_LENGTH), \ uint8_t(uint32_t(green) * (fraction) / TRAIL_LENGTH), \ uint8_t(uint32_t(blue) * (fraction) / TRAIL_LENGTH) ) @@ -82,7 +82,7 @@ constexpr uint8_t alive = (1 << TRAIL_POWER); COLOR_SHADE(r,g,b,8), COLOR_SHADE(r,g,b,9), COLOR_SHADE(r,g,b,10),COLOR_SHADE(r,g,b,11), \ COLOR_SHADE(r,g,b,12),COLOR_SHADE(r,g,b,13),COLOR_SHADE(r,g,b,14),COLOR_SHADE(r,g,b,15) } -static const Color shades_of_color[][16] { +static const modm::color::Rgb565 shades_of_color[][16] { COLOR_PALETTE(0xff, 0xff, 0xff), COLOR_PALETTE(0xff, 0, 0), @@ -137,7 +137,7 @@ static inline void touch(framebuffer_t buffer) static inline void setPixel(int x, int y, uint8_t color) { -#define DRAW(x, y) displayBuffer[(y) * 800 + (x)] = GET_TRAIL_COLOR(color).getValue(); +#define DRAW(x, y) displayBuffer[(y) * 800 + (x)] = GET_TRAIL_COLOR(color).color; #if SCALE >= 8 // >:v x:y // 0 | | @@ -148,7 +148,7 @@ static inline void setPixel(int x, int y, uint8_t color) // 5 | x x | // 6 | xxxx | // 7 | | - +GET_TRAIL_COLOR(color).color; // 1 DRAW(x+2, y+1); DRAW(x+3, y+1); diff --git a/examples/stm32f469_discovery/touchscreen/main.cpp b/examples/stm32f469_discovery/touchscreen/main.cpp index b83fbb4bc4..13444a6321 100644 --- a/examples/stm32f469_discovery/touchscreen/main.cpp +++ b/examples/stm32f469_discovery/touchscreen/main.cpp @@ -23,7 +23,7 @@ class LineDrawer : public modm::pt::Protothread touch(touchData), display{Board::getDisplay()}, px{-1, -1}, py{-1, -1}, - c{Color::white(), Color::white()} + c{modm::color::html::White, modm::color::html::White} {} bool @@ -72,7 +72,7 @@ class LineDrawer : public modm::pt::Protothread // invalidate points px[tp.id] = -1; py[tp.id] = -1; // generate new random color - c[tp.id] = Color(uint16_t(rand())); + c[tp.id] = modm::color::Rgb565(uint16_t(rand())); } } LedRed::reset(); @@ -86,7 +86,7 @@ class LineDrawer : public modm::pt::Protothread Touch touch; modm::ColorGraphicDisplay& display; int16_t px[2], py[2]; - Color c[2]; + modm::color::Rgb565 c[2]; }; LineDrawer drawer; diff --git a/examples/stm32f4_discovery/colour_tcs3414/main.cpp b/examples/stm32f4_discovery/colour_tcs3414/main.cpp index 7064e694df..c8cc5a5e65 100644 --- a/examples/stm32f4_discovery/colour_tcs3414/main.cpp +++ b/examples/stm32f4_discovery/colour_tcs3414/main.cpp @@ -98,11 +98,8 @@ class ThreadOne : public modm::pt::Protothread while (true) { if (PT_CALL(sensor.readColor())) { - auto color = data.getColor(); - stream << "RGB: " << color; - modm::color::HsvT hsv; - color.toHsv(&hsv); - stream << "\tHSV: " << hsv << modm::endl; + const auto rgb = data.getColor(); + stream << "RGB: " << rgb << "\tHSV: " << modm::color::Hsv(rgb) << modm::endl; } timeout.restart(500ms); PT_WAIT_UNTIL(timeout.isExpired()); diff --git a/examples/stm32f4_discovery/open407v-d/gui/main.cpp b/examples/stm32f4_discovery/open407v-d/gui/main.cpp index 51229d694b..994beaf434 100644 --- a/examples/stm32f4_discovery/open407v-d/gui/main.cpp +++ b/examples/stm32f4_discovery/open407v-d/gui/main.cpp @@ -29,6 +29,8 @@ #include "images/bluetooth_12x16.hpp" +using namespace modm::color::html; + // ---------------------------------------------------------------------------- /* * Setup UART Logger @@ -175,13 +177,13 @@ initTouchscreen() static void drawCross(modm::ColorGraphicDisplay& display, modm::glcd::Point center) { - display.setColor(modm::glcd::Color::red()); + display.setColor(Red); display.drawLine(center.x - 15, center.y, center.x - 2, center.y); display.drawLine(center.x + 2, center.y, center.x + 15, center.y); display.drawLine(center.x, center.y - 15, center.x, center.y - 2); display.drawLine(center.x, center.y + 2, center.x, center.y + 15); - display.setColor(modm::glcd::Color::white()); + display.setColor(White); display.drawLine(center.x - 15, center.y + 15, center.x - 7, center.y + 15); display.drawLine(center.x - 15, center.y + 7, center.x - 15, center.y + 15); @@ -206,7 +208,7 @@ calibrateTouchscreen(modm::ColorGraphicDisplay& display, modm::glcd::Point *fixe { display.clear(); - display.setColor(modm::glcd::Color::yellow()); + display.setColor(Yellow); display.setCursor(50, 5); display << "Touch crosshair to calibrate"; @@ -394,17 +396,17 @@ test_callback(const modm::gui::InputEvent& ev, modm::gui::Widget* w, void* data) //modm::gui::ColorPalette colorpalette[modm::gui::Color::PALETTE_SIZE] = { -// modm::glcd::Color::black(), -// modm::glcd::Color::white(), -// modm::glcd::Color::gray(), -// modm::glcd::Color::red(), -// modm::glcd::Color::green(), -// modm::glcd::Color::blue(), -// modm::glcd::Color::blue(), // BORDER -// modm::glcd::Color::red(), // TEXT -// modm::glcd::Color::black(), // BACKGROUND -// modm::glcd::Color::red(), // ACTIVATED -// modm::glcd::Color::blue(), // DEACTIVATED +// Black, +// White, +// Gray, +// Red, +// Green, +// Blue, +// Blue, // BORDER +// Red, // TEXT +// Black, // BACKGROUND +// Red, // ACTIVATED +// Blue, // DEACTIVATED // //}; @@ -437,7 +439,7 @@ main() * manipulate the color palette */ -// colorpalette[modm::gui::Color::TEXT] = modm::glcd::Color::yellow(); +// colorpalette[modm::gui::Color::TEXT] = Yellow; /* diff --git a/examples/stm32f4_discovery/open407v-d/touchscreen/main.cpp b/examples/stm32f4_discovery/open407v-d/touchscreen/main.cpp index a8f21388c0..c82fbdc9bb 100644 --- a/examples/stm32f4_discovery/open407v-d/touchscreen/main.cpp +++ b/examples/stm32f4_discovery/open407v-d/touchscreen/main.cpp @@ -23,6 +23,8 @@ #include "touchscreen_calibrator.hpp" +using namespace modm::color::html; + // ---------------------------------------------------------------------------- @@ -132,13 +134,13 @@ initTouchscreen() static void drawCross(modm::ColorGraphicDisplay& display, modm::glcd::Point center) { - display.setColor(modm::glcd::Color::red()); + display.setColor(Red); display.drawLine(center.x - 15, center.y, center.x - 2, center.y); display.drawLine(center.x + 2, center.y, center.x + 15, center.y); display.drawLine(center.x, center.y - 15, center.x, center.y - 2); display.drawLine(center.x, center.y + 2, center.x, center.y + 15); - display.setColor(modm::glcd::Color::white()); + display.setColor(White); display.drawLine(center.x - 15, center.y + 15, center.x - 7, center.y + 15); display.drawLine(center.x - 15, center.y + 7, center.x - 15, center.y + 15); @@ -162,7 +164,7 @@ calibrateTouchscreen(modm::ColorGraphicDisplay& display) { display.clear(); - display.setColor(modm::glcd::Color::yellow()); + display.setColor(Yellow); display.setCursor(50, 5); display << "Touch crosshair to calibrate"; @@ -205,7 +207,7 @@ main() calibrateTouchscreen(tft); - tft.setColor(modm::glcd::Color::lime()); + tft.setColor(Lime); while (true) { diff --git a/src/modm/board/disco_f469ni/board_display.cpp b/src/modm/board/disco_f469ni/board_display.cpp index ed7105cf0f..664a544484 100644 --- a/src/modm/board/disco_f469ni/board_display.cpp +++ b/src/modm/board/disco_f469ni/board_display.cpp @@ -49,7 +49,7 @@ class DsiDisplay : public modm::ColorGraphicDisplay void clear() final { - std::fill(buffer, buffer + this->getBufferWidth()*this->getBufferHeight(), this->backgroundColor.getValue()); + std::fill(buffer, buffer + this->getBufferWidth()*this->getBufferHeight(), this->backgroundColor.color); } void @@ -62,17 +62,17 @@ class DsiDisplay : public modm::ColorGraphicDisplay setPixel(int16_t x, int16_t y) final { if (x < 0 or 800 <= x or y < 0 or 480 <= y) return; - buffer[y * 800 + x] = this->foregroundColor.getValue(); + buffer[y * 800 + x] = this->foregroundColor.color; } void clearPixel(int16_t x, int16_t y) final { if (x < 0 or 800 <= x or y < 0 or 480 <= y) return; - buffer[y * 800 + x] = this->backgroundColor.getValue(); + buffer[y * 800 + x] = this->backgroundColor.color; } - modm::glcd::Color + modm::color::Rgb565 getPixel(int16_t x, int16_t y) const final { if (x < 0 or 800 <= x or y < 0 or 480 <= y) return false; diff --git a/src/modm/driver/color/tcs3414.hpp b/src/modm/driver/color/tcs3414.hpp index 0ac732098f..c2fb3e6f85 100644 --- a/src/modm/driver/color/tcs3414.hpp +++ b/src/modm/driver/color/tcs3414.hpp @@ -132,26 +132,6 @@ struct tcs3414 getColor() { return {getRed(), getGreen(), getBlue()}; } - /** Normalize color values based on clear value - * - * Imagine a low band light. For example a green laser. In case the filters - * of this sensors do not transfer this wavelength well, it might - * result in all colors being very low. The clear value will not - * filter colors and thus it will see a bright light (intensity). - * In order to still have some signal the very low green value can be - * amplified with the clear value. - */ - inline Rgb - getNormalizedColor() - { - Rgb color = getColor(); - float scalar = getClear() / float(color.red + color.green + color.blue); - color.red *= scalar; - color.green *= scalar; - color.blue *= scalar; - return color; - } - inline uint16_t getClear() { return getValue(3); } inline uint16_t diff --git a/src/modm/driver/color/tcs3472.hpp b/src/modm/driver/color/tcs3472.hpp index 0dd5e29f54..1a20c34ba7 100644 --- a/src/modm/driver/color/tcs3472.hpp +++ b/src/modm/driver/color/tcs3472.hpp @@ -148,28 +148,9 @@ struct tcs3472 getColor() { return {getRed(), getGreen(), getBlue()}; } - /** Normalize color values based on clear value - * - * Imagine a low band light. For example a green laser. In case the filters - * of this sensors do not transfer this wavelength well, it might - * result in all colors being very low. The clear value will not - * filter colors and thus it will see a bright light (intensity). - * In order to still have some signal the very low green value can be - * amplified with the clear value. - */ - inline Rgb - getNormalizedColor() - { - Rgb color = getColor(); - const float scalar = getClear() / float(color.red + color.green + color.blue); - color.red *= scalar; - color.green *= scalar; - color.blue *= scalar; - return color; - } - inline uint16_t getClear() { return getValue(0); } + inline uint16_t getRed() { return getValue(1); } inline uint16_t diff --git a/src/modm/driver/display/ili9341.hpp b/src/modm/driver/display/ili9341.hpp index 0fb75fc1e2..b5cbc2e4de 100644 --- a/src/modm/driver/display/ili9341.hpp +++ b/src/modm/driver/display/ili9341.hpp @@ -236,12 +236,12 @@ class Ili9341 : public Interface, public modm::ColorGraphicDisplay { setColoredPixel(x, y, backgroundColor); } // TODO implement getPixel for ili9341 - glcd::Color + color::Rgb565 getPixel(int16_t x, int16_t y) const final { (void) x; (void) y; - return glcd::Color::white(); + return modm::color::html::White; } void @@ -270,7 +270,7 @@ class Ili9341 : public Interface, public modm::ColorGraphicDisplay modm::accessor::Flash data) final; void - drawRaw(glcd::Point upperLeft, uint16_t width, uint16_t height, glcd::Color* data); + drawRaw(glcd::Point upperLeft, uint16_t width, uint16_t height, color::Rgb565* data); void setScrollArea(uint16_t topFixedRows, uint16_t bottomFixedRows, uint16_t firstRow); @@ -290,7 +290,7 @@ class Ili9341 : public Interface, public modm::ColorGraphicDisplay private: void - setColoredPixel(int16_t x, int16_t y, glcd::Color const &color); + setColoredPixel(int16_t x, int16_t y, color::Rgb565 const &color); void setClipping(uint16_t x, uint16_t y, uint16_t width, uint16_t height); diff --git a/src/modm/driver/display/ili9341_impl.hpp b/src/modm/driver/display/ili9341_impl.hpp index f6e9ca2cf0..d44ce85c69 100644 --- a/src/modm/driver/display/ili9341_impl.hpp +++ b/src/modm/driver/display/ili9341_impl.hpp @@ -202,7 +202,7 @@ void Ili9341::drawHorizontalLine( glcd::Point start, uint16_t length) { - uint16_t const pixelValue { modm::toBigEndian(foregroundColor.getValue()) }; + uint16_t const pixelValue { modm::toBigEndian(foregroundColor.color) }; auto minLength { std::min(std::size_t(length), BufferSize) }; uint16_t *buffer16 { reinterpret_cast(buffer) }; std::fill(buffer16, buffer16+minLength, pixelValue); @@ -223,7 +223,7 @@ void Ili9341::drawVerticalLine( glcd::Point start, uint16_t length) { - uint16_t const pixelValue { modm::toBigEndian(foregroundColor.getValue()) }; + uint16_t const pixelValue { modm::toBigEndian(foregroundColor.color) }; auto minLength { std::min(std::size_t(length), BufferSize) }; uint16_t *buffer16 { reinterpret_cast(buffer) }; std::fill(buffer16, buffer16+minLength, pixelValue); @@ -248,7 +248,7 @@ Ili9341::fillRectangle( auto const y { upperLeft.getY() }; std::size_t pixelCount { std::size_t(width) * std::size_t(height) }; - uint16_t const pixelValue { modm::toBigEndian(foregroundColor.getValue()) }; + uint16_t const pixelValue { modm::toBigEndian(foregroundColor.color) }; auto minLength { std::min(std::size_t(pixelCount), BufferSize) }; uint16_t *buffer16 { reinterpret_cast(buffer) }; std::fill(buffer16, buffer16+minLength, pixelValue); @@ -270,9 +270,8 @@ void Ili9341::fillCircle( glcd::Point center, uint16_t radius) { - auto const fgColor { foregroundColor.getValue() }; - uint8_t const setColor[] { uint8_t((fgColor >> 8) & 0xff), - uint8_t(fgColor & 0xff) }; + uint8_t const setColor[] { uint8_t((foregroundColor.color >> 8) & 0xff), + uint8_t(foregroundColor.color & 0xff) }; int16_t f = 1 - radius; int16_t ddF_x = 0; @@ -318,12 +317,10 @@ void Ili9341::drawImageRaw(glcd::Point upperLeft, uint16_t width, uint16_t height, modm::accessor::Flash data) { - auto const fgColor { foregroundColor.getValue() }; - auto const bgColor { backgroundColor.getValue() }; - uint8_t const setColor[] { uint8_t((fgColor >> 8) & 0xff), - uint8_t(fgColor & 0xff) }; - uint8_t const clearColor[] { uint8_t((bgColor >> 8) & 0xff), - uint8_t(bgColor & 0xff) }; + uint8_t const setColor[] { uint8_t((foregroundColor.color >> 8) & 0xff), + uint8_t(foregroundColor.color & 0xff) }; + uint8_t const clearColor[] { uint8_t((backgroundColor.color >> 8) & 0xff), + uint8_t(backgroundColor.color & 0xff) }; BatchHandle h(*this); @@ -350,7 +347,7 @@ Ili9341::drawImageRaw(glcd::Point upper template void Ili9341::drawRaw(glcd::Point upperLeft, - uint16_t width, uint16_t height, glcd::Color* data) + uint16_t width, uint16_t height, color::Rgb565* data) { BatchHandle h(*this); @@ -392,10 +389,10 @@ Ili9341::scrollTo(uint16_t row) template void Ili9341::setColoredPixel( - int16_t x, int16_t y, glcd::Color const &color) + int16_t x, int16_t y, color::Rgb565 const &color) { - auto const pixelColor { color.getValue() }; - uint8_t const setColor[] { uint8_t((pixelColor >> 8) & 0xff), uint8_t(pixelColor & 0xff) }; + auto const pixelColor { color }; + uint8_t const setColor[] { uint8_t((pixelColor.color >> 8) & 0xff), uint8_t(pixelColor.color & 0xff) }; BatchHandle h(*this); diff --git a/src/modm/driver/display/parallel_tft.hpp b/src/modm/driver/display/parallel_tft.hpp index d1f186d416..e4d98a28e9 100644 --- a/src/modm/driver/display/parallel_tft.hpp +++ b/src/modm/driver/display/parallel_tft.hpp @@ -72,7 +72,7 @@ class ParallelTft : public ColorGraphicDisplay void clearPixel(int16_t x, int16_t y) final; - glcd::Color + color::Rgb565 getPixel(int16_t x, int16_t y) const final; // set GraphicDisplay::clear() diff --git a/src/modm/driver/display/parallel_tft_impl.hpp b/src/modm/driver/display/parallel_tft_impl.hpp index c32f82ce46..be3f5c6579 100644 --- a/src/modm/driver/display/parallel_tft_impl.hpp +++ b/src/modm/driver/display/parallel_tft_impl.hpp @@ -110,7 +110,7 @@ modm::ParallelTft::clear() interface.writeIndex(0x0022); for (uint32_t i = 0; i < MAX_X * MAX_Y; i++) { - interface.writeData(backgroundColor.getValue()); + interface.writeData(backgroundColor.color); } } @@ -123,7 +123,7 @@ modm::ParallelTft::setPixel(int16_t x, int16_t y) } writeCursor(x, y); - interface.writeRegister(0x0022, foregroundColor.getValue()); + interface.writeRegister(0x0022, foregroundColor.color); } template @@ -142,7 +142,7 @@ modm::ParallelTft::clearPixel(int16_t x, int16_t y) } template -modm::glcd::Color +modm::color::Rgb565 modm::ParallelTft::getPixel(int16_t x, int16_t y) const { (void) x; diff --git a/src/modm/ui/color.hpp b/src/modm/ui/color.hpp index 477c22c88f..64e4ef53ce 100644 --- a/src/modm/ui/color.hpp +++ b/src/modm/ui/color.hpp @@ -3,6 +3,7 @@ * Copyright (c) 2009-2013, Fabian Greif * Copyright (c) 2012-2013, 2015, Niklas Hauser * Copyright (c) 2013, David Hebbeker + * Copyright (c) 2021, Thomas Sommer * * This file is part of the modm project. * @@ -12,130 +13,9 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_COLOR_HPP -#define MODM_COLOR_HPP +#include "color/rgb.hpp" +#include "color/hsv.hpp" +#include "color/brightness.hpp" -#include -#include - -namespace modm -{ - -/// @ingroup modm_ui_color -namespace color -{ - -template -class HsvT; - -template -class RgbT; - -/// @ingroup modm_ui_color -template -class RgbT -{ -public: - UnderlyingType red{0}; - UnderlyingType green{0}; - UnderlyingType blue{0}; - - constexpr RgbT() = default; - - constexpr RgbT(UnderlyingType red, UnderlyingType green, UnderlyingType blue) - : red(red), green(green), blue(blue) - { - } - - template - ReturnType getRelative(const UnderlyingType color) const - { - return static_cast( - (static_cast(color) * - static_cast(multiplier)) / - static_cast(red + green + blue)); - } - - template - ReturnType getRelativeRed() const - { - return getRelative(red); - } - - template - ReturnType getRelativeGreen() const - { - return getRelative(green); - } - - template - ReturnType getRelativeBlue() const - { - return getRelative(blue); - } - - template - RgbT getRelativeColors() const - { - return RgbT( - getRelativeRed (), - getRelativeGreen(), - getRelativeBlue () - ); - } - - template void - toHsv(HsvT* color) const; - - constexpr bool - operator == (const RgbT& other) const - { - return (red == other.red and green == other.green and blue == other.blue); - } - -private: - template - friend IOStream& - operator << ( IOStream& os, const RgbT&); -}; - -/// @ingroup modm_ui_color -typedef RgbT<> Rgb; - -/// @ingroup modm_ui_color -template -class HsvT -{ -public: - UnderlyingType hue{0}; - UnderlyingType saturation{0}; - UnderlyingType value{0}; - - constexpr HsvT() = default; - - constexpr HsvT(UnderlyingType hue, UnderlyingType saturation, UnderlyingType value) - : hue(hue), saturation(saturation), value(value) - { - } - - template - void - toRgb(RgbT* color) const; -}; - -/// @ingroup modm_ui_color -typedef HsvT<> Hsv; - -template -IOStream& operator << ( IOStream& os, const color::RgbT& color); - -template -IOStream& operator << ( IOStream& os, const color::HsvT& color); - -} // namespace color - -} // namespace modm - -#include "color_impl.hpp" - -#endif // MODM_COLOR_HPP +#include "color/rgb565.hpp" +#include "color/rgbhtml.hpp" diff --git a/src/modm/ui/color/brightness.hpp b/src/modm/ui/color/brightness.hpp new file mode 100644 index 0000000000..bc5e961cb5 --- /dev/null +++ b/src/modm/ui/color/brightness.hpp @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include + +#include + +#include "hsv.hpp" +#include "rgb.hpp" +#include "rgb565.hpp" + +namespace modm::color +{ + +// forward declarations for convertion constructors +template +class RgbT; + +template +class HsvT; + +class Rgb565; + +/** + * @brief Brightness as unsigned integral. Add's the math for conversion to and from + * Color-Types. Use with: Grayscale Buffers, Dimmed LEDs, Brightness sensors + * + * @author Thomas Sommer + * + * @tparam T Unsigned integral for the brightness-value + * @ingroup modm_ui_color + */ +template +class BrightnessT +{ +public: + T value{0}; + + constexpr BrightnessT() = default; + + constexpr BrightnessT(T value) : value(value) {} + + /** + * Copy Constructor 8bit->16bit + */ + template + requires std::is_same_v && std::is_same_v + constexpr BrightnessT(const BrightnessT &brightness_other) + : value(brightness_other.value << 8) + {} + + /** + * Copy Constructor 16bit->8bit + */ + template + requires std::is_same_v && std::is_same_v + constexpr BrightnessT(const BrightnessT &brightness_other) + : value(brightness_other.value >> 8) + {} + + /** + * Convertion Constructor for RGB Color + * + * @param rgb RGB Color + */ + template + constexpr BrightnessT(RgbT rgb) + : value((0.2125 * float(rgb.red)) + (0.7154 * float(rgb.green)) + + (0.0721 * float(rgb.blue))) + {} + + /** + * Convertion Constructor for HSV Color + * + * @param hsv HSV Color + */ + template + constexpr BrightnessT(HsvT hsv) : value(hsv.value) + {} + + /** + * Convertion Constructor for RGB565 Color + * + * @param rgb565 RGB565 Color + */ + constexpr BrightnessT(Rgb565 rgb565) : BrightnessT(RgbT(rgb565)) {} + + constexpr bool + operator==(const BrightnessT &other) const = default; +}; + +/// @ingroup modm_ui_color +using Brightness = BrightnessT; + +} // namespace modm::color diff --git a/src/modm/ui/color.lb b/src/modm/ui/color/color.lb similarity index 68% rename from src/modm/ui/color.lb rename to src/modm/ui/color/color.lb index 1c0bb069d0..f0d4dcf5f1 100644 --- a/src/modm/ui/color.lb +++ b/src/modm/ui/color/color.lb @@ -12,20 +12,17 @@ def init(module): module.name = ":ui:color" - module.description = """\ + module.description = """ # Color -RGB and HSV containers and converters. +Color containers and converters in various formats: RGB, HSV, Brightness, Rgb565 """ def prepare(module, options): - module.depends( - ":io", - ":math:utils") + module.depends(":math:utils") return True def build(env): - env.outbasepath = "modm/src/modm/ui" - env.copy("color.hpp") - env.copy("color.cpp") - env.copy("color_impl.hpp") + env.outbasepath = "modm/src/modm/ui/color" + env.copy(".") + env.copy("../color.hpp") diff --git a/src/modm/ui/color/hsv.hpp b/src/modm/ui/color/hsv.hpp new file mode 100644 index 0000000000..57fada273b --- /dev/null +++ b/src/modm/ui/color/hsv.hpp @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2009, Martin Rosekeit + * Copyright (c) 2009-2013, Fabian Greif + * Copyright (c) 2012-2013, 2015, Niklas Hauser + * Copyright (c) 2013, David Hebbeker + * Copyright (c) 2021, Thomas Sommer + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#ifndef MODM_COLOR_HSV_HPP +#define MODM_COLOR_HSV_HPP + +#include +#include + +#include "brightness.hpp" +#include "rgb.hpp" +#include "rgb565.hpp" + +namespace modm::color +{ + +// forward declarations for convertion constructors +template +class RgbT; + +template +class BrightnessT; + +class Rgb565; + +/** + * @brief Color in HSV Colorspace + * + * @author Martin Rosekeit, Fabian Greif, Niklas Hauser, David Hebbeker, Thomas Sommer + * @ingroup modm_ui_color + */ +template +class HsvT +{ +public: + T hue{0}; + T saturation{0}; + T value{0}; + + constexpr HsvT() = default; + + constexpr HsvT(T hue, T saturation, T value) : hue(hue), saturation(saturation), value(value) {} + + /** + * Copy Constructor 8bit->16bit + */ + template + requires std::is_same_v && std::is_same_v + constexpr HsvT(const HsvT &hsv_other) + : hue(hsv_other.hue << 8), saturation(hsv_other.saturation << 8), value(hsv_other.value << 8) + {} + + /** + * Copy Constructor 16bit->8bit + */ + template + requires std::is_same_v && std::is_same_v + constexpr HsvT(const HsvT &hsv_other) + : hue(hsv_other.hue >> 8), saturation(hsv_other.saturation >> 8), value(hsv_other.value >> 8) + {} + + /** + * Convertion Constructor for RGB Color + * + * @param rgb RGB Color + */ + template + constexpr HsvT(const RgbT& rgb); + + /** + * Convertion Constructor for Brightness + * + * @param brightness Brightness 'Color'-object + */ + template + constexpr HsvT(const BrightnessT gray) : hue(0), saturation(0), value(gray.value) + {} + + /** + * Convertion Constructor for RGB565 Color + * + * @param rgb565 RGB565 Color + */ + constexpr HsvT(const Rgb565& rgb565) : HsvT(RgbT(rgb565)) {} + + constexpr bool + operator==(const HsvT& other) const = default; + +private: + template + friend IOStream& + operator<<(IOStream&, const HsvT&); +}; + +/// @ingroup modm_ui_color +using Hsv = HsvT; + + +#if __has_include() +#include + +template +IOStream& +operator<<(IOStream& os, const color::HsvT& color) +{ + os << color.hue << "\t" << color.saturation << "\t" << color.value; + return os; +} +#endif + +} // namespace modm::color + +#include "hsv_impl.hpp" + +#endif // MODM_COLOR_HSV_HPP diff --git a/src/modm/ui/color/hsv_impl.hpp b/src/modm/ui/color/hsv_impl.hpp new file mode 100644 index 0000000000..c9851b787f --- /dev/null +++ b/src/modm/ui/color/hsv_impl.hpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2009-2010, 2012, Fabian Greif + * Copyright (c) 2010, Martin Rosekeit + * Copyright (c) 2012-2013, Niklas Hauser + * Copyright (c) 2013, David Hebbeker + * Copyright (c) 2021, Thomas Sommer + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#ifndef MODM_COLOR_HSV_HPP +#error "Don't include this file directly, use 'hsv.hpp' instead!" +#endif + +#include + +/** + * @see http://de.wikipedia.org/wiki/HSV-Farbraum#Umrechnung_RGB_in_HSV.2FHSL + * @param rgb + */ +template +template +constexpr modm::color::HsvT::HsvT(const modm::color::RgbT &rgb) +{ + using CalcType = float; + const CalcType maxValue = std::numeric_limits::max(); + const CalcType _red = CalcType(rgb.red) / maxValue; + const CalcType _blue = CalcType(rgb.blue) / maxValue; + const CalcType _green = CalcType(rgb.green) / maxValue; + const CalcType _max = std::max(_red, std::max(_green, _blue)); + const CalcType _min = std::min(_red, std::min(_green, _blue)); + const CalcType _diff = _max - _min; + + CalcType hue_temp; + + // CALCULATE HUE + if (_max == _min) + { + // all three color values are the same + hue_temp = 0; + value = _max * maxValue; + } else if (_max == _red) + { + hue_temp = 60 * (0 + (_green - _blue) / _diff); + value = rgb.red; + } else if (_max == _green) + { + hue_temp = 60 * (2 + (_blue - _red) / _diff); + value = rgb.green; + } else /*if(_max == _blue)*/ + { + hue_temp = 60 * (4 + (_red - _green) / _diff); + value = rgb.blue; + } + + if (hue_temp < 0) + hue = (hue_temp + 360) * (maxValue / 360); + else + hue = (hue_temp) * (maxValue / 360); + + // CALCULATE SATURATION + if (_max == 0) + saturation = 0; + else + saturation = _diff / _max * maxValue; +} diff --git a/src/modm/ui/color/rgb.hpp b/src/modm/ui/color/rgb.hpp new file mode 100644 index 0000000000..cb5df9f00a --- /dev/null +++ b/src/modm/ui/color/rgb.hpp @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2009, Martin Rosekeit + * Copyright (c) 2009-2013, Fabian Greif + * Copyright (c) 2012-2013, 2015, Niklas Hauser + * Copyright (c) 2013, David Hebbeker + * Copyright (c) 2021, Thomas Sommer + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#ifndef MODM_COLOR_RGB_HPP +#define MODM_COLOR_RGB_HPP + +#include +#include + +#include +#include +#include +#include + +#include "brightness.hpp" +#include "hsv.hpp" +#include "rgb565.hpp" + +namespace modm::color +{ + +// forward declarations for convertion constructors +template +class HsvT; + +template +class BrightnessT; + +class Rgb565; + +/** + * Color in HSV Colorspace + * + * @author Martin Rosekeit, Fabian Greif, Niklas Hauser, David Hebbeker, Thomas Sommer + * @ingroup modm_ui_color + */ +template +class RgbT +{ +public: + T red{0}; + T green{0}; + T blue{0}; + + using TSum = modm::WideType; + + constexpr RgbT() = default; + + constexpr RgbT(T red, T green, T blue) : red(red), green(green), blue(blue) {} + + /** + * Copy Constructor 8bit->16bit + */ + template + requires std::is_same_v && std::is_same_v + constexpr RgbT(const RgbT &rgb_other) + : red(rgb_other.red << 8), green(rgb_other.green << 8), blue(rgb_other.blue << 8) + {} + + /** + * Copy Constructor 16bit->8bit + */ + template + requires std::is_same_v && std::is_same_v + constexpr RgbT(const RgbT &rgb_other) + : red(rgb_other.red >> 8), green(rgb_other.green >> 8), blue(rgb_other.blue >> 8) + {} + + /** + * Convertion Constructor for HSV Color + * + * @param hsv HSV Color + */ + template + constexpr RgbT(const HsvT& hsv); + + /** + * Convertion Constructor for Brightness + * + * @param brightness Brightness 'Color'-object + */ + // TODO Plump conversion, implement the right way + template + constexpr RgbT(const BrightnessT brightness) + : red(brightness), green(brightness), blue(brightness) + {} + + /** + * Convertion Constructor for RGB565 Color + * + * @param rgb565 RGB565 Color + */ + constexpr RgbT(const Rgb565& rgb565) + : red((rgb565.color >> 8) & 0xF8), + green((rgb565.color >> 3) & 0xFC), + blue(rgb565.color << 3) + {} + + constexpr bool + operator==(const RgbT& other) const = default; + +private: + template + friend IOStream& + operator<<(IOStream&, const RgbT&); +}; + +/// @ingroup modm_ui_color +using Rgb = RgbT; + + +/** + * Normalize color values based on a clear value + * + * Imagine a low band light, for example a green laser. In case the filters + * of a sensor do not transfer this wavelength well, it might result in all + * colors being very low. An aditional clear value (provided f.e. by TCS3472) + * will not filter colors and thus it will see a bright light (intensity). + * In order to still have some signal the very low green value can be + * amplified with the clear value. + * + * @ingroup modm_ui_color + */ +template + requires std::is_fundamental_v +constexpr RgbT +normalizeColor(RgbT rgb, IntermediateType multiplier = 1) +{ + const IntermediateType sum = IntermediateType(rgb.red) + rgb.green + rgb.blue; + return RgbT(IntermediateType(rgb.red) * multiplier / sum, + IntermediateType(rgb.green) * multiplier / sum, + IntermediateType(rgb.blue) * multiplier / sum); +} + + +#if __has_include() +#include + +template +IOStream& +operator<<(IOStream& os, const color::RgbT& color) +{ + os << color.red << "\t" << color.green << "\t" << color.blue; + return os; +} +#endif + +} // namespace modm::color + +#include "rgb_impl.hpp" + +#endif // MODM_COLOR_RGB_HPP diff --git a/src/modm/ui/color/rgb565.hpp b/src/modm/ui/color/rgb565.hpp new file mode 100644 index 0000000000..dbb19aba56 --- /dev/null +++ b/src/modm/ui/color/rgb565.hpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include + +#include "brightness.hpp" +#include "hsv.hpp" +#include "rgb.hpp" + +namespace modm::color +{ + +// forward declarations for convertion constructors +template +class RgbT; + +template +class HsvT; + +template +class BrightnessT; + +/** + * Color in RGB Colorspace, 16 bits: RRRR RGGG GGGB BBBB + * + * @author Fabian Greif, Thomas Sommer + * @ingroup modm_ui_color + */ +class Rgb565 +{ +public: + uint16_t color{0x0000}; + + using RgbCalcType = RgbT; + + constexpr Rgb565() = default; + + /** + * Constructor for preformatted Rgb565 Color + * + * @param color Preformatted RGB-color in 565-format: RRRR RGGG GGGB BBBB + */ + constexpr Rgb565(uint16_t color) : color(color) {} + + /** + * Constructor for components: red, green, blue + * + * @param red Red color component + * @param green Green color component + * @param blue Blue color component + */ + constexpr Rgb565(uint8_t red, uint8_t green, uint8_t blue) + : color(uint16_t(red & 0xF8) << 8 | uint16_t(green & 0xFC) << 3 | uint16_t(blue >> 3)) + {} + + /** + * Convertion Constructor for RGB Color + * + * @param rgb RGB Color + */ + template + constexpr Rgb565(const RgbT &rgb) : Rgb565(rgb.red, rgb.green, rgb.blue) + {} + + /** + * Convertion Constructor for HSV Color + * + * @param hsv HSV Color + */ + template + constexpr Rgb565(const HsvT &hsv) : Rgb565(RgbCalcType(hsv)) + {} + + /** + * Convertion Constructor for Brightness + * + * @param brightness Brightness 'Color'-object + */ + template + constexpr Rgb565(const BrightnessT brightness) : Rgb565(RgbCalcType(brightness)) + {} + + constexpr bool + operator==(const Rgb565 &other) const = default; + + /// Saturated addition ⊕ + Rgb565 + operator+(const Rgb565 other) const + { + const int8_t red_raw = (color >> 11) + (other.color >> 11); + const uint16_t red = std::clamp(red_raw, 0, 31) << 11; + + const int8_t green_raw = (color >> 5 & 0x3F) + (other.color >> 5 & 0x3F); + const uint16_t green = std::clamp(green_raw, 0, 63) << 5; + + const int8_t blue_raw = (color & 0x1F) + (other.color & 0x1F); + const uint16_t blue = std::clamp(blue_raw, 0, 31); + + return Rgb565(red | green | blue); + } + + /// Saturated substraction ⊖ + Rgb565 + operator-(const Rgb565 other) const + { + const int8_t red_raw = (color >> 11) - (other.color >> 11); + const uint16_t red = std::clamp(red_raw, 0, 0x1F) << 11; + + const int8_t green_raw = (color >> 5 & 0x3F) - (other.color >> 5 & 0x3F); + const uint16_t green = std::clamp(green_raw, 0, 0x3F) << 5; + + const int8_t blue_raw = (color & 0x1F) - (other.color & 0x1F); + const uint16_t blue = std::clamp(blue_raw, 0, 0x1F); + + return Rgb565(red | green | blue); + } +}; + +} // namespace modm::color diff --git a/src/modm/ui/color/rgb_impl.hpp b/src/modm/ui/color/rgb_impl.hpp new file mode 100644 index 0000000000..b8b9a17841 --- /dev/null +++ b/src/modm/ui/color/rgb_impl.hpp @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2009-2010, 2012, Fabian Greif + * Copyright (c) 2010, Martin Rosekeit + * Copyright (c) 2012-2013, Niklas Hauser + * Copyright (c) 2013, David Hebbeker + * Copyright (c) 2021, Thomas Sommer + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#ifndef MODM_COLOR_RGB_HPP +#error "Don't include this file directly, use 'rgb.hpp' instead!" +#endif + +#include + +namespace modm::color +{ + +// TODO Finish generalisation for uint16_t +template +template +constexpr RgbT::RgbT(const HsvT &hsv) +{ + uint16_t vs = hsv.value * hsv.saturation; + uint16_t h6 = 6 * hsv.hue; + + T p = ((hsv.value << 8) - vs) >> 8; + T i = h6 >> 8; + uint16_t f = ((i | 1) << 8) - h6; + if (i & 1) { f = -f; } + T u = (((uint32_t)hsv.value << 16) - (uint32_t)vs * f) >> 16; + + switch (i) + { + case 0: red = hsv.value; green = u; blue = p; break; + case 1: red = u; green = hsv.value; blue = p; break; + case 2: red = p; green = hsv.value; blue = u; break; + case 3: red = p; green = u; blue = hsv.value; break; + case 4: red = u; green = p; blue = hsv.value; break; + case 5: red = hsv.value; green = p; blue = u; break; + } +} + +} // namespace modm::color diff --git a/src/modm/ui/color/rgbhtml.hpp b/src/modm/ui/color/rgbhtml.hpp new file mode 100644 index 0000000000..71d6c9dccd --- /dev/null +++ b/src/modm/ui/color/rgbhtml.hpp @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#pragma once + +#include "rgb.hpp" + +namespace modm::color::html +{ + +/** + * Constant HTML Colornames in RGB Colorspace + * + * @see https://htmlcolorcodes.com/color-names/ + * @see modm:color:RgbT + * @ingroup modm_ui_color + * @{ + */ + +// Red HTML Color Names +static constexpr Rgb IndianRed(205, 92, 92); +static constexpr Rgb LightCoral(240, 128, 128); +static constexpr Rgb Salmon(250, 128, 114); +static constexpr Rgb DarkSalmon(233, 150, 122); +static constexpr Rgb LightSalmon(255, 160, 122); +static constexpr Rgb Crimson(220, 20, 60); +static constexpr Rgb Red(255, 0, 0); +static constexpr Rgb FireBrick(178, 34, 34); +static constexpr Rgb DarkRed(139, 0, 0); + +// Pink HTML Color Names +static constexpr Rgb Pink(255, 192, 203); +static constexpr Rgb LightPink(255, 182, 193); +static constexpr Rgb HotPink(255, 105, 180); +static constexpr Rgb DeepPink(255, 20, 147); +static constexpr Rgb MediumVioletRed(199, 21, 133); +static constexpr Rgb PaleVioletRed(219, 112, 147); + +// Orange HTML Color Names +static constexpr Rgb Coral(255, 127, 80); +static constexpr Rgb Tomato(255, 99, 71); +static constexpr Rgb OrangeRed(255, 69, 0); +static constexpr Rgb DarkOrange(255, 140, 0); +static constexpr Rgb Orange(25, 165, 0); + +// Yellow HTML Color Names +static constexpr Rgb Gold(255, 215, 0); +static constexpr Rgb Yellow(255, 255, 0); +static constexpr Rgb LightYellow(255, 255, 224); +static constexpr Rgb LemonChiffon(255, 250, 205); +static constexpr Rgb LightGoldenrodYellow(250, 250, 210); +static constexpr Rgb PapayaWhip(255, 239, 213); +static constexpr Rgb Moccasin(255, 228, 181); +static constexpr Rgb PeachPuff(255, 218, 185); +static constexpr Rgb PaleGoldenrod(238, 232, 170); +static constexpr Rgb Khaki(240, 230, 140); +static constexpr Rgb DarkKhaki(189, 183, 107); + +// Purple HTML Color Names +static constexpr Rgb Lavender(230, 230, 250); +static constexpr Rgb Thistle(216, 191, 216); +static constexpr Rgb Plum(221, 160, 221); +static constexpr Rgb Violet(238, 130, 238); +static constexpr Rgb Orchid(218, 112, 214); +static constexpr Rgb Fuchsia(255, 0, 255); +static constexpr Rgb Magenta(255, 0, 255); +static constexpr Rgb MediumOrchid(186, 85, 211); +static constexpr Rgb MediumPurple(147, 112, 219); +static constexpr Rgb RebeccaPurple(102, 51, 153); +static constexpr Rgb BlueViolet(138, 43, 226); +static constexpr Rgb DarkViolet(148, 0, 211); +static constexpr Rgb DarkOrchid(153, 50, 204); +static constexpr Rgb DarkMagenta(139, 0, 139); +static constexpr Rgb Purple(128, 0, 128); +static constexpr Rgb Indigo(75, 0, 130); +static constexpr Rgb SlateBlue(106, 90, 205); +static constexpr Rgb DarkSlateBlue(72, 61, 139); + +// Green HTML Color Names +static constexpr Rgb GreenYellow(173, 255, 47); +static constexpr Rgb Chartreuse(127, 255, 0); +static constexpr Rgb LawnGreen(124, 252, 0); +static constexpr Rgb Lime(0, 255, 0); +static constexpr Rgb LimeGreen(50, 205, 50); +static constexpr Rgb PaleGreen(152, 251, 152); +static constexpr Rgb LightGreen(144, 238, 144); +static constexpr Rgb MediumSpringGreen(0, 250, 154); +static constexpr Rgb SpringGreen(0, 255, 127); +static constexpr Rgb MediumSeaGreen(60, 179, 113); +static constexpr Rgb SeaGreen(46, 139, 87); +static constexpr Rgb ForestGreen(34, 139, 34); +static constexpr Rgb Green(0, 128, 0); +static constexpr Rgb DarkGreen(0, 100, 0); +static constexpr Rgb YellowGreen(154, 205, 50); +static constexpr Rgb OliveDrab(107, 142, 35); +static constexpr Rgb Olive(128, 128, 0); +static constexpr Rgb DarkOliveGreen(85, 107, 47); +static constexpr Rgb MediumAquamarine(102, 205, 170); +static constexpr Rgb DarkSeaGreen(143, 188, 139); +static constexpr Rgb LightSeaGreen(32, 178, 170); +static constexpr Rgb DarkCyan(0, 139, 139); +static constexpr Rgb Teal(0, 128, 128); + +// Blue HTML Color Names +static constexpr Rgb Aqua(0, 255, 255); +static constexpr Rgb Cyan(0, 255, 255); +static constexpr Rgb LightCyan(224, 255, 255); +static constexpr Rgb PaleTurquoise(175, 238, 238); +static constexpr Rgb Aquamarine(127, 255, 212); +static constexpr Rgb Turquoise(64, 224, 208); +static constexpr Rgb MediumTurquoise(72, 209, 204); +static constexpr Rgb DarkTurquoise(0, 206, 209); +static constexpr Rgb CadetBlue(95, 158, 160); +static constexpr Rgb SteelBlue(70, 130, 180); +static constexpr Rgb LightSteelBlue(176, 196, 222); +static constexpr Rgb PowderBlue(176, 224, 230); +static constexpr Rgb LightBlue(173, 216, 230); +static constexpr Rgb SkyBlue(135, 206, 235); +static constexpr Rgb LightSkyBlue(135, 206, 250); +static constexpr Rgb DeepSkyBlue(0, 191, 255); +static constexpr Rgb DodgerBlue(30, 144, 255); +static constexpr Rgb CornflowerBlue(100, 149, 237); +static constexpr Rgb MediumSlateBlue(123, 104, 238); +static constexpr Rgb RoyalBlue(65, 105, 225); +static constexpr Rgb Blue(0, 0, 255); +static constexpr Rgb MediumBlue(0, 0, 205); +static constexpr Rgb DarkBlue(0, 0, 139); +static constexpr Rgb Navy(0, 0, 128); +static constexpr Rgb MidnightBlue(25, 25, 112); + +// Brown HTML Color Names +static constexpr Rgb Cornsilk(255, 248, 220); +static constexpr Rgb BlanchedAlmond(255, 235, 205); +static constexpr Rgb Bisque(255, 228, 196); +static constexpr Rgb NavajoWhite(255, 222, 173); +static constexpr Rgb Wheat(245, 222, 179); +static constexpr Rgb BurlyWood(222, 184, 135); +static constexpr Rgb Tan(210, 180, 140); +static constexpr Rgb RosyBrown(188, 143, 143); +static constexpr Rgb SandyBrown(244, 164, 96); +static constexpr Rgb Goldenrod(218, 165, 32); +static constexpr Rgb DarkGoldenrod(184, 134, 11); +static constexpr Rgb Peru(205, 133, 63); +static constexpr Rgb Chocolate(210, 105, 30); +static constexpr Rgb SaddleBrown(139, 69, 19); +static constexpr Rgb Sienna(160, 82, 45); +static constexpr Rgb Brown(165, 42, 42); +static constexpr Rgb Maroon(128, 0, 0); + +// White HTML Color Names +static constexpr Rgb White(255, 255, 255); +static constexpr Rgb Snow(255, 250, 250); +static constexpr Rgb HoneyDew(240, 255, 240); +static constexpr Rgb MintCream(245, 255, 250); +static constexpr Rgb Azure(240, 255, 255); +static constexpr Rgb AliceBlue(240, 248, 255); +static constexpr Rgb GhostWhite(248, 248, 255); +static constexpr Rgb WhiteSmoke(245, 245, 245); +static constexpr Rgb SeaShell(255, 245, 238); +static constexpr Rgb Beige(245, 245, 220); +static constexpr Rgb OldLace(253, 245, 230); +static constexpr Rgb FloralWhite(255, 250, 230); +static constexpr Rgb Ivory(255, 255, 240); +static constexpr Rgb AntiqueWhite(250, 235, 215); +static constexpr Rgb Linen(250, 240, 230); +static constexpr Rgb LavenderBlush(255, 240, 245); +static constexpr Rgb MistyRose(255, 228, 225); + +// Gray HTML Color Names +static constexpr Rgb Gainsboro(220, 220, 220); +static constexpr Rgb LightGray(211, 211, 211); +static constexpr Rgb Silver(192, 192, 192); +static constexpr Rgb DarkGray(169, 169, 169); +static constexpr Rgb Gray(128, 128, 128); +static constexpr Rgb DimGray(105, 105, 105); +static constexpr Rgb LightSlateGray(119, 136, 153); +static constexpr Rgb SlateGray(112, 128, 144); +static constexpr Rgb DarkSlateGray(47, 79, 79); +static constexpr Rgb Black(0, 0, 0); + +/// @} + +} // namespace modm::color::html diff --git a/src/modm/ui/display/color_graphic_display.hpp b/src/modm/ui/display/color_graphic_display.hpp index 08159c1fcd..c9a6cbf5ef 100644 --- a/src/modm/ui/display/color_graphic_display.hpp +++ b/src/modm/ui/display/color_graphic_display.hpp @@ -9,75 +9,14 @@ using namespace modm::platform; namespace modm { - -// Backwards compatibility -namespace glcd -{ -/// @ingroup modm_ui_display -using Point = Vector; - -// RGB16 (565) Format -/// @ingroup modm_ui_display -class Color -{ -public: - static constexpr Color white() { return Color(0xffff); }; - static constexpr Color yellow() { return Color(0xFFE0); }; - static constexpr Color magenta() { return Color(0xF81F); }; - static constexpr Color red() { return Color(0xF800); }; - static constexpr Color orange() { return Color(0xFD20); }; - static constexpr Color silver() { return Color(0xC618); }; - static constexpr Color gray() { return Color(0x8410); }; - static constexpr Color maroon() { return Color(0x8000); }; - static constexpr Color lime() { return Color(0x07E0); }; - static constexpr Color green() { return Color(0x0400); }; - static constexpr Color blue() { return Color(0x001F); }; - static constexpr Color navy() { return Color(0x0010); }; - static constexpr Color black() { return Color(0x0000); }; - static constexpr Color signalViolet() { return Color(0x8010); }; - static constexpr Color emeraldGreen() { return Color(0x5DCC); }; - - constexpr Color() = default; - - constexpr Color(uint16_t color) : color(color) {} - - /** - * @param red - * Range [0..255] - * @param green - * Range [0..255] - * @param blue - * Range [0..255] - */ - constexpr Color(uint8_t red, uint8_t green, uint8_t blue) : - color(uint16_t((red >> 3) << 11) | uint16_t((green >> 2) << 5) | uint16_t(blue >> 3)) - {} - - inline uint16_t - getValue() const - { - return color; - } - - bool - operator==(const Color &other) const - { - return (color == other.color); - } - -private: - uint16_t color{0x000}; -}; -} // namespace glcd - class ColorGraphicDisplay : public GraphicDisplay { public: ColorGraphicDisplay() - : foregroundColor(glcd::Color::white()), backgroundColor(glcd::Color::black()) + : foregroundColor(color::html::White), backgroundColor(color::html::Black) {} - virtual glcd::Color + virtual color::Rgb565 getPixel(int16_t x, int16_t y) const = 0; /** @@ -85,12 +24,12 @@ class ColorGraphicDisplay : public GraphicDisplay * Used for drawing operations. Default is white. */ inline void - setColor(const glcd::Color color) + setColor(const color::Rgb565 color) { foregroundColor = color; } - inline glcd::Color + inline color::Rgb565 getColor() const { return foregroundColor; @@ -101,20 +40,20 @@ class ColorGraphicDisplay : public GraphicDisplay * Used when clearing the screen. Default is black. */ inline void - setBackgroundColor(const glcd::Color color) + setBackgroundColor(const color::Rgb565 color) { backgroundColor = color; } - inline glcd::Color + inline color::Rgb565 getBackgroundColor() const { return backgroundColor; } protected: - glcd::Color foregroundColor; - glcd::Color backgroundColor; + color::Rgb565 foregroundColor; + color::Rgb565 backgroundColor; }; } // namespace modm diff --git a/src/modm/ui/display/graphic_display.hpp b/src/modm/ui/display/graphic_display.hpp index 7afdacb1ef..a1c708f21c 100644 --- a/src/modm/ui/display/graphic_display.hpp +++ b/src/modm/ui/display/graphic_display.hpp @@ -24,6 +24,7 @@ #include #include +#include #include "font.hpp" namespace modm diff --git a/src/modm/ui/display/graphic_display_text.cpp b/src/modm/ui/display/graphic_display_text.cpp index b7920853bb..f1e6d1d68d 100644 --- a/src/modm/ui/display/graphic_display_text.cpp +++ b/src/modm/ui/display/graphic_display_text.cpp @@ -102,9 +102,9 @@ modm::GraphicDisplay::write(char c) // all characters below 128 have whitespace afterwards (number given // by vspace). if (character < 128) { - //glcd::Color oldColor = this->color; + //color::Rgb565 oldColor = this->color; - //this->setColor(glcd::Color::white()); + //this->setColor(color::html::White); for (uint_fast8_t i = 0; i < vspace; ++i) { //this->drawVerticalLine(cursor, height); cursor.setX(cursor.x + 1); diff --git a/src/modm/ui/display/module.lb b/src/modm/ui/display/module.lb index 521f03f342..e4918ec448 100644 --- a/src/modm/ui/display/module.lb +++ b/src/modm/ui/display/module.lb @@ -44,7 +44,8 @@ def prepare(module, options): ":architecture:accessor", ":io", ":math:geometry", - ":math:utils") + ":math:utils", + ":ui:color") return True def build(env): diff --git a/src/modm/ui/display/virtual_graphic_display.cpp b/src/modm/ui/display/virtual_graphic_display.cpp index b86a4b6438..936629c168 100644 --- a/src/modm/ui/display/virtual_graphic_display.cpp +++ b/src/modm/ui/display/virtual_graphic_display.cpp @@ -31,9 +31,9 @@ void modm::VirtualGraphicDisplay::clear() { //TODO switch black , white - this->display->setColor(glcd::Color::black()); + this->display->setColor(color::Rgb(0, 0, 0)); this->display->fillRectangle(this->leftUpper, width, height); - this->display->setColor(glcd::Color::white()); + this->display->setColor(color::Rgb(255, 255, 255)); } void @@ -55,7 +55,7 @@ modm::VirtualGraphicDisplay::clearPixel(int16_t x, int16_t y) this->display->clearPixel(x + this->leftUpper[0], y + this->leftUpper[1] ); } -modm::glcd::Color +modm::color::Rgb565 modm::VirtualGraphicDisplay::getPixel(int16_t x, int16_t y) const { return this->display->getPixel(x + this->leftUpper[0], y + this->leftUpper[1] ); diff --git a/src/modm/ui/display/virtual_graphic_display.hpp b/src/modm/ui/display/virtual_graphic_display.hpp index 4c2795bf50..5d8b9d4b2d 100644 --- a/src/modm/ui/display/virtual_graphic_display.hpp +++ b/src/modm/ui/display/virtual_graphic_display.hpp @@ -55,7 +55,7 @@ class VirtualGraphicDisplay : public modm::ColorGraphicDisplay void clearPixel(int16_t x, int16_t y) final; - glcd::Color + color::Rgb565 getPixel(int16_t x, int16_t y) const final; private: diff --git a/src/modm/ui/gui/colorpalette.cpp b/src/modm/ui/gui/colorpalette.cpp index 11fa93ef3d..85ede4ba3e 100644 --- a/src/modm/ui/gui/colorpalette.cpp +++ b/src/modm/ui/gui/colorpalette.cpp @@ -14,21 +14,23 @@ #include "colorpalette.hpp" -modm::glcd::Color defaultColors[] = { - modm::glcd::Color::black(), // BLACK - modm::glcd::Color::white(), // WHITE - modm::glcd::Color::gray(), // GRAY - modm::glcd::Color::red(), // RED - modm::glcd::Color::green(), // GREEN - modm::glcd::Color::blue(), // BLUE - modm::glcd::Color::yellow(), // YELLOW - modm::glcd::Color::signalViolet(), //SIGNALVIOLET - modm::glcd::Color::emeraldGreen(), //EMERALDGREEN - modm::glcd::Color::blue(), // BORDER - modm::glcd::Color::yellow(), // TEXT - modm::glcd::Color::black(), // BACKGROUND - modm::glcd::Color::red(), // ACTIVATED - modm::glcd::Color::blue(), // DEACTIVATED +using namespace modm::color::html; + +modm::color::Rgb565 defaultColors[] = { + Black, + White, + Gray, + Red, + Green, + Blue, + Yellow, + Purple, + MediumSeaGreen, + Blue, // BORDER + Yellow, // TEXT + Black, // BACKGROUND + Red, // ACTIVATED + Blue, // DEACTIVATED }; modm::gui::ColorPalette modm::gui::DefaultColorPalette(defaultColors); diff --git a/src/modm/ui/gui/colorpalette.hpp b/src/modm/ui/gui/colorpalette.hpp index 078253c3fb..a276fffbcf 100644 --- a/src/modm/ui/gui/colorpalette.hpp +++ b/src/modm/ui/gui/colorpalette.hpp @@ -56,7 +56,7 @@ Color { class ColorPalette { public: - ColorPalette(modm::glcd::Color colors[Color::PALETTE_SIZE]) : + ColorPalette(modm::color::Rgb565 colors[Color::PALETTE_SIZE]) : colors(colors) { } @@ -74,7 +74,7 @@ class ColorPalette } void - setColor(Color name, modm::glcd::Color color) + setColor(Color name, modm::color::Rgb565 color) { if (name < Color::PALETTE_SIZE) { @@ -82,28 +82,28 @@ class ColorPalette } } - const modm::glcd::Color + const modm::color::Rgb565 getColor(Color name) const { if (name >= Color::PALETTE_SIZE) - return modm::glcd::Color(0xffff); + return modm::color::Rgb565(0xffff); return colors[name]; } - const modm::glcd::Color + const modm::color::Rgb565 operator[](Color name) { return getColor(name); } - const modm::glcd::Color* + const modm::color::Rgb565* getPointer() const { return colors; } private: - modm::glcd::Color *colors; + modm::color::Rgb565 *colors; }; } // namespace gui diff --git a/src/modm/ui/gui/widgets/button.hpp b/src/modm/ui/gui/widgets/button.hpp index 71e280242a..5098be9348 100644 --- a/src/modm/ui/gui/widgets/button.hpp +++ b/src/modm/ui/gui/widgets/button.hpp @@ -77,14 +77,14 @@ class ArrowButton : public Widget class FilledAreaButton : public Widget { public: - FilledAreaButton(modm::glcd::Color color, Dimension d) : + FilledAreaButton(modm::color::Rgb565 color, Dimension d) : Widget(d, true), color(color) { } void - setBackgroundColor(modm::glcd::Color color) + setBackgroundColor(modm::color::Rgb565 color) { this->color = color; } @@ -93,7 +93,7 @@ class FilledAreaButton : public Widget render(View* view); private: - modm::glcd::Color color; + modm::color::Rgb565 color; }; } // namespace gui diff --git a/src/modm/ui/gui/widgets/label.hpp b/src/modm/ui/gui/widgets/label.hpp index 06dbce9685..4076fe6bf9 100644 --- a/src/modm/ui/gui/widgets/label.hpp +++ b/src/modm/ui/gui/widgets/label.hpp @@ -29,7 +29,7 @@ namespace gui class Label : public Widget { public: - Label(const char* lbl, modm::glcd::Color color) : + Label(const char* lbl, modm::color::Rgb565 color) : Widget(Dimension(0,0), false), label(lbl), color(color) @@ -41,7 +41,7 @@ class Label : public Widget render(View* view); void - setColor(modm::glcd::Color color) + setColor(modm::color::Rgb565 color) { this->color = color; this->markDirty(); @@ -83,7 +83,7 @@ class Label : public Widget private: const char* label; - modm::glcd::Color color; + modm::color::Rgb565 color; }; } // namespace gui diff --git a/src/modm/ui/gui/widgets/widget.hpp b/src/modm/ui/gui/widgets/widget.hpp index 3b6c812ab7..5b74ace262 100644 --- a/src/modm/ui/gui/widgets/widget.hpp +++ b/src/modm/ui/gui/widgets/widget.hpp @@ -23,7 +23,6 @@ #include - namespace modm { @@ -154,7 +153,7 @@ class Widget } void - setColor(modm::gui::Color name, modm::glcd::Color color) + setColor(modm::gui::Color name, modm::color::Rgb565 color) { this->color_palette.setColor(name, color); this->markDirty(); diff --git a/src/modm/ui/led/rgb.hpp b/src/modm/ui/led/rgb.hpp index 894c88c50b..4386e283b2 100644 --- a/src/modm/ui/led/rgb.hpp +++ b/src/modm/ui/led/rgb.hpp @@ -12,17 +12,13 @@ */ // ---------------------------------------------------------------------------- -#ifndef MODM_UI_RGB_LED_HPP -#define MODM_UI_RGB_LED_HPP +#pragma once #include -#include "led.hpp" #include +#include "led.hpp" -namespace modm -{ - -namespace ui +namespace modm::ui { /** @@ -42,44 +38,30 @@ class RgbLed ::modm::color::Rgb absolute; public: - RgbLed(Led& red, Led& green, Led& blue) - : red(red), green(green), blue(blue), absolute() - { - } + RgbLed(Led& red, Led& green, Led& blue): + red(red), green(green), blue(blue) {} inline void setColor(::modm::color::Rgb color) { absolute = color; - red.setBrightness(absolute.red); - green.setBrightness(absolute.green); - blue.setBrightness(absolute.blue); - } - - inline void - setColor(::modm::color::Hsv color) - { - color.toRgb(&absolute); - setColor(absolute); + red.setBrightness(color.red); + green.setBrightness(color.green); + blue.setBrightness(color.blue); } inline ::modm::color::Rgb getColor() { return ::modm::color::Rgb( - red.getBrightness(), - green.getBrightness(), - blue.getBrightness() - ); + red.getBrightness(), green.getBrightness(), blue.getBrightness()); } inline bool isFading() { - return (red.isFading() || - green.isFading() || - blue.isFading()); + return (red.isFading() || green.isFading() || blue.isFading()); } inline void @@ -92,13 +74,6 @@ class RgbLed blue.fadeTo(absolute.blue, time); } - inline void - fadeTo(::modm::color::Hsv color, uint16_t time) - { - color.toRgb(&absolute); - fadeTo(absolute, time); - } - /// should be called every 1ms or more. inline void update() @@ -109,8 +84,4 @@ class RgbLed } }; -} - -} - -#endif // MODM_PWM_RGB_LED_HPP +} // namespace modm::ui diff --git a/test/modm/ui/color/color_test.cpp b/test/modm/ui/color/color_test.cpp new file mode 100644 index 0000000000..ce4aca9a24 --- /dev/null +++ b/test/modm/ui/color/color_test.cpp @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#include "color_test.hpp" +#include +#include +#include +#include + +using namespace modm::color; + +void ColorTest::testRgbCopyConstructors() { + RgbT rgb8(html::Orchid); + RgbT rgb8_b(rgb8); + TEST_ASSERT_EQUALS(rgb8, rgb8_b); + + RgbT rgb16(rgb8); + TEST_ASSERT_EQUALS(uint16_t(rgb8.red) << 8, rgb16.red); + TEST_ASSERT_EQUALS(uint16_t(rgb8.green) << 8, rgb16.green); + TEST_ASSERT_EQUALS(uint16_t(rgb8.blue) << 8, rgb16.blue); + + RgbT rgb8_c(rgb16); + TEST_ASSERT_EQUALS(rgb8, rgb8_c); +} + +void ColorTest::testHsvCopyConstructors() { + HsvT hsv8(html::Orchid); + HsvT hsv8_b(hsv8); + TEST_ASSERT_EQUALS(hsv8, hsv8_b); + + HsvT hsv16(hsv8); + TEST_ASSERT_EQUALS(uint16_t(hsv8.hue) << 8, hsv16.hue); + TEST_ASSERT_EQUALS(uint16_t(hsv8.saturation) << 8, hsv16.saturation); + TEST_ASSERT_EQUALS(uint16_t(hsv8.value) << 8, hsv16.value); + + HsvT hsv8_c(hsv16); + TEST_ASSERT_EQUALS(hsv8, hsv8_c); +} + +void ColorTest::testBrightnessCopyConstructors() { + BrightnessT brightness8(127); + BrightnessT brightness8_b(brightness8); + TEST_ASSERT_EQUALS(brightness8.value, brightness8_b.value); + + BrightnessT brightness16(brightness8); + TEST_ASSERT_EQUALS(uint16_t(brightness8.value) << 8, brightness16.value); + + BrightnessT brightness8_c(brightness16); + TEST_ASSERT_EQUALS(brightness8.value, brightness8_c.value); +} + +void ColorTest::testConvertion_8bit() +{ + RgbT rgb(124, 128, 10); + + HsvT hsv(rgb); + TEST_ASSERT_EQUALS(hsv.hue, 43); + TEST_ASSERT_EQUALS(hsv.saturation, 235); + TEST_ASSERT_EQUALS(hsv.value, 128); + + BrightnessT brightness(rgb); + TEST_ASSERT_EQUALS(brightness.value, 118); +} + +// TODO 16bit convertion not yet working +// see hsv_impl.hpp and rgb_impl.hpp +// void ColorTest::testConvertion_16bit() +// { +// RgbT rgb8(html::Orchid); +// HsvT hsv8(rgb8); +// HsvT hsv16(hsv8); + +// RgbT rgb16(rgb8); +// HsvT hsv16_b(rgb16); + +// // Test, if rgb->hsv conversion produces the same result for 8 and 16bits +// TEST_ASSERT_EQUALS(hsv16, hsv16_b); +// } + +void ColorTest::testRgbHsvPingPongConvertion_8bit() +{ + RgbT rgb8(html::Orchid); + HsvT hsv8(rgb8); + RgbT rgb8_b(hsv8); + + // Convertion can distort - allow some tolerance. + using namespace modm; + TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb8.red, rgb8_b.red, 1_pct)); + TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb8.green, rgb8_b.green, 1_pct)); + TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb8.blue, rgb8_b.blue, 1_pct)); +} + +// TODO 16bit convertion not yet working +// see hsv_impl.hpp and rgb_impl.hpp +// void ColorTest::testRgbHsvPingPongConvertion_16bit() +// { +// // Rgb->Hsv->Rgb, both 16 bit +// RgbT rgb16(html::Orchid); +// HsvT hsv16(rgb16); +// RgbT rgb16_b(hsv16); + +// // Convertion can distort - allow some tolerance. +// using namespace modm; +// TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb.red, rgb16_b.red, 1_pct)); +// TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb.green, rgb16_b.green, 1_pct)); +// TEST_ASSERT_TRUE(modm::Tolerance::isValueInTolerance(rgb.blue, rgb16_b.blue, 1_pct)); +// } \ No newline at end of file diff --git a/test/modm/ui/color/color_test.hpp b/test/modm/ui/color/color_test.hpp new file mode 100644 index 0000000000..bb9bb1cc0a --- /dev/null +++ b/test/modm/ui/color/color_test.hpp @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021, Thomas Sommer + * + * This file is part of the modm project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ +// ---------------------------------------------------------------------------- + +#ifndef COLOR_TEST_HPP +#define COLOR_TEST_HPP + +#include + +/// @ingroup modm_test_test_ui +class ColorTest : public unittest::TestSuite +{ +public: + void + testRgbCopyConstructors(); + + void + testHsvCopyConstructors(); + + void + testBrightnessCopyConstructors(); + + void + testConvertion_8bit(); + + // TODO 16bit convertion not yet working + // see hsv_impl.hpp and rgb_impl.hpp + // void + // testConvertion_16bit(); + + void + testRgbHsvPingPongConvertion_8bit(); + + // TODO 16bit convertion not yet working + // see hsv_impl.hpp and rgb_impl.hpp + // void + // testRgbHsvPingPongConvertion_16bit(); +}; + +#endif // COLOR_TEST_HPP diff --git a/test/modm/ui/module.lb b/test/modm/ui/module.lb index 064b4a83b7..ff88e35e1a 100644 --- a/test/modm/ui/module.lb +++ b/test/modm/ui/module.lb @@ -18,6 +18,8 @@ def init(module): def prepare(module, options): module.depends( "modm:ui:button", + "modm:ui:color", + "modm:math", "modm:ui:time") return True