From 31e0cefb6c1eabfe931d3b95b585947cce3b21ff Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 19 Sep 2019 16:57:22 +0300
Subject: SL-6109 New cell type with icon and text (and 1 pixel offset for all
 text cells)

---
 indra/llui/llscrolllistcell.cpp | 146 +++++++++++++++++++++++++++++++++++++++-
 indra/llui/llscrolllistcell.h   |  29 +++++++-
 2 files changed, 169 insertions(+), 6 deletions(-)

(limited to 'indra/llui')

diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp
index 8000efad0e..63762ab8b8 100644
--- a/indra/llui/llscrolllistcell.cpp
+++ b/indra/llui/llscrolllistcell.cpp
@@ -50,6 +50,10 @@ LLScrollListCell* LLScrollListCell::create(const LLScrollListCell::Params& cell_
 	{
 		cell = new LLScrollListDate(cell_p);
 	}
+	else if (cell_p.type() == "icontext")
+	{
+		cell = new LLScrollListIconText(cell_p);
+	}
 	else	// default is "text"
 	{
 		cell = new LLScrollListText(cell_p);
@@ -168,7 +172,7 @@ U32 LLScrollListText::sCount = 0;
 
 LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p)
 :	LLScrollListCell(p),
-	mText(p.value().asString()),
+	mText(p.text.isProvided() ? p.text() : p.value().asString()),
 	mFont(p.font),
 	mColor(p.color),
 	mUseColor(p.color.isProvided()),
@@ -296,7 +300,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
 		switch(mFontAlignment)
 		{
 		case LLFontGL::LEFT:
-			left = mFont->getWidth(mText.getString(), 0, mHighlightOffset);
+			left = mFont->getWidth(mText.getString(), 1, mHighlightOffset);
 			break;
 		case LLFontGL::RIGHT:
 			left = getWidth() - mFont->getWidth(mText.getString(), mHighlightOffset, S32_MAX);
@@ -319,7 +323,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
 	switch(mFontAlignment)
 	{
 	case LLFontGL::LEFT:
-		start_x = 0.f;
+		start_x = 1.f;
 		break;
 	case LLFontGL::RIGHT:
 		start_x = (F32)getWidth();
@@ -435,3 +439,139 @@ const LLSD LLScrollListDate::getValue() const
 {
 	return mDate;
 }
+
+//
+// LLScrollListIconText
+//
+LLScrollListIconText::LLScrollListIconText(const LLScrollListCell::Params& p)
+    : LLScrollListText(p),
+    mIcon(p.value().isUUID() ? LLUI::getUIImageByID(p.value().asUUID()) : LLUI::getUIImage(p.value().asString())),
+    mPad(4)
+{
+    mTextWidth = getWidth() - mPad /*padding*/ - mFont->getLineHeight();
+}
+
+LLScrollListIconText::~LLScrollListIconText()
+{
+}
+
+const LLSD LLScrollListIconText::getValue() const
+{
+    if (mIcon.isNull())
+    {
+        return LLStringUtil::null;
+    }
+    return mIcon->getName();
+}
+
+void LLScrollListIconText::setValue(const LLSD& value)
+{
+    if (value.isUUID())
+    {
+        // don't use default image specified by LLUUID::null, use no image in that case
+        LLUUID image_id = value.asUUID();
+        mIcon = image_id.notNull() ? LLUI::getUIImageByID(image_id) : LLUIImagePtr(NULL);
+    }
+    else
+    {
+        std::string value_string = value.asString();
+        if (LLUUID::validate(value_string))
+        {
+            setValue(LLUUID(value_string));
+        }
+        else if (!value_string.empty())
+        {
+            mIcon = LLUI::getUIImage(value.asString());
+        }
+        else
+        {
+            mIcon = NULL;
+        }
+    }
+}
+
+void LLScrollListIconText::setWidth(S32 width)
+{
+    LLScrollListCell::setWidth(width);
+    // Assume that iamge height and width is identical to font height and width
+    mTextWidth = width - mPad /*padding*/ - mFont->getLineHeight();
+}
+
+
+void LLScrollListIconText::draw(const LLColor4& color, const LLColor4& highlight_color)	 const
+{
+    LLColor4 display_color;
+    if (mUseColor)
+    {
+        display_color = mColor;
+    }
+    else
+    {
+        display_color = color;
+    }
+
+    S32 icon_height = mFont->getLineHeight();
+    S32 icon_space = mIcon ? (icon_height + mPad) : 0;
+
+    if (mHighlightCount > 0)
+    {
+        S32 left = 0;
+        switch (mFontAlignment)
+        {
+        case LLFontGL::LEFT:
+            left = mFont->getWidth(mText.getString(), icon_space + 1, mHighlightOffset);
+            break;
+        case LLFontGL::RIGHT:
+            left = getWidth() - mFont->getWidth(mText.getString(), mHighlightOffset, S32_MAX) - icon_space;
+            break;
+        case LLFontGL::HCENTER:
+            left = (getWidth() - mFont->getWidth(mText.getString()) - icon_space) / 2;
+            break;
+        }
+        LLRect highlight_rect(left - 2,
+            mFont->getLineHeight() + 1,
+            left + mFont->getWidth(mText.getString(), mHighlightOffset, mHighlightCount) + 1,
+            1);
+        mRoundedRectImage->draw(highlight_rect, highlight_color);
+    }
+
+    // Try to draw the entire string
+    F32 right_x;
+    U32 string_chars = mText.length();
+    F32 start_text_x = 0.f;
+    S32 start_icon_x = 0;
+    switch (mFontAlignment)
+    {
+    case LLFontGL::LEFT:
+        start_text_x = icon_space + 1;
+        start_icon_x = 1;
+        break;
+    case LLFontGL::RIGHT:
+        start_text_x = (F32)getWidth();
+        start_icon_x = getWidth() - mFont->getWidth(mText.getString()) - icon_space;
+        break;
+    case LLFontGL::HCENTER:
+        F32 center = (F32)getWidth()* 0.5f;
+        start_text_x = center + ((F32)icon_space * 0.5f);
+        start_icon_x = center - (((F32)icon_space + mFont->getWidth(mText.getString())) * 0.5f);
+        break;
+    }
+    mFont->render(mText.getWString(), 0,
+        start_text_x, 0.f,
+        display_color,
+        mFontAlignment,
+        LLFontGL::BOTTOM,
+        0,
+        LLFontGL::NO_SHADOW,
+        string_chars,
+        getTextWidth(),
+        &right_x,
+        TRUE);
+
+    if (mIcon)
+    {
+        mIcon->draw(start_icon_x, 0, icon_height, icon_height, mColor);
+    }
+}
+
+
diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h
index d625ebddcc..1604a9b1dc 100644
--- a/indra/llui/llscrolllistcell.h
+++ b/indra/llui/llscrolllistcell.h
@@ -59,7 +59,8 @@ public:
 									visible;
 
 		Optional<void*>				userdata;
-		Optional<LLSD>				value;
+		Optional<LLSD>				value; // state of checkbox, icon id/name, date
+		Optional<std::string>		text; // description or text
 		Optional<std::string>		tool_tip;
 
 		Optional<const LLFontGL*>	font;
@@ -152,7 +153,7 @@ public:
 	void			setText(const LLStringExplicit& text);
 	void			setFontStyle(const U8 font_style);
 
-private:
+protected:
 	LLUIString		mText;
 	S32				mTextWidth;
 	const LLFontGL*	mFont;
@@ -169,7 +170,7 @@ private:
 };
 
 /*
- * Cell displaying an image.
+ * Cell displaying an image. AT the moment, this is specifically UI image
  */
 class LLScrollListIcon : public LLScrollListCell
 {
@@ -223,4 +224,26 @@ private:
 	LLDate		mDate;
 };
 
+/*
+* Cell displaying icon and text.
+*/
+
+class LLScrollListIconText : public LLScrollListText
+{
+public:
+    LLScrollListIconText(const LLScrollListCell::Params& p);
+    /*virtual*/ ~LLScrollListIconText();
+    /*virtual*/ void	draw(const LLColor4& color, const LLColor4& highlight_color) const;
+    /*virtual*/ const LLSD		getValue() const;
+    /*virtual*/ void	setValue(const LLSD& value);
+
+
+    S32					getIconWidth() const;
+    /*virtual*/ void	setWidth(S32 width);/* { LLScrollListCell::setWidth(width); mTextWidth = width - ; }*/
+
+private:
+    LLPointer<LLUIImage>	mIcon;
+    S32						mPad;
+};
+
 #endif
-- 
cgit v1.2.3


From 5322f41250851e210ad130cbf7b5fa1c04efb6ce Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 19 Sep 2019 16:59:23 +0300
Subject: SL-6109 Extended Key-to-string functionality

---
 indra/llui/llmenugl.cpp | 10 +++++-----
 indra/llui/llmenugl.h   | 13 ++++++++++---
 2 files changed, 15 insertions(+), 8 deletions(-)

(limited to 'indra/llui')

diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index 5568a84494..c266bec777 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -263,13 +263,13 @@ BOOL LLMenuItemGL::handleRightMouseUp(S32 x, S32 y, MASK mask)
 
 // This function checks to see if the accelerator key is already in use;
 // if not, it will be added to the list
-BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp)
+BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLMenuKeyboardBinding*> *listp)
 {
-	LLKeyBinding *accelerator = NULL;
+	LLMenuKeyboardBinding *accelerator = NULL;
 
 	if (mAcceleratorKey != KEY_NONE)
 	{
-		std::list<LLKeyBinding*>::iterator list_it;
+		std::list<LLMenuKeyboardBinding*>::iterator list_it;
 		for (list_it = listp->begin(); list_it != listp->end(); ++list_it)
 		{
 			accelerator = *list_it;
@@ -293,7 +293,7 @@ BOOL LLMenuItemGL::addToAcceleratorList(std::list <LLKeyBinding*> *listp)
 		}
 		if (!accelerator)
 		{				
-			accelerator = new LLKeyBinding;
+			accelerator = new LLMenuKeyboardBinding;
 			if (accelerator)
 			{
 				accelerator->mKey = mAcceleratorKey;
@@ -1024,7 +1024,7 @@ BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask)
 
 // This function checks to see if the accelerator key is already in use;
 // if not, it will be added to the list
-BOOL LLMenuItemBranchGL::addToAcceleratorList(std::list<LLKeyBinding*> *listp)
+BOOL LLMenuItemBranchGL::addToAcceleratorList(std::list<LLMenuKeyboardBinding*> *listp)
 {
 	LLMenuGL* branch = getBranch();
 	if (!branch)
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 1f11f26192..b47b6a5214 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -42,6 +42,13 @@
 extern S32 MENU_BAR_HEIGHT;
 extern S32 MENU_BAR_WIDTH;
 
+class LLMenuKeyboardBinding
+{
+public:
+    KEY				mKey;
+    MASK			mMask;
+};
+
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLMenuItemGL
 //
@@ -109,7 +116,7 @@ public:
 	virtual void setBriefItem(BOOL brief);
 	virtual BOOL isBriefItem() const;
 
-	virtual BOOL addToAcceleratorList(std::list<LLKeyBinding*> *listp);
+	virtual BOOL addToAcceleratorList(std::list<LLMenuKeyboardBinding*> *listp);
 	void setAllowKeyRepeat(BOOL allow) { mAllowKeyRepeat = allow; }
 	BOOL getAllowKeyRepeat() const { return mAllowKeyRepeat; }
 
@@ -631,7 +638,7 @@ public:
 	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
 
 	// check if we've used these accelerators already
-	virtual BOOL addToAcceleratorList(std::list <LLKeyBinding*> *listp);
+	virtual BOOL addToAcceleratorList(std::list <LLMenuKeyboardBinding*> *listp);
 
 	// called to rebuild the draw label
 	virtual void buildDrawLabel( void );
@@ -797,7 +804,7 @@ private:
 
 	void checkMenuTrigger();
 
-	std::list <LLKeyBinding*>	mAccelerators;
+	std::list <LLMenuKeyboardBinding*>	mAccelerators;
 	BOOL						mAltKeyTrigger;
 };
 
-- 
cgit v1.2.3


From 4df05c5a8995158922c7b7aacfef442ac8ae6fdd Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 17 Sep 2019 21:36:59 +0300
Subject: SL-6109 Keyaboard support ready

---
 indra/llui/llscrolllistctrl.cpp | 4 ++++
 indra/llui/llscrolllistctrl.h   | 4 +++-
 2 files changed, 7 insertions(+), 1 deletion(-)

(limited to 'indra/llui')

diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 763c3aeb81..6c30bdde17 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -130,6 +130,7 @@ LLScrollListCtrl::Params::Params()
 	search_column("search_column", 0),
 	sort_column("sort_column", -1),
 	sort_ascending("sort_ascending", true),
+	can_sort("can_sort", true),
 	mouse_wheel_opaque("mouse_wheel_opaque", false),
 	commit_on_keyboard_movement("commit_on_keyboard_movement", true),
 	heading_height("heading_height"),
@@ -166,6 +167,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
 	mSelectionChanged(false),
 	mNeedsScroll(false),
 	mCanSelect(true),
+	mCanSort(p.can_sort),
 	mColumnsDirty(false),
 	mMaxItemCount(INT_MAX), 
 	mBorderThickness( 2 ),
@@ -2801,6 +2803,8 @@ void LLScrollListCtrl::onClickColumn(void *userdata)
 	LLScrollListCtrl *parent = info->mParentCtrl;
 	if (!parent) return;
 
+	if (!parent->mCanSort) return;
+
 	S32 column_index = info->mIndex;
 
 	LLScrollListColumn* column = parent->mColumnsIndexed[info->mIndex];
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 43e1c0d707..edfbaa6548 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -115,7 +115,8 @@ public:
 		// sort and search behavior
 		Optional<S32>	search_column,
 						sort_column;
-		Optional<bool>	sort_ascending;
+		Optional<bool>	sort_ascending,
+						can_sort; // whether user is allowed to sort
 
 		// colors
 		Optional<LLUIColor>	fg_unselected_color,
@@ -460,6 +461,7 @@ private:
 	bool			mNeedsScroll;
 	bool			mMouseWheelOpaque;
 	bool			mCanSelect;
+    bool			mCanSort;		// Whether user is allowed to sort
 	bool			mDisplayColumnHeaders;
 	bool			mColumnsDirty;
 	bool			mColumnWidthsDirty;
-- 
cgit v1.2.3


From c60b929fbb615f8d73f7bf42849b5628bf0f8f7a Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Wed, 25 Sep 2019 17:54:36 +0300
Subject: SL-6109 Mouse support ready

---
 indra/llui/llscrolllistcell.cpp | 5 +++++
 1 file changed, 5 insertions(+)

(limited to 'indra/llui')

diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp
index 63762ab8b8..0a33ee8878 100644
--- a/indra/llui/llscrolllistcell.cpp
+++ b/indra/llui/llscrolllistcell.cpp
@@ -314,6 +314,11 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
 				left + mFont->getWidth(mText.getString(), mHighlightOffset, mHighlightCount) + 1, 
 				1);
 		mRoundedRectImage->draw(highlight_rect, highlight_color);
+		/*LLRect highlight_rect(left - 2, 
+				mFont->getLineHeight() + 2, 
+				left + getWidth() + 2, 
+				1);
+		mRoundedRectImage->draw(highlight_rect, LLColor4::black);*/
 	}
 
 	// Try to draw the entire string
-- 
cgit v1.2.3


From 2532a2ee9ee9003e2c6b72f8da19979a9e3dd2f6 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 26 Sep 2019 22:28:18 +0300
Subject: SL-6109 Conflict resolution

---
 indra/llui/llscrolllistcell.cpp | 24 ++++++++++++++++++------
 indra/llui/llscrolllistcell.h   |  2 ++
 2 files changed, 20 insertions(+), 6 deletions(-)

(limited to 'indra/llui')

diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp
index 0a33ee8878..d6627a6957 100644
--- a/indra/llui/llscrolllistcell.cpp
+++ b/indra/llui/llscrolllistcell.cpp
@@ -196,7 +196,14 @@ LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p)
 void LLScrollListText::highlightText(S32 offset, S32 num_chars)
 {
 	mHighlightOffset = offset;
-	mHighlightCount = num_chars;
+	mHighlightCount = llmax(0, num_chars);
+}
+
+//virtual
+void LLScrollListText::setHighlighted(bool highlighted)
+{
+    mHighlightOffset = 0;
+    mHighlightCount = highlighted ? -1 : 0;
 }
 
 //virtual 
@@ -296,6 +303,7 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
 
 	if (mHighlightCount > 0)
 	{
+		// Highlight text
 		S32 left = 0;
 		switch(mFontAlignment)
 		{
@@ -314,11 +322,15 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
 				left + mFont->getWidth(mText.getString(), mHighlightOffset, mHighlightCount) + 1, 
 				1);
 		mRoundedRectImage->draw(highlight_rect, highlight_color);
-		/*LLRect highlight_rect(left - 2, 
-				mFont->getLineHeight() + 2, 
-				left + getWidth() + 2, 
-				1);
-		mRoundedRectImage->draw(highlight_rect, LLColor4::black);*/
+	}
+	else if (mHighlightCount < 0)
+	{
+		// Highlight whole cell
+		LLRect highlight_rect(0,
+		getHeight(),
+		getWidth() - 1,
+		-1);
+		gl_rect_2d(highlight_rect, LLColor4(0.38f, 0.694f, 0.573f, 0.35f));
 	}
 
 	// Try to draw the entire string
diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h
index 1604a9b1dc..b4bb14bcf1 100644
--- a/indra/llui/llscrolllistcell.h
+++ b/indra/llui/llscrolllistcell.h
@@ -103,6 +103,7 @@ public:
 	virtual BOOL			getVisible() const { return TRUE; }
 	virtual void			setWidth(S32 width) { mWidth = width; }
 	virtual void			highlightText(S32 offset, S32 num_chars) {}
+	virtual void			setHighlighted(bool highlighted) {}
 	virtual BOOL			isText() const { return FALSE; }
 	virtual BOOL			needsToolTip() const { return ! mToolTip.empty(); }
 	virtual void			setColor(const LLColor4&) {}
@@ -140,6 +141,7 @@ public:
 	/*virtual*/ const LLSD getValue() const;
 	/*virtual*/ BOOL	getVisible() const;
 	/*virtual*/ void	highlightText(S32 offset, S32 num_chars);
+	/*virtual*/ void	setHighlighted(bool highlighted);
 
 	/*virtual*/ void	setColor(const LLColor4&);
 	/*virtual*/ BOOL	isText() const;
-- 
cgit v1.2.3


From af7cefe031b0680253c7b0c082216af841a10939 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Tue, 1 Oct 2019 22:21:37 +0300
Subject: SL-6109 Cell selection support

---
 indra/llui/llscrolllistcell.cpp |  18 +----
 indra/llui/llscrolllistcell.h   |   8 +-
 indra/llui/llscrolllistctrl.cpp | 173 ++++++++++++++++++++++++++++++++--------
 indra/llui/llscrolllistctrl.h   |  17 +++-
 indra/llui/llscrolllistitem.cpp |  56 ++++++++++++-
 indra/llui/llscrolllistitem.h   |  21 ++++-
 6 files changed, 230 insertions(+), 63 deletions(-)

(limited to 'indra/llui')

diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp
index d6627a6957..13839da400 100644
--- a/indra/llui/llscrolllistcell.cpp
+++ b/indra/llui/llscrolllistcell.cpp
@@ -172,7 +172,7 @@ U32 LLScrollListText::sCount = 0;
 
 LLScrollListText::LLScrollListText(const LLScrollListCell::Params& p)
 :	LLScrollListCell(p),
-	mText(p.text.isProvided() ? p.text() : p.value().asString()),
+	mText(p.label.isProvided() ? p.label() : p.value().asString()),
 	mFont(p.font),
 	mColor(p.color),
 	mUseColor(p.color.isProvided()),
@@ -199,13 +199,6 @@ void LLScrollListText::highlightText(S32 offset, S32 num_chars)
 	mHighlightCount = llmax(0, num_chars);
 }
 
-//virtual
-void LLScrollListText::setHighlighted(bool highlighted)
-{
-    mHighlightOffset = 0;
-    mHighlightCount = highlighted ? -1 : 0;
-}
-
 //virtual 
 BOOL LLScrollListText::isText() const
 {
@@ -323,15 +316,6 @@ void LLScrollListText::draw(const LLColor4& color, const LLColor4& highlight_col
 				1);
 		mRoundedRectImage->draw(highlight_rect, highlight_color);
 	}
-	else if (mHighlightCount < 0)
-	{
-		// Highlight whole cell
-		LLRect highlight_rect(0,
-		getHeight(),
-		getWidth() - 1,
-		-1);
-		gl_rect_2d(highlight_rect, LLColor4(0.38f, 0.694f, 0.573f, 0.35f));
-	}
 
 	// Try to draw the entire string
 	F32 right_x;
diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h
index b4bb14bcf1..ef7f717b57 100644
--- a/indra/llui/llscrolllistcell.h
+++ b/indra/llui/llscrolllistcell.h
@@ -60,7 +60,7 @@ public:
 
 		Optional<void*>				userdata;
 		Optional<LLSD>				value; // state of checkbox, icon id/name, date
-		Optional<std::string>		text; // description or text
+		Optional<std::string>		label; // description or text
 		Optional<std::string>		tool_tip;
 
 		Optional<const LLFontGL*>	font;
@@ -70,12 +70,13 @@ public:
 		Optional<LLColor4>			color;
 
 		Params()
-		:	type("type", "text"),
+		:	type("cell_type", "text"), // Don't use "type", it overlaps with xml's parameter
 			column("column"),
 			width("width"),
 			enabled("enabled", true),
 			visible("visible", true),
 			value("value"),
+			label("label"),
 			tool_tip("tool_tip", ""),
 			font("font", LLFontGL::getFontSansSerifSmall()),
 			font_color("font_color", LLColor4::black),
@@ -103,7 +104,6 @@ public:
 	virtual BOOL			getVisible() const { return TRUE; }
 	virtual void			setWidth(S32 width) { mWidth = width; }
 	virtual void			highlightText(S32 offset, S32 num_chars) {}
-	virtual void			setHighlighted(bool highlighted) {}
 	virtual BOOL			isText() const { return FALSE; }
 	virtual BOOL			needsToolTip() const { return ! mToolTip.empty(); }
 	virtual void			setColor(const LLColor4&) {}
@@ -141,7 +141,6 @@ public:
 	/*virtual*/ const LLSD getValue() const;
 	/*virtual*/ BOOL	getVisible() const;
 	/*virtual*/ void	highlightText(S32 offset, S32 num_chars);
-	/*virtual*/ void	setHighlighted(bool highlighted);
 
 	/*virtual*/ void	setColor(const LLColor4&);
 	/*virtual*/ BOOL	isText() const;
@@ -160,6 +159,7 @@ protected:
 	S32				mTextWidth;
 	const LLFontGL*	mFont;
 	LLColor4		mColor;
+	LLColor4		mHighlightColor;
 	U8				mUseColor;
 	LLFontGL::HAlign mFontAlignment;
 	BOOL			mVisible;
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 6c30bdde17..83f80cfb9e 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -115,6 +115,13 @@ struct SortScrollListItem
 // LLScrollListCtrl
 //---------------------------------------------------------------------------
 
+void LLScrollListCtrl::SelectionTypeNames::declareValues()
+{
+    declare("row", LLScrollListCtrl::ROW);
+    declare("cell", LLScrollListCtrl::CELL);
+    declare("header", LLScrollListCtrl::HEADER);
+}
+
 LLScrollListCtrl::Contents::Contents()
 :	columns("column"),
 	rows("row")
@@ -128,6 +135,7 @@ LLScrollListCtrl::Params::Params()
 	has_border("draw_border"),
 	draw_heading("draw_heading"),
 	search_column("search_column", 0),
+	selection_type("selection_type", ROW),
 	sort_column("sort_column", -1),
 	sort_ascending("sort_ascending", true),
 	can_sort("can_sort", true),
@@ -165,6 +173,7 @@ LLScrollListCtrl::LLScrollListCtrl(const LLScrollListCtrl::Params& p)
 	mCommitOnKeyboardMovement(p.commit_on_keyboard_movement),
 	mCommitOnSelectionChange(false),
 	mSelectionChanged(false),
+	mSelectionType(p.selection_type),
 	mNeedsScroll(false),
 	mCanSelect(true),
 	mCanSort(p.can_sort),
@@ -821,7 +830,15 @@ BOOL LLScrollListCtrl::selectFirstItem()
 		{
 			if (!itemp->getSelected())
 			{
-				selectItem(itemp);
+                switch (mSelectionType)
+                {
+                case CELL:
+                    selectItem(itemp, 0);
+                    break;
+                case HEADER:
+                case ROW:
+                    selectItem(itemp, -1);
+                }
 			}
 			success = TRUE;
 			mOriginalSelection = 0;
@@ -880,7 +897,8 @@ BOOL LLScrollListCtrl::selectItemRange( S32 first_index, S32 last_index )
 		{
 			if( itemp->getEnabled() )
 			{
-				selectItem(itemp, FALSE);
+				// TODO: support range selection for cells
+				selectItem(itemp, -1, FALSE);
 				success = TRUE;				
 			}
 		}
@@ -1006,10 +1024,14 @@ void LLScrollListCtrl::clearHighlightedItems()
 
 void LLScrollListCtrl::mouseOverHighlightNthItem(S32 target_index)
 {
-	if (mHighlightedItem != target_index)
-	{
-		mHighlightedItem = target_index;
-	}
+    if (mHighlightedItem != target_index)
+    {
+        if (mHighlightedItem >= 0 && mHighlightedItem < mItemList.size())
+        {
+            mItemList[mHighlightedItem]->setHoverCell(-1);
+        }
+        mHighlightedItem = target_index;
+    }
 }
 
 S32	LLScrollListCtrl::selectMultiple( uuid_vec_t ids )
@@ -1024,7 +1046,8 @@ S32	LLScrollListCtrl::selectMultiple( uuid_vec_t ids )
 		{
 			if (item->getEnabled() && (item->getUUID() == (*iditr)))
 			{
-				selectItem(item,FALSE);
+				// TODO: support multiple selection for cells
+				selectItem(item, -1, FALSE);
 				++count;
 				break;
 			}
@@ -1097,7 +1120,7 @@ void LLScrollListCtrl::selectPrevItem( BOOL extend_selection)
 			{
 				if (prev_item)
 				{
-					selectItem(prev_item, !extend_selection);
+					selectItem(prev_item, cur_item->getSelectedCell(), !extend_selection);
 				}
 				else
 				{
@@ -1141,7 +1164,7 @@ void LLScrollListCtrl::selectNextItem( BOOL extend_selection)
 			{
 				if (next_item)
 				{
-					selectItem(next_item, !extend_selection);
+					selectItem(next_item, cur_item->getSelectedCell(), !extend_selection);
 				}
 				else
 				{
@@ -1212,7 +1235,7 @@ BOOL LLScrollListCtrl::selectItemByLabel(const std::string& label, BOOL case_sen
 	bool found = NULL != item;
 	if(found)
 	{
-		selectItem(item);
+		selectItem(item, -1);
 	}
 
 	if (mCommitOnSelectionChange)
@@ -1280,7 +1303,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
 			BOOL select = cellp ? item->getEnabled() && ('\0' == cellp->getValue().asString()[0]) : FALSE;
 			if (select)
 			{
-				selectItem(item);
+				selectItem(item, -1);
 				found = TRUE;
 				break;
 			}
@@ -1320,7 +1343,7 @@ BOOL LLScrollListCtrl::selectItemByPrefix(const LLWString& target, BOOL case_sen
 				// find offset of matching text (might have leading whitespace)
 				S32 offset = item_label.find(target_trimmed);
 				cellp->highlightText(offset, target_trimmed.size());
-				selectItem(item);
+				selectItem(item, -1);
 				found = TRUE;
 				break;
 			}
@@ -1386,7 +1409,7 @@ BOOL LLScrollListCtrl::setSelectedByValue(const LLSD& value, BOOL selected)
 		{
 			if (selected)
 			{
-				selectItem(item);
+				selectItem(item, -1);
 			}
 			else
 			{
@@ -1466,7 +1489,7 @@ void LLScrollListCtrl::drawItems()
 		
 		S32 max_columns = 0;
 
-		LLColor4 highlight_color = LLColor4::white;
+		LLColor4 highlight_color = LLColor4::white; // ex: text inside cells
 		static LLUICachedControl<F32> type_ahead_timeout ("TypeAheadTimeout", 0);
 		highlight_color.mV[VALPHA] = clamp_rescale(mSearchTimer.getElapsedTimeF32(), type_ahead_timeout * 0.7f, type_ahead_timeout(), 0.4f, 0.f);
 
@@ -1492,7 +1515,8 @@ void LLScrollListCtrl::drawItems()
 			max_columns = llmax(max_columns, item->getNumColumns());
 
 			LLColor4 fg_color;
-			LLColor4 bg_color(LLColor4::transparent);
+			LLColor4 hover_color(LLColor4::transparent);
+			LLColor4 select_color(LLColor4::transparent);
 
 			if( mScrollLines <= line && line < mScrollLines + num_page_lines )
 			{
@@ -1501,44 +1525,44 @@ void LLScrollListCtrl::drawItems()
 				{
 					if(item->getHighlighted())	// if it's highlighted, average the colors
 					{
-						bg_color = lerp(mBgSelectedColor.get(), mHighlightedColor.get(), 0.5f);
+						select_color = lerp(mBgSelectedColor.get(), mHighlightedColor.get(), 0.5f);
 					}
 					else						// otherwise just select-highlight it
 					{
-						bg_color = mBgSelectedColor.get();
+						select_color = mBgSelectedColor.get();
 					}
 
 					fg_color = (item->getEnabled() ? mFgSelectedColor.get() : mFgDisabledColor.get());
 				}
-				else if (mHighlightedItem == line && mCanSelect)
+				if (mHighlightedItem == line && mCanSelect)
 				{
 					if(item->getHighlighted())	// if it's highlighted, average the colors
 					{
-						bg_color = lerp(mHoveredColor.get(), mHighlightedColor.get(), 0.5f);
+						hover_color = lerp(mHoveredColor.get(), mHighlightedColor.get(), 0.5f);
 					}
 					else						// otherwise just hover-highlight it
 					{
-						bg_color = mHoveredColor.get();
+						hover_color = mHoveredColor.get();
 					}
 				}
 				else if (item->getHighlighted())
 				{
-					bg_color = mHighlightedColor.get();
+					hover_color = mHighlightedColor.get();
 				}
 				else 
 				{
 					if (mDrawStripes && (line % 2 == 0) && (max_columns > 1))
 					{
-						bg_color = mBgStripeColor.get();
+						hover_color = mBgStripeColor.get();
 					}
 				}
 
 				if (!item->getEnabled())
 				{
-					bg_color = mBgReadOnlyColor.get();
+					hover_color = mBgReadOnlyColor.get();
 				}
 
-				item->draw(item_rect, fg_color % alpha, bg_color% alpha, highlight_color % alpha, mColumnPadding);
+				item->draw(item_rect, fg_color % alpha, hover_color% alpha, select_color% alpha, highlight_color % alpha, mColumnPadding);
 
 				cur_y -= mLineHeight;
 			}
@@ -1690,7 +1714,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
 			{
 				if (mLastSelected == NULL)
 				{
-					selectItem(hit_item);
+					selectItem(hit_item, getColumnIndexFromOffset(x));
 				}
 				else
 				{
@@ -1714,7 +1738,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
 						LLScrollListItem *item = *itor;
                         if (item == hit_item || item == lastSelected)
 						{
-							selectItem(item, FALSE);
+							selectItem(item, getColumnIndexFromOffset(x), FALSE);
 							selecting = !selecting;
 							if (hit_item == lastSelected)
 							{
@@ -1724,7 +1748,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
 						}
 						if (selecting)
 						{
-							selectItem(item, FALSE);
+							selectItem(item, getColumnIndexFromOffset(x), FALSE);
 						}
 					}
 				}
@@ -1739,7 +1763,7 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
 				{
 					if(!(mMaxSelectable > 0 && getAllSelected().size() >= mMaxSelectable))
 					{
-						selectItem(hit_item, FALSE);
+						selectItem(hit_item, getColumnIndexFromOffset(x), FALSE);
 					}
 					else
 					{
@@ -1753,12 +1777,12 @@ BOOL LLScrollListCtrl::selectItemAt(S32 x, S32 y, MASK mask)
 			else
 			{
 				deselectAllItems(TRUE);
-				selectItem(hit_item);
+				selectItem(hit_item, getColumnIndexFromOffset(x));
 			}
 		}
 		else
 		{
-			selectItem(hit_item);
+			selectItem(hit_item, getColumnIndexFromOffset(x));
 		}
 
 		selection_changed = mSelectionChanged;
@@ -2126,8 +2150,29 @@ BOOL LLScrollListCtrl::handleHover(S32 x,S32 y,MASK mask)
 	{
 		LLScrollListItem* item = hitItem(x, y);
 		if (item)
-		{
-			mouseOverHighlightNthItem(getItemIndex(item));
+        {
+            mouseOverHighlightNthItem(getItemIndex(item));
+            switch (mSelectionType)
+            {
+            case CELL:
+                item->setHoverCell(getColumnIndexFromOffset(x));
+                break;
+            case HEADER:
+                {
+                    S32 cell = getColumnIndexFromOffset(x);
+                    if (cell > 0)
+                    {
+                        item->setHoverCell(cell);
+                    }
+                    else
+                    {
+                        item->setHoverCell(-1);
+                    }
+                    break;
+                }
+            case ROW:
+                break;
+            }
 		}
 		else
 		{
@@ -2175,6 +2220,52 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
 					handled = TRUE;
 				}
 				break;
+            case KEY_LEFT:
+                if (mAllowKeyboardMovement || hasFocus())
+                {
+                    // TODO: support multi-select
+                    LLScrollListItem *item = getFirstSelected();
+                    S32 cell = item->getSelectedCell();
+                    switch (mSelectionType)
+                    {
+                    case CELL:
+                        if (cell < mColumns.size()) cell++;
+                        break;
+                    case HEADER:
+                        if (cell == -1) cell = 1;
+                        else if (cell > 1 && cell < mColumns.size()) cell++; // skip header
+                        break;
+                    case ROW:
+                        cell = -1;
+                        break;
+                    }
+                    item->setSelectedCell(cell);
+                    handled = TRUE;
+                }
+                break;
+            case KEY_RIGHT:
+                if (mAllowKeyboardMovement || hasFocus())
+                {
+                    // TODO: support multi-select
+                    LLScrollListItem *item = getFirstSelected();
+                    S32 cell = item->getSelectedCell();
+                    switch (mSelectionType)
+                    {
+                    case CELL:
+                        if (cell >= 0) cell--;
+                        break;
+                    case HEADER:
+                        if (cell > 1) cell--;
+                        else if (cell == 1) cell = -1; // skip header
+                        break;
+                    case ROW:
+                        cell = -1;
+                        break;
+                    }
+                    item->setSelectedCell(cell);
+                    handled = TRUE;
+                }
+                break;
 			case KEY_PAGE_UP:
 				if (mAllowKeyboardMovement || hasFocus())
 				{
@@ -2343,7 +2434,7 @@ BOOL LLScrollListCtrl::handleUnicodeCharHere(llwchar uni_char)
 				LLWString item_label = utf8str_to_wstring(cellp->getValue().asString());
 				if (item->getEnabled() && LLStringOps::toLower(item_label[0]) == uni_char)
 				{
-					selectItem(item);
+					selectItem(item, -1);
 					mNeedsScroll = true;
 					cellp->highlightText(0, 1);
 					mSearchTimer.reset();
@@ -2395,7 +2486,7 @@ BOOL LLScrollListCtrl::isRepeatedChars(const LLWString& string) const
 	return TRUE;
 }
 
-void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_item)
+void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, S32 cell, BOOL select_single_item)
 {
 	if (!itemp) return;
 
@@ -2414,6 +2505,18 @@ void LLScrollListCtrl::selectItem(LLScrollListItem* itemp, BOOL select_single_it
 			deselectAllItems(TRUE);
 		}
 		itemp->setSelected(TRUE);
+        switch (mSelectionType)
+        {
+        case CELL:
+            itemp->setSelectedCell(cell);
+            break;
+        case HEADER:
+            itemp->setSelectedCell(cell <= 0 ? -1 : cell);
+            break;
+        case ROW:
+            itemp->setSelectedCell(-1);
+            break;
+        }
 		mLastSelected = itemp;
 		mSelectionChanged = true;
 	}
@@ -2674,7 +2777,7 @@ void	LLScrollListCtrl::selectAll()
 		LLScrollListItem *itemp = *iter;
 		if( itemp->getEnabled() )
 		{
-			selectItem(itemp, FALSE);
+			selectItem(itemp, -1, FALSE);
 		}
 	}
 
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index edfbaa6548..45ce67349a 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -54,6 +54,18 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	public LLCtrlListInterface, public LLCtrlScrollInterface
 {
 public:
+    typedef enum e_selection_type
+    {
+        ROW, // default
+        CELL, // does not support multi-selection
+        HEADER, // when pointing to cells in column 0 will highlight whole row, otherwise cell, no multi-select
+    } ESelectionType;
+
+    struct SelectionTypeNames : public LLInitParam::TypeValuesHelper<LLScrollListCtrl::ESelectionType, SelectionTypeNames>
+    {
+        static void declareValues();
+    };
+
 	struct Contents : public LLInitParam::Block<Contents>
 	{
 		Multiple<LLScrollListColumn::Params>	columns;
@@ -99,6 +111,8 @@ public:
 						commit_on_keyboard_movement,
 						mouse_wheel_opaque;
 
+		Optional<ESelectionType, SelectionTypeNames> selection_type;
+
 		// display flags
 		Optional<bool>	has_border,
 						draw_heading,
@@ -433,7 +447,7 @@ private:
 	void            updateLineHeightInsert(LLScrollListItem* item);
 	void			reportInvalidInput();
 	BOOL			isRepeatedChars(const LLWString& string) const;
-	void			selectItem(LLScrollListItem* itemp, BOOL single_select = TRUE);
+	void			selectItem(LLScrollListItem* itemp, S32 cell, BOOL single_select = TRUE);
 	void			deselectItem(LLScrollListItem* itemp);
 	void			commitIfChanged();
 	BOOL			setSort(S32 column, BOOL ascending);
@@ -458,6 +472,7 @@ private:
 	bool			mCommitOnKeyboardMovement;
 	bool			mCommitOnSelectionChange;
 	bool			mSelectionChanged;
+	ESelectionType	mSelectionType;
 	bool			mNeedsScroll;
 	bool			mMouseWheelOpaque;
 	bool			mCanSelect;
diff --git a/indra/llui/llscrolllistitem.cpp b/indra/llui/llscrolllistitem.cpp
index df22c88afb..51c615dd00 100644
--- a/indra/llui/llscrolllistitem.cpp
+++ b/indra/llui/llscrolllistitem.cpp
@@ -40,6 +40,8 @@
 LLScrollListItem::LLScrollListItem( const Params& p )
 :	mSelected(FALSE),
 	mHighlighted(FALSE),
+	mHoverIndex(-1),
+	mSelectedIndex(-1),
 	mEnabled(p.enabled),
 	mUserdata(p.userdata),
 	mItemValue(p.value)
@@ -53,6 +55,28 @@ LLScrollListItem::~LLScrollListItem()
 	mColumns.clear();
 }
 
+void LLScrollListItem::setSelected(BOOL b)
+{
+    mSelected = b;
+    mSelectedIndex = -1;
+}
+
+void LLScrollListItem::setHighlighted(BOOL b)
+{
+    mHighlighted = b;
+    mHoverIndex = -1;
+}
+
+void LLScrollListItem::setHoverCell(S32 cell)
+{
+    mHoverIndex = cell;
+}
+
+void LLScrollListItem::setSelectedCell(S32 cell)
+{
+    mSelectedIndex = cell;
+}
+
 void LLScrollListItem::addColumn(const LLScrollListCell::Params& p)
 {
 	mColumns.push_back(LLScrollListCell::create(p));
@@ -120,12 +144,21 @@ std::string LLScrollListItem::getContentsCSV() const
 }
 
 
-void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding)
+void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& hover_color, const LLColor4& select_color, const LLColor4& highlight_color, S32 column_padding)
 {
 	// draw background rect
 	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 	LLRect bg_rect = rect;
-	gl_rect_2d( bg_rect, bg_color );
+    if (mSelectedIndex < 0 && getSelected())
+    {
+        // Whole item is highlighted/selected
+        gl_rect_2d(bg_rect, select_color);
+    }
+    else if (mHoverIndex < 0)
+    {
+        // Whole item is highlighted/selected
+        gl_rect_2d(bg_rect, hover_color);
+    }
 
 	S32 cur_x = rect.mLeft;
 	S32 num_cols = getNumColumns();
@@ -141,6 +174,25 @@ void LLScrollListItem::draw(const LLRect& rect, const LLColor4& fg_color, const
 		{
 			LLUI::translate((F32) cur_x, (F32) rect.mBottom);
 
+            if (mSelectedIndex == cur_col)
+            {
+                // select specific cell
+                LLRect highlight_rect(0,
+                    cell->getHeight(),
+                    cell->getWidth(),
+                    0);
+                gl_rect_2d(highlight_rect, select_color);
+            }
+            else if (mHoverIndex == cur_col)
+            {
+                // highlight specific cell
+                LLRect highlight_rect(0,
+                    cell->getHeight(),
+                    cell->getWidth() ,
+                    0);
+                gl_rect_2d(highlight_rect, hover_color);
+            }
+
 			cell->draw( fg_color, highlight_color );
 		}
 		LLUI::popMatrix();
diff --git a/indra/llui/llscrolllistitem.h b/indra/llui/llscrolllistitem.h
index 13655b5873..d2c3dd7721 100644
--- a/indra/llui/llscrolllistitem.h
+++ b/indra/llui/llscrolllistitem.h
@@ -77,15 +77,21 @@ public:
 
 	virtual ~LLScrollListItem();
 
-	void	setSelected( BOOL b )			{ mSelected = b; }
+	void	setSelected( BOOL b );
 	BOOL	getSelected() const				{ return mSelected; }
 
 	void	setEnabled( BOOL b )			{ mEnabled = b; }
 	BOOL	getEnabled() const 				{ return mEnabled; }
 
-	void	setHighlighted( BOOL b )		{ mHighlighted = b; }
+	void	setHighlighted( BOOL b );
 	BOOL	getHighlighted() const			{ return mHighlighted; }
 
+	void	setSelectedCell( S32 cell );
+	S32		getSelectedCell() const			{ return mSelectedIndex; }
+
+	void	setHoverCell( S32 cell );
+	S32		getHoverCell() const			{ return mHoverIndex; }
+
 	void	setUserdata( void* userdata )	{ mUserdata = userdata; }
 	void*	getUserdata() const 			{ return mUserdata; }
 
@@ -107,14 +113,21 @@ public:
 
 	std::string getContentsCSV() const;
 
-	virtual void draw(const LLRect& rect, const LLColor4& fg_color, const LLColor4& bg_color, const LLColor4& highlight_color, S32 column_padding);
+	virtual void draw(const LLRect& rect,
+					  const LLColor4& fg_color,
+					  const LLColor4& hover_color, // highlight/hover selection of whole item or cell
+					  const LLColor4& select_color, // highlight/hover selection of whole item or cell
+					  const LLColor4& highlight_color, // highlights contents of cells (ex: text)
+					  S32 column_padding);
 
 protected:
 	LLScrollListItem( const Params& );
 
 private:
 	BOOL	mSelected;
-	BOOL	mHighlighted;
+    BOOL	mHighlighted;
+    S32		mHoverIndex;
+	S32		mSelectedIndex;
 	BOOL	mEnabled;
 	void*	mUserdata;
 	LLSD	mItemValue;
-- 
cgit v1.2.3


From 13a25be08f0c81a759076907d7950baf4f2c3ef2 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 3 Oct 2019 19:46:12 +0300
Subject: SL-6109 Better menu accelerator support and slight reorganization

---
 indra/llui/llmenugl.cpp | 21 +++++++++++++++++++++
 indra/llui/llmenugl.h   |  2 ++
 2 files changed, 23 insertions(+)

(limited to 'indra/llui')

diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index c266bec777..d97bf2d674 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -3536,6 +3536,27 @@ S32 LLMenuBarGL::getRightmostMenuEdge()
 	return (*item_iter)->getRect().mRight;
 }
 
+bool LLMenuBarGL::hasAccelerator(const KEY &key, const MASK &mask) const
+{
+    if (key == KEY_NONE)
+    {
+        return false;
+    }
+
+    LLMenuKeyboardBinding *accelerator = NULL;
+    std::list<LLMenuKeyboardBinding*>::const_iterator list_it;
+    for (list_it = mAccelerators.begin(); list_it != mAccelerators.end(); ++list_it)
+    {
+        accelerator = *list_it;
+        if ((accelerator->mKey == key) && (accelerator->mMask == (mask & MASK_NORMALKEYS)))
+        {
+            return true;
+        }
+    }
+
+    return false;
+}
+
 // add a vertical separator to this menu
 BOOL LLMenuBarGL::addSeparator()
 {
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index b47b6a5214..adcb2ca2f9 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -795,6 +795,8 @@ public:
 
 	void resetMenuTrigger() { mAltKeyTrigger = FALSE; }
 
+	bool hasAccelerator(const KEY &key, const MASK &mask) const;
+
 private:
 	// add a menu - this will create a drop down menu.
 	virtual BOOL appendMenu( LLMenuGL* menu );
-- 
cgit v1.2.3


From e211372923bed31e632bc9825913d3d57cdc2d52 Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Thu, 3 Oct 2019 22:45:29 +0300
Subject: SL-6109 Remade 'ignore' list processing, renamed and reformed
 keybindings

---
 indra/llui/llscrolllistcell.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'indra/llui')

diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h
index ef7f717b57..19576fb247 100644
--- a/indra/llui/llscrolllistcell.h
+++ b/indra/llui/llscrolllistcell.h
@@ -70,7 +70,7 @@ public:
 		Optional<LLColor4>			color;
 
 		Params()
-		:	type("cell_type", "text"), // Don't use "type", it overlaps with xml's parameter
+		:	type("type", "text"),
 			column("column"),
 			width("width"),
 			enabled("enabled", true),
-- 
cgit v1.2.3


From 62214b53f09c453dc410465ba6e64a772562e6db Mon Sep 17 00:00:00 2001
From: andreykproductengine <andreykproductengine@lindenlab.com>
Date: Mon, 28 Oct 2019 18:27:13 +0200
Subject: SL-6109 Fixed conflict resolution issue caused by menu accelerators

---
 indra/llui/llmenugl.cpp | 53 +++++++++++++++++++++++++++++--------------------
 indra/llui/llmenugl.h   |  7 ++++---
 2 files changed, 36 insertions(+), 24 deletions(-)

(limited to 'indra/llui')

diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index d97bf2d674..b87819102b 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -212,6 +212,12 @@ LLSD LLMenuItemGL::getValue() const
 	return getLabel();
 }
 
+//virtual
+bool LLMenuItemGL::hasAccelerator(const KEY &key, const MASK &mask) const
+{
+	return (mAcceleratorKey == key) && (mAcceleratorMask == mask);
+}
+
 //virtual
 BOOL LLMenuItemGL::handleAcceleratorKey(KEY key, MASK mask)
 {
@@ -1017,6 +1023,11 @@ BOOL LLMenuItemBranchGL::handleMouseUp(S32 x, S32 y, MASK mask)
 	return TRUE;
 }
 
+bool LLMenuItemBranchGL::hasAccelerator(const KEY &key, const MASK &mask) const
+{
+	return getBranch() && getBranch()->hasAccelerator(key, mask);
+}
+
 BOOL LLMenuItemBranchGL::handleAcceleratorKey(KEY key, MASK mask)
 {
 	return getBranch() && getBranch()->handleAcceleratorKey(key, mask);
@@ -3023,6 +3034,27 @@ void LLMenuGL::updateParent(LLView* parentp)
 	}
 }
 
+bool LLMenuGL::hasAccelerator(const KEY &key, const MASK &mask) const
+{
+	if (key == KEY_NONE)
+	{
+		return false;
+	}
+	// Note: checking this way because mAccelerators seems to be broken
+	// mAccelerators probably needs to be cleaned up or fixed
+	// It was used for dupplicate accelerator avoidance.
+	item_list_t::const_iterator item_iter;
+	for (item_iter = mItems.begin(); item_iter != mItems.end(); ++item_iter)
+	{
+		LLMenuItemGL* itemp = *item_iter;
+		if (itemp->hasAccelerator(key, mask))
+		{
+			return true;
+		}
+	}
+	return false;
+}
+
 BOOL LLMenuGL::handleAcceleratorKey(KEY key, MASK mask)
 {
 	// don't handle if not enabled
@@ -3536,27 +3568,6 @@ S32 LLMenuBarGL::getRightmostMenuEdge()
 	return (*item_iter)->getRect().mRight;
 }
 
-bool LLMenuBarGL::hasAccelerator(const KEY &key, const MASK &mask) const
-{
-    if (key == KEY_NONE)
-    {
-        return false;
-    }
-
-    LLMenuKeyboardBinding *accelerator = NULL;
-    std::list<LLMenuKeyboardBinding*>::const_iterator list_it;
-    for (list_it = mAccelerators.begin(); list_it != mAccelerators.end(); ++list_it)
-    {
-        accelerator = *list_it;
-        if ((accelerator->mKey == key) && (accelerator->mMask == (mask & MASK_NORMALKEYS)))
-        {
-            return true;
-        }
-    }
-
-    return false;
-}
-
 // add a vertical separator to this menu
 BOOL LLMenuBarGL::addSeparator()
 {
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index adcb2ca2f9..8cef9c6463 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -98,6 +98,7 @@ public:
 	/*virtual*/ void setValue(const LLSD& value);
 	/*virtual*/ LLSD getValue() const;
 
+	virtual bool hasAccelerator(const KEY &key, const MASK &mask) const;
 	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
 
 	LLColor4 getHighlightBgColor() { return mHighlightBackground.get(); }
@@ -443,7 +444,8 @@ public:
 	/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
 	/*virtual*/ void removeChild( LLView* ctrl);
 	/*virtual*/ BOOL postBuild();
-
+	
+	virtual bool hasAccelerator(const KEY &key, const MASK &mask) const;
 	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
 
 	LLMenuGL* findChildMenuByName(const std::string& name, BOOL recurse) const;
@@ -635,6 +637,7 @@ public:
 	
 	virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask);
 
+	virtual bool hasAccelerator(const KEY &key, const MASK &mask) const;
 	virtual BOOL handleAcceleratorKey(KEY key, MASK mask);
 
 	// check if we've used these accelerators already
@@ -795,8 +798,6 @@ public:
 
 	void resetMenuTrigger() { mAltKeyTrigger = FALSE; }
 
-	bool hasAccelerator(const KEY &key, const MASK &mask) const;
-
 private:
 	// add a menu - this will create a drop down menu.
 	virtual BOOL appendMenu( LLMenuGL* menu );
-- 
cgit v1.2.3


From 65d661bc67a1ea712a8311fa474cf222f2bd3504 Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Thu, 3 Dec 2020 13:26:44 +0200
Subject: SL-6109 Crash fix for left right selection shift when nothing or
 whole string is selected

---
 indra/llui/llscrolllistctrl.cpp | 62 ++++++++++++++++++++++-------------------
 1 file changed, 34 insertions(+), 28 deletions(-)

(limited to 'indra/llui')

diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 208fc0a219..7d4661c6c7 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -2226,22 +2226,25 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
                 {
                     // TODO: support multi-select
                     LLScrollListItem *item = getFirstSelected();
-                    S32 cell = item->getSelectedCell();
-                    switch (mSelectionType)
+                    if (item)
                     {
-                    case CELL:
-                        if (cell < mColumns.size()) cell++;
-                        break;
-                    case HEADER:
-                        if (cell == -1) cell = 1;
-                        else if (cell > 1 && cell < mColumns.size()) cell++; // skip header
-                        break;
-                    case ROW:
-                        cell = -1;
-                        break;
+                        S32 cell = item->getSelectedCell();
+                        switch (mSelectionType)
+                        {
+                        case CELL:
+                            if (cell < mColumns.size()) cell++;
+                            break;
+                        case HEADER:
+                            if (cell == -1) cell = 1;
+                            else if (cell > 1 && cell < mColumns.size()) cell++; // skip header
+                            break;
+                        case ROW:
+                            cell = -1;
+                            break;
+                        }
+                        item->setSelectedCell(cell);
+                        handled = TRUE;
                     }
-                    item->setSelectedCell(cell);
-                    handled = TRUE;
                 }
                 break;
             case KEY_RIGHT:
@@ -2249,22 +2252,25 @@ BOOL LLScrollListCtrl::handleKeyHere(KEY key,MASK mask )
                 {
                     // TODO: support multi-select
                     LLScrollListItem *item = getFirstSelected();
-                    S32 cell = item->getSelectedCell();
-                    switch (mSelectionType)
+                    if (item)
                     {
-                    case CELL:
-                        if (cell >= 0) cell--;
-                        break;
-                    case HEADER:
-                        if (cell > 1) cell--;
-                        else if (cell == 1) cell = -1; // skip header
-                        break;
-                    case ROW:
-                        cell = -1;
-                        break;
+                        S32 cell = item->getSelectedCell();
+                        switch (mSelectionType)
+                        {
+                        case CELL:
+                            if (cell >= 0) cell--;
+                            break;
+                        case HEADER:
+                            if (cell > 1) cell--;
+                            else if (cell == 1) cell = -1; // skip header
+                            break;
+                        case ROW:
+                            cell = -1;
+                            break;
+                        }
+                        item->setSelectedCell(cell);
+                        handled = TRUE;
                     }
-                    item->setSelectedCell(cell);
-                    handled = TRUE;
                 }
                 break;
 			case KEY_PAGE_UP:
-- 
cgit v1.2.3