v0.35
- moves transistion time and app time setting into onscreen-menu - Text starts to scroll on the left side instead from right - allows to switch to a page by name via mqtt - custompages doesnt need to have integers as an id anymore, you can also use strings now. closes #7 closes #4
This commit is contained in:
52
.vscode/settings.json
vendored
Normal file
52
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"files.associations": {
|
||||||
|
"array": "cpp",
|
||||||
|
"atomic": "cpp",
|
||||||
|
"*.tcc": "cpp",
|
||||||
|
"cctype": "cpp",
|
||||||
|
"clocale": "cpp",
|
||||||
|
"cmath": "cpp",
|
||||||
|
"cstdarg": "cpp",
|
||||||
|
"cstddef": "cpp",
|
||||||
|
"cstdint": "cpp",
|
||||||
|
"cstdio": "cpp",
|
||||||
|
"cstdlib": "cpp",
|
||||||
|
"cstring": "cpp",
|
||||||
|
"ctime": "cpp",
|
||||||
|
"cwchar": "cpp",
|
||||||
|
"cwctype": "cpp",
|
||||||
|
"deque": "cpp",
|
||||||
|
"unordered_map": "cpp",
|
||||||
|
"unordered_set": "cpp",
|
||||||
|
"vector": "cpp",
|
||||||
|
"exception": "cpp",
|
||||||
|
"algorithm": "cpp",
|
||||||
|
"functional": "cpp",
|
||||||
|
"iterator": "cpp",
|
||||||
|
"map": "cpp",
|
||||||
|
"memory": "cpp",
|
||||||
|
"memory_resource": "cpp",
|
||||||
|
"numeric": "cpp",
|
||||||
|
"optional": "cpp",
|
||||||
|
"random": "cpp",
|
||||||
|
"string": "cpp",
|
||||||
|
"string_view": "cpp",
|
||||||
|
"system_error": "cpp",
|
||||||
|
"tuple": "cpp",
|
||||||
|
"type_traits": "cpp",
|
||||||
|
"utility": "cpp",
|
||||||
|
"fstream": "cpp",
|
||||||
|
"initializer_list": "cpp",
|
||||||
|
"iomanip": "cpp",
|
||||||
|
"iosfwd": "cpp",
|
||||||
|
"istream": "cpp",
|
||||||
|
"limits": "cpp",
|
||||||
|
"new": "cpp",
|
||||||
|
"ostream": "cpp",
|
||||||
|
"sstream": "cpp",
|
||||||
|
"stdexcept": "cpp",
|
||||||
|
"streambuf": "cpp",
|
||||||
|
"cinttypes": "cpp",
|
||||||
|
"typeinfo": "cpp"
|
||||||
|
}
|
||||||
|
}
|
||||||
Binary file not shown.
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "AWTRIX Light",
|
"name": "AWTRIX Light",
|
||||||
"version": "0.33",
|
"version": "0.35",
|
||||||
"home_assistant_domain": "AwtrixLight",
|
"home_assistant_domain": "AwtrixLight",
|
||||||
"funding_url": "https://blueforcer.de",
|
"funding_url": "https://blueforcer.de",
|
||||||
"new_install_prompt_erase": true,
|
"new_install_prompt_erase": true,
|
||||||
|
|||||||
@@ -4,8 +4,8 @@
|
|||||||
* Copyright (c) 2016 by Daniel Eichhorn
|
* Copyright (c) 2016 by Daniel Eichhorn
|
||||||
* Copyright (c) 2016 by Fabrice Weinberg
|
* Copyright (c) 2016 by Fabrice Weinberg
|
||||||
* Copyright (c) 2023 by Stephan Muehl (Blueforcer)
|
* Copyright (c) 2023 by Stephan Muehl (Blueforcer)
|
||||||
* Note: This old lib for SSD1306 displays has been extremly
|
* Note: This old lib for SSD1306 displays has been extremly
|
||||||
* modified for AWTRIX Light and has nothing to do with the original purposes.
|
* modified for AWTRIX Light and has nothing to do with the original purposes.
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
@@ -89,7 +89,7 @@ void MatrixDisplayUi::setAppAnimation(AnimationDirection dir)
|
|||||||
this->frameAnimationDirection = dir;
|
this->frameAnimationDirection = dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MatrixDisplayUi::setApps(const std::vector<std::pair<uint16_t, AppCallback>> &appPairs)
|
void MatrixDisplayUi::setApps(const std::vector<std::pair<String, AppCallback>> &appPairs)
|
||||||
{
|
{
|
||||||
delete[] AppFunctions;
|
delete[] AppFunctions;
|
||||||
AppCount = appPairs.size();
|
AppCount = appPairs.size();
|
||||||
@@ -262,8 +262,9 @@ void MatrixDisplayUi::drawApp()
|
|||||||
y *= dir;
|
y *= dir;
|
||||||
x1 *= dir;
|
x1 *= dir;
|
||||||
y1 *= dir;
|
y1 *= dir;
|
||||||
bool FirstFrame = progress < 0.1;
|
Serial.println(progress);
|
||||||
bool LastFrame = progress > 0.9;
|
bool FirstFrame = progress < 0.2;
|
||||||
|
bool LastFrame = progress > 0.8;
|
||||||
this->matrix->drawRect(x, y, x1, y1, matrix->Color(0, 0, 0));
|
this->matrix->drawRect(x, y, x1, y1, matrix->Color(0, 0, 0));
|
||||||
(this->AppFunctions[this->state.currentFrame])(this->matrix, &this->state, x, y, FirstFrame, LastFrame);
|
(this->AppFunctions[this->state.currentFrame])(this->matrix, &this->state, x, y, FirstFrame, LastFrame);
|
||||||
(this->AppFunctions[this->getnextAppNumber()])(this->matrix, &this->state, x1, y1, FirstFrame, LastFrame);
|
(this->AppFunctions[this->getnextAppNumber()])(this->matrix, &this->state, x1, y1, FirstFrame, LastFrame);
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ public:
|
|||||||
/**
|
/**
|
||||||
* Add frame drawing functions
|
* Add frame drawing functions
|
||||||
*/
|
*/
|
||||||
void setApps(const std::vector<std::pair<uint16_t, AppCallback>> &appPairs);
|
void setApps(const std::vector<std::pair<String, AppCallback>> &appPairs);
|
||||||
|
|
||||||
// Overlay
|
// Overlay
|
||||||
|
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ void DisplayManager_::drawJPG(uint16_t x, uint16_t y, fs::File jpgFile)
|
|||||||
void DisplayManager_::setSettings()
|
void DisplayManager_::setSettings()
|
||||||
{
|
{
|
||||||
ui.setTargetFPS(MATRIX_FPS);
|
ui.setTargetFPS(MATRIX_FPS);
|
||||||
ui.setTimePerApp(TIME_PER_FRAME);
|
ui.setTimePerApp(TIME_PER_APP);
|
||||||
ui.setTimePerTransition(TIME_PER_TRANSITION);
|
ui.setTimePerTransition(TIME_PER_TRANSITION);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,11 +128,11 @@ bool jpg_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t *bitmap)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayManager_::printText(int16_t x, int16_t y, const char *text, bool centered)
|
void DisplayManager_::printText(int16_t x, int16_t y, const char *text, bool centered, bool ignoreUppercase)
|
||||||
{
|
{
|
||||||
if (centered)
|
if (centered)
|
||||||
{
|
{
|
||||||
uint16_t textWidth = getTextWidth(text);
|
uint16_t textWidth = getTextWidth(text, ignoreUppercase);
|
||||||
int16_t textX = ((32 - textWidth) / 2);
|
int16_t textX = ((32 - textWidth) / 2);
|
||||||
matrix.setCursor(textX, y);
|
matrix.setCursor(textX, y);
|
||||||
}
|
}
|
||||||
@@ -141,7 +141,7 @@ void DisplayManager_::printText(int16_t x, int16_t y, const char *text, bool cen
|
|||||||
matrix.setCursor(x, y);
|
matrix.setCursor(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (UPPERCASE_LETTERS)
|
if (UPPERCASE_LETTERS && !ignoreUppercase)
|
||||||
{
|
{
|
||||||
size_t length = strlen(text);
|
size_t length = strlen(text);
|
||||||
char upperText[length + 1]; // +1 for the null terminator
|
char upperText[length + 1]; // +1 for the null terminator
|
||||||
@@ -184,64 +184,37 @@ void DisplayManager_::HSVtext(int16_t x, int16_t y, const char *text, bool clear
|
|||||||
}
|
}
|
||||||
char temp_str[2] = {'\0', '\0'};
|
char temp_str[2] = {'\0', '\0'};
|
||||||
temp_str[0] = text[i];
|
temp_str[0] = text[i];
|
||||||
xpos += getTextWidth(temp_str);
|
xpos += getTextWidth(temp_str, false);
|
||||||
}
|
}
|
||||||
hueOffset++;
|
hueOffset++;
|
||||||
if (clear)
|
if (clear)
|
||||||
matrix.show();
|
matrix.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
void pushCustomFrame(uint16_t id)
|
void pushCustomFrame(String name)
|
||||||
{
|
{
|
||||||
if (customFrames.count(id) == 0)
|
|
||||||
|
if (customFrames.count(name) == 0)
|
||||||
{
|
{
|
||||||
uint16_t newID = nativeAppsCount + id;
|
++customPagesCount;
|
||||||
switch (id)
|
void (*customFrames[10])(FastLED_NeoMatrix *, MatrixDisplayUiState *, int16_t, int16_t, bool, bool) = {CFrame1, CFrame2, CFrame3, CFrame4, CFrame5, CFrame6, CFrame7, CFrame8, CFrame9, CFrame10};
|
||||||
|
if (customFrames[customPagesCount] != NULL)
|
||||||
{
|
{
|
||||||
case 1:
|
Apps.push_back(std::make_pair(name, customFrames[customPagesCount]));
|
||||||
Apps.push_back(std::make_pair(newID, CFrame1));
|
ui.setApps(Apps); // Add frames
|
||||||
break;
|
}
|
||||||
case 2:
|
else
|
||||||
Apps.push_back(std::make_pair(newID, CFrame2));
|
{
|
||||||
break;
|
++customPagesCount;
|
||||||
case 3:
|
|
||||||
Apps.push_back(std::make_pair(newID, CFrame3));
|
|
||||||
break;
|
|
||||||
case 4:
|
|
||||||
Apps.push_back(std::make_pair(newID, CFrame4));
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
Apps.push_back(std::make_pair(newID, CFrame5));
|
|
||||||
break;
|
|
||||||
case 6:
|
|
||||||
Apps.push_back(std::make_pair(newID, CFrame6));
|
|
||||||
break;
|
|
||||||
case 7:
|
|
||||||
Apps.push_back(std::make_pair(newID, CFrame7));
|
|
||||||
break;
|
|
||||||
case 8:
|
|
||||||
Apps.push_back(std::make_pair(newID, CFrame8));
|
|
||||||
break;
|
|
||||||
case 9:
|
|
||||||
Apps.push_back(std::make_pair(newID, CFrame9));
|
|
||||||
break;
|
|
||||||
case 10:
|
|
||||||
Apps.push_back(std::make_pair(newID, CFrame10));
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
ui.setApps(Apps); // Add frames
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void removeCustomFrame(uint16_t id)
|
void removeCustomFrame(const String &name)
|
||||||
{
|
{
|
||||||
id += nativeAppsCount;
|
// Suchen Sie nach dem Element, das dem Namen entspricht
|
||||||
// Suchen Sie nach dem Element, das der ID entspricht
|
auto it = std::find_if(Apps.begin(), Apps.end(), [&name](const std::pair<String, AppCallback> &appPair)
|
||||||
auto it = std::find_if(Apps.begin(), Apps.end(), [id](const std::pair<uint16_t, AppCallback> &appPair)
|
{ return appPair.first == name; });
|
||||||
{ return appPair.first == id; });
|
|
||||||
|
|
||||||
// Wenn das Element gefunden wurde, entfernen Sie es aus dem Vektor
|
// Wenn das Element gefunden wurde, entfernen Sie es aus dem Vektor
|
||||||
if (it != Apps.end())
|
if (it != Apps.end())
|
||||||
@@ -251,13 +224,13 @@ void removeCustomFrame(uint16_t id)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayManager_::generateCustomPage(uint16_t id, String payload)
|
void DisplayManager_::generateCustomPage(String name, String payload)
|
||||||
{
|
{
|
||||||
|
|
||||||
if (payload == "" && customFrames.count(id))
|
if (payload == "" && customFrames.count(name))
|
||||||
{
|
{
|
||||||
customFrames.erase(customFrames.find(id));
|
customFrames.erase(customFrames.find(name));
|
||||||
removeCustomFrame(id);
|
removeCustomFrame(name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,21 +241,6 @@ void DisplayManager_::generateCustomPage(uint16_t id, String payload)
|
|||||||
|
|
||||||
CustomFrame customFrame;
|
CustomFrame customFrame;
|
||||||
|
|
||||||
if (id == 0)
|
|
||||||
{
|
|
||||||
if (doc.containsKey("id"))
|
|
||||||
{
|
|
||||||
customFrame.id = doc["id"].as<uint8_t>();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (id > 10)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (doc.containsKey("sound"))
|
if (doc.containsKey("sound"))
|
||||||
{
|
{
|
||||||
customFrame.sound = ("/" + doc["sound"].as<String>() + ".txt");
|
customFrame.sound = ("/" + doc["sound"].as<String>() + ".txt");
|
||||||
@@ -292,27 +250,18 @@ void DisplayManager_::generateCustomPage(uint16_t id, String payload)
|
|||||||
customFrame.sound = "";
|
customFrame.sound = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc.containsKey("name"))
|
|
||||||
{
|
|
||||||
customFrame.name = doc["name"].as<String>();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
customFrame.name = "Custom " + String(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
customFrame.rainbow = doc.containsKey("rainbow") ? doc["rainbow"] : false;
|
customFrame.rainbow = doc.containsKey("rainbow") ? doc["rainbow"] : false;
|
||||||
customFrame.pushIcon = doc.containsKey("pushIcon") ? doc["pushIcon"] : 0;
|
customFrame.pushIcon = doc.containsKey("pushIcon") ? doc["pushIcon"] : 0;
|
||||||
customFrame.id = id;
|
customFrame.name = name;
|
||||||
customFrame.text = utf8ascii(doc["text"].as<String>());
|
customFrame.text = utf8ascii(doc["text"].as<String>());
|
||||||
|
|
||||||
customFrame.color = doc.containsKey("color") ? doc["color"].is<String>() ? hexToRgb565(doc["color"]) : doc["color"].is<JsonArray>() ? hexToRgb565(doc["color"].as<String>())
|
customFrame.color = doc.containsKey("color") ? doc["color"].is<String>() ? hexToRgb565(doc["color"]) : doc["color"].is<JsonArray>() ? hexToRgb565(doc["color"].as<String>())
|
||||||
: TEXTCOLOR_565
|
: TEXTCOLOR_565
|
||||||
: TEXTCOLOR_565;
|
: TEXTCOLOR_565;
|
||||||
|
|
||||||
if (currentCustomFrame != id)
|
if (currentCustomFrame != name)
|
||||||
{
|
{
|
||||||
customFrame.scrollposition = 34;
|
customFrame.scrollposition = 9;
|
||||||
}
|
}
|
||||||
|
|
||||||
customFrame.repeat = doc.containsKey("repeat") ? doc["repeat"].as<uint8_t>() : -1;
|
customFrame.repeat = doc.containsKey("repeat") ? doc["repeat"].as<uint8_t>() : -1;
|
||||||
@@ -333,8 +282,8 @@ void DisplayManager_::generateCustomPage(uint16_t id, String payload)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pushCustomFrame(id);
|
pushCustomFrame(name);
|
||||||
customFrames[id] = customFrame;
|
customFrames[name] = customFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
void DisplayManager_::generateNotification(String payload)
|
void DisplayManager_::generateNotification(String payload)
|
||||||
@@ -342,7 +291,7 @@ void DisplayManager_::generateNotification(String payload)
|
|||||||
StaticJsonDocument<1024> doc;
|
StaticJsonDocument<1024> doc;
|
||||||
deserializeJson(doc, payload);
|
deserializeJson(doc, payload);
|
||||||
|
|
||||||
notify.duration = doc.containsKey("duration") ? doc["duration"].as<int>() * 1000 : TIME_PER_FRAME;
|
notify.duration = doc.containsKey("duration") ? doc["duration"].as<int>() * 1000 : TIME_PER_APP;
|
||||||
notify.text = utf8ascii(doc["text"].as<String>());
|
notify.text = utf8ascii(doc["text"].as<String>());
|
||||||
notify.repeat = doc.containsKey("repeat") ? doc["repeat"].as<uint16_t>() : -1;
|
notify.repeat = doc.containsKey("repeat") ? doc["repeat"].as<uint16_t>() : -1;
|
||||||
notify.rainbow = doc.containsKey("rainbow") ? doc["rainbow"].as<bool>() : false;
|
notify.rainbow = doc.containsKey("rainbow") ? doc["rainbow"].as<bool>() : false;
|
||||||
@@ -350,7 +299,7 @@ void DisplayManager_::generateNotification(String payload)
|
|||||||
notify.pushIcon = doc.containsKey("pushIcon") ? doc["pushIcon"] : 0;
|
notify.pushIcon = doc.containsKey("pushIcon") ? doc["pushIcon"] : 0;
|
||||||
notify.flag = true;
|
notify.flag = true;
|
||||||
notify.startime = millis();
|
notify.startime = millis();
|
||||||
notify.scrollposition = 34;
|
notify.scrollposition = 9;
|
||||||
notify.iconWasPushed = false;
|
notify.iconWasPushed = false;
|
||||||
notify.iconPosition = 0;
|
notify.iconPosition = 0;
|
||||||
|
|
||||||
@@ -387,15 +336,15 @@ void DisplayManager_::generateNotification(String payload)
|
|||||||
void DisplayManager_::loadApps()
|
void DisplayManager_::loadApps()
|
||||||
{
|
{
|
||||||
Apps.clear();
|
Apps.clear();
|
||||||
Apps.push_back(std::make_pair(0, TimeFrame));
|
Apps.push_back(std::make_pair("time", TimeFrame));
|
||||||
if (SHOW_DATE)
|
if (SHOW_DATE)
|
||||||
Apps.push_back(std::make_pair(1, DateFrame));
|
Apps.push_back(std::make_pair("date", DateFrame));
|
||||||
if (SHOW_TEMP)
|
if (SHOW_TEMP)
|
||||||
Apps.push_back(std::make_pair(2, TempFrame));
|
Apps.push_back(std::make_pair("temp", TempFrame));
|
||||||
if (SHOW_HUM)
|
if (SHOW_HUM)
|
||||||
Apps.push_back(std::make_pair(3, HumFrame));
|
Apps.push_back(std::make_pair("hum", HumFrame));
|
||||||
if (SHOW_BATTERY)
|
if (SHOW_BATTERY)
|
||||||
Apps.push_back(std::make_pair(4, BatFrame));
|
Apps.push_back(std::make_pair("bat", BatFrame));
|
||||||
// if (SHOW_WEATHER)
|
// if (SHOW_WEATHER)
|
||||||
// Apps.push_back(std::make_pair(5, WeatherFrame));
|
// Apps.push_back(std::make_pair(5, WeatherFrame));
|
||||||
nativeAppsCount = Apps.size();
|
nativeAppsCount = Apps.size();
|
||||||
@@ -531,3 +480,16 @@ void DisplayManager_::gererateTimer(String Payload)
|
|||||||
int interval = difftime(futureTime, now) * 1000;
|
int interval = difftime(futureTime, now) * 1000;
|
||||||
TimerTicker.attach_ms(interval, timerCallback);
|
TimerTicker.attach_ms(interval, timerCallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DisplayManager_::switchToApp(String Payload)
|
||||||
|
{
|
||||||
|
DynamicJsonDocument doc(512);
|
||||||
|
DeserializationError error = deserializeJson(doc, Payload);
|
||||||
|
if (error)
|
||||||
|
return;
|
||||||
|
String name = doc["name"].as<String>();
|
||||||
|
bool fast = doc["fast"] | false;
|
||||||
|
int index = findAppIndexByName(name);
|
||||||
|
if (index > -1)
|
||||||
|
ui.transitionToApp(index);
|
||||||
|
}
|
||||||
@@ -44,9 +44,10 @@ public:
|
|||||||
void setFPS(uint8_t);
|
void setFPS(uint8_t);
|
||||||
void MatrixState(bool);
|
void MatrixState(bool);
|
||||||
void generateNotification(String);
|
void generateNotification(String);
|
||||||
void generateCustomPage(uint16_t, String);
|
void generateCustomPage(String, String);
|
||||||
void printText(int16_t x, int16_t y, const char *text, bool centered);
|
void printText(int16_t x, int16_t y, const char *text, bool centered, bool ignoreUppercase);
|
||||||
bool setAutoTransition(bool active);
|
bool setAutoTransition(bool active);
|
||||||
|
void switchToApp(String Payload);
|
||||||
void drawGIF(uint16_t x, uint16_t y, fs::File gifFile);
|
void drawGIF(uint16_t x, uint16_t y, fs::File gifFile);
|
||||||
void drawJPG(uint16_t x, uint16_t y, fs::File jpgFile);
|
void drawJPG(uint16_t x, uint16_t y, fs::File jpgFile);
|
||||||
};
|
};
|
||||||
|
|||||||
219
src/Frames.h
219
src/Frames.h
@@ -20,6 +20,7 @@ Ticker downloader;
|
|||||||
|
|
||||||
tm timeInfo;
|
tm timeInfo;
|
||||||
uint16_t nativeAppsCount;
|
uint16_t nativeAppsCount;
|
||||||
|
uint16_t customPagesCount;
|
||||||
|
|
||||||
int WEATHER_CODE;
|
int WEATHER_CODE;
|
||||||
String WEATHER_TEMP;
|
String WEATHER_TEMP;
|
||||||
@@ -27,8 +28,8 @@ String WEATHER_HUM;
|
|||||||
|
|
||||||
struct CustomFrame
|
struct CustomFrame
|
||||||
{
|
{
|
||||||
uint8_t id;
|
int16_t scrollposition = 0;
|
||||||
int16_t scrollposition = 34;
|
int16_t scrollDelay = 0;
|
||||||
String text;
|
String text;
|
||||||
uint16_t color;
|
uint16_t color;
|
||||||
File icon;
|
File icon;
|
||||||
@@ -44,13 +45,13 @@ struct CustomFrame
|
|||||||
bool iconWasPushed = false;
|
bool iconWasPushed = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t currentCustomFrame;
|
String currentCustomFrame;
|
||||||
std::map<uint8_t, CustomFrame> customFrames;
|
std::map<String, CustomFrame> customFrames;
|
||||||
|
|
||||||
struct Notification
|
struct Notification
|
||||||
{
|
{
|
||||||
uint8_t id;
|
|
||||||
int16_t scrollposition = 34;
|
int16_t scrollposition = 34;
|
||||||
|
int16_t scrollDelay = 0;
|
||||||
String text;
|
String text;
|
||||||
uint16_t color;
|
uint16_t color;
|
||||||
File icon;
|
File icon;
|
||||||
@@ -68,9 +69,35 @@ struct Notification
|
|||||||
|
|
||||||
Notification notify;
|
Notification notify;
|
||||||
|
|
||||||
CustomFrame *getCustomFrameById(uint8_t id)
|
std::vector<std::pair<String, AppCallback>> Apps;
|
||||||
|
|
||||||
|
CustomFrame *getCustomFrameById(String name)
|
||||||
{
|
{
|
||||||
return customFrames.count(id) ? &customFrames[id] : nullptr;
|
return customFrames.count(name) ? &customFrames[name] : nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getFrameNameByFunction(AppCallback frameFunction)
|
||||||
|
{
|
||||||
|
for (const auto &appPair : Apps)
|
||||||
|
{
|
||||||
|
if (appPair.second == frameFunction)
|
||||||
|
{
|
||||||
|
return appPair.first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ""; // Gibt einen leeren String zurück, wenn die Frame-Funktion nicht gefunden wurde
|
||||||
|
}
|
||||||
|
|
||||||
|
int findAppIndexByName(const String &name)
|
||||||
|
{
|
||||||
|
auto it = std::find_if(Apps.begin(), Apps.end(), [&name](const std::pair<String, AppCallback> &appPair)
|
||||||
|
{ return appPair.first == name; });
|
||||||
|
if (it != Apps.end())
|
||||||
|
{
|
||||||
|
return std::distance(Apps.begin(), it);
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TimeFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
void TimeFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||||
@@ -181,7 +208,7 @@ void MenuFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
|||||||
if (!MenuManager.inMenu)
|
if (!MenuManager.inMenu)
|
||||||
return;
|
return;
|
||||||
matrix->fillScreen(0);
|
matrix->fillScreen(0);
|
||||||
DisplayManager.printText(0, 6, MenuManager.menutext().c_str(), true);
|
DisplayManager.printText(0, 6, MenuManager.menutext().c_str(), true, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AlarmFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
void AlarmFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
||||||
@@ -191,7 +218,7 @@ void AlarmFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
|||||||
{
|
{
|
||||||
matrix->fillScreen(matrix->Color(255, 0, 0));
|
matrix->fillScreen(matrix->Color(255, 0, 0));
|
||||||
CURRENT_APP = "Alarm";
|
CURRENT_APP = "Alarm";
|
||||||
uint16_t textWidth = getTextWidth("ALARM");
|
uint16_t textWidth = getTextWidth("ALARM",false);
|
||||||
int16_t textX = ((32 - textWidth) / 2);
|
int16_t textX = ((32 - textWidth) / 2);
|
||||||
matrix->setTextColor(0);
|
matrix->setTextColor(0);
|
||||||
matrix->setCursor(textX, 6);
|
matrix->setCursor(textX, 6);
|
||||||
@@ -211,7 +238,7 @@ void TimerFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
|||||||
matrix->fillScreen(matrix->Color(0, 255, 0));
|
matrix->fillScreen(matrix->Color(0, 255, 0));
|
||||||
CURRENT_APP = "Timer";
|
CURRENT_APP = "Timer";
|
||||||
String menuText = "TIMER";
|
String menuText = "TIMER";
|
||||||
uint16_t textWidth = getTextWidth(menuText.c_str());
|
uint16_t textWidth = getTextWidth(menuText.c_str(),false);
|
||||||
int16_t textX = ((32 - textWidth) / 2);
|
int16_t textX = ((32 - textWidth) / 2);
|
||||||
matrix->setTextColor(0);
|
matrix->setTextColor(0);
|
||||||
matrix->setCursor(textX, 6);
|
matrix->setCursor(textX, 6);
|
||||||
@@ -224,7 +251,7 @@ void TimerFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowCustomFrame(uint8_t id, FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
void ShowCustomFrame(String name, FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||||
{
|
{
|
||||||
// Abort if notify.flag is set
|
// Abort if notify.flag is set
|
||||||
if (notify.flag)
|
if (notify.flag)
|
||||||
@@ -233,7 +260,7 @@ void ShowCustomFrame(uint8_t id, FastLED_NeoMatrix *matrix, MatrixDisplayUiState
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get custom frame by ID
|
// Get custom frame by ID
|
||||||
CustomFrame *cf = getCustomFrameById(id);
|
CustomFrame *cf = getCustomFrameById(name);
|
||||||
|
|
||||||
// Abort if custom frame not found
|
// Abort if custom frame not found
|
||||||
if (cf == nullptr)
|
if (cf == nullptr)
|
||||||
@@ -241,26 +268,24 @@ void ShowCustomFrame(uint8_t id, FastLED_NeoMatrix *matrix, MatrixDisplayUiState
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize custom frame properties if first frame
|
// reset custom frame properties if last frame
|
||||||
if (lastFrame)
|
if (lastFrame)
|
||||||
{
|
{
|
||||||
cf->iconWasPushed = false;
|
cf->iconWasPushed = false;
|
||||||
cf->scrollposition = 34;
|
cf->scrollposition = 9;
|
||||||
cf->iconPosition = 0;
|
cf->iconPosition = 0;
|
||||||
|
cf->scrollDelay = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update current app and custom frame IDs
|
|
||||||
CURRENT_APP = cf->name;
|
CURRENT_APP = cf->name;
|
||||||
currentCustomFrame = id;
|
currentCustomFrame = name;
|
||||||
|
|
||||||
// Check if there is an icon
|
|
||||||
bool hasIcon = cf->icon;
|
bool hasIcon = cf->icon;
|
||||||
|
|
||||||
// Calculate available display width based on icon
|
|
||||||
uint16_t availableWidth = (hasIcon) ? 24 : 32;
|
uint16_t availableWidth = (hasIcon) ? 24 : 32;
|
||||||
|
|
||||||
// Disable auto transition if text is repeating and too wide
|
bool noScrolling = getTextWidth(cf->text.c_str(),false) <= availableWidth;
|
||||||
if ((cf->repeat > 0) && (getTextWidth(cf->text.c_str()) > availableWidth) && (state->frameState == FIXED))
|
|
||||||
|
if ((cf->repeat > 0) && (getTextWidth(cf->text.c_str(),false) > availableWidth) && (state->frameState == FIXED))
|
||||||
{
|
{
|
||||||
DisplayManager.setAutoTransition(false);
|
DisplayManager.setAutoTransition(false);
|
||||||
}
|
}
|
||||||
@@ -269,21 +294,16 @@ void ShowCustomFrame(uint8_t id, FastLED_NeoMatrix *matrix, MatrixDisplayUiState
|
|||||||
DisplayManager.setAutoTransition(true);
|
DisplayManager.setAutoTransition(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if text is wider than available display width and frame is not in transition
|
if (getTextWidth(cf->text.c_str(),false) > availableWidth && !(state->frameState == IN_TRANSITION))
|
||||||
if (getTextWidth(cf->text.c_str()) > availableWidth && !(state->frameState == IN_TRANSITION))
|
|
||||||
{
|
{
|
||||||
// Reset scroll position when text has finished scrolling all the way to the left
|
if (cf->scrollposition <= -getTextWidth(cf->text.c_str(),false))
|
||||||
if (cf->scrollposition <= -getTextWidth(cf->text.c_str()))
|
|
||||||
{
|
{
|
||||||
cf->scrollposition = 38;
|
cf->scrollDelay = 0;
|
||||||
|
cf->scrollposition = 9;
|
||||||
// Set iconWasPushed to false if icon has been pushed
|
|
||||||
if (cf->iconWasPushed && cf->pushIcon == 2)
|
if (cf->iconWasPushed && cf->pushIcon == 2)
|
||||||
{
|
{
|
||||||
cf->iconWasPushed = false;
|
cf->iconWasPushed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Transition to next app if frame is repeating and repeat limit has been reached
|
|
||||||
if ((cf->currentRepeat + 1 >= cf->repeat) && (cf->repeat > 0))
|
if ((cf->currentRepeat + 1 >= cf->repeat) && (cf->repeat > 0))
|
||||||
{
|
{
|
||||||
DisplayManager.setAutoTransition(true);
|
DisplayManager.setAutoTransition(true);
|
||||||
@@ -296,24 +316,39 @@ void ShowCustomFrame(uint8_t id, FastLED_NeoMatrix *matrix, MatrixDisplayUiState
|
|||||||
++cf->currentRepeat;
|
++cf->currentRepeat;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update scroll position
|
|
||||||
--cf->scrollposition;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate horizontal text alignment
|
if (!noScrolling)
|
||||||
int16_t textX = (hasIcon) ? ((24 - getTextWidth(cf->text.c_str())) / 2) + 9 : ((32 - getTextWidth(cf->text.c_str())) / 2);
|
{
|
||||||
|
if ((cf->scrollDelay > MATRIX_FPS * 1.2))
|
||||||
// Set text color
|
{
|
||||||
|
--cf->scrollposition;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++cf->scrollDelay;
|
||||||
|
if (hasIcon)
|
||||||
|
{
|
||||||
|
if (cf->iconWasPushed && cf->pushIcon == 1)
|
||||||
|
{
|
||||||
|
cf->scrollposition = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cf->scrollposition = 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cf->scrollposition = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int16_t textX = (hasIcon) ? ((24 - getTextWidth(cf->text.c_str(),false)) / 2) + 9 : ((32 - getTextWidth(cf->text.c_str(),false)) / 2);
|
||||||
matrix->setTextColor(cf->color);
|
matrix->setTextColor(cf->color);
|
||||||
|
|
||||||
// Check if text is scrolling or not
|
|
||||||
bool noScrolling = getTextWidth(cf->text.c_str()) <= availableWidth;
|
|
||||||
|
|
||||||
if (noScrolling)
|
if (noScrolling)
|
||||||
{
|
{
|
||||||
cf->repeat = -1; // Disable repeat if text is too short for scrolling
|
cf->repeat = -1; // Disable repeat if text is too short for scrolling
|
||||||
|
|
||||||
// Display text with rainbow effect if enabled
|
// Display text with rainbow effect if enabled
|
||||||
if (cf->rainbow)
|
if (cf->rainbow)
|
||||||
{
|
{
|
||||||
@@ -322,8 +357,7 @@ void ShowCustomFrame(uint8_t id, FastLED_NeoMatrix *matrix, MatrixDisplayUiState
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Display text
|
// Display text
|
||||||
|
DisplayManager.printText(x + textX, y + 6, cf->text.c_str(), false, false);
|
||||||
DisplayManager.printText(x + textX, y + 6, cf->text.c_str(), false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -335,7 +369,7 @@ void ShowCustomFrame(uint8_t id, FastLED_NeoMatrix *matrix, MatrixDisplayUiState
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
DisplayManager.printText(x + cf->scrollposition, 6 + y, cf->text.c_str(), false);
|
DisplayManager.printText(x + cf->scrollposition, 6 + y, cf->text.c_str(), false, false);
|
||||||
}
|
}
|
||||||
} // Display icon if present and not pushed
|
} // Display icon if present and not pushed
|
||||||
if (hasIcon)
|
if (hasIcon)
|
||||||
@@ -343,14 +377,14 @@ void ShowCustomFrame(uint8_t id, FastLED_NeoMatrix *matrix, MatrixDisplayUiState
|
|||||||
// Push icon if enabled and text is scrolling
|
// Push icon if enabled and text is scrolling
|
||||||
if (cf->pushIcon > 0 && !noScrolling)
|
if (cf->pushIcon > 0 && !noScrolling)
|
||||||
{
|
{
|
||||||
if (cf->iconPosition < 0 && cf->iconWasPushed == false && cf->scrollposition > 9)
|
if (cf->iconPosition < 0 && cf->iconWasPushed == false && cf->scrollposition > 8)
|
||||||
{
|
{
|
||||||
++cf->iconPosition;
|
++cf->iconPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cf->scrollposition < 9 && !cf->iconWasPushed)
|
if (cf->scrollposition < 8 && !cf->iconWasPushed)
|
||||||
{
|
{
|
||||||
cf->iconPosition = cf->scrollposition - 9;
|
cf->iconPosition = cf->scrollposition - 8;
|
||||||
|
|
||||||
if (cf->iconPosition <= -9)
|
if (cf->iconPosition <= -9)
|
||||||
{
|
{
|
||||||
@@ -376,10 +410,9 @@ void ShowCustomFrame(uint8_t id, FastLED_NeoMatrix *matrix, MatrixDisplayUiState
|
|||||||
// Draw vertical line if text is scrolling
|
// Draw vertical line if text is scrolling
|
||||||
if (!noScrolling)
|
if (!noScrolling)
|
||||||
{
|
{
|
||||||
matrix->drawLine(8 + x + notify.iconPosition, 0 + y, 8 + x + notify.iconPosition, 7 + y, 0);
|
// matrix->drawLine(8 + x + cf->iconPosition, 0 + y, 8 + x + cf->iconPosition, 7 + y, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset text color
|
// Reset text color
|
||||||
DisplayManager.getInstance().resetTextColor();
|
DisplayManager.getInstance().resetTextColor();
|
||||||
}
|
}
|
||||||
@@ -407,6 +440,7 @@ void NotifyFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
|||||||
notify.scrollposition = 34;
|
notify.scrollposition = 34;
|
||||||
notify.iconWasPushed = false;
|
notify.iconWasPushed = false;
|
||||||
notify.iconPosition = 0;
|
notify.iconPosition = 0;
|
||||||
|
notify.scrollDelay = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,30 +451,57 @@ void NotifyFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
|||||||
matrix->fillRect(0, 0, 32, 8, 0);
|
matrix->fillRect(0, 0, 32, 8, 0);
|
||||||
|
|
||||||
// Calculate text and available width
|
// Calculate text and available width
|
||||||
uint16_t textWidth = getTextWidth(notify.text.c_str());
|
uint16_t textWidth = getTextWidth(notify.text.c_str(),false);
|
||||||
uint16_t availableWidth = hasIcon ? 24 : 32;
|
uint16_t availableWidth = hasIcon ? 24 : 32;
|
||||||
|
|
||||||
|
// Check if text is scrolling
|
||||||
|
bool noScrolling = textWidth <= availableWidth;
|
||||||
|
|
||||||
// Check if text needs to be scrolled
|
// Check if text needs to be scrolled
|
||||||
if (textWidth > availableWidth && notify.scrollposition <= -textWidth)
|
if (textWidth > availableWidth && notify.scrollposition <= -textWidth)
|
||||||
{
|
{
|
||||||
// Reset scroll position and icon position if needed
|
// Reset scroll position and icon position if needed
|
||||||
notify.scrollposition = 38;
|
notify.scrollDelay = 0;
|
||||||
|
notify.scrollposition = 9;
|
||||||
|
|
||||||
if (notify.pushIcon == 2)
|
if (notify.pushIcon == 2)
|
||||||
{
|
{
|
||||||
notify.iconWasPushed = false;
|
notify.iconWasPushed = false;
|
||||||
// notify.iconPosition = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notify.repeat > 0)
|
if (notify.repeat > 0)
|
||||||
{
|
{
|
||||||
--notify.repeat;
|
--notify.repeat;
|
||||||
|
if (notify.repeat == 0)
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (textWidth > availableWidth)
|
|
||||||
|
if (!noScrolling)
|
||||||
{
|
{
|
||||||
// Update scroll position
|
if ((notify.scrollDelay > MATRIX_FPS * 1.2))
|
||||||
--notify.scrollposition;
|
{
|
||||||
|
--notify.scrollposition;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
++notify.scrollDelay;
|
||||||
|
if (hasIcon)
|
||||||
|
{
|
||||||
|
if (notify.iconWasPushed && notify.pushIcon == 1)
|
||||||
|
{
|
||||||
|
notify.scrollposition = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
notify.scrollposition = 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
notify.scrollposition = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate text X position based on icon presence
|
// Calculate text X position based on icon presence
|
||||||
@@ -449,9 +510,6 @@ void NotifyFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
|||||||
// Set text color
|
// Set text color
|
||||||
matrix->setTextColor(notify.color);
|
matrix->setTextColor(notify.color);
|
||||||
|
|
||||||
// Check if text is scrolling
|
|
||||||
bool noScrolling = textWidth <= availableWidth;
|
|
||||||
|
|
||||||
if (noScrolling)
|
if (noScrolling)
|
||||||
{
|
{
|
||||||
// Disable repeat if text is not scrolling
|
// Disable repeat if text is not scrolling
|
||||||
@@ -465,7 +523,7 @@ void NotifyFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Display text in solid color
|
// Display text in solid color
|
||||||
DisplayManager.printText(textX, 6, notify.text.c_str(), false);
|
DisplayManager.printText(textX, 6, notify.text.c_str(), false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -478,7 +536,7 @@ void NotifyFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Display scrolling text in solid color
|
// Display scrolling text in solid color
|
||||||
DisplayManager.printText(notify.scrollposition, 6, notify.text.c_str(), false);
|
DisplayManager.printText(notify.scrollposition, 6, notify.text.c_str(), false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -488,12 +546,12 @@ void NotifyFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
|||||||
// Push icon if enabled and text is scrolling
|
// Push icon if enabled and text is scrolling
|
||||||
if (notify.pushIcon > 0 && !noScrolling)
|
if (notify.pushIcon > 0 && !noScrolling)
|
||||||
{
|
{
|
||||||
if (notify.iconPosition < 0 && notify.iconWasPushed == false && notify.scrollposition > 9)
|
if (notify.iconPosition < 0 && notify.iconWasPushed == false && notify.scrollposition > 8)
|
||||||
{
|
{
|
||||||
++notify.iconPosition;
|
++notify.iconPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (notify.scrollposition < 9 && !notify.iconWasPushed)
|
if (notify.scrollposition < 8 && !notify.iconWasPushed)
|
||||||
{
|
{
|
||||||
notify.iconPosition = notify.scrollposition - 9;
|
notify.iconPosition = notify.scrollposition - 9;
|
||||||
|
|
||||||
@@ -519,7 +577,7 @@ void NotifyFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
|||||||
// Display icon divider line if text is scrolling
|
// Display icon divider line if text is scrolling
|
||||||
if (!noScrolling)
|
if (!noScrolling)
|
||||||
{
|
{
|
||||||
matrix->drawLine(8 + notify.iconPosition, 0, 8 + notify.iconPosition, 7, 0);
|
// matrix->drawLine(8 + notify.iconPosition, 0, 8 + notify.iconPosition, 7, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,52 +587,62 @@ void NotifyFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state)
|
|||||||
|
|
||||||
void CFrame1(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
void CFrame1(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||||
{
|
{
|
||||||
ShowCustomFrame(1, matrix, state, x, y, firstFrame, lastFrame);
|
String name = getFrameNameByFunction(CFrame1);
|
||||||
|
ShowCustomFrame(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame2(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
void CFrame2(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||||
{
|
{
|
||||||
ShowCustomFrame(2, matrix, state, x, y, firstFrame, lastFrame);
|
String name = getFrameNameByFunction(CFrame2);
|
||||||
|
ShowCustomFrame(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame3(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
void CFrame3(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||||
{
|
{
|
||||||
ShowCustomFrame(3, matrix, state, x, y, firstFrame, lastFrame);
|
String name = getFrameNameByFunction(CFrame3);
|
||||||
|
ShowCustomFrame(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame4(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
void CFrame4(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||||
{
|
{
|
||||||
ShowCustomFrame(4, matrix, state, x, y, firstFrame, lastFrame);
|
String name = getFrameNameByFunction(CFrame4);
|
||||||
|
ShowCustomFrame(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame5(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
void CFrame5(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||||
{
|
{
|
||||||
ShowCustomFrame(5, matrix, state, x, y, firstFrame, lastFrame);
|
String name = getFrameNameByFunction(CFrame5);
|
||||||
|
ShowCustomFrame(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame6(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
void CFrame6(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||||
{
|
{
|
||||||
ShowCustomFrame(6, matrix, state, x, y, firstFrame, lastFrame);
|
String name = getFrameNameByFunction(CFrame6);
|
||||||
|
ShowCustomFrame(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame7(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
void CFrame7(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||||
{
|
{
|
||||||
ShowCustomFrame(7, matrix, state, x, y, firstFrame, lastFrame);
|
String name = getFrameNameByFunction(CFrame7);
|
||||||
|
ShowCustomFrame(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame8(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
void CFrame8(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||||
{
|
{
|
||||||
ShowCustomFrame(8, matrix, state, x, y, firstFrame, lastFrame);
|
String name = getFrameNameByFunction(CFrame8);
|
||||||
|
ShowCustomFrame(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame9(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
void CFrame9(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||||
{
|
{
|
||||||
ShowCustomFrame(9, matrix, state, x, y, firstFrame, lastFrame);
|
String name = getFrameNameByFunction(CFrame9);
|
||||||
|
ShowCustomFrame(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrame10(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
void CFrame10(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_t x, int16_t y, bool firstFrame, bool lastFrame)
|
||||||
{
|
{
|
||||||
ShowCustomFrame(10, matrix, state, x, y, firstFrame, lastFrame);
|
String name = getFrameNameByFunction(CFrame10);
|
||||||
|
ShowCustomFrame(name, matrix, state, x, y, firstFrame, lastFrame);
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint16_t *getWeatherIcon(int code)
|
const uint16_t *getWeatherIcon(int code)
|
||||||
@@ -599,7 +667,7 @@ void WeatherFrame(FastLED_NeoMatrix *matrix, MatrixDisplayUiState *state, int16_
|
|||||||
DisplayManager.getInstance().resetTextColor();
|
DisplayManager.getInstance().resetTextColor();
|
||||||
matrix->drawRGBBitmap(x, y, getWeatherIcon(WEATHER_CODE), 8, 8);
|
matrix->drawRGBBitmap(x, y, getWeatherIcon(WEATHER_CODE), 8, 8);
|
||||||
String text = WEATHER_TEMP + "°" + WEATHER_HUM + "%";
|
String text = WEATHER_TEMP + "°" + WEATHER_HUM + "%";
|
||||||
uint16_t textWidth = getTextWidth(text.c_str());
|
uint16_t textWidth = getTextWidth(text.c_str(), false);
|
||||||
int16_t textX = ((23 - textWidth) / 2);
|
int16_t textX = ((23 - textWidth) / 2);
|
||||||
matrix->setCursor(textX + 11, 6 + y);
|
matrix->setCursor(textX + 11, 6 + y);
|
||||||
matrix->print(utf8ascii(text));
|
matrix->print(utf8ascii(text));
|
||||||
@@ -647,6 +715,5 @@ void StartAppUpdater()
|
|||||||
// getWeatherData();
|
// getWeatherData();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::pair<uint16_t, AppCallback>> Apps;
|
|
||||||
OverlayCallback overlays[] = {MenuFrame, NotifyFrame, AlarmFrame, TimerFrame};
|
OverlayCallback overlays[] = {MenuFrame, NotifyFrame, AlarmFrame, TimerFrame};
|
||||||
#endif
|
#endif
|
||||||
@@ -28,13 +28,13 @@ uint16_t hexToRgb565(String hexValue)
|
|||||||
return color;
|
return color;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint16_t getTextWidth(const char *text)
|
uint16_t getTextWidth(const char *text, bool ignoreUpperCase)
|
||||||
{
|
{
|
||||||
uint16_t width = 0;
|
uint16_t width = 0;
|
||||||
for (const char *c = text; *c != '\0'; ++c)
|
for (const char *c = text; *c != '\0'; ++c)
|
||||||
{
|
{
|
||||||
char current_char = *c;
|
char current_char = *c;
|
||||||
if (UPPERCASE_LETTERS)
|
if (UPPERCASE_LETTERS && !ignoreUpperCase)
|
||||||
{
|
{
|
||||||
current_char = toupper(current_char);
|
current_char = toupper(current_char);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,8 @@ void loadSettings()
|
|||||||
AUTO_BRIGHTNESS = Settings.getBool("ABRI", true);
|
AUTO_BRIGHTNESS = Settings.getBool("ABRI", true);
|
||||||
TEXTCOLOR_565 = Settings.getUInt("COL", 0xFFFF);
|
TEXTCOLOR_565 = Settings.getUInt("COL", 0xFFFF);
|
||||||
AUTO_TRANSITION = Settings.getBool("TRANS", true);
|
AUTO_TRANSITION = Settings.getBool("TRANS", true);
|
||||||
|
TIME_PER_TRANSITION = Settings.getUInt("TSPEED", 500);
|
||||||
|
TIME_PER_APP = Settings.getUInt("ADUR", 5000);
|
||||||
Settings.end();
|
Settings.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,6 +24,8 @@ void saveSettings()
|
|||||||
Settings.putBool("ABRI", AUTO_BRIGHTNESS);
|
Settings.putBool("ABRI", AUTO_BRIGHTNESS);
|
||||||
Settings.putBool("TRANS", AUTO_TRANSITION);
|
Settings.putBool("TRANS", AUTO_TRANSITION);
|
||||||
Settings.putUInt("COL", TEXTCOLOR_565);
|
Settings.putUInt("COL", TEXTCOLOR_565);
|
||||||
|
Settings.putUInt("TSPEED", TIME_PER_TRANSITION);
|
||||||
|
Settings.putUInt("ADUR", TIME_PER_APP);
|
||||||
Settings.end();
|
Settings.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,7 +34,7 @@ IPAddress gateway;
|
|||||||
IPAddress subnet;
|
IPAddress subnet;
|
||||||
IPAddress primaryDNS;
|
IPAddress primaryDNS;
|
||||||
IPAddress secondaryDNS;
|
IPAddress secondaryDNS;
|
||||||
const char *VERSION = "0.33";
|
const char *VERSION = "0.35";
|
||||||
String MQTT_HOST = "";
|
String MQTT_HOST = "";
|
||||||
uint16_t MQTT_PORT = 1883;
|
uint16_t MQTT_PORT = 1883;
|
||||||
String MQTT_USER;
|
String MQTT_USER;
|
||||||
@@ -51,7 +55,7 @@ String NET_GW = "192.168.178.1";
|
|||||||
String NET_SN = "255.255.255.0";
|
String NET_SN = "255.255.255.0";
|
||||||
String NET_PDNS = "8.8.8.8";
|
String NET_PDNS = "8.8.8.8";
|
||||||
String NET_SDNS = "1.1.1.1";
|
String NET_SDNS = "1.1.1.1";
|
||||||
int TIME_PER_FRAME = 7000;
|
int TIME_PER_APP = 7000;
|
||||||
uint8_t MATRIX_FPS = 23;
|
uint8_t MATRIX_FPS = 23;
|
||||||
int TIME_PER_TRANSITION = 500;
|
int TIME_PER_TRANSITION = 500;
|
||||||
String NTP_SERVER = "de.pool.ntp.org";
|
String NTP_SERVER = "de.pool.ntp.org";
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ extern String NET_GW;
|
|||||||
extern String NET_SN;
|
extern String NET_SN;
|
||||||
extern String NET_PDNS;
|
extern String NET_PDNS;
|
||||||
extern String NET_SDNS;
|
extern String NET_SDNS;
|
||||||
extern int TIME_PER_FRAME;
|
extern int TIME_PER_APP;
|
||||||
extern uint8_t MATRIX_FPS;
|
extern uint8_t MATRIX_FPS;
|
||||||
extern int TIME_PER_TRANSITION;
|
extern int TIME_PER_TRANSITION;
|
||||||
extern String NTP_SERVER;
|
extern String NTP_SERVER;
|
||||||
|
|||||||
@@ -132,6 +132,12 @@ void onMqttMessage(const char *topic, const uint8_t *payload, uint16_t length)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (strTopic == MQTT_PREFIX + "/switch")
|
||||||
|
{
|
||||||
|
DisplayManager.switchToApp(strPayload);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
else if (strTopic.startsWith(MQTT_PREFIX + "/custom"))
|
else if (strTopic.startsWith(MQTT_PREFIX + "/custom"))
|
||||||
{
|
{
|
||||||
String topic_str = topic;
|
String topic_str = topic;
|
||||||
@@ -140,8 +146,8 @@ void onMqttMessage(const char *topic, const uint8_t *payload, uint16_t length)
|
|||||||
{
|
{
|
||||||
topic_str = topic_str.substring(prefix.length());
|
topic_str = topic_str.substring(prefix.length());
|
||||||
}
|
}
|
||||||
uint16_t id = topic_str.toInt();
|
|
||||||
DisplayManager.generateCustomPage(id, strPayload);
|
DisplayManager.generateCustomPage(topic_str, strPayload);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,6 +160,7 @@ void onMqttConnected()
|
|||||||
mqtt.subscribe((prefix + String("/notify")).c_str());
|
mqtt.subscribe((prefix + String("/notify")).c_str());
|
||||||
mqtt.subscribe((prefix + String("/timer")).c_str());
|
mqtt.subscribe((prefix + String("/timer")).c_str());
|
||||||
mqtt.subscribe((prefix + String("/custom/#")).c_str());
|
mqtt.subscribe((prefix + String("/custom/#")).c_str());
|
||||||
|
mqtt.subscribe((prefix + String("/switch")).c_str());
|
||||||
Serial.println("MQTT Connected");
|
Serial.println("MQTT Connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -18,12 +18,13 @@ enum MenuState
|
|||||||
RadioMenu,
|
RadioMenu,
|
||||||
StationSelection,
|
StationSelection,
|
||||||
PlayingStation,
|
PlayingStation,
|
||||||
Reset,
|
|
||||||
VolumeMenu,
|
VolumeMenu,
|
||||||
BrightnessMenu,
|
BrightnessMenu,
|
||||||
FPSMenu,
|
FPSMenu,
|
||||||
ColorMenu,
|
ColorMenu,
|
||||||
SwitchMenu
|
SwitchMenu,
|
||||||
|
TspeedMenu,
|
||||||
|
AppTimeMenu
|
||||||
};
|
};
|
||||||
|
|
||||||
const char *menuItems[] = {
|
const char *menuItems[] = {
|
||||||
@@ -31,9 +32,10 @@ const char *menuItems[] = {
|
|||||||
"FPS",
|
"FPS",
|
||||||
"COLOR",
|
"COLOR",
|
||||||
"SWITCH",
|
"SWITCH",
|
||||||
"RESET"};
|
"T-SPEED",
|
||||||
|
"APPTIME"};
|
||||||
|
|
||||||
byte menuItemCount = 5;
|
byte menuItemCount = 6;
|
||||||
|
|
||||||
MenuState currentState = MainMenu;
|
MenuState currentState = MainMenu;
|
||||||
|
|
||||||
@@ -98,6 +100,18 @@ String MenuManager_::menutext()
|
|||||||
{
|
{
|
||||||
return AUTO_TRANSITION ? "ON" : "OFF";
|
return AUTO_TRANSITION ? "ON" : "OFF";
|
||||||
}
|
}
|
||||||
|
else if (currentState == TspeedMenu)
|
||||||
|
{
|
||||||
|
float seconds = (float)TIME_PER_TRANSITION / 1000.0;
|
||||||
|
return String(seconds, 1) + "s";
|
||||||
|
;
|
||||||
|
}
|
||||||
|
else if (currentState == AppTimeMenu)
|
||||||
|
{
|
||||||
|
float seconds = (float)TIME_PER_APP / 1000.0;
|
||||||
|
return String(seconds, 0) + "s";
|
||||||
|
;
|
||||||
|
}
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,6 +156,14 @@ void MenuManager_::rightButton()
|
|||||||
{
|
{
|
||||||
AUTO_TRANSITION = !AUTO_TRANSITION;
|
AUTO_TRANSITION = !AUTO_TRANSITION;
|
||||||
}
|
}
|
||||||
|
else if (currentState == TspeedMenu)
|
||||||
|
{
|
||||||
|
TIME_PER_TRANSITION = min(1200, TIME_PER_TRANSITION + 100);
|
||||||
|
}
|
||||||
|
else if (currentState == AppTimeMenu)
|
||||||
|
{
|
||||||
|
TIME_PER_APP = min(30000, TIME_PER_APP + 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuManager_::leftButton()
|
void MenuManager_::leftButton()
|
||||||
@@ -185,6 +207,14 @@ void MenuManager_::leftButton()
|
|||||||
{
|
{
|
||||||
AUTO_TRANSITION = !AUTO_TRANSITION;
|
AUTO_TRANSITION = !AUTO_TRANSITION;
|
||||||
}
|
}
|
||||||
|
else if (currentState == TspeedMenu)
|
||||||
|
{
|
||||||
|
TIME_PER_TRANSITION = max(200, TIME_PER_TRANSITION - 100);
|
||||||
|
}
|
||||||
|
else if (currentState == AppTimeMenu)
|
||||||
|
{
|
||||||
|
TIME_PER_APP = max(1000, TIME_PER_APP - 1000);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MenuManager_::selectButton()
|
void MenuManager_::selectButton()
|
||||||
@@ -210,9 +240,13 @@ void MenuManager_::selectButton()
|
|||||||
{
|
{
|
||||||
currentState = SwitchMenu;
|
currentState = SwitchMenu;
|
||||||
}
|
}
|
||||||
else if (menuIndex == 4) // FPS
|
else if (menuIndex == 4) // TSPEED
|
||||||
{
|
{
|
||||||
ESP.restart();
|
currentState = TspeedMenu;
|
||||||
|
}
|
||||||
|
else if (menuIndex == 5) // AppTIme
|
||||||
|
{
|
||||||
|
currentState = AppTimeMenu;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (currentState == StationSelection)
|
else if (currentState == StationSelection)
|
||||||
@@ -253,6 +287,16 @@ void MenuManager_::selectButtonLong()
|
|||||||
DisplayManager.setAutoTransition(AUTO_TRANSITION);
|
DisplayManager.setAutoTransition(AUTO_TRANSITION);
|
||||||
saveSettings();
|
saveSettings();
|
||||||
}
|
}
|
||||||
|
else if (currentState == TspeedMenu)
|
||||||
|
{
|
||||||
|
DisplayManager.setSettings();
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
|
else if (currentState == AppTimeMenu)
|
||||||
|
{
|
||||||
|
DisplayManager.setSettings();
|
||||||
|
saveSettings();
|
||||||
|
}
|
||||||
currentState = MainMenu;
|
currentState = MainMenu;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -94,8 +94,6 @@ void ServerManager_::setup()
|
|||||||
mws.addCSS(custom_css);
|
mws.addCSS(custom_css);
|
||||||
mws.addJavascript(custom_script);
|
mws.addJavascript(custom_script);
|
||||||
mws.addOptionBox("General");
|
mws.addOptionBox("General");
|
||||||
mws.addOption("Duration per Page", TIME_PER_FRAME);
|
|
||||||
mws.addOption("Transistion duration", TIME_PER_TRANSITION);
|
|
||||||
mws.addOption("Uppercase letters", UPPERCASE_LETTERS);
|
mws.addOption("Uppercase letters", UPPERCASE_LETTERS);
|
||||||
mws.addOption("Show date", SHOW_DATE);
|
mws.addOption("Show date", SHOW_DATE);
|
||||||
mws.addOption("Show temperature", SHOW_TEMP);
|
mws.addOption("Show temperature", SHOW_TEMP);
|
||||||
@@ -193,8 +191,6 @@ void ServerManager_::loadSettings()
|
|||||||
MQTT_USER = doc["Username"].as<String>();
|
MQTT_USER = doc["Username"].as<String>();
|
||||||
MQTT_PASS = doc["Password"].as<String>();
|
MQTT_PASS = doc["Password"].as<String>();
|
||||||
MQTT_PREFIX = doc["Prefix"].as<String>();
|
MQTT_PREFIX = doc["Prefix"].as<String>();
|
||||||
TIME_PER_FRAME = doc["Duration per Page"].as<int>();
|
|
||||||
TIME_PER_TRANSITION = doc["Transistion duration"].as<int>();
|
|
||||||
NET_STATIC = doc["Static IP"];
|
NET_STATIC = doc["Static IP"];
|
||||||
HA_DISCOVERY = doc["Homeassistant Discovery"];
|
HA_DISCOVERY = doc["Homeassistant Discovery"];
|
||||||
NET_IP = doc["Local IP"].as<String>();
|
NET_IP = doc["Local IP"].as<String>();
|
||||||
|
|||||||
Reference in New Issue
Block a user