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