Merge with develop

--HG--
branch : compatibility-develop
hg/compatibility-develop
Nimetu 6 years ago
commit 9d3667cab4

@ -84,6 +84,9 @@ namespace NLGUI
// NOTE: Does not check combinator // NOTE: Does not check combinator
bool match(const CHtmlElement &elm) const; bool match(const CHtmlElement &elm) const;
// debug
std::string toString() const;
private: private:
bool matchClass(const CHtmlElement &elm) const; bool matchClass(const CHtmlElement &elm) const;
bool matchAttributes(const CHtmlElement &elm) const; bool matchAttributes(const CHtmlElement &elm) const;

@ -61,7 +61,7 @@ namespace NLGUI
Height=-1; Height=-1;
MaxWidth=-1; MaxWidth=-1;
MaxHeight=-1; MaxHeight=-1;
BorderWidth=1; BorderWidth=-1;
BackgroundColor=NLMISC::CRGBA::Black; BackgroundColor=NLMISC::CRGBA::Black;
BackgroundColorOver=NLMISC::CRGBA::Black; BackgroundColorOver=NLMISC::CRGBA::Black;
} }
@ -176,7 +176,7 @@ namespace NLGUI
Current.Height=-1; Current.Height=-1;
Current.MaxWidth=-1; Current.MaxWidth=-1;
Current.MaxHeight=-1; Current.MaxHeight=-1;
Current.BorderWidth=1; Current.BorderWidth=-1;
Current.StyleRules.clear(); Current.StyleRules.clear();
} }

@ -107,7 +107,7 @@ namespace NLGUI
void refresh(); void refresh();
// submit form // submit form
void submitForm (uint formId, const char *submitButtonType, const char *submitButtonName, const char *submitButtonValue, sint32 x, sint32 y); void submitForm(uint button, sint32 x, sint32 y);
// Browse error // Browse error
void browseError (const char *msg); void browseError (const char *msg);
@ -332,7 +332,7 @@ namespace NLGUI
// Add a button in the current paragraph. actionHandler, actionHandlerParams and tooltip can be NULL. // Add a button in the current paragraph. actionHandler, actionHandlerParams and tooltip can be NULL.
CCtrlButton *addButton(CCtrlButton::EType type, const std::string &name, const std::string &normalBitmap, const std::string &pushedBitmap, CCtrlButton *addButton(CCtrlButton::EType type, const std::string &name, const std::string &normalBitmap, const std::string &pushedBitmap,
const std::string &overBitmap, const char *actionHandler, const char *actionHandlerParams, const char *tooltip, const std::string &overBitmap, const char *actionHandler, const char *actionHandlerParams, const std::string &tooltip,
const CStyleParams &style = CStyleParams()); const CStyleParams &style = CStyleParams());
// Set the background color // Set the background color
@ -392,6 +392,7 @@ namespace NLGUI
bool _BrowseNextTime; bool _BrowseNextTime;
bool _PostNextTime; bool _PostNextTime;
uint _PostFormId; uint _PostFormId;
std::string _PostFormAction;
std::string _PostFormSubmitType; std::string _PostFormSubmitType;
std::string _PostFormSubmitButton; std::string _PostFormSubmitButton;
std::string _PostFormSubmitValue; std::string _PostFormSubmitValue;
@ -414,6 +415,7 @@ namespace NLGUI
// True when the <lua> element has been encountered // True when the <lua> element has been encountered
bool _ParsingLua; bool _ParsingLua;
bool _IgnoreText; bool _IgnoreText;
bool _IgnoreChildElements;
// the script to execute // the script to execute
std::string _LuaScript; std::string _LuaScript;
bool _LuaHrefHack; bool _LuaHrefHack;
@ -472,6 +474,64 @@ namespace NLGUI
}; };
std::vector<HTMLOListElement> _UL; std::vector<HTMLOListElement> _UL;
class HTMLMeterElement {
public:
enum EValueRegion {
VALUE_OPTIMUM = 0,
VALUE_SUB_OPTIMAL,
VALUE_EVEN_LESS_GOOD
};
public:
HTMLMeterElement()
: value(0.f), min(0.f), max(1.f), low(0.f), high(1.f), optimum(0.5f)
{}
// read attributes from html element
void readValues(const CHtmlElement &elm);
// return value ratio to min-max
float getValueRatio() const;
// return optimum region based current value
EValueRegion getValueRegion() const;
// return meter bar color
NLMISC::CRGBA getBarColor(const CHtmlElement &elm, CCssStyle &style) const;
// return meter value bar color based value and optimum range
NLMISC::CRGBA getValueColor(const CHtmlElement &elm, CCssStyle &style) const;
float value;
float min;
float max;
float low;
float high;
float optimum;
};
class HTMLProgressElement
{
public:
HTMLProgressElement()
: value(0.f), max(1.f)
{}
// read attributes from html element
void readValues(const CHtmlElement &elm);
// return value ratio to min-max
float getValueRatio() const;
// return meter bar color
NLMISC::CRGBA getBarColor(const CHtmlElement &elm, CCssStyle &style) const;
// return meter value bar color based value and optimum range
NLMISC::CRGBA getValueColor(const CHtmlElement &elm, CCssStyle &style) const;
float value;
float max;
};
// A mode // A mode
std::vector<bool> _A; std::vector<bool> _A;
inline bool getA() const inline bool getA() const
@ -607,6 +667,9 @@ namespace NLGUI
sint InitialSelection; // initial selection for the combo box sint InitialSelection; // initial selection for the combo box
}; };
// <form> element "id" attribute
std::string id;
// The action the form has to perform // The action the form has to perform
std::string Action; std::string Action;
@ -614,6 +677,25 @@ namespace NLGUI
std::vector<CEntry> Entries; std::vector<CEntry> Entries;
}; };
std::vector<CForm> _Forms; std::vector<CForm> _Forms;
// submit buttons added to from
struct SFormSubmitButton
{
SFormSubmitButton(const std::string &form, const std::string &name, const std::string &value, const std::string &type, const std::string &formAction="")
: form(form), name(name), value(value), type(type), formAction(formAction)
{ }
std::string form; // form 'id'
std::string name; // submit button name
std::string value; // submit button value
std::string type; // button type, ie 'image'
std::string formAction; // override form action attribute (url)
};
// submit buttons added to form
std::vector<SFormSubmitButton> _FormSubmit;
std::vector<CInterfaceGroup *> _Groups; std::vector<CInterfaceGroup *> _Groups;
// Cells parameters // Cells parameters
@ -826,12 +908,31 @@ namespace NLGUI
// apply background from current style (for html, body) // apply background from current style (for html, body)
void applyBackground(const CHtmlElement &elm); void applyBackground(const CHtmlElement &elm);
void insertFormImageButton(const std::string &name,
const std::string &tooltip,
const std::string &src,
const std::string &over,
const std::string &formId,
const std::string &formAction = "",
uint32 minWidth = 0,
const std::string &templateName = "");
void insertFormTextButton(const std::string &name,
const std::string &tooltip,
const std::string &value,
const std::string &formId,
const std::string &formAction = "",
uint32 minWidth = 0,
const std::string &templateName = "");
// HTML elements // HTML elements
void htmlA(const CHtmlElement &elm); void htmlA(const CHtmlElement &elm);
void htmlAend(const CHtmlElement &elm); void htmlAend(const CHtmlElement &elm);
void htmlBASE(const CHtmlElement &elm); void htmlBASE(const CHtmlElement &elm);
void htmlBODY(const CHtmlElement &elm); void htmlBODY(const CHtmlElement &elm);
void htmlBR(const CHtmlElement &elm); void htmlBR(const CHtmlElement &elm);
void htmlBUTTON(const CHtmlElement &elm);
void htmlBUTTONend(const CHtmlElement &elm);
void htmlDD(const CHtmlElement &elm); void htmlDD(const CHtmlElement &elm);
void htmlDDend(const CHtmlElement &elm); void htmlDDend(const CHtmlElement &elm);
//void htmlDEL(const CHtmlElement &elm); //void htmlDEL(const CHtmlElement &elm);
@ -859,6 +960,7 @@ namespace NLGUI
void htmlLUA(const CHtmlElement &elm); void htmlLUA(const CHtmlElement &elm);
void htmlLUAend(const CHtmlElement &elm); void htmlLUAend(const CHtmlElement &elm);
void htmlMETA(const CHtmlElement &elm); void htmlMETA(const CHtmlElement &elm);
void htmlMETER(const CHtmlElement &elm);
void htmlOBJECT(const CHtmlElement &elm); void htmlOBJECT(const CHtmlElement &elm);
void htmlOBJECTend(const CHtmlElement &elm); void htmlOBJECTend(const CHtmlElement &elm);
void htmlOL(const CHtmlElement &elm); void htmlOL(const CHtmlElement &elm);
@ -869,6 +971,7 @@ namespace NLGUI
void htmlPend(const CHtmlElement &elm); void htmlPend(const CHtmlElement &elm);
void htmlPRE(const CHtmlElement &elm); void htmlPRE(const CHtmlElement &elm);
void htmlPREend(const CHtmlElement &elm); void htmlPREend(const CHtmlElement &elm);
void htmlPROGRESS(const CHtmlElement &elm);
void htmlSCRIPT(const CHtmlElement &elm); void htmlSCRIPT(const CHtmlElement &elm);
void htmlSCRIPTend(const CHtmlElement &elm); void htmlSCRIPTend(const CHtmlElement &elm);
void htmlSELECT(const CHtmlElement &elm); void htmlSELECT(const CHtmlElement &elm);

@ -47,8 +47,6 @@ namespace NLGUI
// defined style and :before/:after pseudo elements // defined style and :before/:after pseudo elements
TStyle Style; TStyle Style;
TStyle StyleBefore;
TStyle StyleAfter;
// hierarchy // hierarchy
CHtmlElement *parent; CHtmlElement *parent;
@ -79,6 +77,16 @@ namespace NLGUI
// debug // debug
std::string toString(bool tree = false, uint depth = 0) const; std::string toString(bool tree = false, uint depth = 0) const;
// query, get, set pseudo element style rules
void clearPseudo();
bool hasPseudo(const std::string &key) const;
TStyle getPseudo(const std::string &key) const;
void setPseudo(const std::string &key, const TStyle &style);
private:
// pseudo elements like ":before" and ":after"
std::map<std::string, TStyle> _Pseudo;
}; };
} }

@ -631,19 +631,10 @@ namespace NLGUI
{ {
result.clear(); result.clear();
} }
else if (result.empty() || !current.empty()) else if (!current.empty())
{
// pseudo element like ':before' can only be set on the last selector
if (!result.empty() && !pseudoElement.empty())
{
// failed
result.clear();
}
else
{ {
result.push_back(current); result.push_back(current);
} }
}
return result; return result;
} }

@ -310,5 +310,43 @@ namespace NLGUI
} }
} }
std::string CCssSelector::toString() const
{
std::string ret;
ret += Element;
ret += Id;
if (!Class.empty())
{
for(uint i = 0; i<Class.size(); i++)
ret += "." + Class[i];
}
if (!Attr.empty())
{
for(uint i = 0; i<Attr.size(); ++i)
{
ret += "[" + Attr[i].key;
if (Attr[i].op != ' ')
{
ret += Attr[i].op + Attr[i].value;
}
ret += "]";
}
}
if (!PseudoClass.empty())
{
for(uint i = 0; i<PseudoClass.size(); ++i)
{
ret += ":" + PseudoClass[i];
}
}
if (Combinator != '\0')
{
ret += Combinator;
}
// ret += ":" + PseudoClass;
return ret;
}
} // namespace } // namespace

@ -89,8 +89,7 @@ namespace NLGUI
} }
elm.Style.clear(); elm.Style.clear();
elm.StyleBefore.clear(); elm.clearPseudo();
elm.StyleAfter.clear();
if (!mRules.empty()) if (!mRules.empty())
{ {
@ -101,13 +100,9 @@ namespace NLGUI
{ {
merge(elm.Style, i->Properties); merge(elm.Style, i->Properties);
} }
else if (i->PseudoElement == ":before") else
{
merge(elm.StyleBefore, i->Properties);
}
else if (i->PseudoElement == ":after")
{ {
merge(elm.StyleAfter, i->Properties); elm.setPseudo(i->PseudoElement, i->Properties);
} }
} }
} }

@ -1078,6 +1078,7 @@ namespace NLGUI
case HTML_BASE: htmlBASE(elm); break; case HTML_BASE: htmlBASE(elm); break;
case HTML_BODY: htmlBODY(elm); break; case HTML_BODY: htmlBODY(elm); break;
case HTML_BR: htmlBR(elm); break; case HTML_BR: htmlBR(elm); break;
case HTML_BUTTON: htmlBUTTON(elm); break;
case HTML_DD: htmlDD(elm); break; case HTML_DD: htmlDD(elm); break;
case HTML_DEL: renderPseudoElement(":before", elm); break; case HTML_DEL: renderPseudoElement(":before", elm); break;
case HTML_DIV: htmlDIV(elm); break; case HTML_DIV: htmlDIV(elm); break;
@ -1101,11 +1102,13 @@ namespace NLGUI
case HTML_LI: htmlLI(elm); break; case HTML_LI: htmlLI(elm); break;
case HTML_LUA: htmlLUA(elm); break; case HTML_LUA: htmlLUA(elm); break;
case HTML_META: htmlMETA(elm); break; case HTML_META: htmlMETA(elm); break;
case HTML_METER: htmlMETER(elm); break;
case HTML_OBJECT: htmlOBJECT(elm); break; case HTML_OBJECT: htmlOBJECT(elm); break;
case HTML_OL: htmlOL(elm); break; case HTML_OL: htmlOL(elm); break;
case HTML_OPTION: htmlOPTION(elm); break; case HTML_OPTION: htmlOPTION(elm); break;
case HTML_P: htmlP(elm); break; case HTML_P: htmlP(elm); break;
case HTML_PRE: htmlPRE(elm); break; case HTML_PRE: htmlPRE(elm); break;
case HTML_PROGRESS: htmlPROGRESS(elm); break;
case HTML_SCRIPT: htmlSCRIPT(elm); break; case HTML_SCRIPT: htmlSCRIPT(elm); break;
case HTML_SELECT: htmlSELECT(elm); break; case HTML_SELECT: htmlSELECT(elm); break;
case HTML_SMALL: renderPseudoElement(":before", elm); break; case HTML_SMALL: renderPseudoElement(":before", elm); break;
@ -1137,6 +1140,7 @@ namespace NLGUI
case HTML_BASE: break; case HTML_BASE: break;
case HTML_BODY: renderPseudoElement(":after", elm); break; case HTML_BODY: renderPseudoElement(":after", elm); break;
case HTML_BR: break; case HTML_BR: break;
case HTML_BUTTON: htmlBUTTONend(elm); break;
case HTML_DD: htmlDDend(elm); break; case HTML_DD: htmlDDend(elm); break;
case HTML_DEL: renderPseudoElement(":after", elm); break; case HTML_DEL: renderPseudoElement(":after", elm); break;
case HTML_DIV: htmlDIVend(elm); break; case HTML_DIV: htmlDIVend(elm); break;
@ -1160,6 +1164,7 @@ namespace NLGUI
case HTML_LI: htmlLIend(elm); break; case HTML_LI: htmlLIend(elm); break;
case HTML_LUA: htmlLUAend(elm); break; case HTML_LUA: htmlLUAend(elm); break;
case HTML_META: break; case HTML_META: break;
case HTML_METER: break;
case HTML_OBJECT: htmlOBJECTend(elm); break; case HTML_OBJECT: htmlOBJECTend(elm); break;
case HTML_OL: htmlOLend(elm); break; case HTML_OL: htmlOLend(elm); break;
case HTML_OPTION: htmlOPTIONend(elm); break; case HTML_OPTION: htmlOPTIONend(elm); break;
@ -1191,26 +1196,20 @@ namespace NLGUI
// *************************************************************************** // ***************************************************************************
void CGroupHTML::renderPseudoElement(const std::string &pseudo, const CHtmlElement &elm) void CGroupHTML::renderPseudoElement(const std::string &pseudo, const CHtmlElement &elm)
{ {
if (pseudo == ":before" && !elm.StyleBefore.empty()) if (pseudo != ":before" && pseudo != ":after")
{
_Style.pushStyle();
_Style.applyStyle(elm.StyleBefore);
}
else if (pseudo == ":after" && !elm.StyleAfter.empty())
{
_Style.pushStyle();
_Style.applyStyle(elm.StyleAfter);
}
else
{
// unknown pseudo element
return; return;
}
if (!elm.hasPseudo(pseudo))
return;
_Style.pushStyle();
_Style.applyStyle(elm.getPseudo(pseudo));
// TODO: 'content' should already be tokenized in css parser as it has all the functions for that // TODO: 'content' should already be tokenized in css parser as it has all the functions for that
std::string content = trim(_Style.getStyle("content")); std::string content = trim(_Style.getStyle("content"));
if (toLower(content) == "none" || toLower(content) == "normal") if (toLower(content) == "none" || toLower(content) == "normal")
{ {
_Style.popStyle();
return; return;
} }
@ -1341,12 +1340,16 @@ namespace NLGUI
beginElement(elm); beginElement(elm);
std::list<CHtmlElement>::iterator it = elm.Children.begin(); std::list<CHtmlElement>::iterator it = elm.Children.begin();
if (!_IgnoreChildElements)
{
while(it != elm.Children.end()) while(it != elm.Children.end())
{ {
renderDOM(*it); renderDOM(*it);
++it; ++it;
} }
}
_IgnoreChildElements = false;
endElement(elm); endElement(elm);
} }
@ -1377,6 +1380,7 @@ namespace NLGUI
_ParsingLua = false; _ParsingLua = false;
_LuaHrefHack = false; _LuaHrefHack = false;
_IgnoreText = false; _IgnoreText = false;
_IgnoreChildElements = false;
_BrowseNextTime = false; _BrowseNextTime = false;
_PostNextTime = false; _PostNextTime = false;
_Browsing = false; _Browsing = false;
@ -2759,6 +2763,9 @@ namespace NLGUI
// Translate the tooltip // Translate the tooltip
ctrlButton->setDefaultContextHelp(ucstring::makeFromUtf8(getLinkTitle())); ctrlButton->setDefaultContextHelp(ucstring::makeFromUtf8(getLinkTitle()));
ctrlButton->setText(tmpStr); ctrlButton->setText(tmpStr);
// empty url / button disabled
bool disabled = string(getLink()).empty();
ctrlButton->setFrozen(disabled);
setTextButtonStyle(ctrlButton, style); setTextButtonStyle(ctrlButton, style);
} }
@ -2999,7 +3006,7 @@ namespace NLGUI
CCtrlButton *CGroupHTML::addButton(CCtrlButton::EType type, const std::string &name, const std::string &normalBitmap, const std::string &pushedBitmap, CCtrlButton *CGroupHTML::addButton(CCtrlButton::EType type, const std::string &name, const std::string &normalBitmap, const std::string &pushedBitmap,
const std::string &overBitmap, const char *actionHandler, const char *actionHandlerParams, const std::string &overBitmap, const char *actionHandler, const char *actionHandlerParams,
const char *tooltip, const CStyleParams &style) const std::string &tooltip, const CStyleParams &style)
{ {
// In a paragraph ? // In a paragraph ?
if (!_Paragraph) if (!_Paragraph)
@ -3069,7 +3076,7 @@ namespace NLGUI
ctrlButton->setParamsOnLeftClick (actionHandlerParams); ctrlButton->setParamsOnLeftClick (actionHandlerParams);
// Translate the tooltip or display raw text (tooltip from webig) // Translate the tooltip or display raw text (tooltip from webig)
if (tooltip) if (!tooltip.empty())
{ {
if (CI18N::hasTranslation(tooltip)) if (CI18N::hasTranslation(tooltip))
{ {
@ -3120,6 +3127,7 @@ namespace NLGUI
_Cells.clear(); _Cells.clear();
_TR.clear(); _TR.clear();
_Forms.clear(); _Forms.clear();
_FormSubmit.clear();
_Groups.clear(); _Groups.clear();
_Divs.clear(); _Divs.clear();
_Anchors.clear(); _Anchors.clear();
@ -3330,21 +3338,32 @@ namespace NLGUI
// *************************************************************************** // ***************************************************************************
void CGroupHTML::submitForm (uint formId, const char *submitButtonType, const char *submitButtonName, const char *submitButtonValue, sint32 x, sint32 y) void CGroupHTML::submitForm(uint button, sint32 x, sint32 y)
{ {
// Form id valid ? if (button >= _FormSubmit.size())
if (formId < _Forms.size()) return;
for(uint formId = 0; formId < _Forms.size(); formId++)
{
// case sensitive search (user id is lowecase, auto id is uppercase)
if (_Forms[formId].id == _FormSubmit[button].form)
{ {
_PostNextTime = true; _PostNextTime = true;
_PostFormId = formId; _PostFormId = formId;
_PostFormSubmitType = submitButtonType; _PostFormAction = _FormSubmit[button].formAction;
_PostFormSubmitButton = submitButtonName; _PostFormSubmitType = _FormSubmit[button].type;
_PostFormSubmitValue = submitButtonValue; _PostFormSubmitButton = _FormSubmit[button].name;
_PostFormSubmitValue = _FormSubmit[button].value;
_PostFormSubmitX = x; _PostFormSubmitX = x;
_PostFormSubmitY = y; _PostFormSubmitY = y;
return;
} }
} }
nlwarning("Unable to find form '%s' to submit (button '%s')", _FormSubmit[button].form.c_str(), _FormSubmit[button].name.c_str());
}
// *************************************************************************** // ***************************************************************************
void CGroupHTML::setBackgroundColor (const CRGBA &bgcolor) void CGroupHTML::setBackgroundColor (const CRGBA &bgcolor)
@ -3516,7 +3535,8 @@ namespace NLGUI
// Ref the form // Ref the form
CForm &form = _Forms[_PostFormId]; CForm &form = _Forms[_PostFormId];
_URL = form.Action; // button can override form action url (and methor, but we only do POST)
_URL = _PostFormAction.empty() ? form.Action : _PostFormAction;
CUrlParser uri(_URL); CUrlParser uri(_URL);
_TrustedDomain = isTrustedDomain(uri.host); _TrustedDomain = isTrustedDomain(uri.host);
@ -4893,7 +4913,16 @@ namespace NLGUI
// td { padding: 1px;} - overwrites cellpadding attribute // td { padding: 1px;} - overwrites cellpadding attribute
// table { border-spacing: 2px;} - overwrites cellspacing attribute // table { border-spacing: 2px;} - overwrites cellspacing attribute
css += "table { border-collapse: separate;}"; css += "table { border-collapse: separate;}";
// webkit pseudo elements
css += "meter::-webkit-meter-bar, meter::-webkit-optimum-value, meter::-webkit-suboptimum-value, meter::-webkit-even-less-good-value { background: none; }";
css += "meter::-webkit-meter-bar { background-color: rgb(100, 100, 100); width: 5em; height: 1em;}";
css += "meter::-webkit-meter-optimum-value { background-color: rgb(80, 220, 80); }";
css += "meter::-webkit-meter-suboptimum-value { background-color: rgb(220, 220, 80); }";
css += "meter::-webkit-meter-even-less-good-value { background-color: rgb(220, 80, 80); }";
// webkit pseudo elements
css += "progress::-webkit-progress-bar, progress::-webkit-progress-value { background: none; }";
css += "progress::-webkit-progress-bar { background-color: rgb(230, 230, 230); width: 10em; height: 1em; }";
css += "progress::-webkit-progress-value { background-color: rgb(0, 100, 180);}";
_Style.parseStylesheet(css); _Style.parseStylesheet(css);
} }
@ -4998,6 +5027,177 @@ namespace NLGUI
return ret; return ret;
} }
void CGroupHTML::HTMLMeterElement::readValues(const CHtmlElement &elm)
{
if (!elm.hasAttribute("value") || !fromString(elm.getAttribute("value"), value))
value = 0.f;
if (!elm.hasAttribute("min") || !fromString(elm.getAttribute("min"), min))
min = 0.f;
if (!elm.hasAttribute("max") || !fromString(elm.getAttribute("max"), max))
max = 1.f;
// ensure min < max
if (max < min)
std::swap(min, max);
if (!elm.hasAttribute("low") || !fromString(elm.getAttribute("low"), low))
low = min;
if (!elm.hasAttribute("high") || !fromString(elm.getAttribute("high"), high))
high = max;
if (!elm.hasAttribute("optimum") || !fromString(elm.getAttribute("optimum"), optimum))
optimum = (max - min) / 2.f;
// ensure low < high
if (high < low)
std::swap(low, high);
if (low < min)
low = min;
if (high > max)
max = max;
}
float CGroupHTML::HTMLMeterElement::getValueRatio() const
{
if (max <= min)
return 0.f;
return (value - min) / (max - min);
}
CGroupHTML::HTMLMeterElement::EValueRegion CGroupHTML::HTMLMeterElement::getValueRegion() const
{
if (optimum <= low)
{
// low region is optimum
if (value <= low)
return VALUE_OPTIMUM;
else if (value <= high)
return VALUE_SUB_OPTIMAL;
return VALUE_EVEN_LESS_GOOD;
}
else if (optimum >= high)
{
// high region is optimum
if (value >= high)
return VALUE_OPTIMUM;
else if (value >= low)
return VALUE_SUB_OPTIMAL;
return VALUE_EVEN_LESS_GOOD;
}
// middle region is optimum
if (value >= low && value <= high)
return VALUE_OPTIMUM;
return VALUE_SUB_OPTIMAL;
}
NLMISC::CRGBA CGroupHTML::HTMLMeterElement::getBarColor(const CHtmlElement &elm, CCssStyle &style) const
{
// color meter (inactive) bar segment
// firefox:: meter { background:none; background-color: #555; },
// webkit:: meter::-webkit-meter-bar { background:none; background-color: #555; }
// webkit makes background color visible when padding is added
CRGBA color(150, 150, 150, 255);
// use webkit pseudo elements as thats easier than firefox pseudo classes
// background-color is expected to be set from browser.css
style.pushStyle();
style.applyStyle(elm.getPseudo(":-webkit-meter-bar"));
if(style.hasStyle("background-color"))
color = style.Current.BackgroundColor;
style.popStyle();
return color;
}
NLMISC::CRGBA CGroupHTML::HTMLMeterElement::getValueColor(const CHtmlElement &elm, CCssStyle &style) const
{
// background-color is expected to be set from browser.css
CRGBA color;
style.pushStyle();
switch(getValueRegion())
{
case VALUE_OPTIMUM:
{
style.applyStyle(elm.getPseudo(":-webkit-meter-optimum-value"));
if (style.hasStyle("background-color"))
color = style.Current.BackgroundColor;
break;
}
case VALUE_SUB_OPTIMAL:
{
style.applyStyle(elm.getPseudo(":-webkit-meter-suboptimum-value"));
if (style.hasStyle("background-color"))
color = style.Current.BackgroundColor;
break;
}
case VALUE_EVEN_LESS_GOOD: // fall through
default:
{
style.applyStyle(elm.getPseudo(":-webkit-meter-even-less-good-value"));
if (style.hasStyle("background-color"))
color = style.Current.BackgroundColor;
break;
}
}//switch
style.popStyle();
return color;
}
// ****************************************************************************
void CGroupHTML::HTMLProgressElement::readValues(const CHtmlElement &elm)
{
if (!elm.hasAttribute("value") || !fromString(elm.getAttribute("value"), value))
value = 0.f;
if (!elm.hasAttribute("max") || !fromString(elm.getAttribute("max"), max))
max = 1.f;
if (value > max)
value = max;
}
// ****************************************************************************
float CGroupHTML::HTMLProgressElement::getValueRatio() const
{
if (max > 0.f)
return value / max;
return 0.f;
}
// ****************************************************************************
NLMISC::CRGBA CGroupHTML::HTMLProgressElement::getBarColor(const CHtmlElement &elm, CCssStyle &style) const
{
CRGBA color;
style.pushStyle();
style.applyStyle(elm.getPseudo(":-webkit-progress-bar"));
if (style.hasStyle("background-color"))
color = style.Current.BackgroundColor;
style.popStyle();
return color;
}
// ****************************************************************************
NLMISC::CRGBA CGroupHTML::HTMLProgressElement::getValueColor(const CHtmlElement &elm, CCssStyle &style) const
{
CRGBA color;
style.pushStyle();
style.applyStyle(elm.getPseudo(":-webkit-progress-value"));
if (style.hasStyle("background-color"))
color = style.Current.BackgroundColor;
style.popStyle();
return color;
}
// ****************************************************************************
void CGroupHTML::getCellsParameters(const CHtmlElement &elm, bool inherit) void CGroupHTML::getCellsParameters(const CHtmlElement &elm, bool inherit)
{ {
CGroupHTML::CCellParams cellParams; CGroupHTML::CCellParams cellParams;
@ -5091,6 +5291,71 @@ namespace NLGUI
} }
// ***************************************************************************
void CGroupHTML::insertFormImageButton(const std::string &name, const std::string &tooltip, const std::string &src, const std::string &over, const std::string &formId, const std::string &action, uint32 minWidth, const std::string &templateName)
{
_FormSubmit.push_back(SFormSubmitButton(formId, name, "", "image"));
// Action handler parameters
std::string param = "name=" + getId() + "|button=" + toString(_FormSubmit.size()-1);
// Add the ctrl button
addButton (CCtrlButton::PushButton, name, src, src, over, "html_submit_form", param.c_str(), tooltip.c_str(), _Style.Current);
}
// ***************************************************************************
void CGroupHTML::insertFormTextButton(const std::string &name, const std::string &tooltip, const std::string &value, const std::string &formId, const std::string &formAction, uint32 minWidth, const std::string &templateName)
{
_FormSubmit.push_back(SFormSubmitButton(formId, name, value, "submit"));
// Action handler parameters
string param = "name=" + getId() + "|button=" + toString(_FormSubmit.size()-1);
// Add the ctrl button
if (!_Paragraph)
{
newParagraph (0);
paragraphChange ();
}
string buttonTemplate(!templateName.empty() ? templateName : DefaultButtonGroup);
typedef pair<string, string> TTmplParam;
vector<TTmplParam> tmplParams;
tmplParams.push_back(TTmplParam("id", name));
tmplParams.push_back(TTmplParam("onclick", "html_submit_form"));
tmplParams.push_back(TTmplParam("onclick_param", param));
tmplParams.push_back(TTmplParam("active", "true"));
if (minWidth > 0) tmplParams.push_back(TTmplParam("wmin", toString(minWidth)));
CInterfaceGroup *buttonGroup = CWidgetManager::getInstance()->getParser()->createGroupInstance(buttonTemplate, _Paragraph->getId(), tmplParams);
if (buttonGroup)
{
// Add the ctrl button
CCtrlTextButton *ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("button"));
if (!ctrlButton) ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("b"));
if (ctrlButton)
{
ctrlButton->setModulateGlobalColorAll (_Style.Current.GlobalColor);
// Translate the tooltip
if (!tooltip.empty())
{
if (CI18N::hasTranslation(tooltip))
{
ctrlButton->setDefaultContextHelp(CI18N::get(tooltip));
}
else
{
ctrlButton->setDefaultContextHelp(ucstring(tooltip));
}
}
ctrlButton->setText(ucstring::makeFromUtf8(value));
setTextButtonStyle(ctrlButton, _Style.Current);
}
getParagraph()->addChild (buttonGroup);
paragraphChange ();
}
}
// *************************************************************************** // ***************************************************************************
void CGroupHTML::htmlA(const CHtmlElement &elm) void CGroupHTML::htmlA(const CHtmlElement &elm)
{ {
@ -5176,6 +5441,55 @@ namespace NLGUI
addString(tmp); addString(tmp);
} }
// ***************************************************************************
void CGroupHTML::htmlBUTTON(const CHtmlElement &elm)
{
std::string name = elm.getAttribute("name");
std::string value = elm.getAttribute("value");
std::string formId = elm.getAttribute("form");
std::string formAction = elm.getAttribute("formaction");
std::string tooltip = elm.getAttribute("tooltip");
bool disabled = elm.hasAttribute("disabled");
if (!formAction.empty())
{
formAction = getAbsoluteUrl(formAction);
}
_FormSubmit.push_back(SFormSubmitButton(formId, name, value, "text", formAction));
// Action handler parameters
std::string param;
if (!disabled)
{
if (elm.getAttribute("type") == "submit")
{
param = "ah:html_submit_form&name=" + getId() + "&button=" + toString(_FormSubmit.size()-1);
}
else
{
param = "ah:";
}
}
_A.push_back(true);
_Link.push_back(param);
_LinkTitle.push_back(tooltip);
_LinkClass.push_back("ryzom-ui-button");
// TODO: this creates separate button element
//renderPseudoElement(":before", elm);
}
void CGroupHTML::htmlBUTTONend(const CHtmlElement &elm)
{
// TODO: this creates separate button element
//renderPseudoElement(":after", elm);
popIfNotEmpty(_A);
popIfNotEmpty(_Link);
popIfNotEmpty(_LinkTitle);
popIfNotEmpty(_LinkClass);
}
// *************************************************************************** // ***************************************************************************
void CGroupHTML::htmlDD(const CHtmlElement &elm) void CGroupHTML::htmlDD(const CHtmlElement &elm)
{ {
@ -5429,6 +5743,12 @@ namespace NLGUI
{ {
// Build the form // Build the form
CGroupHTML::CForm form; CGroupHTML::CForm form;
// id check is case sensitive and auto id's are uppercase
form.id = toLower(trim(elm.getAttribute("id")));
if (form.id.empty())
{
form.id = toString("FORM%d", _Forms.size());
}
// Get the action name // Get the action name
if (elm.hasNonEmptyAttribute("action")) if (elm.hasNonEmptyAttribute("action"))
@ -5552,26 +5872,23 @@ namespace NLGUI
// Tooltip // Tooltip
// keep "alt" attribute for backward compatibility // keep "alt" attribute for backward compatibility
std::string strtooltip = elm.getAttribute("alt"); std::string tooltip = elm.getAttribute("alt");
// tooltip // tooltip
if (elm.hasNonEmptyAttribute("title")) if (elm.hasNonEmptyAttribute("title"))
strtooltip = elm.getAttribute("title"); tooltip = elm.getAttribute("title");
const char *tooltip = NULL;
// note: uses pointer to string data
if (!strtooltip.empty())
tooltip = strtooltip.c_str();
// Mouse over image // Mouse over image
string overSrc = elm.getAttribute("data-over-src"); string overSrc = elm.getAttribute("data-over-src");
if (getA() && getParent () && getParent ()->getParent()) // inside a/button with valid url (ie, button is not disabled)
string url = getLink();
if (getA() && !url.empty() && getParent() && getParent()->getParent())
{ {
string params = "name=" + getId() + "|url=" + getLink (); string params = "name=" + getId() + "|url=" + url;
addButton(CCtrlButton::PushButton, id, src, src, overSrc, "browse", params.c_str(), tooltip, _Style.Current); addButton(CCtrlButton::PushButton, id, src, src, overSrc, "browse", params.c_str(), tooltip, _Style.Current);
} }
else else
if (tooltip || !overSrc.empty()) if (!tooltip.empty() || !overSrc.empty())
{ {
addButton(CCtrlButton::PushButton, id, src, src, overSrc, "", "", tooltip, _Style.Current); addButton(CCtrlButton::PushButton, id, src, src, overSrc, "", "", tooltip, _Style.Current);
} }
@ -5611,7 +5928,8 @@ namespace NLGUI
templateName = elm.getAttribute("z_input_tmpl"); templateName = elm.getAttribute("z_input_tmpl");
// Widget minimal width // Widget minimal width
string minWidth = elm.getAttribute("z_input_width"); uint32 minWidth = 0;
fromString(elm.getAttribute("z_input_width"), minWidth);
// <input type="..."> // <input type="...">
std::string type = trim(elm.getAttribute("type")); std::string type = trim(elm.getAttribute("type"));
@ -5626,96 +5944,23 @@ namespace NLGUI
_Style.Current.GlobalColor = true; _Style.Current.GlobalColor = true;
// Tooltip // Tooltip
std::string strtooltip = elm.getAttribute("alt"); std::string tooltip = elm.getAttribute("alt");
const char *tooltip = NULL;
// note: uses pointer to strtooltip data
if (!strtooltip.empty())
tooltip = strtooltip.c_str();
if (type == "image") if (type == "image")
{ {
// The submit button
string name = elm.getAttribute("name"); string name = elm.getAttribute("name");
string normal = elm.getAttribute("src"); string src = elm.getAttribute("src");
string pushed; string over = elm.getAttribute("data-over-src");
string over;
// Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name" insertFormImageButton(name, tooltip, src, over, _Forms.back().id, "", minWidth, templateName);
string param = "name=" + getId() + "|form=" + toString (_Forms.size()-1) + "|submit_button=" + name + "|submit_button_type=image";
// Add the ctrl button
addButton (CCtrlButton::PushButton, name, normal, pushed.empty()?normal:pushed, over,
"html_submit_form", param.c_str(), tooltip, _Style.Current);
} }
else if (type == "button" || type == "submit") else if (type == "button" || type == "submit")
{ {
// The submit button // The submit button
string name = elm.getAttribute("name"); string name = elm.getAttribute("name");
string normal = elm.getAttribute("src"); string value = elm.getAttribute("value");
string text = elm.getAttribute("value");
string pushed;
string over;
string buttonTemplate(!templateName.empty() ? templateName : DefaultButtonGroup );
// Action handler parameters : "name=group_html_id|form=id_of_the_form|submit_button=button_name"
string param = "name=" + getId() + "|form=" + toString (_Forms.size()-1) + "|submit_button=" + name + "|submit_button_type=submit";
if (!text.empty())
{
// escape AH param separator
string tmp = text;
while(NLMISC::strFindReplace(tmp, "|", "&#124;"))
;
param = param + "|submit_button_value=" + tmp;
}
// Add the ctrl button insertFormTextButton(name, tooltip, value, _Forms.back().id, "", minWidth, templateName);
if (!_Paragraph)
{
newParagraph (0);
paragraphChange ();
}
typedef pair<string, string> TTmplParam;
vector<TTmplParam> tmplParams;
tmplParams.push_back(TTmplParam("id", name));
tmplParams.push_back(TTmplParam("onclick", "html_submit_form"));
tmplParams.push_back(TTmplParam("onclick_param", param));
//tmplParams.push_back(TTmplParam("text", text));
tmplParams.push_back(TTmplParam("active", "true"));
if (!minWidth.empty())
tmplParams.push_back(TTmplParam("wmin", minWidth));
CInterfaceGroup *buttonGroup = CWidgetManager::getInstance()->getParser()->createGroupInstance(buttonTemplate, _Paragraph->getId(), tmplParams);
if (buttonGroup)
{
// Add the ctrl button
CCtrlTextButton *ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("button"));
if (!ctrlButton) ctrlButton = dynamic_cast<CCtrlTextButton*>(buttonGroup->getCtrl("b"));
if (ctrlButton)
{
ctrlButton->setModulateGlobalColorAll (_Style.Current.GlobalColor);
// Translate the tooltip
if (tooltip)
{
if (CI18N::hasTranslation(tooltip))
{
ctrlButton->setDefaultContextHelp(CI18N::get(tooltip));
}
else
{
ctrlButton->setDefaultContextHelp(ucstring(tooltip));
}
}
ctrlButton->setText(ucstring::makeFromUtf8(text));
setTextButtonStyle(ctrlButton, _Style.Current);
}
getParagraph()->addChild (buttonGroup);
paragraphChange ();
}
} }
else if (type == "text") else if (type == "text")
{ {
@ -5935,6 +6180,50 @@ namespace NLGUI
} }
} }
// ***************************************************************************
void CGroupHTML::htmlMETER(const CHtmlElement &elm)
{
HTMLMeterElement meter;
meter.readValues(elm);
std::string id = "meter";
if (elm.hasAttribute("id"))
id = elm.getAttribute("id");
// width: 5em, height: 1em
uint32 width = _Style.Current.Width > -1 ? _Style.Current.Width : _Style.Current.FontSize * 5;
uint32 height = _Style.Current.Height > -1 ? _Style.Current.Height : _Style.Current.FontSize;
uint32 border = _Style.Current.BorderWidth > -1 ? _Style.Current.BorderWidth : 0;
uint barw = (uint) (width * meter.getValueRatio());
CRGBA bgColor = meter.getBarColor(elm, _Style);
CRGBA valueColor = meter.getValueColor(elm, _Style);
typedef pair<string, string> TTmplParam;
vector<TTmplParam> tmplParams;
tmplParams.push_back(TTmplParam("id", id));
tmplParams.push_back(TTmplParam("active", "true"));
tmplParams.push_back(TTmplParam("w", toString(width)));
tmplParams.push_back(TTmplParam("h", toString(height)));
tmplParams.push_back(TTmplParam("border_x2", toString(border*2)));
tmplParams.push_back(TTmplParam("bgtexture", "blank.tga"));
tmplParams.push_back(TTmplParam("bgcolor", bgColor.toString()));
tmplParams.push_back(TTmplParam("value_w", toString(barw)));
tmplParams.push_back(TTmplParam("value_texture", "blank.tga"));
tmplParams.push_back(TTmplParam("value_color", valueColor.toString()));
CInterfaceGroup *gr = CWidgetManager::getInstance()->getParser()->createGroupInstance("html_meter", getParagraph()->getId(), &tmplParams[0], (uint)tmplParams.size());
if (gr)
{
renderPseudoElement(":before", elm);
getParagraph()->addChild(gr);
renderPseudoElement(":after", elm);
// ignore any inner elements
_IgnoreChildElements = true;
}
}
// *************************************************************************** // ***************************************************************************
void CGroupHTML::htmlOBJECT(const CHtmlElement &elm) void CGroupHTML::htmlOBJECT(const CHtmlElement &elm)
{ {
@ -6109,6 +6398,50 @@ namespace NLGUI
popIfNotEmpty(_PRE); popIfNotEmpty(_PRE);
} }
// ***************************************************************************
void CGroupHTML::htmlPROGRESS(const CHtmlElement &elm)
{
HTMLProgressElement progress;
progress.readValues(elm);
std::string id = "progress";
if (elm.hasAttribute("id"))
id = elm.getAttribute("id");
// width: 10em, height: 1em
uint32 width = _Style.Current.Width > -1 ? _Style.Current.Width : _Style.Current.FontSize * 10;
uint32 height = _Style.Current.Height > -1 ? _Style.Current.Height : _Style.Current.FontSize;
uint32 border = _Style.Current.BorderWidth > -1 ? _Style.Current.BorderWidth : 0;
uint barw = (uint) (width * progress.getValueRatio());
CRGBA bgColor = progress.getBarColor(elm, _Style);
CRGBA valueColor = progress.getValueColor(elm, _Style);
typedef pair<string, string> TTmplParam;
vector<TTmplParam> tmplParams;
tmplParams.push_back(TTmplParam("id", id));
tmplParams.push_back(TTmplParam("active", "true"));
tmplParams.push_back(TTmplParam("w", toString(width)));
tmplParams.push_back(TTmplParam("h", toString(height)));
tmplParams.push_back(TTmplParam("border_x2", toString(border*2)));
tmplParams.push_back(TTmplParam("bgtexture", "blank.tga"));
tmplParams.push_back(TTmplParam("bgcolor", bgColor.toString()));
tmplParams.push_back(TTmplParam("value_w", toString(barw)));
tmplParams.push_back(TTmplParam("value_texture", "blank.tga"));
tmplParams.push_back(TTmplParam("value_color", valueColor.toString()));
CInterfaceGroup *gr = CWidgetManager::getInstance()->getParser()->createGroupInstance("html_progress", getParagraph()->getId(), &tmplParams[0], (uint)tmplParams.size());
if (gr)
{
renderPseudoElement(":before", elm);
getParagraph()->addChild(gr);
renderPseudoElement(":after", elm);
// ignore any inner elements
_IgnoreChildElements = true;
}
}
// *************************************************************************** // ***************************************************************************
void CGroupHTML::htmlSCRIPT(const CHtmlElement &elm) void CGroupHTML::htmlSCRIPT(const CHtmlElement &elm)
{ {

@ -82,6 +82,46 @@ namespace NLGUI
} }
} }
// ***************************************************************************
void CHtmlElement::clearPseudo()
{
_Pseudo.clear();
}
// ***************************************************************************
bool CHtmlElement::hasPseudo(const std::string &key) const
{
return _Pseudo.find(key) != _Pseudo.end();
}
// ***************************************************************************
TStyle CHtmlElement::getPseudo(const std::string &key) const
{
std::map<std::string, TStyle>::const_iterator it = _Pseudo.find(key);
if (it != _Pseudo.end())
return it->second;
return TStyle();
}
// ***************************************************************************
void CHtmlElement::setPseudo(const std::string &key, const TStyle &style)
{
std::map<std::string, TStyle>::iterator it = _Pseudo.find(key);
if (it != _Pseudo.end())
{
// insert into previous, override previous values if they exist
for(TStyle::const_iterator itStyle = style.begin(); itStyle != style.end(); ++itStyle)
{
it->second[itStyle->first] = itStyle->second;
}
}
else
{
_Pseudo[key] = style;
}
}
// *************************************************************************** // ***************************************************************************
std::string CHtmlElement::toString(bool tree, uint depth) const std::string CHtmlElement::toString(bool tree, uint depth) const
{ {

@ -1103,20 +1103,18 @@ REGISTER_ACTION_HANDLER( CHandlerBrowseRefresh, "browse_refresh");
// *************************************************************************** // ***************************************************************************
/** Build the help window for a pact/item/brick and open it.
*/
class CHandlerHTMLSubmitForm : public IActionHandler class CHandlerHTMLSubmitForm : public IActionHandler
{ {
void execute (CCtrlBase *pCaller, const std::string &sParams) void execute (CCtrlBase *pCaller, const std::string &sParams)
{ {
string container = getParam (sParams, "name"); string container = getParam (sParams, "name");
uint form; uint button;
fromString(getParam (sParams, "form"), form); if (!fromString(getParam(sParams, "button"), button))
{
string submit_button = getParam (sParams, "submit_button"); nlwarning("Invalid button index: '%s', expected integer", getParam(sParams, "button").c_str());
string type = getParam (sParams, "submit_button_type"); return;
string value = getParam (sParams, "submit_button_value"); }
sint32 x = pCaller->getEventX(); sint32 x = pCaller->getEventX();
sint32 y = pCaller->getEventY(); sint32 y = pCaller->getEventY();
@ -1127,8 +1125,7 @@ class CHandlerHTMLSubmitForm : public IActionHandler
CGroupHTML *groupHtml = dynamic_cast<CGroupHTML*>(element); CGroupHTML *groupHtml = dynamic_cast<CGroupHTML*>(element);
if (groupHtml) if (groupHtml)
{ {
// Submit the form the url groupHtml->submitForm(button, x, y);
groupHtml->submitForm (form, type.c_str(), submit_button.c_str(), value.c_str(), x, y);
} }
} }
} }

Loading…
Cancel
Save