From 9184ae0e8baa5b87eb45140d7027b91ab5947a31 Mon Sep 17 00:00:00 2001 From: Nikola Kirov Date: Sat, 6 Jan 2024 14:10:38 +0200 Subject: [PATCH] Controls Label in flash and other fixes --- src/ESPUI.cpp | 47 +++- src/ESPUI.h | 8 +- src/ESPUIcontrol.cpp | 584 ++++++++++++++++++++++--------------------- src/ESPUIcontrol.h | 289 +++++++++++---------- 4 files changed, 514 insertions(+), 414 deletions(-) diff --git a/src/ESPUI.cpp b/src/ESPUI.cpp index 49cabc4..a5f44a3 100644 --- a/src/ESPUI.cpp +++ b/src/ESPUI.cpp @@ -650,7 +650,16 @@ uint16_t ESPUIClass::addControl( Control * ctrl = new Control(type, label, nullptr, value, color, true, parentControl); if (auto_update_values && ctrl) ctrl->auto_update_value = true; - return addControl(type, label, value, color, parentControl, ctrl); + return addControl(ctrl); +} + +uint16_t ESPUIClass::addControl( + ControlType type, const __FlashStringHelper* label, const String& value, ControlColor color, uint16_t parentControl) +{ + Control* ctrl = new Control(type, label, nullptr, value, color, true, parentControl); + if (auto_update_values && ctrl) + ctrl->auto_update_value = true; + return addControl(ctrl); } uint16_t ESPUIClass::addControl(ControlType type, const char* label, const String& value, ControlColor color, @@ -662,8 +671,16 @@ uint16_t ESPUIClass::addControl(ControlType type, const char* label, const Strin return id; } -uint16_t ESPUIClass::addControl( - ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl, Control* control) +uint16_t ESPUIClass::addControl(ControlType type, const __FlashStringHelper* label, const String& value, ControlColor color, + uint16_t parentControl, std::function callback) +{ + uint16_t id = addControl(type, label, value, color, parentControl); + // set the original style callback + getControl(id)->callback = callback; + return id; +} + +uint16_t ESPUIClass::addControl(Control* control) { #ifdef ESP32 xSemaphoreTake(ControlsSemaphore, portMAX_DELAY); @@ -788,6 +805,10 @@ uint16_t ESPUIClass::button(const char* label, std::function callback, uint16_t parentControl, ControlColor color){ + return addControl(ControlType::Button, label, text, color, parentControl, callback); +} + uint16_t ESPUIClass::switcher(const char* label, std::function callback, ControlColor color, bool startState) { return addControl(ControlType::Switcher, label, startState ? "1" : "0", color, Control::noParent, callback); @@ -1015,7 +1036,25 @@ void ESPUIClass::updateControlLabel(Control* control, const char* value, int cli #endif return; } - control->label = value; + control->label_r = value; + control->lablel_is_in_flash = 0; + updateControl(control, clientId); +} + +void ESPUIClass::updateControlLabel(Control* control, const __FlashStringHelper* value, int clientId) +{ + if (!control) + { +#if defined(DEBUG_ESPUI) + if (verbosity) + { + ESPU_DBGf_P(PSTR("Error: updateControlLabel Control: There is no control with the requested ID \n")); + } +#endif + return; + } + control->label_f = value; + control->lablel_is_in_flash = 1; updateControl(control, clientId); } diff --git a/src/ESPUI.h b/src/ESPUI.h index d27a02c..742b57a 100644 --- a/src/ESPUI.h +++ b/src/ESPUI.h @@ -132,13 +132,18 @@ public: uint16_t addControl(ControlType type, const char* label, const String& value); uint16_t addControl(ControlType type, const char* label, const String& value, ControlColor color); uint16_t addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl); + uint16_t addControl(ControlType type, const __FlashStringHelper* label, const String& value, ControlColor color, uint16_t parentControl); uint16_t addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl, std::function callback); + uint16_t addControl(ControlType type, const __FlashStringHelper * label, const String& value, ControlColor color, uint16_t parentControl, std::function callback); bool removeControl(uint16_t id, bool force_rebuild_ui = false); // create Elements // Create Event Button uint16_t button(const char* label, std::function callback, ControlColor color, const String& value = ""); + uint16_t button(const __FlashStringHelper* label, const __FlashStringHelper* value, + std::function callback, uint16_t parentControl = Control::noParent, ControlColor color = ControlColor::Dark); + uint16_t switcher(const char* label, std::function callback, ControlColor color, bool startState = false); // Create Toggle Button uint16_t pad(const char* label, std::function callback, ControlColor color); // Create Pad Control uint16_t padWithCenter(const char* label, std::function callback, ControlColor color); // Create Pad Control with Centerbutton @@ -168,6 +173,7 @@ public: void updateControlLabel(uint16_t control, const char * value, int clientId = -1); void updateControlLabel(Control* control, const char * value, int clientId = -1); + void updateControlLabel(Control* control, const __FlashStringHelper* value, int clientId = -1); void updateControl(uint16_t id, int clientId = -1); void updateControl(Control* control, int clientId = -1); @@ -285,7 +291,7 @@ protected: bool basicAuth = true; uint16_t controlCount = 0; - uint16_t addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl, Control* control); + uint16_t addControl(Control* control); #define ClientUpdateType_t ESPUIclient::ClientUpdateType_t void NotifyClients(ClientUpdateType_t newState); diff --git a/src/ESPUIcontrol.cpp b/src/ESPUIcontrol.cpp index 0773be5..26b9343 100644 --- a/src/ESPUIcontrol.cpp +++ b/src/ESPUIcontrol.cpp @@ -1,282 +1,302 @@ -#include "ESPUI.h" - -static uint16_t idCounter = 0; -static const String ControlError = "*** ESPUI ERROR: Could not transfer control ***"; - -Control::Control(ControlType type, const char* label, std::function callback, const String& value, - ControlColor color, bool visible, uint16_t parentControl) - : type(type), - label(label), - callback(callback), - value(value), - color(color), - visible(visible), - wide(false), - vertical(false), - enabled(true), - auto_update_value(false), - parentControl(parentControl), - next(nullptr) -{ - id = ++idCounter; - ControlChangeID = 1; -} - -Control::Control(const Control& Control) - : type(Control.type), - id(Control.id), - label(Control.label), - callback(Control.callback), - value(Control.value), - color(Control.color), - visible(Control.visible), - parentControl(Control.parentControl), - next(Control.next), - ControlChangeID(Control.ControlChangeID) -{ } - -void Control::SendCallback(int type) -{ - if(callback) - { - callback(this, type); - } -} - -void Control::DeleteControl() -{ - _ToBeDeleted = true; - callback = nullptr; -} - -void Control::MarshalControl(JsonObject & _item, bool refresh, uint32_t StartingOffset) -{ - JsonObject & item = _item; - uint32_t length = value.length(); - uint32_t maxLength = uint32_t(double(ESPUI.jsonInitialDocumentSize) * 0.75); - if((length > maxLength) || StartingOffset) - { - /* - Serial.println(String("MarshalControl:Start Fragment Processing")); - Serial.println(String("MarshalControl:id: ") + String(id)); - Serial.println(String("MarshalControl:length: ") + String(length)); - Serial.println(String("MarshalControl:StartingOffset: ") + String(StartingOffset)); - Serial.println(String("MarshalControl:maxLength: ") + String(maxLength)); - - if(0 == StartingOffset) - { - Serial.println(String("MarshalControl: New control to fragement. ID: ") + String(id)); - } - else - { - Serial.println(String("MarshalControl: Next fragement. ID: ") + String(id)); - } - */ - - // indicate that no additional controls should be sent - _item[F("type")] = uint32_t(ControlType::Fragment); - _item[F("id")] = id; - - length = min((length - StartingOffset), maxLength); - // Serial.println(String("MarshalControl:Final length: ") + String(length)); - - _item[F("offset")] = StartingOffset; - _item[F("length")] = length; - _item[F("total")] = value.length(); - item = _item.createNestedObject(F("control")); - } - - item[F("id")] = id; - ControlType TempType = (ControlType::Password == type) ? ControlType::Text : type; - if(refresh) - { - item[F("type")] = uint32_t(TempType) + uint32_t(ControlType::UpdateOffset); - } - else - { - item[F("type")] = uint32_t(TempType); - } - - item[F("label")] = label; - item[F ("value")] = (ControlType::Password == type) ? F ("--------") : value.substring(StartingOffset, length + StartingOffset); - item[F("visible")] = visible; - item[F("color")] = (int)color; - item[F("enabled")] = enabled; - - if (!panelStyle.isEmpty()) {item[F("panelStyle")] = panelStyle;} - if (!elementStyle.isEmpty()) {item[F("elementStyle")] = elementStyle;} - if (!inputType.isEmpty()) {item[F("inputType")] = inputType;} - if (wide == true) {item[F("wide")] = true;} - if (vertical == true) {item[F("vertical")] = true;} - if (parentControl != Control::noParent) - { - item[F("parentControl")] = String(parentControl); - } - - // special case for selects: to preselect an option, you have to add - // "selected" to