diff --git a/code/nel/include/nel/gui/css_border_renderer.h b/code/nel/include/nel/gui/css_border_renderer.h new file mode 100644 index 000000000..41ea3b7e6 --- /dev/null +++ b/code/nel/include/nel/gui/css_border_renderer.h @@ -0,0 +1,94 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + + +#ifndef NL_CSS_BORDER_RENDERER_H +#define NL_CSS_BORDER_RENDERER_H + +#include "nel/misc/types_nl.h" +#include "nel/misc/rgba.h" +#include "nel/misc/geom_ext.h" +#include "nel/gui/css_types.h" + +namespace NLGUI +{ + /** + * \brief Border renderer for GUI classes + * \date 2019-09-03 10:50 GMT + * \author Meelis Mägi (Nimetu) + */ + class CSSBorderRenderer + { + private: + // parent element screen coordinates + sint32 _XReal, _YReal; + sint32 _WReal, _HReal; + + NLMISC::CQuadUV _QuadT; + NLMISC::CQuadUV _QuadR; + NLMISC::CQuadUV _QuadB; + NLMISC::CQuadUV _QuadL; + + uint8 _RenderLayer; + bool _ModulateGlobalColor; + + // if true, then updateCoords() is called from draw() + bool _Dirty; + // if true, then at least one border is set + bool _Border; + bool _BorderTop, _BorderRight, _BorderBottom, _BorderLeft; + + public: + uint32 TopWidth, RightWidth, BottomWidth, LeftWidth; + NLMISC::CRGBA TopColor, RightColor, BottomColor, LeftColor; + CSSLineStyle TopStyle, RightStyle, BottomStyle, LeftStyle; + + // alpha value from parent + uint8 CurrentAlpha; + + public: + CSSBorderRenderer(); + + void setRenderLayer(sint layer); + void setModulateGlobalColor(bool m); + + void setRect(sint32 x, sint32 y, sint32 w, sint32 h); + + void setWidth(uint32 top, uint32 right, uint32 bottom, uint32 left); + void setStyle(CSSLineStyle top, CSSLineStyle right, CSSLineStyle bottom, CSSLineStyle left); + void setColor(const NLMISC::CRGBA &top, const NLMISC::CRGBA &right, const NLMISC::CRGBA &bottom, const NLMISC::CRGBA &left); + + void updateCoords(); + void invalidateCoords() { _Dirty = _Border = true; } + void invalidateContent() { _Dirty = _Border = true; }; + + uint32 getTopWidth() const; + uint32 getRightWidth() const; + uint32 getBottomWidth() const; + uint32 getLeftWidth() const; + + uint32 getLeftRightWidth() const; + uint32 getTopBottomWidth() const; + + void draw(); + }; // CSSBorderRenderer + +}//namespace + +#endif // NL_CSS_BORDER_RENDERER_H + + diff --git a/code/nel/include/nel/gui/css_parser.h b/code/nel/include/nel/gui/css_parser.h index cfaf03caa..a6dc92022 100644 --- a/code/nel/include/nel/gui/css_parser.h +++ b/code/nel/include/nel/gui/css_parser.h @@ -31,7 +31,7 @@ namespace NLGUI class CCssParser { public: // parse style declaration, eg "color: red; font-size: 10px;" - static TStyle parseDecls(const std::string &styleString); + static TStyleVec parseDecls(const std::string &styleString); // parse css stylesheet void parseStylesheet(const std::string &cssString, std::vector &rules); diff --git a/code/nel/include/nel/gui/css_style.h b/code/nel/include/nel/gui/css_style.h index 0937ebe0b..d972940e1 100644 --- a/code/nel/include/nel/gui/css_style.h +++ b/code/nel/include/nel/gui/css_style.h @@ -20,12 +20,15 @@ #include "nel/misc/types_nl.h" #include "nel/misc/rgba.h" #include "nel/gui/css_selector.h" +#include "nel/gui/css_types.h" namespace NLGUI { class CHtmlElement; typedef std::map TStyle; + typedef std::pair TStylePair; + typedef std::vector TStyleVec; /** * \brief CSS style rules @@ -62,9 +65,14 @@ namespace NLGUI Height=-1; MaxWidth=-1; MaxHeight=-1; - BorderWidth=-1; + // border style + BorderTopWidth = BorderRightWidth = BorderBottomWidth = BorderLeftWidth = CSSLineWidth::MEDIUM; + BorderTopStyle = BorderRightStyle = BorderBottomStyle = BorderLeftStyle = CSSLineStyle::NONE; + BorderTopColor = BorderRightColor = BorderBottomColor = BorderLeftColor = NLMISC::CRGBA::Transparent; + // background BackgroundColor=NLMISC::CRGBA::Black; BackgroundColorOver=NLMISC::CRGBA::Black; + PaddingTop = PaddingRight = PaddingBottom = PaddingLeft = 0; } bool hasStyle(const std::string &key) const @@ -93,9 +101,12 @@ namespace NLGUI sint32 Height; sint32 MaxWidth; sint32 MaxHeight; - sint32 BorderWidth; + uint32 BorderTopWidth, BorderRightWidth, BorderBottomWidth, BorderLeftWidth; + CSSLineStyle BorderTopStyle, BorderRightStyle, BorderBottomStyle, BorderLeftStyle; + NLMISC::CRGBA BorderTopColor, BorderRightColor, BorderBottomColor, BorderLeftColor; NLMISC::CRGBA BackgroundColor; NLMISC::CRGBA BackgroundColorOver; + uint32 PaddingTop, PaddingRight, PaddingBottom, PaddingLeft; std::string WhiteSpace; std::string TextAlign; @@ -106,9 +117,10 @@ namespace NLGUI class CCssStyle { public: + struct SStyleRule { std::vector Selector; - TStyle Properties; + TStyleVec Properties; // pseudo element like ':before' std::string PseudoElement; @@ -132,6 +144,9 @@ namespace NLGUI // test if str is one of "thin/medium/thick" and return its pixel value bool scanCssLength(const std::string& str, uint32 &px) const; + // split css properties string, ie '1px solid rgb(100, 100, 100)' split by ' ' returns 3 parts. + void splitParams(const std::string &str, char sep, std::vector &result) const; + // read style attribute void getStyleParams(const std::string &styleString, CStyleParams &style, const CStyleParams ¤t) const; void getStyleParams(const TStyle &styleRules, CStyleParams &style, const CStyleParams ¤t) const; @@ -143,13 +158,35 @@ namespace NLGUI void apply(CStyleParams &style, const CStyleParams ¤t) const; // merge src into dest by overwriting key in dest - void merge(TStyle &dst, const TStyle &src) const; + void merge(TStyle &dst, const TStyleVec &src) const; // match selector to dom path bool match(const std::vector &selector, const CHtmlElement &elm) const; + // get shorthang 'top right bottom left' index values based size, ie 'padding' syntax + bool getShorthandIndices(const uint32 size, uint8 &t, uint8 &r, uint8 &b, uint8 &l) const; + + // break 'border' into 'border-top-color', 'border-top-style', etc rules + bool tryBorderWidthShorthand(const std::string &prop, const std::string &value, TStyle &style) const; + bool tryBorderStyleShorthand(const std::string &prop, const std::string &value, TStyle &style) const; + bool tryBorderColorShorthand(const std::string &prop, const std::string &value, TStyle &style) const; + void expandBorderShorthand(const std::string &prop, const std::string &value, TStyle &style) const; + // parse 'background' into 'background-color', 'background-image', etc - void parseBackgroundShorthand(const std::string &value, CStyleParams &style) const; + void expandBackgroundShorthand(const std::string &value, TStyle &style) const; + + // parse 'padding' into 'padding-top', 'padding-left', etc + void expandPaddingShorthand(const std::string &value, TStyle &style) const; + + // expand shorthand rule, ie "border", into longhand names, ie "border-top-width" + // if shorthand is present in style, then its removed + void expandShorthand(const std::string &prop, const std::string &value, TStyle &style) const; + + // parse string value into corresponding value + void applyBorderWidth(const std::string &value, uint32 *dest, const uint32 currentWidth, const uint32 fontSize) const; + void applyBorderColor(const std::string &value, NLMISC::CRGBA *dest, const NLMISC::CRGBA ¤tColor, const NLMISC::CRGBA &textColor) const; + void applyLineStyle(const std::string &value, CSSLineStyle *dest, const CSSLineStyle ¤tStyle) const; + void applyPaddingWidth(const std::string &value, uint32 *dest, const uint32 currentPadding, uint32 fontSize) const; public: void reset(); @@ -167,26 +204,27 @@ namespace NLGUI return Current.FontSize-2; } - sint styleStackIndex = 0; - inline void pushStyle() { - styleStackIndex++; _StyleStack.push_back(Current); + Current.GlobalColor = false; Current.DisplayBlock = false; Current.Width=-1; Current.Height=-1; Current.MaxWidth=-1; Current.MaxHeight=-1; - Current.BorderWidth=-1; + + Current.BorderTopWidth = Current.BorderRightWidth = Current.BorderBottomWidth = Current.BorderLeftWidth = CSSLineWidth::MEDIUM; + Current.BorderTopStyle = Current.BorderRightStyle = Current.BorderBottomStyle = Current.BorderLeftStyle = CSSLineStyle::NONE; + Current.BorderTopColor = Current.BorderRightColor = Current.BorderBottomColor = Current.BorderLeftColor = Current.TextColor; + Current.PaddingTop = Current.PaddingRight = Current.PaddingBottom = Current.PaddingLeft = 0; Current.StyleRules.clear(); } inline void popStyle() { - styleStackIndex--; if (_StyleStack.empty()) { Current = Root; diff --git a/code/nel/include/nel/gui/css_types.h b/code/nel/include/nel/gui/css_types.h new file mode 100644 index 000000000..aa673a63e --- /dev/null +++ b/code/nel/include/nel/gui/css_types.h @@ -0,0 +1,39 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + +#ifndef CL_CSS_TYPES_H +#define CL_CSS_TYPES_H + +#include "nel/misc/types_nl.h" + +namespace NLGUI +{ + /** + * \brief CSS types used in GUI classes + * \date 2019-09-03 10:50 GMT + * \author Meelis Mägi (Nimetu) + */ + + // ie. border-style + enum CSSLineStyle { NONE = 0, HIDDEN, SOLID, INSET, OUTSET }; + // ie, border-width (px) + enum CSSLineWidth { THIN = 1, MEDIUM = 3, THICK = 5 }; + +}//namespace + +#endif // CL_CSS_TYPES_H + + diff --git a/code/nel/include/nel/gui/group_html.h b/code/nel/include/nel/gui/group_html.h index 655869e7f..17a138eee 100644 --- a/code/nel/include/nel/gui/group_html.h +++ b/code/nel/include/nel/gui/group_html.h @@ -124,7 +124,7 @@ namespace NLGUI void endParagraph(); // add image download (used by view_bitmap.cpp to load web images) - void addImageDownload(const std::string &url, CViewBase *img, const CStyleParams &style = CStyleParams(), const TImageType type = NormalImage); + void addImageDownload(const std::string &url, CViewBase *img, const CStyleParams &style = CStyleParams(), const TImageType type = NormalImage, const std::string &placeholder = "web_del.tga"); // remove image from download list if present void removeImageDownload(CViewBase *img); std::string localImageName(const std::string &url); @@ -546,6 +546,11 @@ namespace NLGUI // IL mode bool _LI; + // style from browser.css + CCssStyle _BrowserStyle; + // local file for browser.css + std::string _BrowserCssFile; + // Keep track of current element style CCssStyle _Style; CHtmlElement _HtmlDOM; @@ -702,6 +707,7 @@ namespace NLGUI VAlign = CGroupCell::Middle; LeftMargin = 0; NoWrap = false; + Height = 0; } NLMISC::CRGBA BgColor; std::string Style; @@ -709,6 +715,7 @@ namespace NLGUI CGroupCell::TVAlign VAlign; sint32 LeftMargin; bool NoWrap; + sint32 Height; }; std::vector _CellParams; diff --git a/code/nel/include/nel/gui/group_menu.h b/code/nel/include/nel/gui/group_menu.h index ecdd8aff0..9c5b37589 100644 --- a/code/nel/include/nel/gui/group_menu.h +++ b/code/nel/include/nel/gui/group_menu.h @@ -136,9 +136,13 @@ namespace NLGUI void removeLine(uint index); const std::string getActionHandler(uint lineIndex) const; const std::string getActionHandlerParam(uint lineIndex) const; + const std::string getRightClickHandler(uint lineIndex) const; + const std::string getRightClickHandlerParam(uint lineIndex) const; void setActionHandler(uint lineIndex, const std::string &ah = ""); void setActionHandlerParam(uint lineIndex, const std::string ¶ms = ""); + void setRightClickHandler(uint lineIndex, const std::string &ah = ""); + void setRightClickHandlerParam(uint lineIndex, const std::string ¶ms = ""); void openSubMenu (sint32 nb); @@ -235,6 +239,8 @@ namespace NLGUI CInterfaceGroup *Separator; std::string AHName; std::string AHParams; + std::string AHRightClick; + std::string AHRightClickParams; std::string Id; std::string Cond; // condition to know if the entry is grayed CViewBitmap *CheckBox; @@ -332,9 +338,13 @@ namespace NLGUI void deleteLine(uint index); const std::string getActionHandler(uint lineIndex) const; const std::string getActionHandlerParam(uint lineIndex) const; + const std::string getRightClickHandler(uint lineIndex) const; + const std::string getRightClickHandlerParam(uint lineIndex) const; void setActionHandler(uint lineIndex, const std::string &ah = ""); void setActionHandlerParam(uint lineIndex, const std::string ¶ms = ""); + void setRightClickHandler(uint lineIndex, const std::string &ah = ""); + void setRightClickHandlerParam(uint lineIndex, const std::string ¶ms = ""); void addLine (const ucstring &name, const std::string &ah = "", const std::string ¶ms = "", const std::string &id = std::string(), @@ -357,7 +367,7 @@ namespace NLGUI void setMinH(sint32 minH); // change fontsize for new menu items - void setFontSize(uint32 fontSize); + void setFontSize(uint32 fontSize, bool coef = true); // Gray a line on the RootMenu void setGrayedLine(uint line, bool g); @@ -397,6 +407,7 @@ namespace NLGUI bool _Formatted; uint8 _Space; sint32 _FontSize; + bool _FontSizeCoef; NLMISC::CRGBA _ColorOver; // Color of the text when the mouse is over it NLMISC::CRGBA _ShadowColorOver; // Color of the shadow when the mouse is over it diff --git a/code/nel/include/nel/gui/group_table.h b/code/nel/include/nel/gui/group_table.h index 2be9ef98c..52839e14b 100644 --- a/code/nel/include/nel/gui/group_table.h +++ b/code/nel/include/nel/gui/group_table.h @@ -23,9 +23,11 @@ #include "nel/gui/group_frame.h" #include "nel/gui/view_text.h" #include "nel/gui/ctrl_button.h" +#include "nel/gui/css_types.h" namespace NLGUI { + class CSSBorderRenderer; /** * This group is used to simulate HTML cells. @@ -39,6 +41,7 @@ namespace NLGUI DECLARE_UI_CLASS( CGroupCell ) CGroupCell(const TCtorParam ¶m); + ~CGroupCell(); enum TAlign { @@ -91,11 +94,18 @@ namespace NLGUI // The cell color NLMISC::CRGBA BgColor; + CSSBorderRenderer* Border; + uint32 PaddingTop, PaddingRight, PaddingBottom, PaddingLeft; + // Texture - CViewRenderer::CTextureId _TextureId; /// Accelerator - bool _UserTexture; + CViewRenderer::CTextureId _TextureId; bool _TextureTiled; bool _TextureScaled; + // cached absolute coords for background texture + sint32 _TextureXReal; + sint32 _TextureYReal; + sint32 _TextureWReal; + sint32 _TextureHReal; // Alignment TAlign Align; @@ -112,10 +122,17 @@ namespace NLGUI void setTextureTile(bool tiled); void setTextureScale(bool scaled); + uint32 getPaddingLeftRight() const { return PaddingLeft + PaddingRight; }; + uint32 getPaddingTopBottom() const { return PaddingTop + PaddingBottom; }; + + virtual void updateCoords(); + static void setDebugUICell( bool d ){ DebugUICell = d; } static bool getDebugUICell(){ return DebugUICell; } private: + void updateTextureCoords(); + void setEnclosedGroupDefaultParams(); static bool DebugUICell; }; @@ -143,9 +160,10 @@ namespace NLGUI // The Width you want in pixel. This is the parameter sint32 ForceWidthMin; - // Table borders - sint32 Border; - NLMISC::CRGBA BorderColor; + CSSBorderRenderer* Border; + + // Cell has 1px solid border when
has 'border' attribute with width > 0 + bool CellBorder; sint32 CellPadding; sint32 CellSpacing; @@ -155,6 +173,10 @@ namespace NLGUI bool ContinuousUpdate; + void setTexture(const std::string & TxName); + void setTextureTile(bool tiled); + void setTextureScale(bool scaled); + std::string getProperties( const std::string &name ) const; void setProperty( const std::string &name, const std::string &value ); xmlNodePtr serialize( xmlNodePtr parentNode, const char *type ) const; @@ -176,6 +198,18 @@ namespace NLGUI virtual bool parse (xmlNodePtr cur, CInterfaceGroup * parentGroup); + // Texture + CViewRenderer::CTextureId _TextureId; + bool _TextureTiled; + bool _TextureScaled; + // cached absolute coords for background texture + sint32 _TextureXReal; + sint32 _TextureYReal; + sint32 _TextureWReal; + sint32 _TextureHReal; + + void updateTextureCoords(); + // Content validated bool _ContentValidated; diff --git a/code/nel/include/nel/gui/interface_group.h b/code/nel/include/nel/gui/interface_group.h index cef9abb45..b646c38b6 100644 --- a/code/nel/include/nel/gui/interface_group.h +++ b/code/nel/include/nel/gui/interface_group.h @@ -321,6 +321,8 @@ namespace NLGUI void deleteLUAEnvTable(bool recurse = false); // Set the LUA script to execute at checkCoords time (empty to reset) void setLuaScriptOnDraw(const std::string &script); + // Get the LUA script executed at checkCoords time + inline CStringShared getLuaScriptOnDraw() { return _LUAOnDraw; } // void executeLuaScriptOnDraw(); // Set the LUA script to execute when a list of DB change (of forms: "@DB1,@DB2" ....). The dbList is the key diff --git a/code/nel/include/nel/gui/lua_ihm.h b/code/nel/include/nel/gui/lua_ihm.h index e45e1125f..a7c5f9e2b 100644 --- a/code/nel/include/nel/gui/lua_ihm.h +++ b/code/nel/include/nel/gui/lua_ihm.h @@ -161,6 +161,7 @@ namespace NLGUI static int luaMethodCall(lua_State *ls); static int setOnDraw(CLuaState &ls); // params: CInterfaceGroup*, "script". return: none + static int getOnDraw(CLuaState &ls); // params: CInterfaceGroup*. return: "script" (nil if none) static int addOnDbChange(CLuaState &ls); // params: CInterfaceGroup*, "dblist", "script". return: none static int removeOnDbChange(CLuaState &ls);// params: CInterfaceGroup*. return: none static int setCaptureKeyboard(CLuaState &ls); diff --git a/code/nel/include/nel/gui/view_renderer.h b/code/nel/include/nel/gui/view_renderer.h index 6a09a085b..1b489802f 100644 --- a/code/nel/include/nel/gui/view_renderer.h +++ b/code/nel/include/nel/gui/view_renderer.h @@ -101,6 +101,12 @@ namespace NLGUI return _TextureId; } + // Return true if TextureId is not set + bool empty() const { return _TextureId < 0; }; + + // delete TextureId if set + void clear(); + void serial(NLMISC::IStream &f); private: diff --git a/code/nel/include/nel/gui/widget_manager.h b/code/nel/include/nel/gui/widget_manager.h index 68576ce0f..518c5be16 100644 --- a/code/nel/include/nel/gui/widget_manager.h +++ b/code/nel/include/nel/gui/widget_manager.h @@ -26,6 +26,7 @@ #include "nel/misc/types_nl.h" #include "nel/gui/interface_common.h" #include "nel/gui/interface_options.h" +#include "nel/gui/interface_group.h" #include "nel/gui/event_descriptor.h" #include "nel/3d/u_camera.h" #include "nel/gui/parser.h" diff --git a/code/nel/include/nel/misc/file.h b/code/nel/include/nel/misc/file.h index 78dba95c6..3e40d122a 100644 --- a/code/nel/include/nel/misc/file.h +++ b/code/nel/include/nel/misc/file.h @@ -119,6 +119,11 @@ public: // Advanced Usage. // return a string separated by \n or eof, used to parsing text file void getline (char *buffer, uint32 bufferSize); + // read whole file into a string. resulting buffer may contain NULL chars. + // internal read position is modified. + // return true on success, false on failure. + bool readAll(std::string &buffer); + // return the size of the file uint32 getFileSize () const { return _FileSize; } diff --git a/code/nel/include/nel/misc/rgba.h b/code/nel/include/nel/misc/rgba.h index 006b1f102..81204aca9 100644 --- a/code/nel/include/nel/misc/rgba.h +++ b/code/nel/include/nel/misc/rgba.h @@ -377,6 +377,7 @@ public: static const CRGBA Magenta ; static const CRGBA Cyan ; static const CRGBA White ; + static const CRGBA Transparent ; }; diff --git a/code/nel/src/gui/css_border_renderer.cpp b/code/nel/src/gui/css_border_renderer.cpp new file mode 100644 index 000000000..fd3ad569f --- /dev/null +++ b/code/nel/src/gui/css_border_renderer.cpp @@ -0,0 +1,320 @@ +// Ryzom - MMORPG Framework +// Copyright (C) 2010 Winch Gate Property Limited +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as +// published by the Free Software Foundation, either version 3 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . + + +#include "stdpch.h" +#include "nel/gui/css_border_renderer.h" +#include "nel/gui/view_renderer.h" +#include "nel/gui/widget_manager.h" + +using namespace std; +using namespace NLMISC; + +#ifdef DEBUG_NEW +#define new DEBUG_NEW +#endif + +namespace NLGUI +{ + + + // ---------------------------------------------------------------------------- + CSSBorderRenderer::CSSBorderRenderer() + { + TopWidth = RightWidth = BottomWidth = LeftWidth = 0; + TopColor = RightColor = BottomColor = LeftColor = CRGBA(128, 128, 128, 255); + TopStyle = RightStyle = BottomStyle = LeftStyle = CSSLineStyle::SOLID; + CurrentAlpha = 255; + + _RenderLayer = 0; + _ModulateGlobalColor = false; + + _Border = true; + _Dirty = true; + _BorderTop = _BorderRight = _BorderBottom = _BorderLeft = false; + + // + _QuadT.Uv0.set(0.f, 0.f); + _QuadT.Uv1.set(0.f, 0.f); + _QuadT.Uv2.set(1.f, 1.f); + _QuadT.Uv3.set(0.f, 1.f); + // + _QuadR.Uv0.set(0.f, 0.f); + _QuadR.Uv1.set(0.f, 0.f); + _QuadR.Uv2.set(1.f, 1.f); + _QuadR.Uv3.set(0.f, 1.f); + // + _QuadB.Uv0.set(0.f, 0.f); + _QuadB.Uv1.set(0.f, 0.f); + _QuadB.Uv2.set(1.f, 1.f); + _QuadB.Uv3.set(0.f, 1.f); + // + _QuadL.Uv0.set(0.f, 0.f); + _QuadL.Uv1.set(0.f, 0.f); + _QuadL.Uv2.set(1.f, 1.f); + _QuadL.Uv3.set(0.f, 1.f); + } + + // ---------------------------------------------------------------------------- + void CSSBorderRenderer::setRenderLayer(sint layer) + { + _RenderLayer = layer; + } + + // ---------------------------------------------------------------------------- + void CSSBorderRenderer::setModulateGlobalColor(bool s) + { + _ModulateGlobalColor = s; + } + + // ---------------------------------------------------------------------------- + void CSSBorderRenderer::setRect(sint32 x, sint32 y, sint32 w, sint32 h) + { + _XReal = x; + _YReal = y; + _WReal = w; + _HReal = h; + + _Dirty = _Border = (w > 0 && h > 0); + } + + // ---------------------------------------------------------------------------- + void CSSBorderRenderer::setWidth(uint32 top, uint32 right, uint32 bottom, uint32 left) + { + TopWidth = top; + RightWidth = right; + BottomWidth = bottom; + LeftWidth = left; + + _Dirty = _Border = (top > 0 || right > 0 || bottom > 0 || left > 0); + } + + // ---------------------------------------------------------------------------- + void CSSBorderRenderer::setStyle(CSSLineStyle top, CSSLineStyle right, CSSLineStyle bottom, CSSLineStyle left) + { + TopStyle = top; + RightStyle = right; + BottomStyle = bottom; + LeftStyle = left; + + _Dirty = _Border = true; + } + + // ---------------------------------------------------------------------------- + void CSSBorderRenderer::setColor(const NLMISC::CRGBA &top, const NLMISC::CRGBA &right, const NLMISC::CRGBA &bottom, const NLMISC::CRGBA &left) + { + TopColor = top; + RightColor = right; + BottomColor = bottom; + LeftColor = left; + + _Dirty = true; + } + + // ---------------------------------------------------------------------------- + uint32 CSSBorderRenderer::getTopWidth() const + { + if (TopStyle == CSSLineStyle::NONE || TopStyle == CSSLineStyle::HIDDEN) + return 0; + + return TopWidth; + } + + // ---------------------------------------------------------------------------- + uint32 CSSBorderRenderer::getRightWidth() const + { + if (RightStyle == CSSLineStyle::NONE || RightStyle == CSSLineStyle::HIDDEN) + return 0; + + return RightWidth; + } + + // ---------------------------------------------------------------------------- + uint32 CSSBorderRenderer::getBottomWidth() const + { + if (BottomStyle == CSSLineStyle::NONE || BottomStyle == CSSLineStyle::HIDDEN) + return 0; + + return BottomWidth; + } + + // ---------------------------------------------------------------------------- + uint32 CSSBorderRenderer::getLeftWidth() const + { + if (LeftStyle == CSSLineStyle::NONE || LeftStyle == CSSLineStyle::HIDDEN) + return 0; + + return LeftWidth; + } + + // ---------------------------------------------------------------------------- + uint32 CSSBorderRenderer::getLeftRightWidth() const + { + return getLeftWidth() + getRightWidth(); + } + + // ---------------------------------------------------------------------------- + uint32 CSSBorderRenderer::getTopBottomWidth() const + { + return getTopWidth() + getBottomWidth(); + } + + // ---------------------------------------------------------------------------- + void CSSBorderRenderer::updateCoords() + { + _Dirty = false; + if (!_Border) return; + + sint dTop = getTopWidth(); _BorderTop = dTop > 0; + sint dRight = getRightWidth(); _BorderRight = dRight > 0; + sint dBottom = getBottomWidth(); _BorderBottom = dBottom > 0; + sint dLeft = getLeftWidth(); _BorderLeft = dLeft > 0; + + _Border = _BorderTop || _BorderRight || _BorderBottom || _BorderLeft; + if (!_Border) return; + + if (_BorderTop) + { + // top-left + _QuadT.V3.x = _XReal; + _QuadT.V3.y = _YReal + _HReal; + // top-right + _QuadT.V2.x = _XReal + _WReal; + _QuadT.V2.y = _YReal + _HReal; + // bottom-right + _QuadT.V1.x = _XReal + _WReal - dRight; + _QuadT.V1.y = _YReal + _HReal - dTop; + // bottom-left + _QuadT.V0.x = _XReal + dLeft; + _QuadT.V0.y = _YReal + _HReal - dTop; + } + + if (_BorderRight) + { + // top-left + _QuadR.V3.x = _XReal + _WReal - dRight; + _QuadR.V3.y = _YReal + _HReal - dTop; + // top-right + _QuadR.V2.x = _XReal + _WReal; + _QuadR.V2.y = _YReal + _HReal; + // bottom-right + _QuadR.V1.x = _XReal + _WReal; + _QuadR.V1.y = _YReal; + // bottom-left + _QuadR.V0.x = _XReal + _WReal - dRight; + _QuadR.V0.y = _YReal + dBottom; + } + + if (_BorderBottom) + { + // top-left + _QuadB.V3.x = _XReal + dLeft; + _QuadB.V3.y = _YReal + dBottom; + // top-right + _QuadB.V2.x = _XReal + _WReal - dRight; + _QuadB.V2.y = _YReal + dBottom; + // bottom-right + _QuadB.V1.x = _XReal + _WReal; + _QuadB.V1.y = _YReal; + // bottom-left + _QuadB.V0.x = _XReal; + _QuadB.V0.y = _YReal; + } + + if (_BorderLeft) + { + // top-left + _QuadL.V3.x = _XReal; + _QuadL.V3.y = _YReal + _HReal; + // top-right + _QuadL.V2.x = _XReal + dLeft; + _QuadL.V2.y = _YReal + _HReal - dTop; + // bottom-right + _QuadL.V1.x = _XReal + dLeft; + _QuadL.V1.y = _YReal + dBottom; + // bottom-left + _QuadL.V0.x = _XReal; + _QuadL.V0.y = _YReal; + } + } + + // ---------------------------------------------------------------------------- + void CSSBorderRenderer::draw() { + if (_Dirty) updateCoords(); + if (!_Border) return; + + CViewRenderer &rVR = *CViewRenderer::getInstance(); + + // TODO: no need for widget manager, if global color is set from parent + CRGBA globalColor; + if (_ModulateGlobalColor) + globalColor = CWidgetManager::getInstance()->getGlobalColor(); + + // TODO: monitor ModulateGlobalColor and CurrentAlpha in table checkCoords and recalculate colors on change only + // OUTSET - bottom/right darker than normal (default table style) + // INSET - top/left darker than normal + if (_BorderTop) + { + CRGBA borderColorT = TopColor; + if (TopStyle == CSSLineStyle::INSET) + borderColorT = blend(borderColorT, CRGBA::Black, 0.5f); + + if (_ModulateGlobalColor) + borderColorT.modulateFromColor (borderColorT, globalColor); + + borderColorT.A = (uint8) (((uint16) CurrentAlpha * (uint16) borderColorT.A) >> 8); + rVR.drawQuad(_RenderLayer, _QuadT, rVR.getBlankTextureId(), borderColorT, false); + } + if (_BorderRight) + { + CRGBA borderColorR = RightColor; + if (RightStyle == CSSLineStyle::OUTSET) + borderColorR = blend(borderColorR, CRGBA::Black, 0.5f); + + if (_ModulateGlobalColor) + borderColorR.modulateFromColor (borderColorR, globalColor); + + borderColorR.A = (uint8) (((uint16) CurrentAlpha * (uint16) borderColorR.A) >> 8); + rVR.drawQuad(_RenderLayer, _QuadR, rVR.getBlankTextureId(), borderColorR, false); + } + if (_BorderBottom) + { + CRGBA borderColorB = BottomColor; + if (BottomStyle == CSSLineStyle::OUTSET) + borderColorB = blend(borderColorB, CRGBA::Black, 0.5f); + + if (_ModulateGlobalColor) + borderColorB.modulateFromColor (borderColorB, globalColor); + + borderColorB.A = (uint8) (((uint16) CurrentAlpha * (uint16) borderColorB.A) >> 8); + rVR.drawQuad(_RenderLayer, _QuadB, rVR.getBlankTextureId(), borderColorB, false); + } + if (_BorderLeft) + { + CRGBA borderColorL = LeftColor; + if (LeftStyle == CSSLineStyle::INSET) + borderColorL = blend(borderColorL, CRGBA::Black, 0.5f); + + if (_ModulateGlobalColor) + borderColorL.modulateFromColor (borderColorL, globalColor); + + borderColorL.A = (uint8) (((uint16) CurrentAlpha * (uint16) borderColorL.A) >> 8); + rVR.drawQuad(_RenderLayer, _QuadL, rVR.getBlankTextureId(), borderColorL, false); + } + } + +}//namespace + diff --git a/code/nel/src/gui/css_parser.cpp b/code/nel/src/gui/css_parser.cpp index 39a4496bc..e59cf832b 100644 --- a/code/nel/src/gui/css_parser.cpp +++ b/code/nel/src/gui/css_parser.cpp @@ -35,9 +35,9 @@ namespace NLGUI // // key is converted to lowercase // value is left as is - TStyle CCssParser::parseDecls(const std::string &styleString) + TStyleVec CCssParser::parseDecls(const std::string &styleString) { - TStyle styles; + TStyleVec styles; std::vector elements; NLMISC::splitString(styleString, ";", elements); @@ -49,7 +49,7 @@ namespace NLGUI { std::string key = trim(toLower(elements[i].substr(0, pos))); std::string value = trim(elements[i].substr(pos+1)); - styles[key] = value; + styles.push_back(TStylePair(key, value)); } } @@ -94,7 +94,7 @@ namespace NLGUI std::vector selectors; NLMISC::explode(selectorString, ucstring(","), selectors); - TStyle props; + TStyleVec props; props = parseDecls(styleString.toUtf8()); // duplicate props to each selector in selector list, diff --git a/code/nel/src/gui/css_style.cpp b/code/nel/src/gui/css_style.cpp index b0b536d0d..fe2dab4fd 100644 --- a/code/nel/src/gui/css_style.cpp +++ b/code/nel/src/gui/css_style.cpp @@ -102,7 +102,9 @@ namespace NLGUI } else { - elm.setPseudo(i->PseudoElement, i->Properties); + TStyle props; + merge(props, i->Properties); + elm.setPseudo(i->PseudoElement, props); } } } @@ -110,17 +112,18 @@ namespace NLGUI // style from "style" attribute overrides