parent
3d0d397bf1
commit
4de6dfb101
@ -0,0 +1,135 @@ |
|||||||
|
/**
|
||||||
|
* Implementation of AutoConnectAux class and subordinated AutoConnectElement class. |
||||||
|
* @file AutoConnectAux.cpp |
||||||
|
* @author hieromon@gmail.com |
||||||
|
* @version 0.9.7 |
||||||
|
* @date 2018-11-17 |
||||||
|
* @copyright MIT license. |
||||||
|
*/ |
||||||
|
|
||||||
|
#include "AutoConnect.h" |
||||||
|
#include "AutoConnectAux.h" |
||||||
|
|
||||||
|
const char AutoConnectAux::_PAGE_AUX[] PROGMEM = { |
||||||
|
"{{HEAD}}" |
||||||
|
"<title>{{AUX_TITLE}}</title>" |
||||||
|
"<style type=\"text/css\">" |
||||||
|
"{{CSS_BASE}}" |
||||||
|
"{{CSS_UL}}" |
||||||
|
"{{CSS_INPUT_BUTTON}}" |
||||||
|
"{{CSS_INPUT_TEXT}}" |
||||||
|
"{{CSS_LUXBAR}}" |
||||||
|
"</style>" |
||||||
|
"</head>" |
||||||
|
"<body style=\"padding-top:58px;\">" |
||||||
|
"<div class=\"container\">" |
||||||
|
"{{MENU_PRE}}" |
||||||
|
"{{MENU_AUX}}" |
||||||
|
"{{MENU_POST}}" |
||||||
|
"<div class=\"base-panel\">" |
||||||
|
"<form id='_aux' method=\"post\">" |
||||||
|
"<ul class=\"noorder\">" |
||||||
|
"{{AUX_ELEMENT}}" |
||||||
|
"</ul>" |
||||||
|
"</form>" |
||||||
|
"</div>" |
||||||
|
"</div>" |
||||||
|
"<script>" |
||||||
|
"function sa(url) {" |
||||||
|
"document.getElementById('_aux').action=url;" |
||||||
|
"document.getElementIyId('_aux').submit();" |
||||||
|
"}" |
||||||
|
"</script>" |
||||||
|
"</body>" |
||||||
|
"</html>" |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructs container of AutoConnectElement and release a unique |
||||||
|
* pointer of AutoConnect instance. |
||||||
|
*/ |
||||||
|
AutoConnectAux::~AutoConnectAux() { |
||||||
|
_addonElm.clear(); |
||||||
|
_addonElm.swap(_addonElm); |
||||||
|
if (_ac) |
||||||
|
_ac.release(); |
||||||
|
} |
||||||
|
|
||||||
|
void AutoConnectAux::add(AutoConnectElement& addon) { |
||||||
|
_addonElm.push_back(addon); |
||||||
|
AC_DBG("ELM:%s placed\n", addon.name().c_str()); |
||||||
|
} |
||||||
|
|
||||||
|
void AutoConnectAux::add(AutoConnectElementVT addons) { |
||||||
|
for (std::size_t n = 0; n < addons.size(); n++) |
||||||
|
add(addons[n]); |
||||||
|
} |
||||||
|
|
||||||
|
void AutoConnectAux::_append(AutoConnectAux& aux) { |
||||||
|
if (_next) { |
||||||
|
AutoConnectAux* next = _next.get(); |
||||||
|
next->_append(aux); |
||||||
|
} |
||||||
|
else |
||||||
|
_next.reset(&aux); |
||||||
|
} |
||||||
|
|
||||||
|
void AutoConnectAux::_join(AutoConnect& ac) { |
||||||
|
_ac.reset(&ac); |
||||||
|
if (_next) { |
||||||
|
AutoConnectAux *next = _next.get(); |
||||||
|
next->_join(ac); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
const String AutoConnectAux::_insertElement(PageArgument& args) { |
||||||
|
String body = String(); |
||||||
|
|
||||||
|
for (std::size_t n = 0; n < _addonElm.size(); n++) { |
||||||
|
AutoConnectElement& addon = _addonElm[n]; |
||||||
|
body += addon.toHTML(); |
||||||
|
} |
||||||
|
return body; |
||||||
|
} |
||||||
|
|
||||||
|
PageElement* AutoConnectAux::_setupPage(String uri) { |
||||||
|
PageElement* elm = nullptr; |
||||||
|
|
||||||
|
if (_ac) { |
||||||
|
if (uri != String(_uri)) { |
||||||
|
if (_next) { |
||||||
|
elm = _next->_setupPage(uri); |
||||||
|
} |
||||||
|
} else { |
||||||
|
AutoConnect* mother = _ac.get(); |
||||||
|
elm = new PageElement(); |
||||||
|
|
||||||
|
// Overwrite the default menu title
|
||||||
|
mother->_menuTitle = _title; |
||||||
|
|
||||||
|
// Construct the auxiliary page
|
||||||
|
elm->setMold(_PAGE_AUX); |
||||||
|
elm->addToken(PSTR("HEAD"), std::bind(&AutoConnect::_token_HEAD, mother, std::placeholders::_1)); |
||||||
|
elm->addToken(PSTR("AUX_TITLE"), std::bind(&AutoConnectAux::_injectTitle, this, std::placeholders::_1)); |
||||||
|
elm->addToken(PSTR("CSS_BASE"), std::bind(&AutoConnect::_token_CSS_BASE, mother, std::placeholders::_1)); |
||||||
|
elm->addToken(PSTR("CSS_UL"), std::bind(&AutoConnect::_token_CSS_UL, mother, std::placeholders::_1)); |
||||||
|
elm->addToken(PSTR("CSS_INPUT_BUTTON"), std::bind(&AutoConnect::_token_CSS_INPUT_BUTTON, mother, std::placeholders::_1)); |
||||||
|
elm->addToken(PSTR("CSS_INPUT_TEXT"), std::bind(&AutoConnect::_token_CSS_INPUT_TEXT, mother, std::placeholders::_1)); |
||||||
|
elm->addToken(PSTR("CSS_LUXBAR"), std::bind(&AutoConnect::_token_CSS_LUXBAR, mother, std::placeholders::_1)); |
||||||
|
elm->addToken(PSTR("MENU_PRE"), std::bind(&AutoConnect::_token_MENU_PRE, mother, std::placeholders::_1)); |
||||||
|
elm->addToken(PSTR("MENU_AUX"), std::bind(&AutoConnect::_token_MENU_AUX, mother, std::placeholders::_1)); |
||||||
|
elm->addToken(PSTR("MENU_POST"), std::bind(&AutoConnect::_token_MENU_POST, mother, std::placeholders::_1)); |
||||||
|
elm->addToken(PSTR("AUX_ELEMENT"), std::bind(&AutoConnectAux::_insertElement, this, std::placeholders::_1)); |
||||||
|
} |
||||||
|
} |
||||||
|
return elm; |
||||||
|
} |
||||||
|
|
||||||
|
const String AutoConnectAux::_injectMenu(PageArgument& args) { |
||||||
|
String menuItem = String(FPSTR("<li class=\"luxbar-item\"><a href=\"")) + String(_uri) + String("\">") + _title + String(FPSTR("</a></li>")); |
||||||
|
if (_next) { |
||||||
|
AutoConnectAux* next = _next.get(); |
||||||
|
menuItem += next->_injectMenu(args); |
||||||
|
} |
||||||
|
return menuItem; |
||||||
|
} |
@ -0,0 +1,156 @@ |
|||||||
|
/**
|
||||||
|
* Declaration of AutoConnectAux class and subordinated AutoConnectElement class. |
||||||
|
* @file AutoConnectAux.h |
||||||
|
* @author hieromon@gmail.com |
||||||
|
* @version 0.9.7 |
||||||
|
* @date 2018-11-17 |
||||||
|
* @copyright MIT license. |
||||||
|
*/ |
||||||
|
|
||||||
|
#ifndef _AUTOCONNECTAUX_H_ |
||||||
|
#define _AUTOCONNECTAUX_H_ |
||||||
|
|
||||||
|
#include <vector> |
||||||
|
#include <memory> |
||||||
|
#include <functional> |
||||||
|
#include <PageBuilder.h> |
||||||
|
|
||||||
|
class AutoConnect; // Reference to avoid circular
|
||||||
|
|
||||||
|
// Add-on element base class
|
||||||
|
class AutoConnectElement { |
||||||
|
public: |
||||||
|
explicit AutoConnectElement(const char* name = nullptr, const char* value = nullptr) : _name(String(name)), _value(String(value)) {} |
||||||
|
virtual ~AutoConnectElement() {} |
||||||
|
const String name(void) const { return _name; } /**< Element name */ |
||||||
|
const String value(void) const { return _value; } /**< Element value */ |
||||||
|
virtual const String toHTML(void) { return String(); }; /**< HTML code to be generated */ |
||||||
|
|
||||||
|
protected: |
||||||
|
String _name; |
||||||
|
String _value; |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Text arrangement class, a part of AutoConnectAux element. |
||||||
|
* @param
|
||||||
|
* @param name Text name string. |
||||||
|
* @param value Text value string. |
||||||
|
* @param style A string of style-code for decoration, optionally. |
||||||
|
* An arrangement text would be placed with <div> contains. A string |
||||||
|
* of style-codes are given for '<div style=>'. |
||||||
|
*/ |
||||||
|
class AutoConnectText : public AutoConnectElement { |
||||||
|
public: |
||||||
|
explicit AutoConnectText(const char* name = nullptr, const char* value = nullptr, const char* style = nullptr) : AutoConnectElement(name, value), _style(String(style)) {} |
||||||
|
~AutoConnectText() {} |
||||||
|
const String style(void) const { return _style; } /**< A modify of HTML 'style' code */ |
||||||
|
const String toHTML(void) { |
||||||
|
return String(FPSTR("<div style=\"")) + _style + String("\">") + _value + String(FPSTR("</div>")); |
||||||
|
} |
||||||
|
|
||||||
|
protected: |
||||||
|
String _style; |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Input-box arrangement class, a part of AutoConnectAux element. |
||||||
|
* Place a optionally labeled input-box that can be added by user sketch. |
||||||
|
* @param name Input-box name string. |
||||||
|
* @param value Button value string. |
||||||
|
* @param label A label string that follows Input-box, optionally. |
||||||
|
* The label is placed in front of Input-box. |
||||||
|
*/ |
||||||
|
class AutoConnectInput : public AutoConnectElement { |
||||||
|
public: |
||||||
|
explicit AutoConnectInput(const char* name = nullptr, const char* value = nullptr, const char* label = nullptr) : AutoConnectElement(name, value), _label(String(label)) {} |
||||||
|
~AutoConnectInput() {} |
||||||
|
const String label(void) const { return _label; } |
||||||
|
const String toHTML(void) { |
||||||
|
return _label + String(FPSTR("<input type=\"text\" name=\"")) + _name + String(FPSTR("\" value=\"")) + _value + String("\"><br>"); |
||||||
|
} |
||||||
|
|
||||||
|
protected: |
||||||
|
String _label; |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Button arrangement class, a part of AutoConnectAux element. |
||||||
|
* Placed a labeled button that can be added by user sketch. |
||||||
|
* @param name Button name string. |
||||||
|
* @param value Button value string. |
||||||
|
* @param action A sting of action code, it contains a simple JavaScript code. |
||||||
|
*/ |
||||||
|
class AutoConnectButton : public AutoConnectElement { |
||||||
|
public: |
||||||
|
explicit AutoConnectButton(const char* name = nullptr, const char* value = nullptr, const String action = String()) : AutoConnectElement(name, value), _action(action) {} |
||||||
|
const String action(void) const { return _action; } |
||||||
|
const String toHTML(void) { |
||||||
|
return String(FPSTR("<button type=\"button\" name=\"")) + _name + String(FPSTR("\" value=\"")) + _value + String(FPSTR("\" onclick=\"")) + _action + String("\">") + _value + String(FPSTR("</button>")); |
||||||
|
} |
||||||
|
|
||||||
|
protected: |
||||||
|
String _action; |
||||||
|
}; |
||||||
|
|
||||||
|
/**
|
||||||
|
* Submit button arrangement class, a part of AutoConnectAux element. |
||||||
|
* Place a submit button with a label that can be added by user sketch. |
||||||
|
* With the button behavior, the values of the elements contained in |
||||||
|
* the form would be sent using the post method. |
||||||
|
* @param name Button name string. |
||||||
|
* @param value Sending value string. |
||||||
|
* @param uri Sending uri string. |
||||||
|
*/ |
||||||
|
class AutoConnectSubmit : public AutoConnectElement { |
||||||
|
public: |
||||||
|
explicit AutoConnectSubmit(const char* name = nullptr, const char* value = nullptr, const char* uri = nullptr) : AutoConnectElement(name, value), _uri(String(uri)) {} |
||||||
|
const String uri(void) const { return _uri; } |
||||||
|
const String toHTML(void) { |
||||||
|
return String(FPSTR("<button type=\"submit\" name=\"")) + _name + String(FPSTR("\" value=\"")) + _value + String(FPSTR("\" onclick=\"sa('")) + _uri + String("')\">") + _value + String(FPSTR("</button>")); |
||||||
|
} |
||||||
|
|
||||||
|
protected: |
||||||
|
String _uri; |
||||||
|
}; |
||||||
|
|
||||||
|
// Manage placed AutoConnectElement with a vector
|
||||||
|
typedef std::vector<std::reference_wrapper<AutoConnectElement>> AutoConnectElementVT; |
||||||
|
|
||||||
|
/**
|
||||||
|
* A class that handles an auxiliary page with AutoConnectElement |
||||||
|
* that placed on it by binding it to the AutoConnect menu. |
||||||
|
* @param uri An uri string of this page. |
||||||
|
* @param title A title string of this page. |
||||||
|
* @param addons A set of AutoConnectElement vector. |
||||||
|
*/ |
||||||
|
class AutoConnectAux : public PageBuilder { |
||||||
|
public: |
||||||
|
explicit AutoConnectAux(const char* uri = nullptr, const char* title = nullptr, const AutoConnectElementVT addons = AutoConnectElementVT()) : |
||||||
|
_title(String(title)), _addonElm(addons) { setUri(uri); _next.release(); _ac.release(); } |
||||||
|
~AutoConnectAux(); |
||||||
|
void add(AutoConnectElement& addon); /**< Add an element to the auxiliary page. */ |
||||||
|
void add(AutoConnectElementVT addons); /**< Add the element set to the auxiliary page. */ |
||||||
|
void setTitle(const char* title) { _title = String(title); } /**< Set a title of the auxiliary page. */ |
||||||
|
|
||||||
|
protected: |
||||||
|
void _append(AutoConnectAux& aux); |
||||||
|
void _join(AutoConnect& ac); |
||||||
|
PageElement* _setupPage(String uri); |
||||||
|
const String _insertElement(PageArgument& args); |
||||||
|
const String _injectTitle(PageArgument& args) { return _title; } |
||||||
|
const String _injectMenu(PageArgument& args); |
||||||
|
|
||||||
|
String _title; /**< A title of the page */ |
||||||
|
|
||||||
|
AutoConnectElementVT _addonElm; /**< A vector set of AutoConnectElements placed on this auxiliary page */ |
||||||
|
std::unique_ptr<AutoConnectAux> _next; /**< Auxiliary pages chain list */ |
||||||
|
std::unique_ptr<AutoConnect> _ac; /**< Hosted AutoConnect instance */ |
||||||
|
|
||||||
|
static const char _PAGE_AUX[] PROGMEM; /**< Auxiliary page template */ |
||||||
|
|
||||||
|
// Protected members can be used from AutoConnect which handles AutoConnectAux pages.
|
||||||
|
friend class AutoConnect; |
||||||
|
}; |
||||||
|
|
||||||
|
#endif // _AUTOCONNECTAUX_H_
|
Loading…
Reference in new issue