Supports AutoConnectStyle element

pull/110/head
Hieromon Ikasamo 5 years ago
parent ece97863c8
commit 478815d1d7
  1. 5
      examples/mqttRSSI/mqttRSSI.ino
  2. 5
      examples/mqttRSSI_FS/data/mqtt_setting.json
  3. 2
      examples/mqttRSSI_NA/mqttRSSI_NA.ino
  4. 32
      src/AutoConnectAux.cpp
  5. 1
      src/AutoConnectAux.h
  6. 17
      src/AutoConnectAuxImpl.h
  7. 3
      src/AutoConnectElement.h
  8. 21
      src/AutoConnectElementBasis.h
  9. 30
      src/AutoConnectElementJson.h
  10. 25
      src/AutoConnectElementJsonImpl.h

@ -44,6 +44,11 @@ static const char AUX_mqtt_setting[] PROGMEM = R"raw(
"uri": "/mqtt_setting",
"menu": true,
"element": [
{
"name": "style",
"type": "ACStyle",
"value": "label+input,label+select{position:sticky;left:120px;width:230px!important;box-sizing:border-box;}"
},
{
"name": "header",
"type": "ACText",

@ -3,6 +3,11 @@
"uri": "/mqtt_setting",
"menu": true,
"element": [
{
"name": "style",
"type": "ACStyle",
"value": "label+input,label+select{position:sticky;left:120px;width:230px!important;box-sizing:border-box;}"
},
{
"name": "header",
"type": "ACText",

@ -46,6 +46,7 @@ typedef WebServer WiFiWebServer;
// facility.
// Declare AutoConnectElements for the page asf /mqtt_setting
ACStyle(style, "label+input,label+select{position:sticky;left:120px;width:230px!important;box-sizing:border-box;}");
ACText(header, "<h2>MQTT broker settings</h2>", "text-align:center;color:#2f4f4f;padding:10px;");
ACText(caption, "Publishing the WiFi signal strength to MQTT channel. RSSI value of ESP8266 to the channel created on ThingSpeak", "font-family:serif;color:#4682b4;");
ACInput(mqttserver, "", "Server", "^(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\\-]*[a-zA-Z0-9])\\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\\-]*[A-Za-z0-9])$", "MQTT broker server");
@ -60,6 +61,7 @@ ACSubmit(discard, "Discard", "/");
// Declare the custom Web page as /mqtt_setting and contains the AutoConnectElements
AutoConnectAux mqtt_setting(AUX_SETTING_URI, "MQTT Setting", true, {
style,
header,
caption,
mqttserver,

@ -36,6 +36,7 @@ const char AutoConnectAux::_PAGE_AUX[] PROGMEM = {
"{{CSS_INPUT_BUTTON}}"
"{{CSS_INPUT_TEXT}}"
"{{CSS_LUXBAR}}"
"{{AUX_CSS}}"
"</style>"
"</head>"
"<body style=\"padding-top:58px;\">"
@ -409,8 +410,14 @@ const String AutoConnectAux::_insertElement(PageArgument& args) {
}
// Generate HTML for all AutoConnectElements contained in the page.
for (AutoConnectElement& addon : _addonElm)
body += addon.toHTML();
for (AutoConnectElement& addon : _addonElm) {
// Since the style sheet has already drained at the time of the
// _insertElement function call, it skips the call to the HTML
// generator by each element.
if (addon.typeOf() != AC_Style)
// Invoke an HTML generator by each element
body += addon.toHTML();
}
// Call user handler after HTML generation.
if (_handler) {
@ -422,6 +429,21 @@ const String AutoConnectAux::_insertElement(PageArgument& args) {
return body;
}
/**
* Insert user defined CSS code to AutoConnectAux page.
* @param args A reference of PageArgument but unused.
* @return HTML string that should be inserted.
*/
const String AutoConnectAux::_insertStyle(PageArgument& args) {
String css = String("");
for (AutoConnectElement& elm : _addonElm) {
if (elm.typeOf() == AC_Style)
css += elm.toHTML();
}
return css;
}
/**
* Generate an auxiliary page assembled with the AutoConnectElement.
* This function is the core procedure of AutoConnectAux, and uses
@ -455,6 +477,7 @@ PageElement* AutoConnectAux::_setupPage(const String& uri) {
elm->addToken(String(FPSTR("CSS_INPUT_BUTTON")), std::bind(&AutoConnect::_token_CSS_INPUT_BUTTON, mother, std::placeholders::_1));
elm->addToken(String(FPSTR("CSS_INPUT_TEXT")), std::bind(&AutoConnect::_token_CSS_INPUT_TEXT, mother, std::placeholders::_1));
elm->addToken(String(FPSTR("CSS_LUXBAR")), std::bind(&AutoConnect::_token_CSS_LUXBAR, mother, std::placeholders::_1));
elm->addToken(String(FPSTR("AUX_CSS")), std::bind(&AutoConnectAux::_insertStyle, this, std::placeholders::_1));
elm->addToken(String(FPSTR("MENU_PRE")), std::bind(&AutoConnect::_token_MENU_PRE, mother, std::placeholders::_1));
elm->addToken(String(FPSTR("MENU_AUX")), std::bind(&AutoConnect::_token_MENU_AUX, mother, std::placeholders::_1));
elm->addToken(String(FPSTR("MENU_POST")), std::bind(&AutoConnect::_token_MENU_POST, mother, std::placeholders::_1));
@ -618,6 +641,10 @@ AutoConnectElement* AutoConnectAux::_createElement(const JsonObject& json) {
AutoConnectSelect* cert_elm = new AutoConnectSelect;
return reinterpret_cast<AutoConnectElement*>(cert_elm);
}
case AC_Style: {
AutoConnectStyle* cert_elm = new AutoConnectStyle;
return reinterpret_cast<AutoConnectElement*>(cert_elm);
}
case AC_Submit: {
AutoConnectSubmit* cert_elm = new AutoConnectSubmit;
return reinterpret_cast<AutoConnectElement*>(cert_elm);
@ -892,6 +919,7 @@ ACElement_t AutoConnectAux::_asElementType(const String& type) {
{ AUTOCONNECT_JSON_TYPE_ACINPUT, AC_Input },
{ AUTOCONNECT_JSON_TYPE_ACRADIO, AC_Radio },
{ AUTOCONNECT_JSON_TYPE_ACSELECT, AC_Select },
{ AUTOCONNECT_JSON_TYPE_ACSTYLE, AC_Style },
{ AUTOCONNECT_JSON_TYPE_ACSUBMIT, AC_Submit },
{ AUTOCONNECT_JSON_TYPE_ACTEXT, AC_Text }
};

@ -92,6 +92,7 @@ class AutoConnectAux : public PageBuilder {
void _join(AutoConnect& ac); /**< Make a link to AutoConnect */
PageElement* _setupPage(const String& uri); /**< AutoConnectAux page builder */
const String _insertElement(PageArgument& args); /**< Insert a generated HTML to the page built by PageBuilder */
const String _insertStyle(PageArgument& args); /**< Insert CSS style */
const String _injectTitle(PageArgument& args) const { (void)(args); return _title; } /**< Returns title of this page to PageBuilder */
const String _injectMenu(PageArgument& args); /**< Inject menu title of this page to PageBuilder */
const String _indicateUri(PageArgument& args); /**< Inject the uri that caused the request */

@ -133,6 +133,23 @@ AutoConnectSelectBasis& AutoConnectAux::getElement(const String& name) {
return reinterpret_cast<AutoConnectSelectBasis&>(_nullElement());
}
/**
* Get AutoConnectStyleBasis element.
* @param name An element name.
* @return A reference of AutoConnectStyle class.
*/
template<>
AutoConnectStyleBasis& AutoConnectAux::getElement(const String& name) {
AutoConnectElement* elm = getElement(name);
if (elm) {
if (elm->typeOf() == AC_Style)
return *(reinterpret_cast<AutoConnectStyleBasis*>(elm));
else
AC_DBG("Element<%s> type mismatch<%d>\n", name.c_str(), elm->typeOf());
}
return reinterpret_cast<AutoConnectStyleBasis&>(_nullElement());
}
/**
* Get AutoConnectSubmitBasis element.
* @param name An element name.

@ -21,6 +21,7 @@ using AutoConnectFile = AutoConnectFileJson;
using AutoConnectInput = AutoConnectInputJson;
using AutoConnectRadio = AutoConnectRadioJson;
using AutoConnectSelect = AutoConnectSelectJson;
using AutoConnectStyle = AutoConnectStyleJson;
using AutoConnectSubmit = AutoConnectSubmitJson;
using AutoConnectText = AutoConnectTextJson;
#define AUTOCONNECT_JSON_BUFFER_SIZE 256
@ -32,6 +33,7 @@ using AutoConnectFile = AutoConnectFileBasis;
using AutoConnectInput = AutoConnectInputBasis;
using AutoConnectRadio = AutoConnectRadioBasis;
using AutoConnectSelect = AutoConnectSelectBasis;
using AutoConnectStyle = AutoConnectStyleBasis;
using AutoConnectSubmit = AutoConnectSubmitBasis;
using AutoConnectText = AutoConnectTextBasis;
#endif // !AUTOCONNECT_USE_JSON
@ -49,6 +51,7 @@ using AutoConnectText = AutoConnectTextBasis;
#define ACRadio(n, ...) AutoConnectRadio n(#n, ##__VA_ARGS__)
#define ACSelect(n, ...) AutoConnectSelect n(#n, ##__VA_ARGS__)
#define ACSubmit(n, ...) AutoConnectSubmit n(#n, ##__VA_ARGS__)
#define ACStyle(n, ...) AutoConnectStyle n(#n, ##__VA_ARGS__)
#define ACText(n, ...) AutoConnectText n(#n, ##__VA_ARGS__)
#endif // _AUTOCONNECTELEMENT_H_

@ -35,6 +35,7 @@ typedef enum {
AC_Input,
AC_Radio,
AC_Select,
AC_Style,
AC_Submit,
AC_Text,
AC_Unknown = -1
@ -236,6 +237,19 @@ class AutoConnectSelectBasis : AC_AUTOCONNECTELEMENT_ON_VIRTUAL public AutoConne
std::vector<String> _options; /**< List options array */
};
/**
* An element class for inserting CSS in AutoConnectAux page.
* @param name Style name string.
* @param value CSS Native code.
*/
class AutoConnectStyleBasis : AC_AUTOCONNECTELEMENT_ON_VIRTUAL public AutoConnectElementBasis {
public:
explicit AutoConnectStyleBasis(const char* name = "", const char* value = "") : AutoConnectElementBasis(name, value, AC_Tag_None) {
_type = AC_Style;
}
virtual ~AutoConnectStyleBasis() {}
};
/**
* Submit button arrangement class, a part of AutoConnectAux element.
* Place a submit button with a label that can be added by user sketch.
@ -325,6 +339,13 @@ inline AutoConnectSelectBasis& AutoConnectElementBasis::as<AutoConnectSelectBasi
return *(reinterpret_cast<AutoConnectSelectBasis*>(this));
}
template<>
inline AutoConnectStyleBasis& AutoConnectElementBasis::as<AutoConnectStyleBasis>(void) {
if (typeOf() != AC_Style)
AC_DBG("%s mismatched type as <%d>\n", name.c_str(), (int)typeOf());
return *(reinterpret_cast<AutoConnectStyleBasis*>(this));
}
template<>
inline AutoConnectSubmitBasis& AutoConnectElementBasis::as<AutoConnectSubmitBasis>(void) {
if (typeOf() != AC_Submit)

@ -39,6 +39,7 @@
#define AUTOCONNECT_JSON_TYPE_ACINPUT "ACInput"
#define AUTOCONNECT_JSON_TYPE_ACRADIO "ACRadio"
#define AUTOCONNECT_JSON_TYPE_ACSELECT "ACSelect"
#define AUTOCONNECT_JSON_TYPE_ACSTYLE "ACStyle"
#define AUTOCONNECT_JSON_TYPE_ACSUBMIT "ACSubmit"
#define AUTOCONNECT_JSON_TYPE_ACTEXT "ACText"
#define AUTOCONNECT_JSON_VALUE_BR "br"
@ -276,6 +277,28 @@ class AutoConnectSelectJson : public AutoConnectElementJson, public AutoConnectS
void serialize(JsonObject& json) override;
};
/**
* CSS style arrangement class, a part of AutoConnectAux element.
* This element assumes CSS that came into effect as a style code will
* assign. Therefore, it does not check whether the CSS error exists in
* the value set in AutoConnectStyle. Also, because AutoConnect inserts
* its style code at the end of the style block on the AutoConnectAux
* page, it may affect the AutoConnect web page elements.
* @param name A style name string.
* @param value CSS style code.
*/
class AutoConnectStyleJson : public AutoConnectElementJson, public AutoConnectStyleBasis {
public:
explicit AutoConnectStyleJson(const char* name = "", const char* value = "") {
AutoConnectStyleBasis::name = String(name);
AutoConnectStyleBasis::value = String(value);
AutoConnectStyleBasis::post = AC_Tag_None;
}
~AutoConnectStyleJson() {}
bool loadMember(const JsonObject& json) override;
void serialize(JsonObject& json) override;
};
/**
* Submit button arrangement class, a part of AutoConnectAux element.
* Place a submit button with a label that can be added by user sketch.
@ -371,6 +394,13 @@ inline AutoConnectSelectJson& AutoConnectElementJson::as<AutoConnectSelectJson>(
return *(reinterpret_cast<AutoConnectSelectJson*>(this));
}
template<>
inline AutoConnectStyleJson& AutoConnectElementJson::as<AutoConnectStyleJson>(void) {
if (typeOf() != AC_Style)
AC_DBG("%s mismatched type as <%d>\n", name.c_str(), (int)typeOf());
return *(reinterpret_cast<AutoConnectStyleJson*>(this));
}
template<>
inline AutoConnectSubmitJson& AutoConnectElementJson::as<AutoConnectSubmitJson>(void) {
if (typeOf() != AC_Submit)

@ -404,6 +404,31 @@ void AutoConnectSelectJson::serialize(JsonObject& json) {
json[F(AUTOCONNECT_JSON_KEY_SELECTED)] = selected;
}
/**
* Load an element member value from the JSON object.
* @param json JSON object with the definition of AutoConnectStyle.
* @return true AutoConnectStyle loaded
* @return false Type of AutoConnectStyle is mismatched.
*/
bool AutoConnectStyleJson::loadMember(const JsonObject& json) {
String type = json[F(AUTOCONNECT_JSON_KEY_TYPE)].as<String>();
if (type.equalsIgnoreCase(F(AUTOCONNECT_JSON_TYPE_ACSTYLE))) {
_setMember(json);
return true;
}
return false;
}
/**
* Serialize AutoConnectStyle to JSON.
* @param json JSON object to be serialized.
*/
void AutoConnectStyleJson::serialize(JsonObject& json) {
_serialize(json);
json[F(AUTOCONNECT_JSON_KEY_TYPE)] = String(F(AUTOCONNECT_JSON_TYPE_ACSTYLE));
json[F(AUTOCONNECT_JSON_KEY_VALUE)] = value;
}
/**
* Returns JSON object size.
* @return An object size for JsonBuffer.

Loading…
Cancel
Save