From 1140ae3489a9e260a0abb808b4152f2d57384d67 Mon Sep 17 00:00:00 2001
From: Kitty Barnett <develop@catznip.com>
Date: Thu, 29 Dec 2022 19:51:33 +0100
Subject: Add a texture inspector and show it when hovering over an inventory
 textory (or folder containing - among others - exactly one texture) and when
 hovering over notecard embedded textures

---
 indra/llui/llfolderview.cpp     | 16 ++++++++++++++++
 indra/llui/llfolderview.h       |  5 +++++
 indra/llui/llfolderviewitem.cpp | 12 +++++++++++-
 indra/llui/lltooltip.cpp        | 36 +++++++++++++++++++++++++-----------
 indra/llui/lltooltip.h          | 12 ++++++++++--
 5 files changed, 67 insertions(+), 14 deletions(-)

(limited to 'indra/llui')

diff --git a/indra/llui/llfolderview.cpp b/indra/llui/llfolderview.cpp
index ea2ca68e47..a6d4a2ae52 100644
--- a/indra/llui/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -1506,6 +1506,22 @@ BOOL LLFolderView::handleHover( S32 x, S32 y, MASK mask )
 	return LLView::handleHover( x, y, mask );
 }
 
+LLFolderViewItem* LLFolderView::getHoveredItem() const
+{
+	return dynamic_cast<LLFolderViewItem*>(mHoveredItem.get());
+}
+
+void LLFolderView::setHoveredItem(LLFolderViewItem* itemp)
+{
+	if (mHoveredItem.get() != itemp)
+	{
+		if (itemp)
+			mHoveredItem = itemp->getHandle();
+		else
+			mHoveredItem.markDead();
+	}
+}
+
 BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 									 EDragAndDropType cargo_type,
 									 void* cargo_data, 
diff --git a/indra/llui/llfolderview.h b/indra/llui/llfolderview.h
index 6bb5e6c02e..bd38d93b33 100644
--- a/indra/llui/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -144,6 +144,10 @@ public:
 	// applies filters to control visibility of items
 	virtual void filter( LLFolderViewFilter& filter);
 
+	void              clearHoveredItem() { setHoveredItem(nullptr); }
+	LLFolderViewItem* getHoveredItem() const;
+	void              setHoveredItem(LLFolderViewItem* itemp);
+
 	// Get the last selected item
 	virtual LLFolderViewItem* getCurSelectedItem( void );
     selected_items_t& getSelectedItems( void );
@@ -273,6 +277,7 @@ protected:
 protected:
 	LLHandle<LLView>					mPopupMenuHandle;
 	
+	LLHandle<LLView>				mHoveredItem;
 	selected_items_t				mSelectedItems;
 	bool							mKeyboardSelection,
 									mAllowMultiSelect,
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
index eba93beed9..d10130619a 100644
--- a/indra/llui/llfolderviewitem.cpp
+++ b/indra/llui/llfolderviewitem.cpp
@@ -624,11 +624,14 @@ BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
 			getWindow()->setCursor(UI_CURSOR_NOLOCKED);
 		}
 
+		root->clearHoveredItem();
 		return TRUE;
 	}
 	else
 	{
-		getRoot()->setShowSelectionContext(FALSE);
+		LLFolderView* pRoot = getRoot();
+		pRoot->setHoveredItem(this);
+		pRoot->setShowSelectionContext(FALSE);
 		getWindow()->setCursor(UI_CURSOR_ARROW);
 		// let parent handle this then...
 		return FALSE;
@@ -683,6 +686,13 @@ BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
 void LLFolderViewItem::onMouseLeave(S32 x, S32 y, MASK mask)
 {
 	mIsMouseOverTitle = false;
+
+	// NOTE: LLViewerWindow::updateUI() calls "enter" before "leave"; if the mouse moved to another item, we can't just outright clear it
+	LLFolderView* pRoot = getRoot();
+	if (this == pRoot->getHoveredItem())
+	{
+		pRoot->clearHoveredItem();
+	}
 }
 
 BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp
index 2f56a8b1d0..a6552d4ff1 100644
--- a/indra/llui/lltooltip.cpp
+++ b/indra/llui/lltooltip.cpp
@@ -163,6 +163,7 @@ LLToolTip::LLToolTip(const LLToolTip::Params& p)
 :	LLPanel(p),
 	mHasClickCallback(p.click_callback.isProvided()),
 	mPadding(p.padding),
+	mMaxWidth(p.max_width),
 	mTextBox(NULL),
 	mInfoButton(NULL),
 	mPlayMediaButton(NULL),
@@ -272,7 +273,7 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)
 
 	// do this *after* we've had our size set in LLPanel::initFromParams();
 	const S32 REALLY_LARGE_HEIGHT = 10000;
-	mTextBox->reshape(p.max_width, REALLY_LARGE_HEIGHT);
+	mTextBox->reshape(mMaxWidth, REALLY_LARGE_HEIGHT);
 
 	if (p.styled_message.isProvided())
 	{
@@ -288,16 +289,19 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)
 		mTextBox->setText(p.message());
 	}
 
-	S32 text_width = llmin(p.max_width(), mTextBox->getTextPixelWidth() + 1);
+	updateTextBox();
+	snapToChildren();
+}
+
+void LLToolTip::updateTextBox()
+{
+	S32 text_width = llmin(mMaxWidth, mTextBox->getTextPixelWidth() + 1);
 	S32 text_height = mTextBox->getTextPixelHeight();
 	mTextBox->reshape(text_width, text_height);
-	if (mInfoButton)
-	{
-		LLRect text_rect = mTextBox->getRect();
-		LLRect icon_rect = mInfoButton->getRect();
-		mTextBox->translate(0, icon_rect.getCenterY() - text_rect.getCenterY());
-	}
-
+}
+ 
+void LLToolTip::snapToChildren()
+{
 	// reshape tooltip panel to fit text box
 	LLRect tooltip_rect = calcBoundingRect();
 	tooltip_rect.mTop += mPadding;
@@ -305,7 +309,14 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)
 	tooltip_rect.mBottom = 0;
 	tooltip_rect.mLeft = 0;
 
-	mTextBox->reshape(mTextBox->getRect().getWidth(), llmax(mTextBox->getRect().getHeight(), tooltip_rect.getHeight() - 2 * mPadding));
+	if (mInfoButton)
+	{
+		mTextBox->reshape(mTextBox->getRect().getWidth(), llmax(mTextBox->getRect().getHeight(), tooltip_rect.getHeight() - 2 * mPadding));
+
+		LLRect text_rect = mTextBox->getRect();
+		LLRect icon_rect = mInfoButton->getRect();
+		mInfoButton->translate(0, text_rect.getCenterY() - icon_rect.getCenterY());
+	}
 
 	setShape(tooltip_rect);
 }
@@ -428,7 +439,10 @@ void LLToolTipMgr::createToolTip(const LLToolTip::Params& params)
 	}
 	tooltip_params.rect = LLRect (0, 1, 1, 0);
 
-	mToolTip = LLUICtrlFactory::create<LLToolTip> (tooltip_params);
+	if (tooltip_params.create_callback.isProvided())
+		mToolTip = tooltip_params.create_callback()(tooltip_params);
+	else
+		mToolTip = LLUICtrlFactory::create<LLToolTip> (tooltip_params);
 
 	gToolTipView->addChild(mToolTip);
 
diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h
index 0b1fbe5367..86943625ff 100644
--- a/indra/llui/lltooltip.h
+++ b/indra/llui/lltooltip.h
@@ -68,6 +68,7 @@ public:
 	struct Params : public LLInitParam::Block<Params, LLPanel::Params> 
 	{
 		typedef boost::function<void(void)> click_callback_t;
+		typedef boost::function<LLToolTip*(LLToolTip::Params)> create_callback_t;
 
 		Optional<std::string>		message;
 		Multiple<StyledText>		styled_message;
@@ -84,6 +85,8 @@ public:
 		Optional<bool>				time_based_media,
 									web_based_media,
 									media_playing;
+		Optional<create_callback_t>	create_callback;
+		Optional<LLSD>				create_params;
 		Optional<click_callback_t>	click_callback,
 									click_playmedia_callback,
 									click_homepage_callback;
@@ -103,11 +106,15 @@ public:
 	bool hasClickCallback();
 
 	LLToolTip(const Params& p);
-	void initFromParams(const LLToolTip::Params& params);
+	virtual void initFromParams(const LLToolTip::Params& params);
 
 	void getToolTipMessage(std::string & message);
 
-private:
+protected:
+	void updateTextBox();
+	void snapToChildren();
+
+protected:
 	class LLTextBox*	mTextBox;
 	class LLButton*     mInfoButton;
 	class LLButton*     mPlayMediaButton;
@@ -117,6 +124,7 @@ private:
 	LLFrameTimer	mVisibleTimer;
 	bool			mHasClickCallback;
 	S32				mPadding;	// pixels
+	S32				mMaxWidth;
 };
 
 // used for the inspector tooltips which need different background images etc.
-- 
cgit v1.2.3