From f30ae5c7812f5449a327a470fd4acaed7546d853 Mon Sep 17 00:00:00 2001
From: Andrey Kleshchev <andreykproductengine@lindenlab.com>
Date: Fri, 23 Jun 2023 21:59:55 +0300
Subject: [PATCH] SL-19914 Inventory gallery Tab support

---
 indra/newview/llinventorygallery.cpp          | 80 ++++++++++++++++++-
 indra/newview/llinventorygallery.h            |  7 ++
 .../xui/en/panel_inventory_gallery.xml        |  1 +
 3 files changed, 87 insertions(+), 1 deletion(-)

diff --git a/indra/newview/llinventorygallery.cpp b/indra/newview/llinventorygallery.cpp
index 0cff30f1aac..248f3ed649e 100644
--- a/indra/newview/llinventorygallery.cpp
+++ b/indra/newview/llinventorygallery.cpp
@@ -63,6 +63,25 @@ BOOL dragCategoryIntoFolder(LLUUID dest_id, LLInventoryCategory* inv_cat, BOOL d
 BOOL dragItemIntoFolder(LLUUID folder_id, LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg, BOOL user_confirm);
 void dropToMyOutfits(LLInventoryCategory* inv_cat);
 
+class LLGalleryPanel: public LLPanel
+{
+public:
+
+    BOOL canFocusChildren() const override
+    {
+        // Tell Tab to not focus children
+        return FALSE;
+    }
+
+protected:
+
+    LLGalleryPanel(const LLPanel::Params& params): LLPanel(params)
+    {
+    };
+
+    friend class LLUICtrlFactory;
+};
+
 //-----------------------------
 // LLInventoryGallery
 //-----------------------------
@@ -622,7 +641,7 @@ void LLInventoryGallery::buildGalleryPanel(int row_count)
     params.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
     params.visible = true;
     params.use_bounding_rect = false;
-    mGalleryPanel = LLUICtrlFactory::create<LLPanel>(params);
+    mGalleryPanel = LLUICtrlFactory::create<LLGalleryPanel>(params);
     reshapeGalleryPanel(row_count);
 }
 
@@ -647,6 +666,8 @@ LLPanel* LLInventoryGallery::buildItemPanel(int left)
         lpparams.visible = true;
         lpparams.rect(LLRect(left, top + mItemHeight, left + mItemWidth + mItemHorizontalGap, top));
         lpparams.use_bounding_rect = false;
+        lpparams.focus_root = false;
+        //lpparams.tab_stop = false;
         lpanel = LLUICtrlFactory::create<LLPanel>(lpparams);
     }
     else
@@ -669,6 +690,8 @@ LLPanel* LLInventoryGallery::buildRowPanel(int left, int bottom)
         sparams.follows.flags(FOLLOWS_LEFT | FOLLOWS_TOP);
         sparams.use_bounding_rect = false;
         sparams.visible = true;
+        sparams.focus_root = false;
+        //sparams.tab_stop = false;
         stack = LLUICtrlFactory::create<LLPanel>(sparams);
     }
     else
@@ -1207,6 +1230,35 @@ void LLInventoryGallery::moveRight()
     }
 }
 
+void LLInventoryGallery::onFocusLost()
+{
+    // inventory no longer handles cut/copy/paste/delete
+    if (gEditMenuHandler == this)
+    {
+        gEditMenuHandler = NULL;
+    }
+
+    LLPanel::onFocusLost();
+
+    if (mSelectedItemID.notNull() && mItemMap[mSelectedItemID])
+    {
+        mItemMap[mSelectedItemID]->setSelected(false);
+    }
+}
+
+void LLInventoryGallery::onFocusReceived()
+{
+    // inventory now handles cut/copy/paste/delete
+    gEditMenuHandler = this;
+
+    LLPanel::onFocusReceived();
+
+    if (mSelectedItemID.notNull() && mItemMap[mSelectedItemID])
+    {
+        mItemMap[mSelectedItemID]->setSelected(true);
+    }
+}
+
 void LLInventoryGallery::showContextMenu(LLUICtrl* ctrl, S32 x, S32 y, const LLUUID& item_id)
 {
     if (mInventoryGalleryMenu && item_id.notNull())
@@ -1595,6 +1647,14 @@ void LLInventoryGallery::claimEditHandler()
     gEditMenuHandler = this;
 }
 
+void LLInventoryGallery::resetEditHandler()
+{
+    if (gEditMenuHandler == this)
+    {
+        gEditMenuHandler = NULL;
+    }
+}
+
 bool LLInventoryGallery::isItemCopyable(const LLUUID & item_id)
 {
     const LLInventoryCategory* cat = gInventory.getCategory(item_id);
@@ -2310,6 +2370,24 @@ BOOL LLInventoryGalleryItem::handleKeyHere(KEY key, MASK mask)
     return handled;
 }
 
+void LLInventoryGalleryItem::onFocusLost()
+{
+    // inventory no longer handles cut/copy/paste/delete
+    mGallery->resetEditHandler();
+    setSelected(false);
+
+    LLPanel::onFocusLost();
+}
+
+void LLInventoryGalleryItem::onFocusReceived()
+{
+    // inventory now handles cut/copy/paste/delete
+    mGallery->claimEditHandler();
+    setSelected(true);
+
+    LLPanel::onFocusReceived();
+}
+
 void LLInventoryGalleryItem::setWorn(bool value)
 {
     mWorn = value;
diff --git a/indra/newview/llinventorygallery.h b/indra/newview/llinventorygallery.h
index f686d8aa2bf..d695da4f953 100644
--- a/indra/newview/llinventorygallery.h
+++ b/indra/newview/llinventorygallery.h
@@ -86,6 +86,9 @@ class LLInventoryGallery : public LLPanel, public LLEditMenuHandler
     void moveLeft();
     void moveRight();
 
+    void onFocusLost();
+    void onFocusReceived();
+
     void setFilterSubString(const std::string& string);
     std::string getFilterSubString() { return mFilterSubString; }
     LLInventoryFilter& getFilter() const { return *mFilter; }
@@ -161,6 +164,7 @@ class LLInventoryGallery : public LLPanel, public LLEditMenuHandler
     U32 getSortOrder() { return mSortOrder; };
 
     void claimEditHandler();
+    void resetEditHandler();
     static bool isItemCopyable(const LLUUID & item_id);
 
     BOOL baseHandleDragAndDrop(LLUUID dest_id, BOOL drop, EDragAndDropType cargo_type,
@@ -290,6 +294,9 @@ class LLInventoryGalleryItem : public LLPanel
                                    std::string& tooltip_msg);
     BOOL handleKeyHere(KEY key, MASK mask);
 
+    void onFocusLost();
+    void onFocusReceived();
+
     LLFontGL* getTextFont();
 
     void setItemName(std::string name);
diff --git a/indra/newview/skins/default/xui/en/panel_inventory_gallery.xml b/indra/newview/skins/default/xui/en/panel_inventory_gallery.xml
index 22cc926e754..ed04e121932 100644
--- a/indra/newview/skins/default/xui/en/panel_inventory_gallery.xml
+++ b/indra/newview/skins/default/xui/en/panel_inventory_gallery.xml
@@ -26,6 +26,7 @@
    layout="topleft"
    left="0"
    top="0"
+   tab_stop="true"
    name="gallery_scroll_panel"
    opaque="false">
   </scroll_container>
-- 
GitLab