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_style.h b/code/nel/include/nel/gui/css_style.h index 0937ebe0b..50dd3180a 100644 --- a/code/nel/include/nel/gui/css_style.h +++ b/code/nel/include/nel/gui/css_style.h @@ -20,6 +20,7 @@ #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 { @@ -62,9 +63,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 +99,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,6 +115,7 @@ namespace NLGUI class CCssStyle { public: + struct SStyleRule { std::vector Selector; TStyle Properties; @@ -148,9 +158,27 @@ namespace NLGUI // 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 &value, CStyleParams &style, const std::string &prop) const; + bool tryBorderStyleShorthand(const std::string &value, CStyleParams &style, const std::string &prop) const; + bool tryBorderColorShorthand(const std::string &value, CStyleParams &style, const std::string &prop) const; + void parseBorderShorthand(const std::string &value, CStyleParams &style, const std::string &prop) const; + // parse 'background' into 'background-color', 'background-image', etc void parseBackgroundShorthand(const std::string &value, CStyleParams &style) const; + // parse 'padding' into 'padding-top', 'padding-left', etc + void parsePaddingShorthand(const std::string &value, CStyleParams &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(); @@ -174,12 +202,17 @@ namespace NLGUI 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(); } 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 51efaacb6..9c5b37589 100644 --- a/code/nel/include/nel/gui/group_menu.h +++ b/code/nel/include/nel/gui/group_menu.h @@ -367,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); @@ -407,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..ccc2ce3cf 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. @@ -91,11 +93,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 +121,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 +159,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 +172,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 +197,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/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/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_style.cpp b/code/nel/src/gui/css_style.cpp index b83d14ead..888044e5c 100644 --- a/code/nel/src/gui/css_style.cpp +++ b/code/nel/src/gui/css_style.cpp @@ -338,9 +338,13 @@ namespace NLGUI // - normalize values void CCssStyle::normalize(const TStyle &styleRules, CStyleParams &style, const CStyleParams ¤t) const { + bool keep = true; TStyle::const_iterator it; for (it=styleRules.begin(); it != styleRules.end(); ++it) { + // shorthands will be replaced with proper statements and shorthand rule is removed + keep = true; + // update local copy of applied style style.StyleRules[it->first] = it->second; @@ -452,9 +456,34 @@ namespace NLGUI style.StyleRules["background-size"] = "100%"; } - TStyle::iterator pos = style.StyleRules.find(it->first); - if (pos != style.StyleRules.end()) - style.StyleRules.erase(pos); + keep = false; + } + else + if (it->first == "border" + || it->first == "border-top" || it->first == "border-right" + || it->first == "border-bottom" || it->first == "border-left") + { + // TODO: use enum or bitmap constant instead of passing a string name (it->first) + parseBorderShorthand(it->second, style, it->first); + keep = false; + } + else + if (it->first == "border-width") + { + tryBorderWidthShorthand(it->second, style, it->first); + keep = false; + } + else + if (it->first == "border-style") + { + tryBorderStyleShorthand(it->second, style, it->first); + keep = false; + } + else + if (it->first == "border-color") + { + tryBorderColorShorthand(it->second, style, it->first); + keep = false; } else if (it->first == "display") @@ -464,6 +493,121 @@ namespace NLGUI else style.DisplayBlock = (it->second == "block" || it->second == "table"); } + else + if (it->first == "padding") + { + parsePaddingShorthand(it->second, style); + keep = false; + } + + if (!keep) + { + TStyle::iterator pos = style.StyleRules.find(it->first); + if (pos != style.StyleRules.end()) + style.StyleRules.erase(pos); + } + } + } + + void CCssStyle::applyBorderWidth(const std::string &value, uint32 *dest, const uint32 currentWidth, const uint32 fontSize) const + { + if (!dest) return; + if (value == "inherit") + { + *dest = currentWidth; + } + else if (value == "thin") + { + *dest = 1; + } + else if (value == "medium") + { + *dest = 3; + } + else if (value == "thick") + { + *dest = 5; + } + else if (value == "0") + { + *dest = 0; + } + else + { + float tmpf; + std::string unit; + if (getCssLength(tmpf, unit, value.c_str())) + { + if (unit == "rem") + *dest = fontSize * tmpf; + else if (unit == "em") + *dest = fontSize * tmpf; + else if (unit == "pt") + *dest = tmpf / 0.75f; + else if (unit == "%") + *dest = 0; // no support for % in border width + else + *dest = tmpf; + } + } + } + + void CCssStyle::applyBorderColor(const std::string &value, CRGBA *dest, const CRGBA ¤tColor, const CRGBA &textColor) const + { + if (!dest) return; + + if (value == "inherit") + *dest = currentColor; + else if (value == "transparent") + *dest = CRGBA::Transparent; + else if (value == "currentcolor") + *dest = textColor; + else + scanHTMLColor(value.c_str(), *dest); + } + + void CCssStyle::applyLineStyle(const std::string &value, CSSLineStyle *dest, const CSSLineStyle ¤tStyle) const + { + if (!dest) return; + + if (value == "inherit") + *dest = currentStyle; + else if (value == "none") + *dest = CSSLineStyle::NONE; + else if (value == "hidden") + *dest = CSSLineStyle::HIDDEN; + else if (value == "inset") + *dest = CSSLineStyle::INSET; + else if (value == "outset") + *dest = CSSLineStyle::OUTSET; + else if (value == "solid") + *dest = CSSLineStyle::SOLID; + } + + void CCssStyle::applyPaddingWidth(const std::string &value, uint32 *dest, const uint32 currentPadding, uint32 fontSize) const + { + if (!dest) return; + + if (value == "inherit") + { + *dest = currentPadding; + return; + } + + float tmpf; + std::string unit; + if (getCssLength(tmpf, unit, value.c_str())) + { + if (unit == "rem") + *dest = fontSize * tmpf; + else if (unit == "em") + *dest = fontSize * tmpf; + else if (unit == "pt") + *dest = tmpf / 0.75f; + else if (unit == "%") + *dest = 0; // TODO: requires content width, must remember 'unit' type + else + *dest = tmpf; } } @@ -474,48 +618,22 @@ namespace NLGUI TStyle::const_iterator it; for (it=style.StyleRules.begin(); it != style.StyleRules.end(); ++it) { - if (it->first == "border" || it->first == "border-width") - { - // TODO: border: 1px solid red; - if (it->second == "inherit") - { - style.BorderWidth = current.BorderWidth; - } - else if (it->second == "none") - { - style.BorderWidth = 0; - } - else if (it->second == "thin") - { - style.BorderWidth = 1; - } - else if (it->second == "medium") - { - style.BorderWidth = 3; - } - else if (it->second == "thick") - { - style.BorderWidth = 5; - } - else - { - float tmpf; - std::string unit; - if (getCssLength(tmpf, unit, it->second.c_str())) - { - if (unit == "rem") - style.BorderWidth = Root.FontSize * tmpf; - else if (unit == "em") - style.BorderWidth = current.FontSize * tmpf; - else if (unit == "pt") - style.BorderWidth = tmpf / 0.75f; - else if (unit == "%") - style.BorderWidth = 0; // no support for % in border width - else - style.BorderWidth = tmpf; - } - } - } + if (it->first == "border-top-width") applyBorderWidth(it->second, &style.BorderTopWidth, current.BorderTopWidth, current.FontSize); + else if (it->first == "border-top-color") applyBorderColor(it->second, &style.BorderTopColor, current.BorderTopColor, current.TextColor); + else if (it->first == "border-top-style") applyLineStyle(it->second, &style.BorderTopStyle, current.BorderTopStyle); + else if (it->first == "border-right-width") applyBorderWidth(it->second, &style.BorderRightWidth, current.BorderRightWidth, current.FontSize); + else if (it->first == "border-right-color") applyBorderColor(it->second, &style.BorderRightColor, current.BorderRightColor, current.TextColor); + else if (it->first == "border-right-style") applyLineStyle(it->second, &style.BorderRightStyle, current.BorderRightStyle); + else if (it->first == "border-bottom-width") applyBorderWidth(it->second, &style.BorderBottomWidth, current.BorderBottomWidth, current.FontSize); + else if (it->first == "border-bottom-color") applyBorderColor(it->second, &style.BorderBottomColor, current.BorderBottomColor, current.TextColor); + else if (it->first == "border-bottom-style") applyLineStyle(it->second, &style.BorderBottomStyle, current.BorderBottomStyle); + else if (it->first == "border-left-width") applyBorderWidth(it->second, &style.BorderLeftWidth, current.BorderLeftWidth, current.FontSize); + else if (it->first == "border-left-color") applyBorderColor(it->second, &style.BorderLeftColor, current.BorderLeftColor, current.TextColor); + else if (it->first == "border-left-style") applyLineStyle(it->second, &style.BorderLeftStyle, current.BorderLeftStyle); + else if (it->first == "padding-top") applyPaddingWidth(it->second, &style.PaddingTop, current.PaddingTop, current.FontSize); + else if (it->first == "padding-right") applyPaddingWidth(it->second, &style.PaddingRight, current.PaddingRight, current.FontSize); + else if (it->first == "padding-bottom") applyPaddingWidth(it->second, &style.PaddingBottom, current.PaddingBottom, current.FontSize); + else if (it->first == "padding-left") applyPaddingWidth(it->second, &style.PaddingLeft, current.PaddingLeft, current.FontSize); else if (it->first == "font-style") { @@ -864,6 +982,7 @@ namespace NLGUI style.StrikeThrough = current.StrikeThrough; } + // *************************************************************************** void CCssStyle::parseBackgroundShorthand(const std::string &value, CStyleParams &style) const { // background: url(image.jpg) top center / 200px 200px no-repeat fixed padding-box content-box red; @@ -1198,6 +1317,249 @@ namespace NLGUI } } + // *************************************************************************** + bool CCssStyle::getShorthandIndices(const uint32 size, uint8 &t, uint8 &r, uint8 &b, uint8 &l) const + { + if (size == 0 || size > 4) return false; + + if (size == 1) + { + t = r = b = l = 0; + } + else if (size == 2) + { + t = b = 0; + r = l = 1; + } + else if (size == 3) + { + t = 0; + r = l = 1; + b = 2; + } + else // size == 4 + { + t = 0; + r = 1; + b = 2; + l = 3; + } + + return true; + } + + // *************************************************************************** + bool CCssStyle::tryBorderWidthShorthand(const std::string &value, CStyleParams &style, const std::string &prop) const + { + std::vector parts; + NLMISC::splitString(toLower(value), " ", parts); + float tmpf; + std::string unit; + + // verify that parts are valid + uint8 maxSize = (prop == "border" || prop == "border-width") ? 4 : 1; + bool hasTop = (prop == "border" || prop == "border-width" || prop == "border-top" || prop == "border-top-width"); + bool hasRight = (prop == "border" || prop == "border-width" || prop == "border-right" || prop == "border-right-width"); + bool hasBottom = (prop == "border" || prop == "border-width" || prop == "border-bottom" || prop == "border-bottom-width"); + bool hasLeft = (prop == "border" || prop == "border-width" || prop == "border-left" || prop == "border-left-width"); + if (parts.size() > maxSize || (!hasTop && !hasRight && !hasBottom && !hasLeft)) + { + return false; + } + + for(uint i = 0; i< parts.size(); ++i) + { + if (parts[i] != "inherit" && parts[i] != "thin" && parts[i] != "medium" && parts[i] != "thick" + && !getCssLength(tmpf, unit, parts[i].c_str())) + { + return false; + } + } + + uint8 t, r, b, l; + if (!getShorthandIndices(parts.size(), t, r, b, l)) return false; + if (hasTop) style.StyleRules["border-top-width"] = parts[t]; + if (hasRight) style.StyleRules["border-right-width"] = parts[r]; + if (hasBottom) style.StyleRules["border-bottom-width"] = parts[b]; + if (hasLeft) style.StyleRules["border-left-width"] = parts[l]; + + return true; + } + // *************************************************************************** + bool CCssStyle::tryBorderStyleShorthand(const std::string &value, CStyleParams &style, const std::string &prop) const + { + std::vector parts; + NLMISC::splitString(toLower(value), " ", parts); + + // verify that parts are valid + uint8 maxSize = (prop == "border" || prop == "border-style") ? 4 : 1; + bool hasTop = (prop == "border" || prop == "border-style" || prop == "border-top" || prop == "border-top-style"); + bool hasRight = (prop == "border" || prop == "border-style" || prop == "border-right" || prop == "border-right-style"); + bool hasBottom = (prop == "border" || prop == "border-style" || prop == "border-bottom" || prop == "border-bottom-style"); + bool hasLeft = (prop == "border" || prop == "border-style" || prop == "border-left" || prop == "border-left-style"); + if (parts.size() > maxSize || (!hasTop && !hasRight && !hasBottom && !hasLeft)) + { + return false; + } + + const uint nbValues = 10; + std::string values[nbValues] = {"none", "hidden", "dotted", "dashed", + "solid", "double", "groove", "ridge", "inset", "outset"}; + + for(uint i = 0; i < parts.size(); ++i) + { + bool found = false; + for(uint iValue = 0; iValue < nbValues; ++iValue) + { + if (parts[i] == values[iValue]) + { + found = true; + break; + } + } + + if (!found) + { + // invalid rule + return false; + } + } + + uint8 t, r, b, l; + if (!getShorthandIndices(parts.size(), t, r, b, l)) return false; + if (hasTop) style.StyleRules["border-top-style"] = parts[t]; + if (hasRight) style.StyleRules["border-right-style"] = parts[r]; + if (hasBottom) style.StyleRules["border-bottom-style"] = parts[b]; + if (hasLeft) style.StyleRules["border-left-style"] = parts[l]; + + return true; + } + // *************************************************************************** + bool CCssStyle::tryBorderColorShorthand(const std::string &value, CStyleParams &style, const std::string &prop) const + { + std::vector parts; + NLMISC::splitString(toLower(value), " ", parts); + CRGBA color; + + // verify that parts are valid + uint8 maxSize = (prop == "border" || prop == "border-color") ? 4 : 1; + bool hasTop = (prop == "border" || prop == "border-color" || prop == "border-top" || prop == "border-top-color"); + bool hasRight = (prop == "border" || prop == "border-color" || prop == "border-right" || prop == "border-right-color"); + bool hasBottom = (prop == "border" || prop == "border-color" || prop == "border-bottom" || prop == "border-bottom-color"); + bool hasLeft = (prop == "border" || prop == "border-color" || prop == "border-left" || prop == "border-left-color"); + if (parts.size() > maxSize || (!hasTop && !hasRight && !hasBottom && !hasLeft)) + { + return false; + } + + for(uint i = 0; i< parts.size(); ++i) + { + if (!scanHTMLColor(parts[i].c_str(), color) && parts[i] != "currentcolor" && parts[i] != "inherit") + return false; + } + + uint8 t, r, b, l; + if (!getShorthandIndices(parts.size(), t, r, b, l)) return false; + if (hasTop) style.StyleRules["border-top-color"] = parts[t]; + if (hasRight) style.StyleRules["border-right-color"] = parts[r]; + if (hasBottom) style.StyleRules["border-bottom-color"] = parts[b]; + if (hasLeft) style.StyleRules["border-left-color"] = parts[l]; + + return true; + } + + // *************************************************************************** + void CCssStyle::parseBorderShorthand(const std::string &value, CStyleParams &style, const std::string &prop) const + { + // border: 1px solid #000; + bool hasTop = (prop == "border" || prop == "border-top"); + bool hasRight = (prop == "border" || prop == "border-right"); + bool hasBottom = (prop == "border" || prop == "border-bottom"); + bool hasLeft = (prop == "border" || prop == "border-left"); + + bool foundWidth = false; + bool foundStyle = false; + bool foundColor = false; + + CStyleParams borderStyle; + std::vector parts; + NLMISC::splitString(toLower(value), " ", parts); + + for(uint index = 0; index < parts.size(); ++index) + { + bool matched = false; + if (!foundWidth) + { + matched = foundWidth = tryBorderWidthShorthand(parts[index], borderStyle, prop); + } + + if (!matched && !foundStyle) + { + matched = foundStyle = tryBorderStyleShorthand(parts[index], borderStyle, prop); + } + + if (!matched && !foundColor) + { + matched = foundColor = tryBorderColorShorthand(parts[index], borderStyle, prop); + } + + // invalid rule if nothing gets matched + if (!matched) + { + return; + } + } + + // apply rules that are present + TStyle::const_iterator it = borderStyle.StyleRules.begin(); + while(it != borderStyle.StyleRules.end()) + { + style.StyleRules[it->first] = it->second; + ++it; + } + + // reset those not present + if (!foundWidth) + { + if (hasTop) style.StyleRules["border-top-width"] = "medium"; + if (hasRight) style.StyleRules["border-right-width"] = "medium"; + if (hasBottom) style.StyleRules["border-bottom-width"] = "medium"; + if (hasLeft) style.StyleRules["border-left-width"] = "medium"; + } + // + if (!foundStyle) + { + if (hasTop) style.StyleRules["border-top-style"] = "none"; + if (hasRight) style.StyleRules["border-right-style"] = "none"; + if (hasBottom) style.StyleRules["border-bottom-style"] = "none"; + if (hasLeft) style.StyleRules["border-left-style"] = "none"; + } + // + if (!foundColor) + { + if (hasTop) style.StyleRules["border-top-color"] = "currentcolor"; + if (hasRight) style.StyleRules["border-right-color"] = "currentcolor"; + if (hasBottom) style.StyleRules["border-bottom-color"] = "currentcolor"; + if (hasLeft) style.StyleRules["border-left-color"] = "currentcolor"; + } + } + + // *************************************************************************** + void CCssStyle::parsePaddingShorthand(const std::string &value, CStyleParams &style) const + { + std::vector parts; + NLMISC::splitString(toLower(value), " ", parts); + + uint8 t, r, b, l; + if (!getShorthandIndices(parts.size(), t, r, b, l)) + return; + + style.StyleRules["padding-top"] = parts[t]; + style.StyleRules["padding-right"] = parts[r]; + style.StyleRules["padding-bottom"] = parts[b]; + style.StyleRules["padding-left"] = parts[l]; + } + // *************************************************************************** void CCssStyle::applyCssMinMax(sint32 &width, sint32 &height, sint32 minw, sint32 minh, sint32 maxw, sint32 maxh) const { diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp index 49a48890a..f80fc511f 100644 --- a/code/nel/src/gui/group_html.cpp +++ b/code/nel/src/gui/group_html.cpp @@ -52,6 +52,7 @@ #include "nel/gui/html_element.h" #include "nel/gui/css_style.h" #include "nel/gui/css_parser.h" +#include "nel/gui/css_border_renderer.h" #include @@ -286,28 +287,38 @@ namespace NLGUI { btn->setTextureOver(file); } + + return; } - else + + CViewBitmap *btm = dynamic_cast(view); + if(btm) { - CViewBitmap *btm = dynamic_cast(view); - if(btm) - { - btm->setTexture (file); - btm->invalidateCoords(); - btm->invalidateContent(); - paragraphChange(); - } - else - { - CGroupCell *btgc = dynamic_cast(view); - if(btgc) - { - btgc->setTexture (file); - btgc->invalidateCoords(); - btgc->invalidateContent(); - paragraphChange(); - } - } + btm->setTexture (file); + btm->invalidateCoords(); + btm->invalidateContent(); + paragraphChange(); + + return; + } + + CGroupCell *btgc = dynamic_cast(view); + if(btgc) + { + btgc->setTexture (file); + btgc->invalidateCoords(); + btgc->invalidateContent(); + paragraphChange(); + + return; + } + + CGroupTable *table = dynamic_cast(view); + if (table) + { + table->setTexture(file); + + return; } } @@ -433,10 +444,9 @@ namespace NLGUI { if (pVT) { - pVT->setFontSize(style.FontSize); pVT->setColor(style.TextColor); pVT->setFontName(style.FontFamily); - pVT->setFontSize(style.FontSize); + pVT->setFontSize(style.FontSize, false); pVT->setEmbolden(style.FontWeight >= FONT_WEIGHT_BOLD); pVT->setOblique(style.FontOblique); pVT->setUnderlined(style.Underlined); @@ -697,7 +707,7 @@ namespace NLGUI } // Add a image download request in the multi_curl - void CGroupHTML::addImageDownload(const string &url, CViewBase *img, const CStyleParams &style, TImageType type) + void CGroupHTML::addImageDownload(const string &url, CViewBase *img, const CStyleParams &style, TImageType type, const std::string &placeholder) { std::string finalUrl; img->setModulateGlobalColor(style.GlobalColor); @@ -723,8 +733,7 @@ namespace NLGUI std::string temp = dest; if (!CFile::fileExists(temp)) { - // TODO: placeholder - temp = "web_del.tga"; + temp = placeholder; } setImage(img, temp, type); setImageSize(img, style); @@ -1144,8 +1153,10 @@ namespace NLGUI case HTML_STRONG: renderPseudoElement(":before", elm); break; case HTML_STYLE: htmlSTYLE(elm); break; case HTML_TABLE: htmlTABLE(elm); break; + case HTML_TBODY: renderPseudoElement(":before", elm); break; case HTML_TD: htmlTD(elm); break; case HTML_TEXTAREA: htmlTEXTAREA(elm); break; + case HTML_TFOOT: renderPseudoElement(":before", elm); break; case HTML_TH: htmlTH(elm); break; case HTML_TITLE: htmlTITLE(elm); break; case HTML_TR: htmlTR(elm); break; @@ -1206,7 +1217,9 @@ namespace NLGUI case HTML_STYLE: htmlSTYLEend(elm); break; case HTML_TABLE: htmlTABLEend(elm); break; case HTML_TD: htmlTDend(elm); break; + case HTML_TBODY: renderPseudoElement(":after", elm); break; case HTML_TEXTAREA: htmlTEXTAREAend(elm); break; + case HTML_TFOOT: renderPseudoElement(":after", elm); break; case HTML_TH: htmlTHend(elm); break; case HTML_TITLE: htmlTITLEend(elm); break; case HTML_TR: htmlTRend(elm); break; @@ -1493,6 +1506,9 @@ namespace NLGUI initImageDownload(); initBnpDownload(); + + // setup default browser style + setProperty("browser_css_file", "browser.css"); } // *************************************************************************** @@ -1771,6 +1787,11 @@ namespace NLGUI { return toString( _TimeoutValue ); } + else + if( name == "browser_css_file" ) + { + return _BrowserCssFile; + } else return CGroupScrollText::getProperty( name ); } @@ -2144,6 +2165,24 @@ namespace NLGUI _TimeoutValue = d; return; } + else + if( name == "browser_css_file") + { + _BrowserStyle.reset(); + _BrowserCssFile = value; + if (!_BrowserCssFile.empty()) + { + std::string filename = CPath::lookup(_BrowserCssFile, false, true, true); + if (!filename.empty()) + { + NLMISC::CSString css; + if (css.readFromFile(filename)) + { + _BrowserStyle.parseStylesheet(css); + } + } + } + } else CGroupScrollText::setProperty( name, value ); } @@ -2217,6 +2256,7 @@ namespace NLGUI xmlSetProp( node, BAD_CAST "browse_redo", BAD_CAST _BrowseRedoButton.c_str() ); xmlSetProp( node, BAD_CAST "browse_refresh", BAD_CAST _BrowseRefreshButton.c_str() ); xmlSetProp( node, BAD_CAST "timeout", BAD_CAST toString( _TimeoutValue ).c_str() ); + xmlSetProp( node, BAD_CAST "browser_css_file", BAD_CAST _BrowserCssFile.c_str() ); return node; } @@ -2400,6 +2440,12 @@ namespace NLGUI if(ptr) fromString((const char*)ptr, _TimeoutValue); + ptr = xmlGetProp (cur, (xmlChar*)"browser_css_file"); + if (ptr) + { + setProperty("browser_css_file", (const char *)ptr); + } + return true; } @@ -2597,31 +2643,49 @@ namespace NLGUI // Keep this char ? bool keep = true; + // char is between table elements + // TODO: only whitespace is handled, text is added to either TD, or after TABLE (should be before) + bool tableWhitespace = getTable() && (_Cells.empty() || _Cells.back() == NULL); + switch (input) { // Return / tab only in
 mode
 		case '\t':
 		case '\n':
 			{
-				// Get the last char
-				ucchar lastChar = lastCharParam;
-				if (lastChar == 0)
-					lastChar = getLastChar();
-				keep = ((lastChar != (ucchar)' ') &&
-						(lastChar != 0)) || getPRE() || (_CurrentViewImage && (lastChar == 0));
-				if(!getPRE())
-					input = ' ';
+				if (tableWhitespace)
+				{
+					keep = false;
+				}
+				else
+				{
+					// Get the last char
+					ucchar lastChar = lastCharParam;
+					if (lastChar == 0)
+						lastChar = getLastChar();
+					keep = ((lastChar != (ucchar)' ') &&
+							(lastChar != 0)) || getPRE() || (_CurrentViewImage && (lastChar == 0));
+					if(!getPRE())
+						input = ' ';
+				}
 			}
 			break;
 		case ' ':
 			{
-				// Get the last char
-				ucchar lastChar = lastCharParam;
-				if (lastChar == 0)
-					lastChar = getLastChar();
-				keep = ((lastChar != (ucchar)' ') &&
-						(lastChar != (ucchar)'\n') &&
-						(lastChar != 0)) || getPRE() || (_CurrentViewImage && (lastChar == 0));
+				if (tableWhitespace)
+				{
+					keep = false;
+				}
+				else
+				{
+					// Get the last char
+					ucchar lastChar = lastCharParam;
+					if (lastChar == 0)
+						lastChar = getLastChar();
+					keep = ((lastChar != (ucchar)' ') &&
+							(lastChar != (ucchar)'\n') &&
+							(lastChar != 0)) || getPRE() || (_CurrentViewImage && (lastChar == 0));
+				}
 			}
 			break;
 		case 0xd:
@@ -3407,6 +3471,7 @@ namespace NLGUI
 			CViewBitmap *bitmap = dynamic_cast (view);
 			if (bitmap)
 			{
+				// TODO: background color should have separate bitmap from background texture
 				// Change the background color
 				bitmap->setColor (bgcolor);
 				bitmap->setModulateGlobalColor(false);
@@ -3429,6 +3494,7 @@ namespace NLGUI
 				bitmap->setPosRef(Hotspot_TL);
 				bitmap->setX(0);
 				bitmap->setY(0);
+				// FIXME: renders behind container background
 				bitmap->setRenderLayer(-2);
 				bitmap->setScale(scale);
 				bitmap->setTile(tile);
@@ -3439,7 +3505,7 @@ namespace NLGUI
 				else
 					bitmap->setSizeRef("");
 
-				addImageDownload(bgtex, view);
+				addImageDownload(bgtex, view, CStyleParams(), TImageType::NormalImage, "");
 			}
 		}
 	}
@@ -4924,49 +4990,7 @@ namespace NLGUI
 		_WaitingForStylesheet = false;
 		_StylesheetQueue.clear();
 		_Style.reset();
-
-		std::string css;
-
-		// TODO: browser css
-		css += "html { background-color: " + getRGBAString(BgColor) + "; color: " + getRGBAString(TextColor) + "; font-size: " + toString(TextFontSize) + "px;}";
-		css += "a { color: " + getRGBAString(LinkColor) + "; text-decoration: underline; -ryzom-modulate-color: "+toString(LinkColorGlobalColor)+";}";
-		css += "h1 { color: " + getRGBAString(H1Color) + "; font-size: "+ toString("%d", H1FontSize) + "px; -ryzom-modulate-color: "+toString(H1ColorGlobalColor)+";}";
-		css += "h2 { color: " + getRGBAString(H2Color) + "; font-size: "+ toString("%d", H2FontSize) + "px; -ryzom-modulate-color: "+toString(H2ColorGlobalColor)+";}";
-		css += "h3 { color: " + getRGBAString(H3Color) + "; font-size: "+ toString("%d", H3FontSize) + "px; -ryzom-modulate-color: "+toString(H3ColorGlobalColor)+";}";
-		css += "h4 { color: " + getRGBAString(H4Color) + "; font-size: "+ toString("%d", H4FontSize) + "px; -ryzom-modulate-color: "+toString(H4ColorGlobalColor)+";}";
-		css += "h5 { color: " + getRGBAString(H5Color) + "; font-size: "+ toString("%d", H5FontSize) + "px; -ryzom-modulate-color: "+toString(H5ColorGlobalColor)+";}";
-		css += "h6 { color: " + getRGBAString(H6Color) + "; font-size: "+ toString("%d", H6FontSize) + "px; -ryzom-modulate-color: "+toString(H6ColorGlobalColor)+";}";
-		css += "input[type=\"text\"] { color: " + getRGBAString(TextColor) + "; font-size: " + toString("%d", TextFontSize) + "px; font-weight: normal; text-shadow: 1px 1px #000;}";
-		css += "pre { font-family: monospace;}";
-		// th { text-align: center; } - overwrites align property
-		css += "th { font-weight: bold; }";
-		css += "textarea { color: " + getRGBAString(TextColor) + "; font-weight: normal; font-size: " + toString("%d", TextFontSize) + "px; text-shadow: 1px 1px #000;}";
-		css += "del { text-decoration: line-through;}";
-		css += "u { text-decoration: underline;}";
-		css += "em { font-style: italic; }";
-		css += "strong { font-weight: bold; }";
-		css += "small { font-size: smaller;}";
-		css += "dt { font-weight: bold; }";
-		css += "hr { color: rgb(120, 120, 120);}";
-		// block level elements
-		css += "address, article, aside, blockquote, details, dialog, dd, div, dl, dt, fieldset, figcaption, figure,";
-		css += "footer, form, h1, h2, h3, h4, h5, h6, header, hgroup, hr, li, main, nav, ol, p, pre, section, table,";
-		css += "ul { display: block; }";
-		css += "table { display: table; }";
-		// td { padding: 1px;} - overwrites cellpadding attribute
-		// table { border-spacing: 2px;} - overwrites cellspacing attribute
-		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 = _BrowserStyle;
 	}
 
 	// ***************************************************************************
@@ -5245,9 +5269,7 @@ namespace NLGUI
 	{
 		CGroupHTML::CCellParams cellParams;
 		if (!_CellParams.empty() && inherit)
-		{
 			cellParams = _CellParams.back();
-		}
 
 		if (_Style.hasStyle("background-color"))
 			cellParams.BgColor = _Style.Current.BackgroundColor;
@@ -5260,6 +5282,11 @@ namespace NLGUI
 		if (elm.hasNonEmptyAttribute("l_margin"))
 			fromString(elm.getAttribute("l_margin"), cellParams.LeftMargin);
 
+		if (_Style.hasStyle("height"))
+			cellParams.Height = _Style.Current.Height;
+		else if (elm.hasNonEmptyAttribute("height"))
+			fromString(elm.getAttribute("height"), cellParams.Height);
+
 		{
 			std::string align;
 			// having text-align on table/tr should not override td align attribute
@@ -5989,16 +6016,20 @@ namespace NLGUI
 			ucstring ucValue;
 			ucValue.fromUtf8(elm.getAttribute("value"));
 
-			uint size = 120;
+			uint size = 20;
 			uint maxlength = 1024;
 			if (elm.hasNonEmptyAttribute("size"))
 				fromString(elm.getAttribute("size"), size);
 			if (elm.hasNonEmptyAttribute("maxlength"))
 				fromString(elm.getAttribute("maxlength"), maxlength);
 
+			// ryzom client used to have 'size' attribute in pixels, (12 == was default font size)
+			if (_Style.hasStyle("-ryzom-input-size-px") && _Style.getStyle("-ryzom-input-size-px") == "true")
+				size = size / 12;
+
 			string textTemplate(!templateName.empty() ? templateName : DefaultFormTextGroup);
 			// Add the editbox
-			CInterfaceGroup *textArea = addTextArea (textTemplate, name.c_str (), 1, size/12, false, ucValue, maxlength);
+			CInterfaceGroup *textArea = addTextArea (textTemplate, name.c_str (), 1, size, false, ucValue, maxlength);
 			if (textArea)
 			{
 				// Add the text area to the form
@@ -6213,7 +6244,8 @@ namespace NLGUI
 		// 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;
+		// FIXME: only using border-top
+		uint32 border = _Style.Current.BorderTopWidth > -1 ? _Style.Current.BorderTopWidth : 0;
 
 		uint barw = (uint) (width * meter.getValueRatio());
 		CRGBA bgColor = meter.getBarColor(elm, _Style);
@@ -6428,7 +6460,8 @@ namespace NLGUI
 		// 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;
+		// FIXME: only using border-top
+		uint32 border = _Style.Current.BorderTopWidth > -1 ? _Style.Current.BorderTopWidth : 0;
 
 		uint barw = (uint) (width * progress.getValueRatio());
 		CRGBA bgColor = progress.getBarColor(elm, _Style);
@@ -6503,7 +6536,7 @@ namespace NLGUI
 					sb->setMinH(_Style.Current.Height);
 
 				sb->setMaxVisibleLine(size);
-				sb->setFontSize(_Style.Current.FontSize);
+				sb->setFontSize(_Style.Current.FontSize, false);
 			}
 
 			entry.SelectBox = sb;
@@ -6576,36 +6609,84 @@ namespace NLGUI
 			fromString(elm.getAttribute("cellpadding"), table->CellPadding);
 
 		if (_Style.hasStyle("width"))
-			getPercentage(table->ForceWidthMin, table->TableRatio, _Style.getStyle("width").c_str());
-		else if (elm.hasNonEmptyAttribute("width"))
-			getPercentage (table->ForceWidthMin, table->TableRatio, elm.getAttribute("width").c_str());
-
-		if (_Style.hasStyle("border") || _Style.hasStyle("border-width"))
 		{
-			table->Border = _Style.Current.BorderWidth;
+			// _Style.Width does not handle '%' unit currently
+			if (_Style.Current.Width > 0)
+			{
+				table->ForceWidthMin = _Style.Current.Width;
+				table->TableRatio = 0;
+			}
+			else
+			{
+				getPercentage (table->ForceWidthMin, table->TableRatio, _Style.getStyle("width").c_str());
+			}
 		}
-		else if (elm.hasAttribute("border"))
+		else if (elm.hasNonEmptyAttribute("width"))
 		{
-			std::string s = elm.getAttribute("border");
-			if (s.empty())
-				table->Border = 1;
-			else
-				fromString(elm.getAttribute("border"), table->Border);
+			getPercentage (table->ForceWidthMin, table->TableRatio, elm.getAttribute("width").c_str());
 		}
 
-		if (_Style.hasStyle("border-color"))
+		// border from css or from attribute
 		{
-			std::string s = toLower(_Style.getStyle("border-color"));
-			if (s == "currentcolor")
-				table->BorderColor = _Style.Current.TextColor;
+			uint32 borderWidth = 0;
+			CRGBA borderColor = CRGBA::Transparent;
+
+			// TODO: _Style->hasBorder() ??
+			table->Border = new CSSBorderRenderer();
+			if (elm.hasAttribute("border"))
+			{
+				std::string s = elm.getAttribute("border");
+				if (s.empty())
+					borderWidth = 1;
+				else
+					fromString(elm.getAttribute("border"), borderWidth);
+
+				if (elm.hasNonEmptyAttribute("bordercolor"))
+					scanHTMLColor(elm.getAttribute("bordercolor").c_str(), borderColor);
+				else
+					borderColor = CRGBA(128, 128, 128, 255);
+
+				table->CellBorder = (borderWidth > 0);
+				table->Border->setWidth(borderWidth, borderWidth, borderWidth, borderWidth);
+				table->Border->setColor(borderColor, borderColor, borderColor, borderColor);
+				table->Border->setStyle(CSSLineStyle::OUTSET, CSSLineStyle::OUTSET, CSSLineStyle::OUTSET, CSSLineStyle::OUTSET);
+			}
 			else
-				scanHTMLColor(s.c_str(), table->BorderColor);
+			{
+				table->CellBorder = false;
+			}
+
+			if (_Style.hasStyle("border-top-width"))	table->Border->TopWidth = _Style.Current.BorderTopWidth;
+			if (_Style.hasStyle("border-right-width"))	table->Border->RightWidth = _Style.Current.BorderRightWidth;
+			if (_Style.hasStyle("border-bottom-width"))	table->Border->BottomWidth = _Style.Current.BorderBottomWidth;
+			if (_Style.hasStyle("border-left-width"))	table->Border->LeftWidth = _Style.Current.BorderLeftWidth;
+
+			if (_Style.hasStyle("border-top-color"))	table->Border->TopColor = _Style.Current.BorderTopColor;
+			if (_Style.hasStyle("border-right-color"))	table->Border->RightColor = _Style.Current.BorderRightColor;
+			if (_Style.hasStyle("border-bottom-color"))	table->Border->BottomColor = _Style.Current.BorderBottomColor;
+			if (_Style.hasStyle("border-left-color"))	table->Border->LeftColor = _Style.Current.BorderLeftColor;
+
+			if (_Style.hasStyle("border-top-style"))	table->Border->TopStyle = _Style.Current.BorderTopStyle;
+			if (_Style.hasStyle("border-right-style"))	table->Border->RightStyle = _Style.Current.BorderRightStyle;
+			if (_Style.hasStyle("border-bottom-style"))	table->Border->BottomStyle = _Style.Current.BorderBottomStyle;
+			if (_Style.hasStyle("border-left-style"))	table->Border->LeftStyle = _Style.Current.BorderLeftStyle;
 		}
-		else if (elm.hasNonEmptyAttribute("bordercolor"))
+
+		if (_Style.hasStyle("background-image"))
 		{
-			scanHTMLColor(elm.getAttribute("bordercolor").c_str(), table->BorderColor);
+			if (_Style.checkStyle("background-repeat", "repeat"))
+				table->setTextureTile(true);
+
+			if (_Style.checkStyle("background-size", "100%"))
+				table->setTextureScale(true);
+
+			string image = _Style.getStyle("background-image");
+			addImageDownload(image, table, CStyleParams(), TImageType::NormalImage, "");
 		}
 
+		// setting ModulateGlobalColor must be after addImageDownload
+		if (_Style.checkStyle("-ryzom-modulate-bgcolor", "true"))
+			table->setModulateGlobalColor(true);
 		table->setMarginLeft(getIndent());
 		addHtmlGroup (table, 0);
 
@@ -6633,9 +6714,21 @@ namespace NLGUI
 	// ***************************************************************************
 	void CGroupHTML::htmlTD(const CHtmlElement &elm)
 	{
+		CRGBA rowColor = CRGBA::Transparent;
+		// remember row color so we can blend it with cell color
+		if (!_CellParams.empty())
+			rowColor = _CellParams.back().BgColor;
+
 		// Get cells parameters
 		getCellsParameters(elm, true);
 
+		// if cell has own background,then it must be blended with row
+		if (rowColor.A > 0 && (elm.hasNonEmptyAttribute("bgcolor") || _Style.hasStyle("background-color")))
+		{
+			if (_CellParams.back().BgColor.A < 255)
+				_CellParams.back().BgColor.blendFromui(rowColor, _CellParams.back().BgColor, _CellParams.back().BgColor.A);
+		}
+
 		if (elm.ID == HTML_TH)
 		{
 			if (!_Style.hasStyle("font-weight"))
@@ -6658,14 +6751,6 @@ namespace NLGUI
 			return;
 		}
 
-		if (_Style.hasStyle("padding"))
-		{
-			uint32 a;
-			// TODO: cssLength
-			if (fromString(_Style.getStyle("padding"), a))
-				table->CellPadding = a;
-		}
-
 		_Cells.back() = new CGroupCell(CViewBase::TCtorParam());
 
 		if (_Style.checkStyle("background-repeat", "repeat"))
@@ -6677,7 +6762,7 @@ namespace NLGUI
 		if (_Style.hasStyle("background-image"))
 		{
 			string image = _Style.getStyle("background-image");
-			addImageDownload(image, _Cells.back());
+			addImageDownload(image, _Cells.back(), CStyleParams(), TImageType::NormalImage, "");
 		}
 
 		if (elm.hasNonEmptyAttribute("colspan"))
@@ -6692,19 +6777,70 @@ namespace NLGUI
 		_Cells.back()->NoWrap = _CellParams.back().NoWrap;
 		_Cells.back()->ColSpan = std::max(1, _Cells.back()->ColSpan);
 		_Cells.back()->RowSpan = std::max(1, _Cells.back()->RowSpan);
+		_Cells.back()->Height = _CellParams.back().Height;
 
 		float temp;
 		if (_Style.hasStyle("width"))
-			getPercentage (_Cells.back()->WidthWanted, _Cells.back()->TableRatio, _Style.getStyle("width").c_str());
+		{
+			// _Style.Width does not handle '%' unit currently
+			if (_Style.Current.Width > 0)
+			{
+				_Cells.back()->WidthWanted = _Style.Current.Width;
+				_Cells.back()->TableRatio = 0;
+			}
+			else
+			{
+				getPercentage (_Cells.back()->WidthWanted, _Cells.back()->TableRatio, _Style.getStyle("width").c_str());
+			}
+		}
 		else if (elm.hasNonEmptyAttribute("width"))
+		{
 			getPercentage (_Cells.back()->WidthWanted, _Cells.back()->TableRatio, elm.getAttribute("width").c_str());
-
-		if (_Style.hasStyle("height"))
-			getPercentage (_Cells.back()->Height, temp, _Style.getStyle("height").c_str());
-		else if (elm.hasNonEmptyAttribute("height"))
-			getPercentage (_Cells.back()->Height, temp, elm.getAttribute("height").c_str());
+		}
 
 		_Cells.back()->NewLine = getTR();
+
+		// setting ModulateGlobalColor must be after addImageDownload
+		if (_Style.checkStyle("-ryzom-modulate-bgcolor", "true"))
+			_Cells.back()->setModulateGlobalColor(true);
+
+		// border from 
+ if (table->CellBorder) + { + _Cells.back()->Border->setWidth(1, 1, 1, 1); + _Cells.back()->Border->setColor(table->Border->TopColor, table->Border->RightColor, table->Border->BottomColor, table->Border->LeftColor); + _Cells.back()->Border->setStyle(CSSLineStyle::INSET, CSSLineStyle::INSET, CSSLineStyle::INSET, CSSLineStyle::INSET); + } + + if (_Style.hasStyle("border-top-width")) _Cells.back()->Border->TopWidth = _Style.Current.BorderTopWidth; + if (_Style.hasStyle("border-right-width")) _Cells.back()->Border->RightWidth = _Style.Current.BorderRightWidth; + if (_Style.hasStyle("border-bottom-width")) _Cells.back()->Border->BottomWidth = _Style.Current.BorderBottomWidth; + if (_Style.hasStyle("border-left-width")) _Cells.back()->Border->LeftWidth = _Style.Current.BorderLeftWidth; + + if (_Style.hasStyle("border-top-color")) _Cells.back()->Border->TopColor = _Style.Current.BorderTopColor; + if (_Style.hasStyle("border-right-color")) _Cells.back()->Border->RightColor = _Style.Current.BorderRightColor; + if (_Style.hasStyle("border-bottom-color")) _Cells.back()->Border->BottomColor = _Style.Current.BorderBottomColor; + if (_Style.hasStyle("border-left-color")) _Cells.back()->Border->LeftColor = _Style.Current.BorderLeftColor; + + if (_Style.hasStyle("border-top-style")) _Cells.back()->Border->TopStyle = _Style.Current.BorderTopStyle; + if (_Style.hasStyle("border-right-style")) _Cells.back()->Border->RightStyle = _Style.Current.BorderRightStyle; + if (_Style.hasStyle("border-bottom-style")) _Cells.back()->Border->BottomStyle = _Style.Current.BorderBottomStyle; + if (_Style.hasStyle("border-left-style")) _Cells.back()->Border->LeftStyle = _Style.Current.BorderLeftStyle; + + // padding from
+ if (table->CellPadding) + { + _Cells.back()->PaddingTop = table->CellPadding; + _Cells.back()->PaddingRight = table->CellPadding; + _Cells.back()->PaddingBottom = table->CellPadding; + _Cells.back()->PaddingLeft = table->CellPadding; + } + + if (_Style.hasStyle("padding-top")) _Cells.back()->PaddingTop = _Style.Current.PaddingTop; + if (_Style.hasStyle("padding-right")) _Cells.back()->PaddingRight = _Style.Current.PaddingRight; + if (_Style.hasStyle("padding-bottom")) _Cells.back()->PaddingBottom = _Style.Current.PaddingBottom; + if (_Style.hasStyle("padding-left")) _Cells.back()->PaddingLeft = _Style.Current.PaddingLeft; + table->addChild (_Cells.back()); // reusing indent pushed by table @@ -6813,6 +6949,13 @@ namespace NLGUI // *************************************************************************** void CGroupHTML::htmlTR(const CHtmlElement &elm) { + // prevent inheriting from table + if (!_CellParams.empty()) + { + _CellParams.back().BgColor = CRGBA::Transparent; + _CellParams.back().Height = 0; + } + // Get cells parameters getCellsParameters(elm, true); diff --git a/code/nel/src/gui/group_menu.cpp b/code/nel/src/gui/group_menu.cpp index 79be55110..c7db05e4f 100644 --- a/code/nel/src/gui/group_menu.cpp +++ b/code/nel/src/gui/group_menu.cpp @@ -1233,7 +1233,7 @@ namespace NLGUI pV->setText (name); } pV->setColor (_GroupMenu->_Color); - pV->setFontSize (_GroupMenu->_FontSize); + pV->setFontSize (_GroupMenu->_FontSize, _GroupMenu->_FontSizeCoef); pV->setShadow (_GroupMenu->_Shadow); pV->setShadowOutline (_GroupMenu->_ShadowOutline); pV->setCheckable(checkable); @@ -1322,7 +1322,7 @@ namespace NLGUI } pV->setColor (_GroupMenu->_Color); - pV->setFontSize (_GroupMenu->_FontSize); + pV->setFontSize (_GroupMenu->_FontSize, _GroupMenu->_FontSizeCoef); pV->setShadow (_GroupMenu->_Shadow); pV->setShadowOutline (_GroupMenu->_ShadowOutline); pV->setCheckable(checkable); @@ -2024,6 +2024,7 @@ namespace NLGUI _ShadowColorGrayed = CRGBA::Black; _HighLightOver.set(128, 0, 0, 255); _FontSize = 12; + _FontSizeCoef = true; _Shadow = false; _ShadowOutline = false; _ResizeFromChildH = _ResizeFromChildW = true; @@ -2618,9 +2619,10 @@ namespace NLGUI } // ------------------------------------------------------------------------------------------------ - void CGroupMenu::setFontSize(uint fontSize) + void CGroupMenu::setFontSize(uint fontSize, bool coef) { _FontSize = fontSize; + _FontSizeCoef = coef; } // ------------------------------------------------------------------------------------------------ diff --git a/code/nel/src/gui/group_table.cpp b/code/nel/src/gui/group_table.cpp index 45c3b7e1e..6f61b7571 100644 --- a/code/nel/src/gui/group_table.cpp +++ b/code/nel/src/gui/group_table.cpp @@ -25,6 +25,7 @@ #include "nel/misc/i_xml.h" #include "nel/misc/i18n.h" #include "nel/misc/xml_auto_ptr.h" +#include "nel/gui/css_border_renderer.h" using namespace std; using namespace NLMISC; @@ -52,6 +53,9 @@ namespace NLGUI RowSpan = 1; TableColumnIndex = 0; Group = new CInterfaceGroup(CViewBase::TCtorParam()); + // TODO: only initialize if border is set + Border = new CSSBorderRenderer(); + PaddingTop = PaddingRight = PaddingBottom = PaddingLeft = 0; Align = Left; VAlign = Middle; LeftMargin = 0; @@ -59,9 +63,12 @@ namespace NLGUI IgnoreMaxWidth = false; IgnoreMinWidth = false; AddChildW = false; - _UserTexture = false; _TextureTiled = false; _TextureScaled = false; + _TextureXReal = 0; + _TextureYReal = 0; + _TextureWReal = 0; + _TextureHReal = 0; setEnclosedGroupDefaultParams(); addGroup (Group); } @@ -481,85 +488,72 @@ namespace NLGUI rVR.drawRotFlipBitmap (_RenderLayer, _XReal+_WReal-1, _YReal, 1, _HReal, 0, false, rVR.getBlankTextureId(), CRGBA(0,255,255,255) ); } + uint8 CurrentAlpha = 255; + CGroupTable *table = NULL; + if (getParent ()) + { + table = static_cast (getParent ()); + CurrentAlpha = table->CurrentAlpha; + } + // Draw the background - if (_UserTexture || BgColor.A != 0) + if (BgColor.A > 0 || !_TextureId.empty()) { CViewRenderer &rVR = *CViewRenderer::getInstance(); - if (_UserTexture) + + bool flush = false; + if (CurrentAlpha > 0 && !_TextureId.empty()) { - CRGBA col; - if (BgColor.A == 0 ) - col = CRGBA(255,255,255,255); - else - col = BgColor; - - + CRGBA col = CRGBA::White; + col.A = CurrentAlpha; + + sint32 oldSciX, oldSciY, oldSciW, oldSciH; + makeNewClip (oldSciX, oldSciY, oldSciW, oldSciH); + if (_TextureScaled && !_TextureTiled) { - rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, - _WReal, _HReal, - 0, false, - _TextureId, - col ); + rVR.drawRotFlipBitmap(_RenderLayer, _TextureXReal, _TextureYReal, _WReal, _HReal, 0, false, _TextureId, col); } else { if (!_TextureTiled) - { - rVR.draw11RotFlipBitmap (_RenderLayer, _XReal, _YReal, - 0, false, - _TextureId, - col); - } + rVR.drawRotFlipBitmap(_RenderLayer, _TextureXReal, _TextureYReal, _TextureWReal, _TextureHReal, 0, false, _TextureId, col); else - { - rVR.drawRotFlipBitmapTiled(_RenderLayer, _XReal, _YReal, - _WReal, _HReal, - 0, false, - _TextureId, - 0, - col); - } + rVR.drawRotFlipBitmapTiled(_RenderLayer, _TextureXReal, _TextureYReal, _WReal, _TextureHReal, 0, false, _TextureId, 0, col); } - + + restoreClip (oldSciX, oldSciY, oldSciW, oldSciH); + + flush = true; } - else + + if (BgColor.A > 0) { - CRGBA finalColor; - finalColor.modulateFromColor (BgColor, CWidgetManager::getInstance()->getGlobalColor()); + CRGBA finalColor = BgColor; + if (_ModulateGlobalColor) + finalColor.modulateFromColor (finalColor, CWidgetManager::getInstance()->getGlobalColor()); + finalColor.A = (uint8) (((uint16) CurrentAlpha * (uint16) finalColor.A) >> 8); - // Get the parent table - if (getParent ()) - { - CGroupTable *table = static_cast (getParent ()); - finalColor.A = (uint8) (((uint16) table->CurrentAlpha * (uint16) finalColor.A) >> 8); - } - - //nlinfo("Blank Texture"); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, _HReal, 0, false, rVR.getBlankTextureId(), finalColor); + if (finalColor.A > 0) + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, _HReal, 0, false, rVR.getBlankTextureId(), finalColor); + + flush = true; } + + if (flush) + rVR.flush(); } // Get the parent table - if (getParent ()) { - CGroupTable *table = static_cast (getParent ()); - if (table->Border) { - CRGBA lighter = blend(table->BorderColor, CRGBA::White, 0.5f); - - CRGBA borderColorTL; - borderColorTL.modulateFromColor (lighter, CWidgetManager::getInstance()->getGlobalColor()); - borderColorTL.A = (uint8) (((uint16) table->CurrentAlpha * (uint16) borderColorTL.A) >> 8); - - CRGBA borderColorBR; - borderColorBR.modulateFromColor (table->BorderColor, CWidgetManager::getInstance()->getGlobalColor()); - borderColorBR.A = (uint8) (((uint16) table->CurrentAlpha * (uint16) borderColorBR.A) >> 8); - - CViewRenderer &rVR = *CViewRenderer::getInstance(); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, 1, 0, false, rVR.getBlankTextureId(), borderColorTL ); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, 1, _HReal, 0, false, rVR.getBlankTextureId(), borderColorBR ); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal+_HReal-1, _WReal, 1, 0, false, rVR.getBlankTextureId(), borderColorBR ); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal+_WReal-1, _YReal, 1, _HReal, 0, false, rVR.getBlankTextureId(), borderColorTL ); + // TODO: monitor these in checkCoords and update when changed + uint8 contentAlpha = CWidgetManager::getInstance()->getGlobalColorForContent().A; + if (contentAlpha > 0) + { + Border->CurrentAlpha = contentAlpha; + Border->setRenderLayer(_RenderLayer); + Border->setModulateGlobalColor(_ModulateGlobalColor); + Border->draw(); } } @@ -584,14 +578,13 @@ namespace NLGUI { if (TxName.empty() || TxName == "none") { - _UserTexture = false; - nlinfo("Set no texture"); + _TextureId.clear(); } else { - nlinfo("Set texture to cell : %s", TxName.c_str()); - _UserTexture = true; _TextureId.setTexture (TxName.c_str (), 0, 0, -1, -1, false); + + updateTextureCoords(); } } @@ -611,6 +604,31 @@ namespace NLGUI _TextureScaled = scaled; } + // ---------------------------------------------------------------------------- + void CGroupCell::updateTextureCoords() + { + if (_TextureId.empty()) return; + + CViewRenderer &rVR = *CViewRenderer::getInstance(); + rVR.getTextureSizeFromId (_TextureId, _TextureWReal, _TextureHReal); + + _TextureXReal = _XReal; + _TextureYReal = _YReal + _HReal - _TextureHReal; + if (_TextureTiled && _TextureHReal > 0) + { + sint diff = (_HReal / _TextureHReal) * _TextureHReal; + _TextureYReal -= diff; + _TextureHReal += diff; + } + } + + // ---------------------------------------------------------------------------- + void CGroupCell::updateCoords() + { + CInterfaceGroup::updateCoords(); + + updateTextureCoords(); + } // ---------------------------------------------------------------------------- NLMISC_REGISTER_OBJECT(CViewBase, CGroupTable, std::string, "table"); @@ -622,11 +640,21 @@ namespace NLGUI _ContentValidated = false; TableRatio = 0.f; ForceWidthMin = 0; - Border=0; - BorderColor = CRGBA(32, 32, 32, 255); + + // TODO: only initialize when needed + Border = new CSSBorderRenderer(); + + CellBorder = false; CellPadding=1; CellSpacing=2; ContinuousUpdate = false; + + _TextureTiled = false; + _TextureScaled = false; + _TextureXReal = 0; + _TextureYReal = 0; + _TextureWReal = 0; + _TextureHReal = 0; } // ---------------------------------------------------------------------------- @@ -688,13 +716,62 @@ namespace NLGUI // ---------------------------------------------------------------------------- CGroupTable::~CGroupTable() { + if (Border) + { + delete Border; + Border = NULL; + } + /* uint i; for (i=0; i<_Cells.size(); i++) delete _Cells[i]; _Cells.clear ();*/ } + // ---------------------------------------------------------------------------- + void CGroupTable::setTexture(const std::string & TxName) + { + if (TxName.empty() || TxName == "none") + { + _TextureId.clear(); + } + else + { + _TextureId.setTexture (TxName.c_str (), 0, 0, -1, -1, false); + + updateTextureCoords(); + } + } + // ---------------------------------------------------------------------------- + void CGroupTable::setTextureTile(bool tiled) + { + _TextureTiled = tiled; + } + + // ---------------------------------------------------------------------------- + void CGroupTable::setTextureScale(bool scaled) + { + _TextureScaled = scaled; + } + + // ---------------------------------------------------------------------------- + void CGroupTable::updateTextureCoords() + { + if (_TextureId.empty()) return; + + CViewRenderer &rVR = *CViewRenderer::getInstance(); + rVR.getTextureSizeFromId (_TextureId, _TextureWReal, _TextureHReal); + + _TextureXReal = _XReal; + _TextureYReal = _YReal + _HReal - _TextureHReal; + if (_TextureTiled && _TextureHReal > 0) + { + sint diff = (_HReal / _TextureHReal) * _TextureHReal; + _TextureYReal -= diff; + _TextureHReal += diff; + } + } // ---------------------------------------------------------------------------- void CGroupTable::updateCoords() @@ -736,24 +813,24 @@ namespace NLGUI additionnalWidth = (sint32) width; } + sint32 cellBorderPadding = cell->getPaddingLeftRight(); + if (cell->Border) + cellBorderPadding += cell->Border->getLeftRightWidth(); + // Get width min and max if( !cell->IgnoreMaxWidth) - { - cell->WidthMax = cell->getMaxUsedW() + cell->LeftMargin; - } + cell->WidthMax = cell->getMaxUsedW() + cell->LeftMargin + cellBorderPadding; else - { cell->WidthMax = cell->WidthWanted + additionnalWidth + cell->LeftMargin; - } + sint32 cellWidth; if(!cell->IgnoreMinWidth) - { - cellWidth = cell->NoWrap ? cell->WidthMax : cell->getMinUsedW() + cell->LeftMargin; - } + cellWidth = cell->NoWrap ? cell->WidthMax : cell->getMinUsedW() + cell->LeftMargin + cellBorderPadding; else - { cellWidth = cell->NoWrap ? cell->WidthMax : cell->LeftMargin; - } + + if (cellWidth < cellBorderPadding) + cellWidth = cellBorderPadding; // New cell ? if (cell->NewLine) @@ -795,11 +872,11 @@ namespace NLGUI _Columns[column].WidthMax = (sint32)(cell->WidthMax*colspan); if (cell->TableRatio*colspan > _Columns[column].TableRatio) _Columns[column].TableRatio = cell->TableRatio*colspan; - if (cell->WidthWanted*colspan + additionnalWidth > _Columns[column].WidthWanted) - _Columns[column].WidthWanted = (sint32)(cell->WidthWanted*colspan) + additionnalWidth; + if ((cell->WidthWanted + additionnalWidth)*colspan > _Columns[column].WidthWanted) + _Columns[column].WidthWanted = (sint32)((cell->WidthWanted + additionnalWidth)*colspan); - if (_Columns[column].WidthWanted + additionnalWidth) - _Columns[column].WidthMax = _Columns[column].WidthWanted + additionnalWidth; + if (_Columns[column].WidthWanted > _Columns[column].WidthMax) + _Columns[column].WidthMax = _Columns[column].WidthWanted; if (_Columns[column].WidthWanted > _Columns[column].Width) _Columns[column].Width = _Columns[column].WidthWanted; @@ -821,15 +898,21 @@ namespace NLGUI column++; } - // Width of cells and table borders - sint32 padding = CellPadding + (Border ? 1 : 0); - sint32 borderWidth = 2*Border + ((sint32)_Columns.size()+1) * CellSpacing + ((sint32)_Columns.size()*2) * padding; + // Additional space contributing to table width + sint32 tableBorderSpacing = Border->getLeftWidth() + Border->getRightWidth(); + tableBorderSpacing += ((sint32)_Columns.size()+1) * CellSpacing;; + + sint32 innerForceWidthMin = ForceWidthMin; + if (innerForceWidthMin < tableBorderSpacing) + innerForceWidthMin = 0; + else + innerForceWidthMin -= tableBorderSpacing; // Get the width - sint32 tableWidthMax = ForceWidthMin?ForceWidthMin:_LastParentW; // getWReal(); - sint32 tableWidthMin = std::max(ForceWidthMin, (sint32)((float)tableWidthMax*TableRatio)); - tableWidthMax = std::max ((sint32)0, tableWidthMax-borderWidth); - tableWidthMin = std::max ((sint32)0, tableWidthMin-borderWidth); + sint32 tableWidthMax = innerForceWidthMin ? innerForceWidthMin : _LastParentW - tableBorderSpacing; // getWReal(); + sint32 tableWidthMin = std::max(innerForceWidthMin, (sint32)((float)tableWidthMax*TableRatio)); + tableWidthMax = std::max ((sint32)0, tableWidthMax); + tableWidthMin = std::max ((sint32)0, tableWidthMin); // Get the width of the table and normalize percent of the cell (sum of TableRatio must == 1) sint32 tableWidth = 0; @@ -845,10 +928,10 @@ namespace NLGUI // force table width to fit all columns // if width is set, then use column min width - if (ForceWidthMin > 0) - tableWidthMax = std::min(_LastParentW - borderWidth, std::max(tableWidthMax, tableWidth)); + if (innerForceWidthMin > 0) + tableWidthMax = std::min(_LastParentW - tableBorderSpacing, std::max(tableWidthMax, tableWidth)); else - tableWidthMax = std::min(_LastParentW - borderWidth, std::max(tableWidthMax, tableMaxContentWidth)); + tableWidthMax = std::min(_LastParentW - tableBorderSpacing, std::max(tableWidthMax, tableMaxContentWidth)); if (tableWidthMax < 0) tableWidthMax = 0; @@ -857,6 +940,7 @@ namespace NLGUI std::swap(tableWidthMin, tableWidthMax); // Eval table size with all percent cells resized + // TODO: _Columns[i].TableRatio is for outer width sint32 tableWidthSizeAfterPercent = tableWidth; for (i=0; i<_Columns.size(); i++) { @@ -1028,8 +1112,9 @@ namespace NLGUI // *** Now we know each column width, resize cells and get the height for each row column = 0; + // FIXME: real cell padding sint32 row = 0; - sint32 currentX = Border + CellSpacing + padding; + sint32 currentX = 0; _Rows.clear (); for (i=0; i<_Cells.size(); i++) @@ -1039,7 +1124,7 @@ namespace NLGUI if (cell->NewLine) { column = 0; - currentX = Border + CellSpacing + padding; + currentX = Border->LeftWidth + CellSpacing; _Rows.push_back(CRow()); } @@ -1048,7 +1133,7 @@ namespace NLGUI { // we have active rowspan, must add up 'skipped' columns for( ; column < (uint)cell->TableColumnIndex; ++column) - currentX += _Columns[column].Width + padding*2 + CellSpacing; + currentX += _Columns[column].Width + CellSpacing; } // Set the x and width @@ -1057,11 +1142,19 @@ namespace NLGUI sint32 alignmentX = 0; sint32 widthReduceX = 0; sint32 columnWidth = _Columns[column].Width; + sint32 cellBorderPaddingLeft = cell->PaddingLeft; + sint32 cellBorderPaddingRight = cell->PaddingRight; + if (cell->Border) + { + cellBorderPaddingLeft += cell->Border->getLeftWidth(); + cellBorderPaddingRight += cell->Border->getRightWidth(); + } + if (cell->ColSpan > 1) { // scan ahead and add up column widths as they might be different for(int j = 1; jColSpan; j++) - columnWidth += CellSpacing + padding*2 + _Columns[column+j].Width; + columnWidth += CellSpacing + _Columns[column+j].Width; } if (cell->WidthMax < columnWidth) @@ -1081,11 +1174,13 @@ namespace NLGUI } } - cell->setX(currentX - padding); - cell->setW(columnWidth + padding*2); + // outer + cell->setX(currentX); + cell->setW(columnWidth); - cell->Group->setX(alignmentX + cell->LeftMargin + padding); - cell->Group->setW(columnWidth - widthReduceX); + // inner + cell->Group->setX(cellBorderPaddingLeft + alignmentX + cell->LeftMargin); + cell->Group->setW(columnWidth - widthReduceX - cellBorderPaddingLeft - cellBorderPaddingRight); cell->Group->CInterfaceElement::updateCoords(); // Update coords to get H @@ -1094,16 +1189,23 @@ namespace NLGUI // Resize the row array float rowspan = 1.f / (float)cell->RowSpan; - _Rows.back().Height = std::max((sint32)(cell->Height*rowspan), std::max(_Rows.back().Height, (sint32)(cell->Group->getH()*rowspan))); + uint cellBorderPadding = cell->getPaddingTopBottom(); + if (cell->Border) + cellBorderPadding += cell->Border->getTopBottomWidth(); + sint32 cellHeight = std::max((sint32)(cell->Height*rowspan), (sint32)(cell->Group->getH()*rowspan + cellBorderPadding)); + _Rows.back().Height = std::max(_Rows.back().Height, (sint32)cellHeight); // Next column - currentX += columnWidth + 2*padding + CellSpacing; + currentX += columnWidth + CellSpacing; column += cell->ColSpan; } // Set cell Y row = 0; - sint32 currentY = -(Border + CellSpacing + padding); + sint32 currentY = -CellSpacing; + if (Border) + currentY -= Border->getTopWidth(); + for (i=0; i<_Cells.size(); i++) { // New cell ? @@ -1112,7 +1214,7 @@ namespace NLGUI { if (_Rows[row].Height != 0) { - currentY -= _Rows[row].Height + 2*padding + CellSpacing; + currentY -= _Rows[row].Height + CellSpacing; } row++; } @@ -1120,12 +1222,19 @@ namespace NLGUI // Check align sint32 alignmentY = 0; sint32 rowHeight = _Rows[row].Height; + sint32 cellBorderPaddingTop = cell->PaddingTop; + sint32 cellBorderPaddingBottom = cell->PaddingBottom; + if (cell->Border) + { + cellBorderPaddingTop += cell->Border->getTopWidth(); + cellBorderPaddingBottom += cell->Border->getBottomWidth(); + } if (cell->RowSpan > 1) { // we need to scan down and add up row heights int k = std::min((sint32)_Rows.size(), row + cell->RowSpan); for(int j=row+1; jGroup->getH() < rowHeight) { @@ -1142,15 +1251,26 @@ namespace NLGUI } } - cell->setY(currentY + padding); - cell->setH (rowHeight + 2*padding); - cell->Group->setY(-(alignmentY + padding)); + // outer + cell->setY(currentY); + cell->setH (rowHeight); + // inner + cell->Group->setY(-(alignmentY + cellBorderPaddingTop - cellBorderPaddingBottom)); } - // Resize the table - setW(finalWidth+borderWidth-_LastParentW); + // final row if (!_Rows.empty()) - currentY -= _Rows[row].Height + padding + CellSpacing + Border; + currentY -= _Rows.back().Height; + currentY -= CellSpacing; + finalWidth += ((sint)_Columns.size() + 1) * CellSpacing; + if (Border) + { + currentY -= Border->getBottomWidth(); + finalWidth += Border->getLeftWidth() + Border->getRightWidth(); + } + + // Resize the table + setW(finalWidth-_LastParentW); setH(-currentY); // All done @@ -1160,8 +1280,22 @@ namespace NLGUI CInterfaceGroup::updateCoords(); + updateTextureCoords(); + // update borders if present + if (Border) + { + Border->setRect(_XReal + _MarginLeft, _YReal, _WReal, _HReal); + } + // update cell borders if present + for (uint32 i=0; i<_Cells.size(); i++) + { + if (_Cells[i]->Border) + { + _Cells[i]->Border->setRect(_Cells[i]->_XReal, _Cells[i]->_YReal, _Cells[i]->_WReal, _Cells[i]->_HReal); + } + } // Validated _ContentValidated = true; @@ -1267,7 +1401,8 @@ namespace NLGUI for (i=0; iLeftWidth + Border->RightWidth + ((sint32)columns.size()+1) * CellSpacing + ((sint32)columns.size()*2) * CellPadding; return maxWidth; } @@ -1312,7 +1447,8 @@ namespace NLGUI for (i=0; iLeftWidth + Border->RightWidth + ((sint32)columns.size()+1) * CellSpacing + ((sint32)columns.size()*2) * CellPadding; return maxWidth; } @@ -1342,64 +1478,62 @@ namespace NLGUI if (!_Columns.empty() && !_Rows.empty()) { - sint32 border = Border + CellSpacing; - if (border && BgColor.A) + bool flush = false; + CViewRenderer &rVR = *CViewRenderer::getInstance(); + + if (BgColor.A > 0) { - CRGBA finalColor; - finalColor.modulateFromColor (BgColor, CWidgetManager::getInstance()->getGlobalColor()); - finalColor.A = CurrentAlpha; + CRGBA finalColor = BgColor; + if (_ModulateGlobalColor) + finalColor.modulateFromColor (finalColor, CWidgetManager::getInstance()->getGlobalColor()); + finalColor.A = (uint8) (((uint16) CurrentAlpha * (uint16) finalColor.A) >> 8); + + rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, _WReal, _HReal, 0, false, rVR.getBlankTextureId(), finalColor); + + flush = true; + } - // Draw the top line - CViewRenderer &rVR = *CViewRenderer::getInstance(); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal-border+_HReal, _WReal, border, 0, false, rVR.getBlankTextureId(), finalColor); + // Draw the background + if (CurrentAlpha > 0 && !_TextureId.empty()) + { + sint32 oldSciX, oldSciY, oldSciW, oldSciH; + makeNewClip (oldSciX, oldSciY, oldSciW, oldSciH); - // Draw the left line - sint32 insideHeight = std::max((sint32)0, (sint32)_HReal - (sint32)border); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal, _YReal, border, insideHeight, 0, false, rVR.getBlankTextureId(), finalColor); + CRGBA col = CRGBA::White; + col.A = CurrentAlpha; - // Draw the inside borders - if (CellSpacing) + if (_TextureScaled && !_TextureTiled) { - uint i; - sint32 x, y; - for (i=0; i<_Cells.size(); i++) - { - CGroupCell *cell = _Cells[i]; - - x = cell->getXReal(); - y = cell->getYReal() - CellSpacing; - // right - rVR.drawRotFlipBitmap (_RenderLayer, x + cell->getW(), y, CellSpacing, cell->getH() + CellSpacing, 0, false, rVR.getBlankTextureId(), finalColor); - // bottom - rVR.drawRotFlipBitmap (_RenderLayer, x, y, cell->getW(), CellSpacing, 0, false, rVR.getBlankTextureId(), finalColor); - } + rVR.drawRotFlipBitmap(_RenderLayer, _TextureXReal, _TextureYReal, _WReal, _HReal, 0, false, _TextureId, col); + } + else + { + if (!_TextureTiled) + rVR.drawRotFlipBitmap(_RenderLayer, _TextureXReal, _TextureYReal, _TextureWReal, _TextureHReal, 0, false, _TextureId, col); + else + rVR.drawRotFlipBitmapTiled(_RenderLayer, _TextureXReal, _TextureYReal, _WReal, _TextureHReal, 0, false, _TextureId, 0, col); } + restoreClip (oldSciX, oldSciY, oldSciW, oldSciH); + flush = true; } - if (Border) - { - CViewRenderer &rVR = *CViewRenderer::getInstance(); - CRGBA borderColorTL; - CRGBA lighter = blend(BorderColor, CRGBA::White, 0.5f); - borderColorTL.modulateFromColor (lighter, CWidgetManager::getInstance()->getGlobalColor()); - borderColorTL.A = CurrentAlpha; + // flush background color and image + if (flush) + rVR.flush(); - CRGBA borderColorBR; - borderColorBR.modulateFromColor (BorderColor, CWidgetManager::getInstance()->getGlobalColor()); - borderColorBR.A = CurrentAlpha; - - // beveled table border - for (sint32 i=0; igetGlobalColorForContent().A; + if (contentAlpha > 0) { - // bottom, left, top, right - rVR.drawRotFlipBitmap (_RenderLayer, _XReal+i, _YReal+i, _WReal-i*2, 1, 0, false, rVR.getBlankTextureId(), borderColorBR); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal+i, _YReal+i, 1, _HReal-i*2, 0, false, rVR.getBlankTextureId(), borderColorTL); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal+i, _YReal+_HReal-i-1, _WReal-i*2, 1, 0, false, rVR.getBlankTextureId(), borderColorTL); - rVR.drawRotFlipBitmap (_RenderLayer, _XReal+_WReal-i-1, _YReal+i, 1, _HReal-i*2, 0, false, rVR.getBlankTextureId(), borderColorBR); + Border->CurrentAlpha = CurrentAlpha; + Border->setRenderLayer(_RenderLayer); + Border->setModulateGlobalColor(_ModulateGlobalColor); + Border->draw(); } } - } CInterfaceGroup::draw (); @@ -1412,12 +1546,12 @@ namespace NLGUI { if( name == "border" ) { - return toString( Border ); + return toString( Border->TopWidth ); } else if( name == "bordercolor" ) { - return toString( BorderColor ); + return toString( Border->TopColor ); } else if( name == "cellpadding" ) @@ -1452,7 +1586,12 @@ namespace NLGUI { sint32 i; if( fromString( value, i ) ) - Border = i; + { + Border->TopWidth = i; + Border->RightWidth = i; + Border->BottomWidth = i; + Border->LeftWidth = i; + } return; } else @@ -1460,7 +1599,12 @@ namespace NLGUI { CRGBA c; if( fromString( value, c ) ) - BorderColor = c; + { + Border->TopColor = c; + Border->RightColor = c; + Border->BottomColor = c; + Border->LeftColor = c; + } return; } else @@ -1505,8 +1649,8 @@ namespace NLGUI return NULL; xmlSetProp( node, BAD_CAST "type", BAD_CAST "table" ); - xmlSetProp( node, BAD_CAST "border", BAD_CAST toString( Border ).c_str() ); - xmlSetProp( node, BAD_CAST "bordercolor", BAD_CAST toString( BorderColor ).c_str() ); + xmlSetProp( node, BAD_CAST "border", BAD_CAST toString( Border->TopWidth ).c_str() ); + xmlSetProp( node, BAD_CAST "bordercolor", BAD_CAST toString( Border->TopColor ).c_str() ); xmlSetProp( node, BAD_CAST "cellpadding", BAD_CAST toString( CellPadding ).c_str() ); xmlSetProp( node, BAD_CAST "cellspacing", BAD_CAST toString( CellSpacing ).c_str() ); xmlSetProp( node, BAD_CAST "bgcolor", BAD_CAST toString( BgColor ).c_str() ); @@ -1528,13 +1672,16 @@ namespace NLGUI ptr = (char*) xmlGetProp( cur, (xmlChar*)"border" ); if (ptr) { - fromString((const char*)ptr, Border); + uint32 w; + fromString((const char*)ptr, w); + Border->setWidth(w, w, w, w); } // ptr = (char*) xmlGetProp( cur, (xmlChar*)"bordercolor" ); if (ptr) { - BorderColor = convertColor((const char*)ptr); + CRGBA c = convertColor((const char*)ptr); + Border->setColor(c, c, c, c); } // ptr = (char*) xmlGetProp( cur, (xmlChar*)"cellpadding" ); diff --git a/code/nel/src/gui/html_parser.cpp b/code/nel/src/gui/html_parser.cpp index 1c5914bb5..3d7303706 100644 --- a/code/nel/src/gui/html_parser.cpp +++ b/code/nel/src/gui/html_parser.cpp @@ -190,6 +190,35 @@ namespace NLGUI elm.reindexChilds(); parent.reindexChilds(); } + + // move all directly under
to its own ("table > tbody > tr" selector). + // TODO: move first real to front, move first real at the end + if (elm.ID == HTML_TABLE) + { + std::list::iterator it = elm.Children.begin(); + std::list::iterator tbody = elm.Children.end(); + for(it = elm.Children.begin(); it != elm.Children.end(); ++it) + { + if (it->ID == HTML_TR) + { + if (tbody == elm.Children.end()) + { + tbody = elm.Children.insert(it, CHtmlElement(CHtmlElement::ELEMENT_NODE, "tbody")); + tbody->ID = HTML_TBODY; + tbody->parent = &elm; + } + tbody->Children.splice(tbody->Children.end(), elm.Children, it); + it = tbody; + } + else if (tbody != elm.Children.end()) + { + tbody->reindexChilds(); + tbody = elm.Children.end(); + } + } + + elm.reindexChilds(); + } } } diff --git a/code/nel/src/gui/view_renderer.cpp b/code/nel/src/gui/view_renderer.cpp index 66da2800b..7d60f3c31 100644 --- a/code/nel/src/gui/view_renderer.cpp +++ b/code/nel/src/gui/view_renderer.cpp @@ -1932,6 +1932,16 @@ namespace NLGUI return _TextureId >= 0; } + // *************************************************************************** + void CViewRenderer::CTextureId::clear() + { + if (_TextureId >= 0) + { + CViewRenderer::getInstance()->deleteTexture(_TextureId); + _TextureId = -1; + } + } + // *************************************************************************** void CViewRenderer::CTextureId::serial(NLMISC::IStream &f) { diff --git a/code/nel/src/misc/rgba.cpp b/code/nel/src/misc/rgba.cpp index 277793489..33b6c42ec 100644 --- a/code/nel/src/misc/rgba.cpp +++ b/code/nel/src/misc/rgba.cpp @@ -48,6 +48,7 @@ const CRGBA CRGBA::Blue(0, 0, 255) ; const CRGBA CRGBA::Magenta(255, 0, 255) ; const CRGBA CRGBA::Cyan(0, 255, 255) ; const CRGBA CRGBA::White(255, 255, 255) ; +const CRGBA CRGBA::Transparent(0, 0, 0, 0); // *************************************************************************** void CRGBA::serial(NLMISC::IStream &f)