From 1ae8a044e021b36d031ac876efba8124854acf9d Mon Sep 17 00:00:00 2001
From: cinder <cinder@cinderblocks.biz>
Date: Mon, 28 Nov 2022 07:23:26 -0600
Subject: [PATCH] Scroll list line editor

---
 indra/llui/llscrolllistcell.cpp | 65 ++++++++++++++++++++++++++++++++-
 indra/llui/llscrolllistcell.h   | 30 +++++++++++++++
 indra/llui/llscrolllistctrl.cpp | 12 ++++++
 indra/llui/llscrolllistctrl.h   |  4 +-
 indra/llui/lltextbase.h         |  4 +-
 5 files changed, 112 insertions(+), 3 deletions(-)

diff --git a/indra/llui/llscrolllistcell.cpp b/indra/llui/llscrolllistcell.cpp
index 28b52823529..6b3e9120f9f 100644
--- a/indra/llui/llscrolllistcell.cpp
+++ b/indra/llui/llscrolllistcell.cpp
@@ -54,6 +54,10 @@ LLScrollListCell* LLScrollListCell::create(const LLScrollListCell::Params& cell_
 	{
 		cell = new LLScrollListIconText(cell_p);
 	}
+	else if(cell_p.type() == "line_editor")
+	{
+		cell = new LLScrollListLineEditor(cell_p);
+	}
 	else	// default is "text"
 	{
 		cell = new LLScrollListText(cell_p);
@@ -94,7 +98,9 @@ LLScrollListIcon::LLScrollListIcon(const LLScrollListCell::Params& p)
 :	LLScrollListCell(p),
 	mIcon(LLUI::getUIImage(p.value().asString())),
 	mColor(p.color),
-	mAlignment(p.font_halign)
+	mAlignment(p.font_halign),
+	mCallback(NULL),
+	mUserData(NULL)
 {}
 
 /*virtual*/
@@ -588,4 +594,61 @@ void LLScrollListIconText::draw(const LLColor4& color, const LLColor4& highlight
     }
 }
 
+//
+// LLScrollListLineEditor
+//
+LLScrollListLineEditor::LLScrollListLineEditor( const LLScrollListCell::Params& p)
+: LLScrollListCell(p)
+{
+	LLLineEditor::Params line_editor_p;
+	line_editor_p.name("line_editor");
+	line_editor_p.rect = LLRect(0, p.width, p.width, 0);
+	line_editor_p.enabled(p.enabled);
+	line_editor_p.initial_value(p.value());
+
+	mLineEditor = LLUICtrlFactory::create<LLLineEditor>(line_editor_p);
+
+	LLRect rect(mLineEditor->getRect());
+	if (p.width())
+	{
+		rect.mRight = rect.mLeft + p.width();
+		mLineEditor->setRect(rect);
+		setWidth(p.width());
+	}
+	else
+	{
+		setWidth(rect.getWidth()); //line_editor->getWidth();
+	}
+}
+
+LLScrollListLineEditor::~LLScrollListLineEditor()
+{
+	delete mLineEditor;
+	mLineEditor = NULL;
+}
 
+void LLScrollListLineEditor::draw(const LLColor4& color, const LLColor4& highlight_color) const
+{
+	mLineEditor->draw();
+}
+
+BOOL LLScrollListLineEditor::handleClick()
+{
+	if (mLineEditor->getEnabled())
+	{
+		mLineEditor->setFocus(TRUE);
+		mLineEditor->selectAll();
+	}
+	// return value changes selection?
+	return FALSE; //TRUE;
+}
+
+BOOL LLScrollListLineEditor::handleUnicodeChar(llwchar uni_char, BOOL called_from_parent)
+{
+	return TRUE;
+}
+
+BOOL LLScrollListLineEditor::handleUnicodeCharHere(llwchar uni_char )
+{
+	return TRUE;
+}
diff --git a/indra/llui/llscrolllistcell.h b/indra/llui/llscrolllistcell.h
index 2d47ece792f..1dd3d2bf7cb 100644
--- a/indra/llui/llscrolllistcell.h
+++ b/indra/llui/llscrolllistcell.h
@@ -34,6 +34,8 @@
 #include "v4color.h"
 #include "llui.h"
 
+#include "lllineeditor.h"
+
 class LLCheckBoxCtrl;
 class LLSD;
 class LLUIImage;
@@ -193,10 +195,16 @@ class LLScrollListIcon : public LLScrollListCell
 	/*virtual*/ void	setColor(const LLColor4&);
 	/*virtual*/ void	setValue(const LLSD& value);
 
+	void setClickCallback(BOOL (*callback)(void*), void* user_data);
+	BOOL handleClick() override;
+
 private:
 	LLPointer<LLUIImage>	mIcon;
 	LLColor4				mColor;
 	LLFontGL::HAlign		mAlignment;
+
+	BOOL (*mCallback)(void*);
+	void* mUserData;
 };
 
 /*
@@ -255,4 +263,26 @@ class LLScrollListIconText : public LLScrollListText
     S32						mPad;
 };
 
+class LLScrollListLineEditor : public LLScrollListCell
+{
+public:
+	LLScrollListLineEditor( const LLScrollListCell::Params&);
+	/*virtual*/ ~LLScrollListLineEditor();
+	void	draw(const LLColor4& color, const LLColor4& highlight_color) const override;
+	S32		getHeight() const override { return 0; }
+	const LLSD	getValue() const override { return mLineEditor->getValue(); }
+	void	setValue(const LLSD& value) override { mLineEditor->setValue(value); }
+	void	onCommit() override { mLineEditor->onCommit(); }
+	BOOL	handleClick() override;
+	virtual BOOL	handleUnicodeChar(llwchar uni_char, BOOL called_from_parent);
+	virtual BOOL	handleUnicodeCharHere(llwchar uni_char );
+	void	setEnabled(BOOL enable) override { mLineEditor->setEnabled(enable); }
+
+	LLLineEditor*	getLineEditor()				{ return mLineEditor; }
+	BOOL	isText() const override { return FALSE; }
+
+private:
+	LLLineEditor* mLineEditor;
+};
+
 #endif
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 6e4764fbd03..33834889acc 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -3330,3 +3330,15 @@ boost::signals2::connection LLScrollListCtrl::setIsFriendCallback(const is_frien
 	}
 	return mIsFriendSignal->connect(cb);
 }
+
+void LLScrollListIcon::setClickCallback(BOOL (*callback)(void*), void* user_data)
+{
+	mCallback = callback;
+	mUserData = user_data;
+}
+
+BOOL LLScrollListIcon::handleClick()
+{
+	if(mCallback) return mCallback(mUserData);
+	return FALSE;
+}
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index ed7af5ce218..9a10735945a 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -179,6 +179,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	virtual LLScrollListColumn* getColumn(S32 index);
     virtual LLScrollListColumn* getColumn(std::string_view name);
 	virtual S32 getNumColumns() const { return mColumnsIndexed.size(); }
+	virtual S32 getPageLines() const { return mPageLines; }
 
 	// Adds a single element, from an array of:
 	// "columns" => [ "column" => column name, "value" => value, "type" => type, "font" => font, "font-style" => style ], "id" => uuid
@@ -314,6 +315,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 
 	virtual S32		getScrollPos() const;
 	virtual void	setScrollPos( S32 pos );
+	S32 getPageLines() { return mPageLines; }
 	S32 getSearchColumn();
 	void			setSearchColumn(S32 column) { mSearchColumn = column; }
 	S32				getColumnIndexFromOffset(S32 x);
@@ -409,6 +411,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	// manually call this whenever editing list items in place to flag need for resorting
 	void			setNeedsSort(bool val = true) { mSorted = !val; }
 	void			dirtyColumns(); // some operation has potentially affected column layout or ordering
+	S32				getLinesPerPage();
 
 	boost::signals2::connection setSortCallback(sort_signal_t::slot_type cb )
 	{
@@ -454,7 +457,6 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	void			deselectItem(LLScrollListItem* itemp);
 	void			commitIfChanged();
 	BOOL			setSort(S32 column, BOOL ascending);
-	S32				getLinesPerPage();
 
 	static void		showProfile(std::string id, bool is_group);
 	static void		sendIM(std::string id);
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 7d9ea43edb2..8fd549eabf7 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -653,7 +653,6 @@ class LLTextBase
 	void							updateScrollFromCursor();
 
 	// text selection
-	bool							hasSelection() const { return (mSelectionStart !=mSelectionEnd); }
 	void 							startSelection();
 	void 							endSelection();
 
@@ -675,6 +674,9 @@ class LLTextBase
 	{
 		return mLabel.getString() + getToolTip();
 	}
+	
+public:
+	bool							hasSelection() const { return (mSelectionStart !=mSelectionEnd); }
 
 protected:
 	// text segmentation and flow
-- 
GitLab