diff --git a/sd_files/themes/README.md b/sd_files/themes/README.md index e44cfd302..67b7b1a92 100644 --- a/sd_files/themes/README.md +++ b/sd_files/themes/README.md @@ -6,7 +6,8 @@ Themes are supposed to change the UI experience of the User by allowing you to c * If displaying the Labels on the Main Menu * Setting the Primary Font color * Setting the Secondary Font Color (Non selected submenu item) -* Setting the Background Color. +* Setting the Background Color +* Setting the LED color and effects ## Images Bruce accepts **.bmp** **.jpg** **.gif** and **.png** (not available on LITE_VERSION) to be used in the Main menu, but the bigger they are, greater will be the time to draw them on screen, **please, try to keep them small**. @@ -43,15 +44,21 @@ Theme settings are stored in a **.json** file, following this structure: "border":0, "label":0, "boot_img":"boot.gif", - "boot_sound":"boot.wav" + "boot_sound":"boot.wav", + "ledBright": 100, + "ledColor": "960064", + "ledEffect": 0, + "ledEffectSpeed": 3, + "ledEffectDirection": 1 } ``` -* Colors: Codes are in **RGB565**, 16bit pattern, so you need to convert it using [this tool](https://rgbcolorpicker.com/565). +* Colors (excluding LED): Codes are in **RGB565**, 16bit pattern, so you need to convert it using [this tool](https://rgbcolorpicker.com/565). +* LED Colors: Codes are in HEX. * border: 0 or 1, 1 to keep UI Borders * label: 0 or 1, 1 to use UI Labels (Use 50px smaller images in this case) ## Theme creator -You can use **Theme_Builder.html** to setup and prepare your images and .json file, it will give you a .zip file that you **need to unzip** somewhere in your device, LittleFS or SD Card. +You can use [Bruce Theme Builder](https://bruce.computer/build_theme.html) to setup and prepare your images, settings and .json file, it will give you a .zip file that you **need to unzip** somewhere in your device, LittleFS or SD Card. ## Setting a Theme Config > UI Theme > (Choose FS) > select the .json file and the theme will be set. diff --git a/src/core/config.cpp b/src/core/config.cpp index 0fc991e9e..9437d3f2c 100644 --- a/src/core/config.cpp +++ b/src/core/config.cpp @@ -20,12 +20,14 @@ JsonDocument BruceConfig::toJson() const { setting["wifiAtStartup"] = wifiAtStartup; setting["instantBoot"] = instantBoot; +#ifdef HAS_RGB_LED setting["ledBright"] = ledBright; setting["ledColor"] = String(ledColor, HEX); setting["ledBlinkEnabled"] = ledBlinkEnabled; setting["ledEffect"] = ledEffect; setting["ledEffectSpeed"] = ledEffectSpeed; setting["ledEffectDirection"] = ledEffectDirection; +#endif JsonObject _webUI = setting["webUI"].to(); _webUI["user"] = webUI.user; @@ -207,6 +209,7 @@ void BruceConfig::fromFile(bool checkFS) { log_e("Fail"); } +#ifdef HAS_RGB_LED if (!setting["ledBright"].isNull()) { ledBright = setting["ledBright"].as(); } else { @@ -243,6 +246,7 @@ void BruceConfig::fromFile(bool checkFS) { count++; log_e("Fail"); } +#endif if (!setting["webUI"].isNull()) { JsonObject webUIObj = setting["webUI"].as(); @@ -499,12 +503,14 @@ void BruceConfig::validateConfig() { validateSoundEnabledValue(); validateSoundVolumeValue(); validateWifiAtStartupValue(); +#ifdef HAS_RGB_LED validateLedBrightValue(); validateLedColorValue(); validateLedBlinkEnabledValue(); validateLedEffectValue(); validateLedEffectSpeedValue(); validateLedEffectDirectionValue(); +#endif validateRfScanRangeValue(); validateRfModuleValue(); validateRfidModuleValue(); @@ -593,6 +599,7 @@ void BruceConfig::validateWifiAtStartupValue() { if (wifiAtStartup > 1) wifiAtStartup = 1; } +#ifdef HAS_RGB_LED void BruceConfig::setLedBright(int value) { ledBright = value; validateLedBrightValue(); @@ -656,6 +663,7 @@ void BruceConfig::validateLedEffectDirectionValue() { if (ledEffectDirection > 1 || ledEffectDirection == 0) ledEffectDirection = 1; if (ledEffectDirection < -1) ledEffectDirection = -1; } +#endif void BruceConfig::setWebUICreds(const String &usr, const String &pwd) { webUI.user = usr; diff --git a/src/core/config.h b/src/core/config.h index f6904fb7d..d02a661aa 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -58,13 +58,15 @@ class BruceConfig : public BruceTheme { int wifiAtStartup = 0; int instantBoot = 0; +#ifdef HAS_RGB_LED // Led - int ledBright = 75; - uint32_t ledColor = 0; + int ledBright = 50; + uint32_t ledColor = 0x960064; int ledBlinkEnabled = 1; int ledEffect = 0; int ledEffectSpeed = 5; int ledEffectDirection = 1; +#endif // Wifi Credential webUI = {"admin", "bruce"}; @@ -157,6 +159,7 @@ class BruceConfig : public BruceTheme { void setWifiAtStartup(int value); void validateWifiAtStartupValue(); +#ifdef HAS_RGB_LED // Led void setLedBright(int value); void validateLedBrightValue(); @@ -170,6 +173,7 @@ class BruceConfig : public BruceTheme { void validateLedEffectSpeedValue(); void setLedEffectDirection(int value); void validateLedEffectDirectionValue(); +#endif // Wifi void setWebUICreds(const String &usr, const String &pwd); diff --git a/src/core/settings.cpp b/src/core/settings.cpp index d4c4a3405..d9ab9cdd1 100644 --- a/src/core/settings.cpp +++ b/src/core/settings.cpp @@ -1,4 +1,5 @@ #include "settings.h" +#include "core/led_control.h" #include "core/wifi/wifi_common.h" #include "display.h" #include "modules/ble_api/ble_api.hpp" @@ -444,6 +445,7 @@ void setSoundVolume() { loopOptions(options, bruceConfig.soundVolume); } +#ifdef HAS_RGB_LED /********************************************************************* ** Function: setLedBlinkConfig ** Enable or disable led blink @@ -455,6 +457,7 @@ void setLedBlinkConfig() { }; loopOptions(options, bruceConfig.ledBlinkEnabled); } +#endif /********************************************************************* ** Function: setWifiStartupConfig @@ -1351,6 +1354,14 @@ void setTheme() { bruceConfig.secColor = DEFAULT_SECCOLOR; bruceConfig.bgColor = TFT_BLACK; bruceConfig.setUiColor(DEFAULT_PRICOLOR); +#ifdef HAS_RGB_LED + bruceConfig.ledBright = 50; + bruceConfig.ledColor = 0x960064; + bruceConfig.ledEffect = 0; + bruceConfig.ledEffectSpeed = 5; + bruceConfig.ledEffectDirection = 1; + ledSetup(); +#endif bruceConfig.saveFile(); fs = nullptr; } }, @@ -1363,7 +1374,7 @@ void setTheme() { if (fs == nullptr) return; String filepath = loopSD(*fs, true, "JSON"); - if (bruceConfig.openThemeFile(fs, filepath)) { + if (bruceConfig.openThemeFile(fs, filepath, true)) { bruceConfig.themePath = filepath; if (fs == &LittleFS) bruceConfig.theme.fs = 1; else if (fs == &SD) bruceConfig.theme.fs = 2; diff --git a/src/core/settings.h b/src/core/settings.h index 20b125c5d..1aeb9e3e4 100644 --- a/src/core/settings.h +++ b/src/core/settings.h @@ -79,7 +79,9 @@ void setSoundConfig(); void setSoundVolume(); +#ifdef HAS_RGB_LED void setLedBlinkConfig(); +#endif void setWifiStartupConfig(); diff --git a/src/core/theme.cpp b/src/core/theme.cpp index 968e861e7..73be72c75 100644 --- a/src/core/theme.cpp +++ b/src/core/theme.cpp @@ -1,4 +1,5 @@ #include "theme.h" +#include "core/led_control.h" #include "display.h" struct ThemeEntry { @@ -16,7 +17,7 @@ FS *BruceTheme::themeFS(void) { else if (theme.fs == 2) return &SD; return &LittleFS; // always get back to safety } -bool BruceTheme::openThemeFile(FS *fs, String filepath) { +bool BruceTheme::openThemeFile(FS *fs, String filepath, bool overwriteConfigSettings) { if (fs == nullptr) return true; if (!fs->exists(filepath)) return false; @@ -72,18 +73,32 @@ bool BruceTheme::openThemeFile(FS *fs, String filepath) { } } - uint16_t _priColor = bruceConfig.priColor; - uint16_t _secColor = bruceConfig.secColor; - uint16_t _bgColor = bruceConfig.bgColor; + file.close(); - if (!_th["priColor"].isNull()) { _priColor = strtoul(_th["priColor"], nullptr, 16); } - if (!_th["secColor"].isNull()) { _secColor = strtoul(_th["secColor"], nullptr, 16); } - if (!_th["bgColor"].isNull()) { _bgColor = strtoul(_th["bgColor"], nullptr, 16); } if (!_th["border"].isNull()) { theme.border = _th["border"].as(); } if (!_th["label"].isNull()) { theme.label = _th["label"].as(); } - file.close(); - _setUiColor(_priColor, &_secColor, &_bgColor); + if (overwriteConfigSettings) { + uint16_t _priColor = bruceConfig.priColor; + uint16_t _secColor = bruceConfig.secColor; + uint16_t _bgColor = bruceConfig.bgColor; + + if (!_th["priColor"].isNull()) { _priColor = strtoul(_th["priColor"], nullptr, 16); } + if (!_th["secColor"].isNull()) { _secColor = strtoul(_th["secColor"], nullptr, 16); } + if (!_th["bgColor"].isNull()) { _bgColor = strtoul(_th["bgColor"], nullptr, 16); } + _setUiColor(_priColor, &_secColor, &_bgColor); + +#ifdef HAS_RGB_LED + if (!_th["ledBright"].isNull()) { bruceConfig.ledBright = _th["ledBright"].as(); } + if (!_th["ledColor"].isNull()) { bruceConfig.ledColor = strtoul(_th["ledColor"], nullptr, 16); } + if (!_th["ledEffect"].isNull()) { bruceConfig.ledEffect = _th["ledEffect"].as(); } + if (!_th["ledEffectSpeed"].isNull()) { bruceConfig.ledEffectSpeed = _th["ledEffectSpeed"].as(); } + if (!_th["ledEffectDirection"].isNull()) { + bruceConfig.ledBright = _th["ledEffectDirection"].as(); + } + ledSetup(); +#endif + } if (fs == &LittleFS) theme.fs = 1; else if (fs == &SD) theme.fs = 2; diff --git a/src/core/theme.h b/src/core/theme.h index 1867d402b..49d2f8e61 100644 --- a/src/core/theme.h +++ b/src/core/theme.h @@ -67,7 +67,7 @@ class BruceTheme { // UI Color void _setUiColor(uint16_t primary, uint16_t *secondary = nullptr, uint16_t *background = nullptr); - bool openThemeFile(FS *fs, String filepath); + bool openThemeFile(FS *fs, String filepath, bool overwriteConfigSettings); bool validateImgFile(FS *fs, String filepath); String getThemeItemImg(String item) { return themePath.substring(0, themePath.lastIndexOf('/')) + "/" + item; diff --git a/src/main.cpp b/src/main.cpp index fac6270f0..ff879b79b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,511 +1,507 @@ -#include "core/main_menu.h" -#include - -#include "core/USBSerial/USBSerial.h" -#include "core/powerSave.h" -#include "core/serial_commands/cli.h" -#include "core/utils.h" -#include "esp32-hal-psram.h" -#include "esp_task_wdt.h" -#include -#include -#include - -io_expander ioExpander; -BruceConfig bruceConfig; -BruceConfigPins bruceConfigPins; - -SerialCli serialCli; -USBSerial USBserial = USBSerial(); -SerialDevice *serialDevice; - -StartupApp startupApp; -MainMenu mainMenu; -SPIClass sdcardSPI; -#ifdef USE_HSPI_PORT -SPIClass CC_NRF_SPI(VSPI); -#else -SPIClass CC_NRF_SPI(HSPI); -#endif - -// Navigation Variables -volatile bool NextPress = false; -volatile bool PrevPress = false; -volatile bool UpPress = false; -volatile bool DownPress = false; -volatile bool SelPress = false; -volatile bool EscPress = false; -volatile bool AnyKeyPress = false; -volatile bool NextPagePress = false; -volatile bool PrevPagePress = false; -volatile bool LongPress = false; -volatile bool SerialCmdPress = false; -volatile int forceMenuOption = -1; -volatile uint8_t menuOptionType = 0; -String menuOptionLabel = ""; -#ifdef HAS_ENCODER_LED -volatile int EncoderLedChange = 0; -#endif - -TouchPoint touchPoint; - -keyStroke KeyStroke; - -TaskHandle_t xHandle; -void __attribute__((weak)) taskInputHandler(void *parameter) { - auto timer = millis(); - while (true) { - checkPowerSaveTime(); - // Sometimes this task run 2 or more times before looptask, - // and navigation gets stuck, the idea here is run the input detection - // if AnyKeyPress is false, or rerun if it was not renewed within 75ms (arbitrary) - // because AnyKeyPress will be true if didn´t passed through a check(bool var) - if (!AnyKeyPress || millis() - timer > 75) { - NextPress = false; - PrevPress = false; - UpPress = false; - DownPress = false; - SelPress = false; - EscPress = false; - AnyKeyPress = false; - SerialCmdPress = false; - NextPagePress = false; - PrevPagePress = false; - touchPoint.pressed = false; - touchPoint.Clear(); -#ifndef USE_TFT_eSPI_TOUCH - InputHandler(); -#endif - timer = millis(); - } - vTaskDelay(pdMS_TO_TICKS(10)); - } -} -// Public Globals Variables -unsigned long previousMillis = millis(); -int prog_handler; // 0 - Flash, 1 - LittleFS, 3 - Download -String cachedPassword = ""; -bool interpreter_start = false; -bool sdcardMounted = false; -bool gpsConnected = false; - -// wifi globals -// TODO put in a namespace -bool wifiConnected = false; -bool isWebUIActive = false; -String wifiIP; - -bool BLEConnected = false; -bool returnToMenu; -bool isSleeping = false; -bool isScreenOff = false; -bool dimmer = false; -char timeStr[10]; -time_t localTime; -struct tm *timeInfo; -#if defined(HAS_RTC) -cplus_RTC _rtc; -RTC_TimeTypeDef _time; -RTC_DateTypeDef _date; -bool clock_set = true; -#else -ESP32Time rtc; -bool clock_set = false; -#endif - -std::vector