From e8c7cdbb32c4bcae6f8d55f745a038765e4e14f4 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Sun, 12 Jun 2016 10:22:22 +0300
Subject: [PATCH 1/5] Added: Minimum lines option to multiline text

--HG--
branch : develop
---
 code/nel/include/nel/gui/view_text.h |  4 +++
 code/nel/src/gui/view_text.cpp       | 53 ++++++++++++++++++++++++++--
 2 files changed, 54 insertions(+), 3 deletions(-)

diff --git a/code/nel/include/nel/gui/view_text.h b/code/nel/include/nel/gui/view_text.h
index 35069a9ea..95507ffe3 100644
--- a/code/nel/include/nel/gui/view_text.h
+++ b/code/nel/include/nel/gui/view_text.h
@@ -94,6 +94,7 @@ namespace NLGUI
 		void setMultiLineClipEndSpace (bool state);	// use it for multiline edit box for instance
 		void setFirstLineX (uint firstLineX);
 		void setMultiMaxLine(uint l) { _MultiMaxLine = l; }
+		void setMultiMinLine(uint l) { _MultiMinLine = l; }
 
 		// Force only a subset of letter to be displayed. Default is 0/0xFFFFFFFF
 		void enableStringSelection(uint start, uint end);
@@ -114,6 +115,8 @@ namespace NLGUI
 		sint			getMultiLineSpace()	const	{ return _MultiLineSpace; }
 		bool			getMultiLineMaxWOnly()	const	{ return _MultiLineMaxWOnly; }
 		uint32			getMultiMaxLine() const { return _MultiMaxLine; }
+		uint32			getMultiMinLine() const { return _MultiMinLine; }
+		uint32			getMultiMinOffsetY() const;
 
 		// get current Hint font width, in pixels
 		uint            getFontWidth() const;
@@ -259,6 +262,7 @@ namespace NLGUI
 		sint		_MultiLineSpace;
 		sint		_LastMultiLineMaxW;
 		uint32		_MultiMaxLine;
+		uint32		_MultiMinLine;
 
 
 		/// FormatTag handling
diff --git a/code/nel/src/gui/view_text.cpp b/code/nel/src/gui/view_text.cpp
index 1ccd0ec71..022347525 100644
--- a/code/nel/src/gui/view_text.cpp
+++ b/code/nel/src/gui/view_text.cpp
@@ -75,6 +75,7 @@ namespace NLGUI
 		_MultiLineMaxWOnly = false;
 		_MultiLineClipEndSpace = false;
 		_LastMultiLineMaxW = 0;
+		_MultiMinLine = 0;
 		_MultiMaxLine = 0;
 		_Index = 0xFFFFFFFF;
 
@@ -305,6 +306,11 @@ namespace NLGUI
 			return toString( _MultiMaxLine );
 		}
 		else
+		if( name == "multi_min_line" )
+		{
+			return toString( _MultiMinLine );
+		}
+		else
 		if( name == "underlined" )
 		{
 			return toString( _Underlined );
@@ -479,6 +485,14 @@ namespace NLGUI
 			return true;
 		}
 		else
+		if( name == "multi_min_line" )
+		{
+			uint32 i;
+			if( fromString( value, i ) )
+				_MultiMinLine = i;
+			return true;
+		}
+		else
 		if( name == "underlined" )
 		{
 			bool b;
@@ -621,6 +635,7 @@ namespace NLGUI
 		xmlSetProp( node, BAD_CAST "multi_line_space", BAD_CAST toString( _MultiLineSpace ).c_str() );
 		xmlSetProp( node, BAD_CAST "multi_line_maxw_only", BAD_CAST toString( _MultiLineMaxWOnly ).c_str() );
 		xmlSetProp( node, BAD_CAST "multi_max_line", BAD_CAST toString( _MultiMaxLine ).c_str() );
+		xmlSetProp( node, BAD_CAST "multi_min_line", BAD_CAST toString( _MultiMinLine ).c_str() );
 		xmlSetProp( node, BAD_CAST "underlined", BAD_CAST toString( _Underlined ).c_str() );
 		xmlSetProp( node, BAD_CAST "strikethrough", BAD_CAST toString( _StrikeThrough ).c_str() );
 		xmlSetProp( node, BAD_CAST "case_mode", BAD_CAST toString( uint32( _CaseMode ) ).c_str() );
@@ -741,6 +756,11 @@ namespace NLGUI
 		if (prop)
 			fromString((const char*)prop, _MultiMaxLine);
 
+		prop = (char*) xmlGetProp( cur, (xmlChar*)"multi_min_line" );
+		_MultiMinLine = 0;
+		if (prop)
+			fromString((const char*)prop, _MultiMinLine);
+
 		prop = (char*) xmlGetProp( cur, (xmlChar*)"underlined" );
 		_Underlined = false;
 		if (prop)
@@ -981,6 +1001,13 @@ namespace NLGUI
 
 			sint y_line = _YReal+_FontLegHeight-2;
 
+			if (_MultiMinLine > _Lines.size())
+			{
+				uint dy = getMultiMinOffsetY();
+				y += dy * ooh;
+				y_line += dy;
+			}
+
 			// special selection code
 			if(_TextSelection)
 			{
@@ -1360,6 +1387,19 @@ namespace NLGUI
 		return _FontLegHeight;
 	}
 
+	// ***************************************************************************
+	uint CViewText::getMultiMinOffsetY() const
+	{
+		uint dy = 0;
+		if (_MultiMinLine > _Lines.size())
+		{
+			// first line is always present even if _Lines is empty
+			uint nbLines = _MultiMinLine - std::max((sint)1, (sint)_Lines.size());
+			dy = nbLines * _FontHeight + (nbLines - 1) * _MultiLineSpace;
+		}
+		return dy;
+	}
+
 	// ***************************************************************************
 	void CViewText::flushWordInLine(ucstring &ucCurrentWord, bool &linePushed, const CFormatInfo &wordFormat)
 	{
@@ -1836,6 +1876,10 @@ namespace NLGUI
 			_W = (sint)rTotalW;
 			_H = std::max(_FontHeight, uint(_FontHeight * _Lines.size() + std::max(0, sint(_Lines.size()) - 1) * _MultiLineSpace));
 
+			// See if we should pretend to have at least X lines
+			if (_MultiMinLine > 1)
+				_H = std::max(_H, sint(_FontHeight * _MultiMinLine + (_MultiMinLine - 1) * _MultiLineSpace));
+
 			// Compute tooltips size
 			if (_Tooltips.size() > 0)
 			for (uint i=0 ; i<_Lines.size() ; ++i)
@@ -2118,11 +2162,13 @@ namespace NLGUI
 		//
 		if (_MultiLine)
 		{
+			uint dy = getMultiMinOffsetY();
+
 			uint charIndex = 0;
 			// special case for end of text
 			if (index == (sint) _Text.length())
 			{
-				y = 0;
+				y = dy;
 				if (_Lines.empty())
 				{
 					x = 0;
@@ -2142,7 +2188,7 @@ namespace NLGUI
 				{
 					// should display the character at the end of previous line
 					CLine &currLine = *_Lines[i - 1];
-					y = (sint) ((_FontHeight + _MultiLineSpace) * (_Lines.size() - i));
+					y = (sint) ((_FontHeight + _MultiLineSpace) * (_Lines.size() - i) + dy);
 					x = (sint) (currLine.getWidth() + currLine.getEndSpaces() * currLine.getSpaceWidth());
 					sint nMaxWidth = getCurrentMultiLineMaxW();
 					x = std::min(x, nMaxWidth);
@@ -2153,7 +2199,7 @@ namespace NLGUI
 				if ((sint) newCharIndex > index)
 				{
 					// ok, this line contains the character, now, see which word contains it.
-					y = (sint) ((_FontHeight + _MultiLineSpace) * (_Lines.size() - 1 - i));
+					y = (sint) ((_FontHeight + _MultiLineSpace) * (_Lines.size() - 1 - i) + dy);
 					// see if the index is in the spaces at the end of line
 					if (index - charIndex >= currLine.getNumChars())
 					{
@@ -2252,6 +2298,7 @@ namespace NLGUI
 		uint      charPos = 0;
 		if (_MultiLine)
 		{
+			y -= getMultiMinOffsetY();
 			// seek the line
 			float py = 0.f;
 			if (py > y)

From caf8c5195c3234a1ba9402f2c3dbfc59fdc308c7 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Sun, 12 Jun 2016 10:22:22 +0300
Subject: [PATCH 2/5] Added: Rows attribute to <textarea> element

--HG--
branch : develop
---
 code/nel/src/gui/group_html.cpp                               | 4 +++-
 .../ryzom/client/data/gamedev/interfaces_v3/login_widgets.xml | 3 ++-
 code/ryzom/client/data/gamedev/interfaces_v3/widgets.xml      | 2 ++
 3 files changed, 7 insertions(+), 2 deletions(-)

diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index c5fccd164..5c561f543 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -3973,7 +3973,7 @@ namespace NLGUI
 
 	// ***************************************************************************
 
-	CInterfaceGroup *CGroupHTML::addTextArea(const std::string &templateName, const char *name, uint /* rows */, uint cols, bool multiLine, const ucstring &content, uint maxlength)
+	CInterfaceGroup *CGroupHTML::addTextArea(const std::string &templateName, const char *name, uint rows, uint cols, bool multiLine, const ucstring &content, uint maxlength)
 	{
 		// In a paragraph ?
 		if (!_Paragraph)
@@ -3993,6 +3993,8 @@ namespace NLGUI
 			templateParams.push_back (std::pair<std::string,std::string> ("id", name));
 			templateParams.push_back (std::pair<std::string,std::string> ("prompt", ""));
 			templateParams.push_back (std::pair<std::string,std::string> ("multiline", multiLine?"true":"false"));
+			if (multiLine)
+				templateParams.push_back (std::pair<std::string,std::string> ("multi_min_line", toString(rows)));
 			templateParams.push_back (std::pair<std::string,std::string> ("want_return", multiLine?"true":"false"));
 			templateParams.push_back (std::pair<std::string,std::string> ("enter_recover_focus", "false"));
 			if (maxlength > 0)
diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/login_widgets.xml b/code/ryzom/client/data/gamedev/interfaces_v3/login_widgets.xml
index 932b96549..67145ff4c 100644
--- a/code/ryzom/client/data/gamedev/interfaces_v3/login_widgets.xml
+++ b/code/ryzom/client/data/gamedev/interfaces_v3/login_widgets.xml
@@ -117,11 +117,12 @@
  color="255 255 255 255"
  sizeref_eb="w"
  render_layer="0"
+ multi_min_line="0"
 >
 	<group id="#id" posref="#posref" x="#x" y="#y" posparent="#posparent" child_resize_h="#child_resize_h" sizeref="#sizeref" w="#w" h="#h" render_layer="#render_layer">
 		<group type="edit_box" sizeref="#sizeref_eb" w="-16" id="eb" posref="TL TL" x="8" y="-8" child_resize_h="#child_resize_h" onenter="#onenter" params="#params" onchange="#onchange" onchange_params="#onchange_params" max_num_chars="#max_num_chars" prompt="#prompt" enter_loose_focus="#enter_loose_focus" enter_recover_focus="#enter_recover_focus" entry_type="#entry_type"  reset_focus_on_hide="#reset_focus_on_hide" menu_r="#menu_r" max_historic="#max_historic" want_return="#want_return" backup_father_container_pos="#backup_father_container_pos" render_layer="#render_layer">
 			<view type="bitmap" id="bg" scale="true" sizeref="hw" h="0" w="0" texture="log_eb_m.tga" inherit_gc_alpha="false" render_layer="#render_layer"/>
-			<view id="edit_text" type="text" x="#text_x" y="#text_y" posref="#text_ref" multi_line="#multi_line" multi_line_space="0" fontsize="#fontsize" color="#color" shadow="true" hardtext="" global_color="false" render_layer="#render_layer"/>
+			<view id="edit_text" type="text" x="#text_x" y="#text_y" posref="#text_ref" multi_line="#multi_line" multi_line_space="0" multi_min_line="#multi_min_line" fontsize="#fontsize" color="#color" shadow="true" hardtext="" global_color="false" render_layer="#render_layer"/>
 		</group>
 	
 		<!-- border around the list -->
diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/widgets.xml b/code/ryzom/client/data/gamedev/interfaces_v3/widgets.xml
index 5234846f1..075102c84 100644
--- a/code/ryzom/client/data/gamedev/interfaces_v3/widgets.xml
+++ b/code/ryzom/client/data/gamedev/interfaces_v3/widgets.xml
@@ -2793,6 +2793,7 @@
             text_ref="BL BL"
             child_resize_h="true"
             multi_line="true"
+            multi_min_line="0"
             x="0"
             y="0"
             w="0"
@@ -2872,6 +2873,7 @@
               posref="#text_ref"
               multi_line="#multi_line"
               multi_line_space="0"
+              multi_min_line="#multi_min_line"
               fontsize="#fontsize"
               color="#color"
               shadow="true"

From f201abe6dbd128c5788907f6b42f21696be58136 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Sun, 12 Jun 2016 10:30:16 +0300
Subject: [PATCH 3/5] Changed: Set <textarea>, <input> font style

--HG--
branch : develop
---
 code/nel/src/gui/group_html.cpp               | 55 ++++++++++++++++---
 .../gamedev/interfaces_v3/login_widgets.xml   |  6 +-
 2 files changed, 52 insertions(+), 9 deletions(-)

diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index 5c561f543..e5f3fe1fd 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -55,6 +55,7 @@ using namespace NLMISC;
 // Allow up to 10 redirects, then give up
 #define DEFAULT_RYZOM_REDIRECT_LIMIT (10)
 //
+#define FONT_WEIGHT_NORMAL 400
 #define FONT_WEIGHT_BOLD 700
 
 namespace NLGUI
@@ -1417,14 +1418,24 @@ namespace NLGUI
 						if (present[MY_HTML_INPUT_ALT] && value[MY_HTML_INPUT_ALT])
 							tooltip = value[MY_HTML_INPUT_ALT];
 
+						// by default not inherited
+						CStyleParams style;
+						style.TextColor = TextColor;
+						style.FontSize = TextFontSize;
+						style.FontWeight = FONT_WEIGHT_NORMAL;
+						style.FontOblique = false;
+
+						if (present[MY_HTML_INPUT_STYLE] && value[MY_HTML_INPUT_STYLE])
+							getStyleParams(value[MY_HTML_INPUT_STYLE], style);
+
+						_TextColor.push_back(style.TextColor);
+						_FontSize.push_back(style.FontSize);
+						_FontWeight.push_back(style.FontWeight);
+						_FontOblique.push_back(style.FontOblique);
+
 						string type = toLower(value[MY_HTML_INPUT_TYPE]);
 						if (type == "image")
 						{
-							CStyleParams style;
-							// width, height from inline css
-							if (present[MY_HTML_INPUT_STYLE] && value[MY_HTML_INPUT_STYLE])
-								getStyleParams(value[MY_HTML_INPUT_STYLE], style);
-							
 							// The submit button
 							string name;
 							string normal;
@@ -1632,6 +1643,11 @@ namespace NLGUI
 								_Forms.back().Entries.push_back (entry);
 							}
 						}
+
+						popIfNotEmpty(_FontSize);
+						popIfNotEmpty(_TextColor);
+						popIfNotEmpty(_FontWeight);
+						popIfNotEmpty(_FontOblique);
 					}
 				}
 				break;
@@ -1871,6 +1887,21 @@ namespace NLGUI
 				// Got one form ?
 				if (!(_Forms.empty()))
 				{
+					// not inherited by default
+					CStyleParams style;
+					style.TextColor = TextColor;
+					style.FontWeight = FONT_WEIGHT_NORMAL;
+					style.FontOblique = false;
+					style.FontSize = TextFontSize;
+
+					if (present[MY_HTML_TEXTAREA_STYLE] && value[MY_HTML_TEXTAREA_STYLE])
+						getStyleParams(value[MY_HTML_TEXTAREA_STYLE], style);
+
+					_TextColor.push_back(style.TextColor);
+					_FontSize.push_back(style.FontSize);
+					_FontWeight.push_back(style.FontWeight);
+					_FontOblique.push_back(style.FontOblique);
+
 					// read general property
 					string templateName;
 
@@ -2187,6 +2218,11 @@ namespace NLGUI
 							entry.TextArea = textArea;
 							_Forms.back().Entries.push_back (entry);
 						}
+
+						popIfNotEmpty (_FontSize);
+						popIfNotEmpty (_FontWeight);
+						popIfNotEmpty (_FontOblique);
+						popIfNotEmpty (_TextColor);
 					}
 				}
 				break;
@@ -3988,11 +4024,16 @@ namespace NLGUI
 		{
 			// Not added ?
 			std::vector<std::pair<std::string,std::string> > templateParams;
-			templateParams.push_back (std::pair<std::string,std::string> ("w", toString (cols*12)));
-			//templateParams.push_back (std::pair<std::string,std::string> ("h", toString (rows*12)));
+			templateParams.push_back (std::pair<std::string,std::string> ("w", toString (cols*getFontSize())));
 			templateParams.push_back (std::pair<std::string,std::string> ("id", name));
 			templateParams.push_back (std::pair<std::string,std::string> ("prompt", ""));
 			templateParams.push_back (std::pair<std::string,std::string> ("multiline", multiLine?"true":"false"));
+			templateParams.push_back (std::pair<std::string,std::string> ("fontsize", toString (getFontSize())));
+			templateParams.push_back (std::pair<std::string,std::string> ("color", getTextColor().toString()));
+			if (getFontWeight() >= FONT_WEIGHT_BOLD)
+				templateParams.push_back (std::pair<std::string,std::string> ("fontweight", "bold"));
+			if (getFontOblique())
+				templateParams.push_back (std::pair<std::string,std::string> ("fontstyle", "oblique"));
 			if (multiLine)
 				templateParams.push_back (std::pair<std::string,std::string> ("multi_min_line", toString(rows)));
 			templateParams.push_back (std::pair<std::string,std::string> ("want_return", multiLine?"true":"false"));
diff --git a/code/ryzom/client/data/gamedev/interfaces_v3/login_widgets.xml b/code/ryzom/client/data/gamedev/interfaces_v3/login_widgets.xml
index 67145ff4c..9821bd34a 100644
--- a/code/ryzom/client/data/gamedev/interfaces_v3/login_widgets.xml
+++ b/code/ryzom/client/data/gamedev/interfaces_v3/login_widgets.xml
@@ -111,7 +111,9 @@
  entry_type="text"
  keep="true" 
  max_historic="40"
- fontsize="10" 
+ fontsize="10"
+ fontweight=""
+ fontstyle=""
  backup_father_container_pos="false" 
  want_return="false"
  color="255 255 255 255"
@@ -122,7 +124,7 @@
 	<group id="#id" posref="#posref" x="#x" y="#y" posparent="#posparent" child_resize_h="#child_resize_h" sizeref="#sizeref" w="#w" h="#h" render_layer="#render_layer">
 		<group type="edit_box" sizeref="#sizeref_eb" w="-16" id="eb" posref="TL TL" x="8" y="-8" child_resize_h="#child_resize_h" onenter="#onenter" params="#params" onchange="#onchange" onchange_params="#onchange_params" max_num_chars="#max_num_chars" prompt="#prompt" enter_loose_focus="#enter_loose_focus" enter_recover_focus="#enter_recover_focus" entry_type="#entry_type"  reset_focus_on_hide="#reset_focus_on_hide" menu_r="#menu_r" max_historic="#max_historic" want_return="#want_return" backup_father_container_pos="#backup_father_container_pos" render_layer="#render_layer">
 			<view type="bitmap" id="bg" scale="true" sizeref="hw" h="0" w="0" texture="log_eb_m.tga" inherit_gc_alpha="false" render_layer="#render_layer"/>
-			<view id="edit_text" type="text" x="#text_x" y="#text_y" posref="#text_ref" multi_line="#multi_line" multi_line_space="0" multi_min_line="#multi_min_line" fontsize="#fontsize" color="#color" shadow="true" hardtext="" global_color="false" render_layer="#render_layer"/>
+			<view id="edit_text" type="text" x="#text_x" y="#text_y" posref="#text_ref" multi_line="#multi_line" multi_line_space="0" multi_min_line="#multi_min_line" fontsize="#fontsize" color="#color" fontweight="#fontweight" fontstyle="#fontstyle" shadow="true" hardtext="" global_color="false" render_layer="#render_layer"/>
 		</group>
 	
 		<!-- border around the list -->

From 69728b9a2eca871c1ce61a8ccc0649be0e2cd9dc Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Sun, 12 Jun 2016 12:46:42 +0300
Subject: [PATCH 4/5] Changed: CSS inherit value for some properties

--HG--
branch : develop
---
 code/nel/src/gui/group_html.cpp | 26 ++++++++++++++++++++------
 1 file changed, 20 insertions(+), 6 deletions(-)

diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index e5f3fe1fd..bf862e289 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -5588,15 +5588,23 @@ namespace NLGUI
 		{
 			if (it->first == "font-size")
 			{
-				float tmp;
-				sint size = 0;
-				getPercentage (size, tmp, it->second.c_str());
-				if (size > 0)
-					style.FontSize = size;
+				if (it->second == "inherit")
+					style.FontSize = getFontSize();
+				else
+				{
+					float tmp;
+					sint size = 0;
+					getPercentage (size, tmp, it->second.c_str());
+					if (size > 0)
+						style.FontSize = size;
+				}
 			}
 			else
 			if (it->first == "font-style")
 			{
+				if (it->second == "inherit")
+					style.FontOblique = getFontOblique();
+				else
 				if (it->second == "italic" || it->second == "oblique")
 					style.FontOblique = true;
 			}
@@ -5605,6 +5613,9 @@ namespace NLGUI
 			{
 				// https://developer.mozilla.org/en-US/docs/Web/CSS/font-weight
 				uint weight = 400;
+				if (it->second == "inherit")
+					weight = getFontWeight();
+				else
 				if (it->second == "normal")
 					weight = 400;
 				else
@@ -5637,7 +5648,10 @@ namespace NLGUI
 			}
 			else
 			if (it->first == "color")
-				scanHTMLColor(it->second.c_str(), style.TextColor);
+				if (it->second == "inherit")
+					style.TextColor = getTextColor();
+				else
+					scanHTMLColor(it->second.c_str(), style.TextColor);
 			else
 			if (it->first == "text-decoration" || it->first == "text-decoration-line")
 			{

From b5a4ba313dfa4510f3b675f8b87a33207cdcea19 Mon Sep 17 00:00:00 2001
From: Nimetu <nimetu@gmail.com>
Date: Sun, 12 Jun 2016 12:46:44 +0300
Subject: [PATCH 5/5] Fixed: Keep \n inside <textarea>

--HG--
branch : develop
---
 code/nel/src/gui/group_html.cpp | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/code/nel/src/gui/group_html.cpp b/code/nel/src/gui/group_html.cpp
index bf862e289..64ca4e2cb 100644
--- a/code/nel/src/gui/group_html.cpp
+++ b/code/nel/src/gui/group_html.cpp
@@ -1884,6 +1884,8 @@ namespace NLGUI
 				}
 				break;
 			case HTML_TEXTAREA:
+				_PRE.push_back(true);
+
 				// Got one form ?
 				if (!(_Forms.empty()))
 				{
@@ -2224,6 +2226,8 @@ namespace NLGUI
 						popIfNotEmpty (_FontOblique);
 						popIfNotEmpty (_TextColor);
 					}
+
+					popIfNotEmpty (_PRE);
 				}
 				break;
 			case HTML_TITLE: