diff --git a/src/AutoConnectElement.h b/src/AutoConnectElement.h index e25043a..1661c4c 100644 --- a/src/AutoConnectElement.h +++ b/src/AutoConnectElement.h @@ -24,6 +24,7 @@ using AutoConnectSelect = AutoConnectSelectJson; using AutoConnectStyle = AutoConnectStyleJson; using AutoConnectSubmit = AutoConnectSubmitJson; using AutoConnectText = AutoConnectTextJson; +using AutoConnectImage = AutoConnectImageJson; #define AUTOCONNECT_JSON_BUFFER_SIZE 256 #else using AutoConnectElement = AutoConnectElementBasis; @@ -36,6 +37,7 @@ using AutoConnectSelect = AutoConnectSelectBasis; using AutoConnectStyle = AutoConnectStyleBasis; using AutoConnectSubmit = AutoConnectSubmitBasis; using AutoConnectText = AutoConnectTextBasis; +using AutoConnectImage = AutoConnectImageBasis; #endif // !AUTOCONNECT_USE_JSON /** @@ -53,5 +55,6 @@ using AutoConnectText = AutoConnectTextBasis; #define ACSubmit(n, ...) AutoConnectSubmit n(#n, ##__VA_ARGS__) #define ACStyle(n, ...) AutoConnectStyle n(#n, ##__VA_ARGS__) #define ACText(n, ...) AutoConnectText n(#n, ##__VA_ARGS__) +#define ACImage(n, ...) AutoConnectImage n(#n, ##__VA_ARGS__) #endif // _AUTOCONNECTELEMENT_H_ diff --git a/src/AutoConnectElementBasis.h b/src/AutoConnectElementBasis.h index cba00f6..0685ef4 100644 --- a/src/AutoConnectElementBasis.h +++ b/src/AutoConnectElementBasis.h @@ -38,6 +38,7 @@ typedef enum { AC_Style, AC_Submit, AC_Text, + AC_Image, AC_Unknown = -1 } ACElement_t; /**< AutoConnectElement class type */ @@ -300,6 +301,29 @@ class AutoConnectTextBasis : AC_AUTOCONNECTELEMENT_ON_VIRTUAL public AutoConnect String format; /**< C string that contains the text to be written */ }; +/** + * Image arrangement class, a part of AutoConnectAux element. + * @param + * @param name Image name string. + * @param value Image value as base64 string. + * @param style A string of style-code for decoration, optionally. + * @param format C string that contains the value to be formatted. + * An arrangement image would be placed with
contains. A string + * of style-codes are given for '
'. + */ + +class AutoConnectImageBasis : AC_AUTOCONNECTELEMENT_ON_VIRTUAL public AutoConnectElementBasis { + public: + explicit AutoConnectImageBasis(const char* name = "", const char* value = "", const char* style = "", const char* format = "", const ACPosterior_t post = AC_Tag_None) : AutoConnectElementBasis(name, value, post), style(String(style)), format(String(format)) { + _type = AC_Image; + } + virtual ~AutoConnectImageBasis() {} + const String toHTML(void) const override; + + String style; /**< CSS style modifier native code */ + String format; /**< C string that contains the text to be written */ +}; + #ifndef AUTOCONNECT_USE_JSON /** * Casts only a class derived from the AutoConnectElement class to the @@ -367,6 +391,13 @@ inline AutoConnectTextBasis& AutoConnectElementBasis::as(v AC_DBG("%s mismatched type as <%d>\n", name.c_str(), (int)typeOf()); return *(reinterpret_cast(this)); } + +template<> +inline AutoConnectImageBasis& AutoConnectElementBasis::as(void) { + if (typeOf() != AC_Image) + AC_DBG("%s mismatched type as <%d>\n", name.c_str(), (int)typeOf()); + return *(reinterpret_cast(this)); +} #endif #endif // _AUTOCONNECTELEMENTBASIS_H_ diff --git a/src/AutoConnectElementBasisImpl.h b/src/AutoConnectElementBasisImpl.h index ed245b8..9246519 100644 --- a/src/AutoConnectElementBasisImpl.h +++ b/src/AutoConnectElementBasisImpl.h @@ -354,4 +354,34 @@ const String AutoConnectTextBasis::toHTML(void) const { return html; } +/** + * Generate an HTML image element from a base64 string of the value member. If a style + * exists, it gives a style attribute. + * @return String an HTML string. + */ +const String AutoConnectImageBasis::toHTML(void) const { + String html = String(""); + + if (enable) { + html = String(F("
"); + if (format.length()) { + int buflen = (value.length() + format.length() + 16 + 1) & (~0xf); + char* buffer; + if ((buffer = (char*)malloc(buflen))) { + snprintf(buffer, buflen, format.c_str(), value.c_str()); + value_f = String(buffer); + free(buffer); + } + } + html += String(F("Image cannot be rendered
")); + html = AutoConnectElementBasis::posterior(html); + } + return html; +} + #endif // _AUTOCONNECTELEMENTBASISIMPL_H_ diff --git a/src/AutoConnectElementJson.h b/src/AutoConnectElementJson.h index 07724ae..0ba7c55 100644 --- a/src/AutoConnectElementJson.h +++ b/src/AutoConnectElementJson.h @@ -44,6 +44,7 @@ #define AUTOCONNECT_JSON_TYPE_ACSTYLE "ACStyle" #define AUTOCONNECT_JSON_TYPE_ACSUBMIT "ACSubmit" #define AUTOCONNECT_JSON_TYPE_ACTEXT "ACText" +#define AUTOCONNECT_JSON_TYPE_ACIMAGE "ACImage" #define AUTOCONNECT_JSON_VALUE_BEHIND "behind" #define AUTOCONNECT_JSON_VALUE_BR "br" #define AUTOCONNECT_JSON_VALUE_EXTERNAL "extern" @@ -303,6 +304,31 @@ class AutoConnectTextJson : public AutoConnectElementJson, public AutoConnectTex void serialize(JsonObject& json) override; }; +/** + * Image arrangement class, a part of AutoConnectAux element. + * @param + * @param name Image name string. + * @param value Image value string. + * @param style A string of style-code for decoration, optionally. + * An arrangement image would be placed with
contains. A string + * of style-codes are given for '
'. + */ +class AutoConnectImageJson : public AutoConnectElementJson, public AutoConnectImageBasis { + public: + explicit AutoConnectImageJson(const char* name = "", const char* value = "", const char* style = "", const char* format = "", const ACPosterior_t post = AC_Tag_None) { + AutoConnectImageBasis::name = String(name); + AutoConnectImageBasis::value = String(value); + AutoConnectImageBasis::style = String(style); + AutoConnectImageBasis::format = String(format); + AutoConnectImageBasis::post = post; + _defaultPost = AC_Tag_None; + } + ~AutoConnectImageJson() {} + size_t getObjectSize(void) const override; + bool loadMember(const JsonObject& json) override; + void serialize(JsonObject& json) override; +}; + /** * Casts only a class derived from the AutoConnectElement class to the * actual element class. @@ -379,4 +405,12 @@ inline AutoConnectTextJson& AutoConnectElementJson::as(void return *(reinterpret_cast(this)); } +template<> +inline AutoConnectImageJson& AutoConnectElementJson::as(void) { + if (typeOf() != AC_Image) { + AC_DBG("%s mismatched type as <%d>\n", name.c_str(), (int)typeOf()); + } + return *(reinterpret_cast(this)); +} + #endif // _AUTOCONNECTELEMENTJSON_H_ diff --git a/src/AutoConnectElementJsonImpl.h b/src/AutoConnectElementJsonImpl.h index 9219ff5..11d3f15 100644 --- a/src/AutoConnectElementJsonImpl.h +++ b/src/AutoConnectElementJsonImpl.h @@ -200,7 +200,7 @@ void AutoConnectCheckboxJson::serialize(JsonObject& json) { size_t AutoConnectFileJson::getObjectSize(void) const { size_t size = AutoConnectElementJson::getObjectSize() + JSON_OBJECT_SIZE(2); size += sizeof(AUTOCONNECT_JSON_KEY_LABEL) + label.length() + 1 + sizeof(AUTOCONNECT_JSON_KEY_STORE) + sizeof(AUTOCONNECT_JSON_VALUE_EXTERNAL); - return size; + return size; } /** @@ -526,4 +526,45 @@ void AutoConnectTextJson::serialize(JsonObject& json) { json[F(AUTOCONNECT_JSON_KEY_FORMAT)] = format; } +/** + * Returns JSON object size. + * @return An object size for JsonBuffer. + */ +size_t AutoConnectImageJson::getObjectSize(void) const { + size_t size = AutoConnectElementJson::getObjectSize() + JSON_OBJECT_SIZE(2); + size += sizeof(AUTOCONNECT_JSON_KEY_STYLE) + style.length() + 1 + sizeof(AUTOCONNECT_JSON_KEY_FORMAT) + format.length() + 1; + return size; +} + +/** + * Load a image element attribute member from the JSON object. + * @param json JSON object with the definition of AutoConnectElement. + * @return true AutoConnectElement loaded + * @return false Type of AutoConnectElement is mismatched. + */ +bool AutoConnectImageJson::loadMember(const JsonObject& json) { + String type = json[F(AUTOCONNECT_JSON_KEY_TYPE)].as(); + if (type.equalsIgnoreCase(F(AUTOCONNECT_JSON_TYPE_ACIMAGE))) { + _setMember(json); + if (json.containsKey(F(AUTOCONNECT_JSON_KEY_STYLE))) + style = json[F(AUTOCONNECT_JSON_KEY_STYLE)].as(); + if (json.containsKey(F(AUTOCONNECT_JSON_KEY_FORMAT))) + format = json[F(AUTOCONNECT_JSON_KEY_FORMAT)].as(); + return true; + } + return false; +} + +/** + * Serialize AutoConnectImage to JSON. + * @param json JSON object to be serialized. + */ +void AutoConnectImageJson::serialize(JsonObject& json) { + _serialize(json); + json[F(AUTOCONNECT_JSON_KEY_TYPE)] = String(F(AUTOCONNECT_JSON_TYPE_ACIMAGE)); + json[F(AUTOCONNECT_JSON_KEY_VALUE)] = value; + json[F(AUTOCONNECT_JSON_KEY_STYLE)] = style; + json[F(AUTOCONNECT_JSON_KEY_FORMAT)] = format; +} + #endif // _AUTOCONNECTELEMENTJSONIMPL_H_