Commits

leslie_linden committed de7e703

EXP-1065 FIX -- Inventory has slowed to a crawl. Clicking between items has an average one second delay. Same with switching between tabs.

* Removed numerous places in the code that called findChild across the inventory panel unnecessarily.
* Conglomerated uses of inbox and outbox inventory panels to the sidepanel class so the pointers can be cached and functionality like selection handling can be done more efficiently.
* Optimized LLView::childHasKeyboardFocus() to work backwards up from the focus object rather than searching for children that may or may not turn out to have focus.

Reviewed by Richard.

Comments (0)

Files changed (11)

indra/llui/llview.cpp

 
 BOOL LLView::childHasKeyboardFocus( const std::string& childname ) const
 {
-	LLView *child = findChildView(childname, TRUE);
-	if (child)
+	LLView *focus = dynamic_cast<LLView *>(gFocusMgr.getKeyboardFocus());
+	
+	while (focus != NULL)
 	{
-		return gFocusMgr.childHasKeyboardFocus(child);
+		if (focus->getName() == childname)
+		{
+			return TRUE;
+		}
+		
+		focus = focus->getParent();
 	}
-	else
-	{
-		return FALSE;
-	}
+	
+	return FALSE;
 }
 
 //-----------------------------------------------------------------------------

indra/newview/llavataractions.cpp

 	if (inventory_selected_uuids.empty())
 	{
 		LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory");
-		LLInventoryPanel * inbox = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_inbox");
-		if (inbox)
-		{
-			inventory_selected_uuids = inbox->getRootFolder()->getSelectionList();
-		}
-
+		
+		inventory_selected_uuids = sidepanel_inventory->getInboxOrOutboxSelectionList();
 	}
 
 	return inventory_selected_uuids;

indra/newview/llfloaterworldmap.cpp

 
 LLFloaterWorldMap::LLFloaterWorldMap(const LLSD& key)
 :	LLFloater(key),
-mInventory(NULL),
-mInventoryObserver(NULL),
-mFriendObserver(NULL),
-mCompletingRegionName(),
-mCompletingRegionPos(),
-mWaitingForTracker(FALSE),
-mIsClosing(FALSE),
-mSetToUserPosition(TRUE),
-mTrackedLocation(0,0,0),
-mTrackedStatus(LLTracker::TRACKING_NOTHING)
+	mInventory(NULL),
+	mInventoryObserver(NULL),
+	mFriendObserver(NULL),
+	mCompletingRegionName(),
+	mCompletingRegionPos(),
+	mWaitingForTracker(FALSE),
+	mIsClosing(FALSE),
+	mSetToUserPosition(TRUE),
+	mTrackedLocation(0,0,0),
+	mTrackedStatus(LLTracker::TRACKING_NOTHING),
+	mListFriendCombo(NULL),
+	mListLandmarkCombo(NULL),
+	mListSearchResults(NULL)
 {
 	gFloaterWorldMap = this;
 	
 	avatar_combo->selectFirstItem();
 	avatar_combo->setPrearrangeCallback( boost::bind(&LLFloaterWorldMap::onAvatarComboPrearrange, this) );
 	avatar_combo->setTextEntryCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
+	mListFriendCombo = dynamic_cast<LLCtrlListInterface *>(avatar_combo);
 	
 	LLSearchEditor *location_editor = getChild<LLSearchEditor>("location");
 	location_editor->setFocusChangedCallback(boost::bind(&LLFloaterWorldMap::onLocationFocusChanged, this, _1));
 	location_editor->setKeystrokeCallback( boost::bind(&LLFloaterWorldMap::onSearchTextEntry, this));
 	
 	getChild<LLScrollListCtrl>("search_results")->setDoubleClickCallback( boost::bind(&LLFloaterWorldMap::onClickTeleportBtn, this));
+	mListSearchResults = childGetListInterface("search_results");
 	
 	LLComboBox *landmark_combo = getChild<LLComboBox>( "landmark combo");
 	landmark_combo->selectFirstItem();
 	landmark_combo->setPrearrangeCallback( boost::bind(&LLFloaterWorldMap::onLandmarkComboPrearrange, this) );
 	landmark_combo->setTextEntryCallback( boost::bind(&LLFloaterWorldMap::onComboTextEntry, this) );
+	mListLandmarkCombo = dynamic_cast<LLCtrlListInterface *>(landmark_combo);
 	
 	mCurZoomVal = log(LLWorldMapView::sMapScale)/log(2.f);
 	getChild<LLUICtrl>("zoom slider")->setValue(LLWorldMapView::sMapScale);
 // No longer really builds a list.  Instead, just updates mAvatarCombo.
 void LLFloaterWorldMap::buildAvatarIDList()
 {
-	LLCtrlListInterface *list = childGetListInterface("friend combo");
+	LLCtrlListInterface *list = mListFriendCombo;
 	if (!list) return;
 	
     // Delete all but the "None" entry
 
 void LLFloaterWorldMap::buildLandmarkIDLists()
 {
-	LLCtrlListInterface *list = childGetListInterface("landmark combo");
+	LLCtrlListInterface *list = mListLandmarkCombo;
 	if (!list) return;
 	
     // Delete all but the "None" entry
 
 void LLFloaterWorldMap::clearLocationSelection(BOOL clear_ui)
 {
-	LLCtrlListInterface *list = childGetListInterface("search_results");
+	LLCtrlListInterface *list = mListSearchResults;
 	if (list)
 	{
 		list->operateOnAll(LLCtrlListInterface::OP_DELETE);
 {
 	if (clear_ui || !childHasKeyboardFocus("landmark combo"))
 	{
-		LLCtrlListInterface *list = childGetListInterface("landmark combo");
+		LLCtrlListInterface *list = mListLandmarkCombo;
 		if (list)
 		{
 			list->selectByValue( "None" );
 	if (clear_ui || !childHasKeyboardFocus("friend combo"))
 	{
 		mTrackedStatus = LLTracker::TRACKING_NOTHING;
-		LLCtrlListInterface *list = childGetListInterface("friend combo");
+		LLCtrlListInterface *list = mListFriendCombo;
 		if (list)
 		{
 			list->selectByValue( "None" );
 		return;
 	}
 	
-	LLCtrlListInterface *list = childGetListInterface("landmark combo");
+	LLCtrlListInterface *list = mListLandmarkCombo;
 	if (!list) return;
 	
 	LLUUID current_choice = list->getCurrentID();
 		return;
 	}
 	
-	LLCtrlListInterface *list = childGetListInterface("landmark combo");
+	LLCtrlListInterface *list = mListLandmarkCombo;
 	if (!list) return;
 	
 	LLUUID asset_id;
 		return;
 	}
 	
-	LLCtrlListInterface *list = childGetListInterface("friend combo");
+	LLCtrlListInterface *list = mListFriendCombo;
 	if (!list) return;
 	
 	LLUUID current_choice;
 		return;
 	}
 	
-	LLCtrlListInterface *list = childGetListInterface("friend combo");
+	LLCtrlListInterface *list = mListFriendCombo;
 	if (!list) return;
 	
 	const LLUUID& new_avatar_id = list->getCurrentID();
 
 void LLFloaterWorldMap::onCommitSearchResult()
 {
-	LLCtrlListInterface *list = childGetListInterface("search_results");
+	LLCtrlListInterface *list = mListSearchResults;
 	if (!list) return;
 	
 	LLSD selected_value = list->getSelectedValue();

indra/newview/llfloaterworldmap.h

 #include "lltracker.h"
 #include "llslurl.h"
 
+class LLCtrlListInterface;
 class LLFriendObserver;
 class LLInventoryModel;
 class LLInventoryObserver;
 	std::string				mTrackedSimName;
 	std::string				mTrackedAvatarName;
 	LLSLURL  				mSLURL;
+
+	LLCtrlListInterface *	mListFriendCombo;
+	LLCtrlListInterface *	mListLandmarkCombo;
+	LLCtrlListInterface *	mListSearchResults;
 };
 
 extern LLFloaterWorldMap* gFloaterWorldMap;

indra/newview/llpanelmaininventory.cpp

 	{
 		text = getString("ItemcountUnknown");
 	}
+	
+	// *TODO: Cache the LLUICtrl* for the ItemcountText control
 	getChild<LLUICtrl>("ItemcountText")->setValue(text);
 }
 
 void LLPanelMainInventory::onFocusReceived()
 {
 	LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory");
-
-	LLInventoryPanel * inbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_inbox");
-
-	if (inbox_panel)
-	{
-		inbox_panel->clearSelection();
-	}
-
-	LLInventoryPanel * outbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_outbox");
-
-	if (outbox_panel)
-	{
-		outbox_panel->clearSelection();
-	}
-
-	sidepanel_inventory->updateVerbs();
+	
+	sidepanel_inventory->clearSelections(false, true, true);
 }
 
 void LLPanelMainInventory::setFilterTextFromFilter() 

indra/newview/llpanelmarketplaceinbox.cpp

 	LLSideTray::getInstance()->setTabButtonBadgeDriver("sidebar_inventory", this);
 }
 
-void LLPanelMarketplaceInbox::setupInventoryPanel()
+LLInventoryPanel * LLPanelMarketplaceInbox::setupInventoryPanel()
 {
 	LLView * inbox_inventory_placeholder = getChild<LLView>("inbox_inventory_placeholder");
 	LLView * inbox_inventory_parent = inbox_inventory_placeholder->getParent();
 	
 	// Hide the placeholder text
 	inbox_inventory_placeholder->setVisible(FALSE);
+	
+	return mInventoryPanel;
 }
 
 void LLPanelMarketplaceInbox::onFocusReceived()
 {
 	LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory");
-
-	if (sidepanel_inventory)
-	{
-		LLInventoryPanel * inv_panel = sidepanel_inventory->getActivePanel();
-
-		if (inv_panel)
-		{
-			inv_panel->clearSelection();
-		}
 	
-		LLInventoryPanel * outbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_outbox");
-
-		if (outbox_panel)
-		{
-			outbox_panel->clearSelection();
-		}
-		
-		sidepanel_inventory->updateVerbs();
-	}
+	sidepanel_inventory->clearSelections(true, false, true);
 }
 
 BOOL LLPanelMarketplaceInbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, EDragAndDropType cargo_type, void *cargo_data, EAcceptance *accept, std::string& tooltip_msg)

indra/newview/llpanelmarketplaceinbox.h

 
 	/*virtual*/ void draw();
 	
-	void setupInventoryPanel();
+	LLInventoryPanel * setupInventoryPanel();
 
 	U32 getFreshItemCount() const;
 	U32 getTotalItemCount() const;

indra/newview/llpanelmarketplaceoutbox.cpp

 void LLPanelMarketplaceOutbox::onFocusReceived()
 {
 	LLSidepanelInventory * sidepanel_inventory = LLSideTray::getInstance()->getPanel<LLSidepanelInventory>("sidepanel_inventory");
-
-	if (sidepanel_inventory)
-	{
-		LLInventoryPanel * inv_panel = sidepanel_inventory->getActivePanel();
-
-		if (inv_panel)
-		{
-			inv_panel->clearSelection();
-		}
-
-		LLInventoryPanel * inbox_panel = sidepanel_inventory->findChild<LLInventoryPanel>("inventory_inbox");
-
-		if (inbox_panel)
-		{
-			inbox_panel->clearSelection();
-		}
-		
-		sidepanel_inventory->updateVerbs();
-	}
+	
+	sidepanel_inventory->clearSelections(true, true, false);
 }
 
 void LLPanelMarketplaceOutbox::onSelectionChange()
 	sidepanel_inventory->updateVerbs();
 }
 
-void LLPanelMarketplaceOutbox::setupInventoryPanel()
+LLInventoryPanel * LLPanelMarketplaceOutbox::setupInventoryPanel()
 {
 	LLView * outbox_inventory_placeholder = getChild<LLView>("outbox_inventory_placeholder");
 	LLView * outbox_inventory_parent = outbox_inventory_placeholder->getParent();
 	
 	// Hide the placeholder text
 	outbox_inventory_placeholder->setVisible(FALSE);
+	
+	return mInventoryPanel;
 }
 
 bool LLPanelMarketplaceOutbox::isOutboxEmpty() const

indra/newview/llpanelmarketplaceoutbox.h

 
 	/*virtual*/ BOOL postBuild();
 
-	void setupInventoryPanel();
+	LLInventoryPanel * setupInventoryPanel();
 
 	bool isOutboxEmpty() const;
 	bool isSyncInProgress() const;

indra/newview/llsidepanelinventory.cpp

 LLSidepanelInventory::LLSidepanelInventory()
 	: LLPanel()
 	, mItemPanel(NULL)
+	, mInventoryPanelInbox(NULL)
+	, mInventoryPanelOutbox(NULL)
 	, mPanelMainInventory(NULL)
 	, mInboxEnabled(false)
 	, mOutboxEnabled(false)
 	//
 	
 	LLPanelMarketplaceInbox * inbox = getChild<LLPanelMarketplaceInbox>(MARKETPLACE_INBOX_PANEL);
-	inbox->setupInventoryPanel();
+	mInventoryPanelInbox = inbox->setupInventoryPanel();
 }
 
 
 	//
 	
 	LLPanelMarketplaceOutbox * outbox = getChild<LLPanelMarketplaceOutbox>(MARKETPLACE_OUTBOX_PANEL);
-	outbox->setupInventoryPanel();
+	mInventoryPanelOutbox = outbox->setupInventoryPanel();
 }
 
 void LLSidepanelInventory::enableInbox(bool enabled)
 
 void LLSidepanelInventory::performActionOnSelection(const std::string &action)
 {
-	LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");
-	LLFolderViewItem* current_item = panel_main_inventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
+	LLFolderViewItem* current_item = mPanelMainInventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
 	if (!current_item)
 	{
-		LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox");
-		if (inbox)
+		if (mInventoryPanelInbox)
 		{
-			current_item = inbox->getRootFolder()->getCurSelectedItem();
+			current_item = mInventoryPanelInbox->getRootFolder()->getCurSelectedItem();
 		}
 
 		if (!current_item)
 		}
 	}
 
-	current_item->getListener()->performAction(panel_main_inventory->getActivePanel()->getModel(), action);
+	current_item->getListener()->performAction(mPanelMainInventory->getActivePanel()->getModel(), action);
 }
 
 void LLSidepanelInventory::onWearButtonClicked()
 
 bool LLSidepanelInventory::canShare()
 {
-	LLPanelMainInventory* panel_main_inventory =
-		mInventoryPanel->findChild<LLPanelMainInventory>("panel_main_inventory");
-
-	LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox");
+	LLInventoryPanel* inbox = mInventoryPanelInbox;
 
 	// Avoid flicker in the Recent tab while inventory is being loaded.
 	if ( (!inbox || inbox->getRootFolder()->getSelectionList().empty())
-		&& (panel_main_inventory && !panel_main_inventory->getActivePanel()->getRootFolder()->hasVisibleChildren()) )
+		&& (mPanelMainInventory && !mPanelMainInventory->getActivePanel()->getRootFolder()->hasVisibleChildren()) )
 	{
 		return false;
 	}
 
-	return ( (panel_main_inventory ? LLAvatarActions::canShareSelectedItems(panel_main_inventory->getActivePanel()) : false)
+	return ( (mPanelMainInventory ? LLAvatarActions::canShareSelectedItems(mPanelMainInventory->getActivePanel()) : false)
 			|| (inbox ? LLAvatarActions::canShareSelectedItems(inbox) : false) );
 }
 
 
 LLInventoryItem *LLSidepanelInventory::getSelectedItem()
 {
-	LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");
-	LLFolderViewItem* current_item = panel_main_inventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
+	LLFolderViewItem* current_item = mPanelMainInventory->getActivePanel()->getRootFolder()->getCurSelectedItem();
+	
 	if (!current_item)
 	{
-		LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox");
-		if (inbox)
+		if (mInventoryPanelInbox)
 		{
-			current_item = inbox->getRootFolder()->getCurSelectedItem();
+			current_item = mInventoryPanelInbox->getRootFolder()->getCurSelectedItem();
 		}
 
 		if (!current_item)
 {
 	int count = 0;
 
-	LLPanelMainInventory *panel_main_inventory = mInventoryPanel->getChild<LLPanelMainInventory>("panel_main_inventory");
-	std::set<LLUUID> selection_list = panel_main_inventory->getActivePanel()->getRootFolder()->getSelectionList();
+	std::set<LLUUID> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
 	count += selection_list.size();
 
-	LLInventoryPanel* inbox = findChild<LLInventoryPanel>("inventory_inbox");
-	if (inbox)
+	if ((count == 0) && mInboxEnabled && (mInventoryPanelInbox != NULL))
 	{
-		selection_list = inbox->getRootFolder()->getSelectionList();
+		selection_list = mInventoryPanelInbox->getRootFolder()->getSelectionList();
+
+		count += selection_list.size();
+	}
+	
+	if ((count == 0) && mOutboxEnabled && (mInventoryPanelOutbox != NULL))
+	{
+		selection_list = mInventoryPanelOutbox->getRootFolder()->getSelectionList();
+		
 		count += selection_list.size();
 	}
 
 {
 	return mInventoryPanel->getVisible();
 }
+
+void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox, bool clearOutbox)
+{
+	if (clearMain)
+	{
+		LLInventoryPanel * inv_panel = getActivePanel();
+		
+		if (inv_panel)
+		{
+			inv_panel->clearSelection();
+		}
+	}
+	
+	if (clearInbox && mInboxEnabled && (mInventoryPanelInbox != NULL))
+	{
+		mInventoryPanelInbox->clearSelection();
+	}
+	
+	if (clearOutbox && mOutboxEnabled && (mInventoryPanelOutbox != NULL))
+	{
+		mInventoryPanelOutbox->clearSelection();
+	}
+	
+	updateVerbs();
+}
+
+std::set<LLUUID> LLSidepanelInventory::getInboxOrOutboxSelectionList()
+{
+	std::set<LLUUID> inventory_selected_uuids;
+	
+	if (mInboxEnabled && (mInventoryPanelInbox != NULL))
+	{
+		inventory_selected_uuids = mInventoryPanelInbox->getRootFolder()->getSelectionList();
+	}
+	
+	if (inventory_selected_uuids.empty() && mOutboxEnabled && (mInventoryPanelOutbox != NULL))
+	{
+		inventory_selected_uuids = mInventoryPanelOutbox->getRootFolder()->getSelectionList();
+	}
+	
+	return inventory_selected_uuids;
+}

indra/newview/llsidepanelinventory.h

 	LLInventoryPanel* getActivePanel(); // Returns an active inventory panel, if any.
 	LLPanelMainInventory* getMainInventoryPanel() const { return mPanelMainInventory; }
 	BOOL isMainInventoryPanelActive() const;
+	
+	void clearSelections(bool clearMain, bool clearInbox, bool clearOutbox);
+	std::set<LLUUID> getInboxOrOutboxSelectionList();
 
 	void showItemInfoPanel();
 	void showTaskInfoPanel();
 	//
 private:
 	LLPanel*					mInventoryPanel; // Main inventory view
+	LLInventoryPanel*			mInventoryPanelInbox;
+	LLInventoryPanel*			mInventoryPanelOutbox;
 	LLSidepanelItemInfo*		mItemPanel; // Individual item view
 	LLSidepanelTaskInfo*		mTaskPanel; // Individual in-world object view
 	LLPanelMainInventory*		mPanelMainInventory;