From c8e2a44f369878a5d1bc7e51b159c2db57ec0bce Mon Sep 17 00:00:00 2001 From: "Andrew J.Swan" Date: Fri, 13 Dec 2024 21:51:50 +0200 Subject: [PATCH] 2024.12.3: Return of the `multicolor_text` --- README.md | 31 +++++++++++++- components/ehmtxv2/EHMTX.cpp | 67 ++++++++++++++++++++++++++++++ components/ehmtxv2/EHMTX.h | 2 +- components/ehmtxv2/EHMTX_queue.cpp | 7 ++++ components/ehmtxv2/__init__.py | 11 ++++- 5 files changed, 114 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 8a4d2bd..e15584f 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ external_components: - source: type: git url: https://github.com/lubeda/EspHoMaTriXv2 - ref: 2024.12.1 + ref: 2024.12.3 refresh: 60s components: [ ehmtxv2 ] ``` @@ -389,6 +389,35 @@ Example: **rainbow_shimmer** (optional, boolean): If true, enables color shimmer when displaying text in rainbow modes. +**multicolor_text** (optional, boolean): If true, enables text multi color support when displaying text. + +Example: +```Yaml +ehmtxv2: + id: rgb8x32 +... + multicolor_text: true +``` + +```Yaml +service: esphome.ulanzi_text_screen +data: + default_font: true + text: "Default Color Text #00FF00Green Color Text #FF0000Red Color Text #0000FFBlue Color Text #000000Default Color Text" + lifetime: 2 + screen_time: 10 + r: 255 + g: 255 + b: 255 +``` +Shows text in different colors, `Default Color Text` in the default color `#FFFFFF` (r: 255, g:255, b: 255), followed by `Green Color Text` in green `#00FF00`, then `Red Color Text` in red `#FF0000`, then `Blue Color Text` in blue `#0000FF` and finally `Default Color Text` in default color, due `#000000`. + +> [!WARNING] +> In this mode, with a large number of color changes, or with long lines, a short-term decrease in performance is possible. +> +> ```[13:26:02][W][component:237]: Component display took a long time for an operation (55 ms).``` +> ```[13:26:02][W][component:238]: Components should block for at most 30 ms.``` + **icons2html** (optional, boolean): If true, generate the HTML-file (*filename*.html) to show all included icons. (default = `false`) **iconscache** (optional, boolean): If true, it caches icons in the `.cache\icons` folder and if it finds the specified icons in the cache, it uses them instead of trying to download them again from the Internet. (default = `false`) diff --git a/components/ehmtxv2/EHMTX.cpp b/components/ehmtxv2/EHMTX.cpp index 5db19ee..7a4d2e6 100644 --- a/components/ehmtxv2/EHMTX.cpp +++ b/components/ehmtxv2/EHMTX.cpp @@ -2890,7 +2890,74 @@ namespace esphome void EHMTX::draw_text(std::string text, esphome::display::BaseFont *font, Color color, int xpos, int ypos) { + #ifdef EHMTXv2_MULTICOLOR_TEXT + std::size_t pos = text.find("#"); + if (pos == std::string::npos) + { this->display->print(xpos, ypos, font, color, esphome::display::TextAlign::BASELINE_LEFT, text.c_str()); + return; + } + + std::regex regex ("(#[A-Fa-f0-9]{6})|(.+?)"); + + std::regex_iterator next ( text.begin(), text.end(), regex ); + std::regex_iterator end; + + std::vector res; + + std::string iter = ""; + while (next != end) + { + std::string part = next->str(); + if (part.length() == 7) + { + if (iter.length() > 0) + { + res.push_back (iter); + iter = ""; + } + res.push_back (part); + } + else + { + iter += part; + } + next++; + } + if (iter.length() > 0) + { + res.push_back (iter); + } + + Color c = color; + int x = xpos; + std::regex is_color ("^#[A-Fa-f0-9]{6}$"); + for (int i = 0; i < res.size(); i++) + { + if (res.at(i).length() > 0) + { + int r, g, b; + if (res.at(i).length() == 7 && std::regex_match(res.at(i), is_color) && sscanf(&res.at(i).c_str()[1], "%02x%02x%02x", &r, &g, &b)) + { + if (r + g + b > 0) + { + c = Color(r, g ,b); + } + else + { + c = color; + } + } + else + { + this->display->print(x, ypos, font, c, esphome::display::TextAlign::BASELINE_LEFT, res.at(i).c_str()); + x += this->GetTextWidth(font, "%s", res.at(i).c_str()); + } + } + } + #else + this->display->print(xpos, ypos, font, color, esphome::display::TextAlign::BASELINE_LEFT, text.c_str()); + #endif } #ifdef EHMTXv2_RAINBOW_SHIMMER diff --git a/components/ehmtxv2/EHMTX.h b/components/ehmtxv2/EHMTX.h index 7b513a9..0bcc3db 100644 --- a/components/ehmtxv2/EHMTX.h +++ b/components/ehmtxv2/EHMTX.h @@ -35,7 +35,7 @@ const uint8_t TEXTSCROLLSTART = 8; const uint8_t TEXTSTARTOFFSET = (32 - 8); const uint16_t POLLINGINTERVAL = 250; -static const char *const EHMTX_VERSION = "2024.12.1"; +static const char *const EHMTX_VERSION = "2024.12.3"; static const char *const TAG = "EHMTXv2"; enum show_mode : uint8_t diff --git a/components/ehmtxv2/EHMTX_queue.cpp b/components/ehmtxv2/EHMTX_queue.cpp index d47f6f0..d8f4a6e 100644 --- a/components/ehmtxv2/EHMTX_queue.cpp +++ b/components/ehmtxv2/EHMTX_queue.cpp @@ -1,4 +1,7 @@ #include "esphome.h" +#ifdef EHMTXv2_MULTICOLOR_TEXT +#include +#endif namespace esphome { @@ -1229,6 +1232,10 @@ namespace esphome uint16_t max_steps = 0; std::string text_ = text; +#ifdef EHMTXv2_MULTICOLOR_TEXT + std::regex color_re("(#[A-Fa-f0-9]{6})"); + text_ = std::regex_replace(text, color_re, ""); +#endif if (this->default_font) { diff --git a/components/ehmtxv2/__init__.py b/components/ehmtxv2/__init__.py index 798f2d9..b98c11d 100644 --- a/components/ehmtxv2/__init__.py +++ b/components/ehmtxv2/__init__.py @@ -19,7 +19,7 @@ _LOGGER = logging.getLogger(__name__) DEPENDENCIES = ["display", "light", "api"] -AUTO_LOAD = ["ehmtxv2","json","image"] +AUTO_LOAD = ["ehmtxv2", "json", "image", "animation"] IMAGE_TYPE_RGB565 = 4 MAXFRAMES = 110 MAXICONS = 120 @@ -109,6 +109,7 @@ def rgb565_888(v565): CONF_BLENDSTEPS = "blend_steps" CONF_RAINBOWINTERVAL = "rainbow_interval" CONF_RAINBOWSHIMMER = "rainbow_shimmer" +CONF_MULTICOLOR_TEXT = "multicolor_text" CONF_FRAMEINTERVAL = "frame_interval" CONF_DEFAULT_FONT_ID = "default_font_id" CONF_DEFAULT_FONT = "default_font" @@ -241,6 +242,8 @@ def rgb565_888(v565): ): cv.templatable(cv.positive_int), cv.Optional(CONF_RAINBOWSHIMMER, default=False ): cv.boolean, + cv.Optional(CONF_MULTICOLOR_TEXT, default=False + ): cv.boolean, cv.Optional(CONF_SCROLLCOUNT, default="2" ): cv.templatable(cv.positive_int), cv.Optional( @@ -325,7 +328,7 @@ def rgb565_888(v565): cv.Length(max=MAXICONS), )}) -CONFIG_SCHEMA = cv.All( EHMTX_SCHEMA) +CONFIG_SCHEMA = cv.All(EHMTX_SCHEMA) CODEOWNERS = ["@lubeda"] @@ -613,6 +616,10 @@ def thumbnails(frames): cg.add_define("EHMTXv2_RAINBOW_SHIMMER") logging.info(f"[X] Rainbow shimmer") + if config[CONF_MULTICOLOR_TEXT]: + cg.add_define("EHMTXv2_MULTICOLOR_TEXT") + logging.info(f"[X] Multi color text") + if config[CONF_SCROLL_SMALL_TEXT]: cg.add_define("EHMTXv2_SCROLL_SMALL_TEXT")