Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion docs/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,8 @@ Here's an example JSON object to draw a red circle, a blue rectangle, and the te

AWTRIX 3 allows you to present text where specific fragments can be colorized. Use an array of fragments with `"t"` representing the text fragment and `"c"` denoting the color's hex value.

Each fragment may also carry an optional `"b"` (Integer, ms): when greater than `0` that fragment blinks at the given interval while the other fragments stay steady. This is the per-fragment counterpart to the app-wide `blinkText`; omitting it (or `0`) falls back to the app-wide `blinkText` value. A typical use is a blinking clock separator, e.g. `[{"t":"12"},{"t":":","b":500},{"t":"34"}]`.

```json
{
"text": [
Expand All @@ -287,7 +289,8 @@ AWTRIX 3 allows you to present text where specific fragments can be colorized. U
},
{
"t": "world!",
"c": "00FF00"
"c": "00FF00",
"b": 500
}
],
"repeat": 2
Expand Down
6 changes: 4 additions & 2 deletions src/Apps.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,8 @@ void ShowCustomApp(String name, FastLED_NeoMatrix *matrix, MatrixDisplayUiState
for (size_t i = 0; i < ca->fragments.size(); ++i)
{
String text = replacePlaceholders(ca->fragments[i]);
DisplayManager.setTextColor(TextEffect(ca->colors[i], ca->fade, ca->blink));
int fragBlink = (i < ca->blinks.size() && ca->blinks[i] > 0) ? ca->blinks[i] : ca->blink;
DisplayManager.setTextColor(TextEffect(ca->colors[i], ca->fade, fragBlink));
DisplayManager.printText(x + fragmentX, y + 6, text.c_str(), false, ca->textCase);
fragmentX += getTextWidth(text.c_str(), ca->textCase);
}
Expand Down Expand Up @@ -706,7 +707,8 @@ void ShowCustomApp(String name, FastLED_NeoMatrix *matrix, MatrixDisplayUiState
for (size_t i = 0; i < ca->fragments.size(); ++i)
{
String text = replacePlaceholders(ca->fragments[i]);
DisplayManager.setTextColor(TextEffect(ca->colors[i], ca->fade, ca->blink));
int fragBlink = (i < ca->blinks.size() && ca->blinks[i] > 0) ? ca->blinks[i] : ca->blink;
DisplayManager.setTextColor(TextEffect(ca->colors[i], ca->fade, fragBlink));
DisplayManager.printText(x + fragmentX, y + 6, text.c_str(), false, ca->textCase);
fragmentX += getTextWidth(text.c_str(), ca->textCase);
}
Expand Down
1 change: 1 addition & 0 deletions src/Apps.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ struct CustomApp
uint64_t lifetime;
std::vector<uint32_t> colors;
std::vector<String> fragments;
std::vector<int> blinks;
int textOffset;
int iconOffset;
int progress = -1;
Expand Down
9 changes: 7 additions & 2 deletions src/DisplayManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,10 +398,12 @@ void removeCustomAppFromApps(const String &name, bool setApps)
DisplayManager.setAppTime(TIME_PER_APP);
}

bool parseFragmentsText(const JsonArray &fragmentArray, std::vector<uint32_t> &colors, std::vector<String> &fragments, uint32_t standardColor)
bool parseFragmentsText(const JsonArray &fragmentArray, std::vector<uint32_t> &colors, std::vector<String> &fragments, uint32_t standardColor, std::vector<int> *blinks = nullptr)
{
colors.clear();
fragments.clear();
if (blinks)
blinks->clear();

for (JsonObject fragmentObj : fragmentArray)
{
Expand All @@ -419,6 +421,8 @@ bool parseFragmentsText(const JsonArray &fragmentArray, std::vector<uint32_t> &c

fragments.push_back(utf8ascii(textFragment));
colors.push_back(color);
if (blinks)
blinks->push_back(fragmentObj.containsKey("b") ? fragmentObj["b"].as<int>() : 0);
}
return true;
}
Expand Down Expand Up @@ -715,11 +719,12 @@ bool DisplayManager_::generateCustomPage(const String &name, JsonObject doc, boo

customApp.colors.clear();
customApp.fragments.clear();
customApp.blinks.clear();

if (doc.containsKey("text") && doc["text"].is<JsonArray>())
{
JsonArray textArray = doc["text"].as<JsonArray>();
parseFragmentsText(textArray, customApp.colors, customApp.fragments, customApp.color);
parseFragmentsText(textArray, customApp.colors, customApp.fragments, customApp.color, &customApp.blinks);
}
else if (doc.containsKey("text"))
{
Expand Down