summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/llcofwearables.cpp21
-rw-r--r--indra/newview/llcofwearables.h5
-rw-r--r--indra/newview/llcurrencyuimanager.cpp2
-rw-r--r--indra/newview/llfloaterbuyland.cpp1
-rw-r--r--indra/newview/llpaneloutfitedit.cpp41
-rw-r--r--indra/newview/llsidetray.cpp321
-rw-r--r--indra/newview/llsidetray.h16
-rw-r--r--indra/newview/llviewerfloaterreg.cpp1
-rw-r--r--indra/newview/llvoavatarself.cpp25
-rw-r--r--indra/newview/skins/default/xui/en/floater_side_bar_tab.xml5
-rw-r--r--indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml14
-rw-r--r--indra/newview/tests/llagentaccess_test.cpp2
-rw-r--r--indra/newview/tests/lldateutil_test.cpp2
-rw-r--r--indra/newview/tests/lllogininstance_test.cpp2
-rw-r--r--indra/newview/tests/llmediadataclient_test.cpp2
-rw-r--r--indra/newview/tests/llsecapi_test.cpp2
-rw-r--r--indra/newview/tests/llsechandler_basic_test.cpp2
-rw-r--r--indra/newview/tests/llslurl_test.cpp2
-rw-r--r--indra/newview/tests/lltextureinfo_test.cpp2
-rw-r--r--indra/newview/tests/lltextureinfodetails_test.cpp2
-rw-r--r--indra/newview/tests/lltexturestatsuploader_test.cpp2
-rw-r--r--indra/newview/tests/llviewerhelputil_test.cpp2
-rw-r--r--indra/newview/tests/llviewernetwork_test.cpp2
-rw-r--r--indra/newview/tests/llworldmap_test.cpp6
-rw-r--r--indra/newview/tests/llworldmipmap_test.cpp2
25 files changed, 436 insertions, 48 deletions
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index 194d461f94..b1e11e1a2a 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -708,4 +708,25 @@ void LLCOFWearables::onListRightClick(LLUICtrl* ctrl, S32 x, S32 y, LLListContex
}
}
+void LLCOFWearables::selectClothing(LLWearableType::EType clothing_type)
+{
+ std::vector<LLPanel*> clothing_items;
+
+ mClothing->getItems(clothing_items);
+
+ std::vector<LLPanel*>::iterator it;
+
+ for (it = clothing_items.begin(); it != clothing_items.end(); ++it )
+ {
+ LLPanelClothingListItem* clothing_item = dynamic_cast<LLPanelClothingListItem*>(*it);
+
+ if (clothing_item && clothing_item->getWearableType() == clothing_type)
+ { // clothing item has specified LLWearableType::EType. Select it and exit.
+
+ mClothing->selectItem(clothing_item);
+ break;
+ }
+ }
+}
+
//EOF
diff --git a/indra/newview/llcofwearables.h b/indra/newview/llcofwearables.h
index d981fa4196..1f8d6d0c94 100644
--- a/indra/newview/llcofwearables.h
+++ b/indra/newview/llcofwearables.h
@@ -86,6 +86,11 @@ public:
LLCOFCallbacks& getCOFCallbacks() { return mCOFCallbacks; }
+ /**
+ * Selects first clothing item with specified LLWearableType::EType from clothing list
+ */
+ void selectClothing(LLWearableType::EType clothing_type);
+
protected:
void populateAttachmentsAndBodypartsLists(const LLInventoryModel::item_array_t& cof_items);
diff --git a/indra/newview/llcurrencyuimanager.cpp b/indra/newview/llcurrencyuimanager.cpp
index 654daa770e..2b92b228b3 100644
--- a/indra/newview/llcurrencyuimanager.cpp
+++ b/indra/newview/llcurrencyuimanager.cpp
@@ -164,6 +164,7 @@ void LLCurrencyUIManager::Impl::updateCurrencyInfo()
keywordArgs.appendString(
"secureSessionId",
gAgent.getSecureSessionID().asString());
+ keywordArgs.appendString("language", LLUI::getLanguage());
keywordArgs.appendInt("currencyBuy", mUserCurrencyBuy);
keywordArgs.appendString("viewerChannel", gSavedSettings.getString("VersionChannelName"));
keywordArgs.appendInt("viewerMajorVersion", LLVersionInfo::getMajor());
@@ -225,6 +226,7 @@ void LLCurrencyUIManager::Impl::startCurrencyBuy(const std::string& password)
keywordArgs.appendString(
"secureSessionId",
gAgent.getSecureSessionID().asString());
+ keywordArgs.appendString("language", LLUI::getLanguage());
keywordArgs.appendInt("currencyBuy", mUserCurrencyBuy);
if (mUSDCurrencyEstimated)
{
diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp
index 69824b3843..a5c62495fe 100644
--- a/indra/newview/llfloaterbuyland.cpp
+++ b/indra/newview/llfloaterbuyland.cpp
@@ -758,6 +758,7 @@ void LLFloaterBuyLandUI::runWebSitePrep(const std::string& password)
keywordArgs.appendString(
"secureSessionId",
gAgent.getSecureSessionID().asString());
+ keywordArgs.appendString("language", LLUI::getLanguage());
keywordArgs.appendString("levelId", newLevel);
keywordArgs.appendInt("billableArea",
mIsForGroup ? 0 : mParcelBillableArea);
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index c9380bf6e6..54b0805a6c 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -911,8 +911,14 @@ LLWearableType::EType LLPanelOutfitEdit::getWearableTypeByItemUUID(const LLUUID&
void LLPanelOutfitEdit::onRemoveFromOutfitClicked(void)
{
LLUUID id_to_remove = mCOFWearables->getSelectedUUID();
-
+ LLWearableType::EType type = getWearableTypeByItemUUID(id_to_remove);
+
LLAppearanceMgr::getInstance()->removeItemFromAvatar(id_to_remove);
+
+ if (!mCOFWearables->getSelectedItem())
+ {
+ mCOFWearables->selectClothing(type);
+ }
}
@@ -1007,6 +1013,10 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void)
// | filter_type = expanded accordion_type
if (nothing_selected)
{
+ if (mInventoryItemsPanel->getVisible())
+ {
+ return;
+ }
showWearablesListView();
//selected accordion tab is more priority than expanded tab
@@ -1021,7 +1031,7 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void)
LLUUID selected_item_id = mWearableItemsList->getSelectedUUID();
LLViewerInventoryItem* item = gInventory.getLinkedItem(selected_item_id);
if(item)
- {
+ {
showFilteredWearablesListView(item->getWearableType());
return;
}
@@ -1051,6 +1061,12 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void)
//resetting selection if more than one item is selected
if (more_than_one_selected)
{
+ if (mInventoryItemsPanel->getVisible())
+ {
+ applyFolderViewFilter(FVIT_ALL);
+ return;
+ }
+
showWearablesListView();
applyListViewFilter(LVIT_ALL);
return;
@@ -1060,6 +1076,12 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void)
//filter wearables by a type represented by a dummy item
if (one_selected && is_dummy_item)
{
+ if (mInventoryItemsPanel->getVisible())
+ {
+ applyFolderViewFilter(FVIT_WEARABLE);
+ return;
+ }
+
onAddWearableClicked();
return;
}
@@ -1067,6 +1089,11 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void)
LLViewerInventoryItem* item = gInventory.getItem(ids[0]);
if (!item && ids[0].notNull())
{
+ if (mInventoryItemsPanel->getVisible())
+ {
+ applyFolderViewFilter(FVIT_ALL);
+ return;
+ }
//Inventory misses an item with non-zero id
showWearablesListView();
applyListViewFilter(LVIT_ALL);
@@ -1077,12 +1104,22 @@ void LLPanelOutfitEdit::filterWearablesBySelectedItem(void)
{
if (item->isWearableType())
{
+ if (mInventoryItemsPanel->getVisible())
+ {
+ applyFolderViewFilter(FVIT_WEARABLE);
+ return;
+ }
//single clothing or bodypart item is selected
showFilteredWearablesListView(item->getWearableType());
return;
}
else
{
+ if (mInventoryItemsPanel->getVisible())
+ {
+ applyFolderViewFilter(FVIT_ATTACHMENT);
+ return;
+ }
//attachment is selected
showWearablesListView();
applyListViewFilter(LVIT_ATTACHMENT);
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
index 78890fae93..85b6e0dec4 100644
--- a/indra/newview/llsidetray.cpp
+++ b/indra/newview/llsidetray.cpp
@@ -31,6 +31,7 @@
#include "llagentcamera.h"
#include "llappviewer.h"
#include "llbottomtray.h"
+#include "llfloaterreg.h"
#include "llsidetray.h"
#include "llviewerwindow.h"
#include "llaccordionctrl.h"
@@ -64,6 +65,7 @@ static const std::string TAB_PANEL_CAPTION_TITLE_BOX = "sidetray_tab_title";
LLSideTray* LLSideTray::sInstance = 0;
+// static
LLSideTray* LLSideTray::getInstance()
{
if (!sInstance)
@@ -75,6 +77,7 @@ LLSideTray* LLSideTray::getInstance()
return sInstance;
}
+// static
bool LLSideTray::instanceCreated ()
{
return sInstance!=0;
@@ -125,7 +128,9 @@ public:
const std::string& getTabTitle() const { return mTabTitle;}
void onOpen (const LLSD& key);
-
+
+ void toggleTabDocked();
+
LLPanel *getPanel();
private:
std::string mTabTitle;
@@ -171,6 +176,8 @@ BOOL LLSideTrayTab::postBuild()
title_panel->getChild<LLTextBox>(TAB_PANEL_CAPTION_TITLE_BOX)->setValue(mTabTitle);
+ getChild<LLButton>("dock")->setCommitCallback(boost::bind(&LLSideTrayTab::toggleTabDocked, this));
+
return true;
}
@@ -203,6 +210,66 @@ void LLSideTrayTab::onOpen (const LLSD& key)
panel->onOpen(key);
}
+void LLSideTrayTab::toggleTabDocked()
+{
+ LLFloater* floater_tab = LLFloaterReg::getInstance("side_bar_tab", LLSD().with("name", mTabTitle));
+ if (!floater_tab) return;
+
+ LLFloaterReg::toggleInstance("side_bar_tab", LLSD().with("name", mTabTitle));
+
+ LLSideTray* side_tray = LLSideTray::getInstance();
+
+ if (LLFloater::isShown(floater_tab))
+ {
+ // Remove the tab from Side Tray's tabs list.
+ // We have to do it despite removing the tab from Side Tray's child view tree
+ // by addChild(). Otherwise the tab could be accessed by the pointer in LLSideTray::mTabs.
+ if (!side_tray->removeTab(this))
+ {
+ llwarns << "Failed to remove tab " << getName() << " from side tray" << llendl;
+ return;
+ }
+
+ setVisible(true); // *HACK: restore visibility after being hidden by LLSideTray::selectTabByName().
+ floater_tab->addChild(this);
+ floater_tab->setTitle(mTabTitle);
+
+ LLRect rect = side_tray->getLocalRect();
+ floater_tab->reshape(rect.getWidth(), rect.getHeight());
+
+ rect.mTop -= floater_tab->getHeaderHeight();
+ setRect(rect);
+ reshape(rect.getWidth(), rect.getHeight());
+
+ // Set FOLLOWS_ALL flag for the tab to follow floater dimensions upon resizing.
+ setFollowsAll();
+
+ if (!side_tray->getCollapsed())
+ {
+ side_tray->collapseSideBar();
+ }
+ }
+ else
+ {
+ if (!side_tray->addTab(this))
+ {
+ llwarns << "Failed to add tab " << getName() << " to side tray" << llendl;
+ return;
+ }
+
+ setRect(side_tray->getLocalRect());
+ reshape(getRect().getWidth(), getRect().getHeight());
+
+ // Select the re-docked tab.
+ side_tray->selectTabByName(getName());
+
+ if (side_tray->getCollapsed())
+ {
+ side_tray->expandSideBar();
+ }
+ }
+}
+
LLPanel* LLSideTrayTab::getPanel()
{
LLPanel* panel = dynamic_cast<LLPanel*>(mMainPanel);
@@ -219,6 +286,93 @@ LLSideTrayTab* LLSideTrayTab::createInstance ()
}
//////////////////////////////////////////////////////////////////////////////
+// LLSideTrayButton
+// Side Tray tab button with "tear off" handling.
+//////////////////////////////////////////////////////////////////////////////
+
+class LLSideTrayButton : public LLButton
+{
+public:
+ /*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask)
+ {
+ // Route future Mouse messages here preemptively. (Release on mouse up.)
+ // No handler needed for focus lost since this class has no state that depends on it.
+ gFocusMgr.setMouseCapture(this);
+
+ localPointToScreen(x, y, &mDragLastScreenX, &mDragLastScreenY);
+
+ // Note: don't pass on to children
+ return TRUE;
+ }
+
+ /*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask)
+ {
+ // We only handle the click if the click both started and ended within us
+ if( !hasMouseCapture() ) return FALSE;
+
+ S32 screen_x;
+ S32 screen_y;
+ localPointToScreen(x, y, &screen_x, &screen_y);
+
+ S32 delta_x = screen_x - mDragLastScreenX;
+ S32 delta_y = screen_y - mDragLastScreenY;
+
+ LLSideTray* side_tray = LLSideTray::getInstance();
+
+ // Check if the tab we are dragging is docked.
+ if (!side_tray->isTabAttached(getName())) return FALSE;
+
+ // Same value is hardcoded in LLDragHandle::handleHover().
+ const S32 undock_threshold = 12;
+
+ // Detach a tab if it has been pulled further than undock_threshold.
+ if (delta_x <= -undock_threshold || delta_x >= undock_threshold ||
+ delta_y <= -undock_threshold || delta_y >= undock_threshold)
+ {
+ LLSideTrayTab* tab = side_tray->getTab(getName());
+ if (!tab) return FALSE;
+
+ tab->toggleTabDocked();
+
+ LLFloater* floater_tab = LLFloaterReg::getInstance("side_bar_tab", LLSD().with("name", tab->getTabTitle()));
+ if (!floater_tab) return FALSE;
+
+
+ LLRect original_rect = floater_tab->getRect();
+ S32 header_snap_y = floater_tab->getHeaderHeight() / 2;
+ S32 snap_x = screen_x - original_rect.mLeft - original_rect.getWidth() / 2;
+ S32 snap_y = screen_y - original_rect.mTop + header_snap_y;
+
+ // Move the floater to appear "under" the mouse pointer.
+ floater_tab->setRect(original_rect.translate(snap_x, snap_y));
+
+ // Snap the mouse pointer to the center of the floater header
+ // and call 'mouse down' event handler to begin dragging.
+ floater_tab->handleMouseDown(original_rect.getWidth() / 2,
+ original_rect.getHeight() - header_snap_y,
+ mask);
+
+ return TRUE;
+ }
+
+ return FALSE;
+ }
+
+protected:
+ LLSideTrayButton(const LLButton::Params& p)
+ : LLButton(p)
+ , mDragLastScreenX(0)
+ , mDragLastScreenY(0)
+ {}
+
+ friend class LLUICtrlFactory;
+
+private:
+ S32 mDragLastScreenX;
+ S32 mDragLastScreenY;
+};
+
+//////////////////////////////////////////////////////////////////////////////
// LLSideTray
//////////////////////////////////////////////////////////////////////////////
@@ -273,6 +427,13 @@ BOOL LLSideTray::postBuild()
LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLSideTray::handleLoginComplete, this));
+ // Remember original tabs order, so that we can restore it if user detaches and then re-attaches a tab.
+ for (child_vector_const_iter_t it = mTabs.begin(); it != mTabs.end(); ++it)
+ {
+ std::string tab_name = (*it)->getName();
+ mOriginalTabOrder.push_back(tab_name);
+ }
+
//EXT-8045
//connect all already created channels to reflect sidetray collapse/expand
std::vector<LLChannelManager::ChannelElem>& channels = LLChannelManager::getInstance()->getChannelList();
@@ -297,6 +458,17 @@ LLSideTrayTab* LLSideTray::getTab(const std::string& name)
return getChild<LLSideTrayTab>(name,false);
}
+bool LLSideTray::isTabAttached(const std::string& name)
+{
+ LLSideTrayTab* tab = getTab(name);
+ return std::find(mTabs.begin(), mTabs.end(), tab) != mTabs.end();
+}
+
+bool LLSideTray::hasTabs()
+{
+ // The open/close tab doesn't count.
+ return mTabs.size() > 1;
+}
void LLSideTray::toggleTabButton(LLSideTrayTab* tab)
{
@@ -324,22 +496,27 @@ bool LLSideTray::selectTabByIndex(size_t index)
bool LLSideTray::selectTabByName (const std::string& name)
{
- LLSideTrayTab* side_bar = getTab(name);
+ LLSideTrayTab* new_tab = getTab(name);
- if(side_bar == mActiveTab)
+ // Bail out if already selected.
+ if (new_tab == mActiveTab)
return false;
+
//deselect old tab
- toggleTabButton(mActiveTab);
- if(mActiveTab)
- mActiveTab->setVisible(false);
+ if (mActiveTab)
+ {
+ toggleTabButton(mActiveTab);
+ }
//select new tab
- mActiveTab = side_bar;
- toggleTabButton(mActiveTab);
- LLSD key;//empty
- mActiveTab->onOpen(key);
+ mActiveTab = new_tab;
- mActiveTab->setVisible(true);
+ if (mActiveTab)
+ {
+ toggleTabButton(mActiveTab);
+ LLSD key;//empty
+ mActiveTab->onOpen(key);
+ }
//arrange();
@@ -348,7 +525,9 @@ bool LLSideTray::selectTabByName (const std::string& name)
for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
{
LLSideTrayTab* sidebar_tab = *child_it;
- sidebar_tab->setVisible(sidebar_tab == mActiveTab);
+ // When the last tab gets detached, for a short moment the "Toggle Sidebar" pseudo-tab
+ // is shown. So, to avoid the flicker we make sure it never gets visible.
+ sidebar_tab->setVisible(sidebar_tab == mActiveTab && (*child_it)->getName() != "sidebar_openclose");
}
return true;
}
@@ -372,8 +551,18 @@ LLButton* LLSideTray::createButton (const std::string& name,const std::string& i
bparams.image_disabled(sidetray_params.tab_btn_image_normal);
bparams.image_disabled_selected(sidetray_params.tab_btn_image_selected);
- LLButton* button = LLUICtrlFactory::create<LLButton> (bparams);
- button->setLabel(name);
+ LLButton* button;
+ if (name == "sidebar_openclose")
+ {
+ // "Open/Close" button shouldn't allow "tear off"
+ // hence it is created as LLButton instance.
+ button = LLUICtrlFactory::create<LLButton>(bparams);
+ }
+ else
+ {
+ button = LLUICtrlFactory::create<LLSideTrayButton>(bparams);
+ }
+
button->setClickedCallback(callback);
button->setToolTip(tooltip);
@@ -400,6 +589,103 @@ bool LLSideTray::addChild(LLView* view, S32 tab_group)
return LLUICtrl::addChild(view, tab_group);
}
+bool LLSideTray::removeTab(LLSideTrayTab* tab)
+{
+ if (!tab) return false;
+ std::string tab_name = tab->getName();
+
+ // Look up the tab in the list of known tabs.
+ child_vector_iter_t tab_it = std::find(mTabs.begin(), mTabs.end(), tab);
+ if (tab_it == mTabs.end())
+ {
+ llwarns << "Cannot find tab named " << tab_name << llendl;
+ return false;
+ }
+
+ // Find the button corresponding to the tab.
+ button_map_t::iterator btn_it = mTabButtons.find(tab_name);
+ if (btn_it == mTabButtons.end())
+ {
+ llwarns << "Cannot find button for tab named " << tab_name << llendl;
+ return false;
+ }
+ LLButton* btn = btn_it->second;
+
+ // Deselect the tab.
+ if (mActiveTab == tab)
+ {
+ child_vector_iter_t next_tab_it =
+ (tab_it < (mTabs.end() - 1)) ? tab_it + 1 : mTabs.begin();
+ selectTabByName((*next_tab_it)->getName());
+ }
+
+ // Remove the tab.
+ removeChild(tab);
+ mTabs.erase(tab_it);
+
+ // Remove the button from the buttons panel so that it isn't drawn anymore.
+ mButtonsPanel->removeChild(btn);
+
+ // Re-arrange remaining tabs.
+ arrange();
+
+ return true;
+}
+
+bool LLSideTray::addTab(LLSideTrayTab* tab)
+{
+ if (tab == NULL) return false;
+
+ std::string tab_name = tab->getName();
+
+ // Make sure the tab isn't already in the list.
+ if (std::find(mTabs.begin(), mTabs.end(), tab) != mTabs.end())
+ {
+ llwarns << "Attempt to re-add existing tab " << tab_name << llendl;
+ return false;
+ }
+
+ // Look up the corresponding button.
+ button_map_t::const_iterator btn_it = mTabButtons.find(tab_name);
+ if (btn_it == mTabButtons.end())
+ {
+ llwarns << "Tab " << tab_name << " has no associated button" << llendl;
+ return false;
+ }
+ LLButton* btn = btn_it->second;
+
+ // Insert the tab at its original position.
+ LLUICtrl::addChild(tab);
+ {
+ tab_order_vector_const_iter_t new_tab_orig_pos =
+ std::find(mOriginalTabOrder.begin(), mOriginalTabOrder.end(), tab_name);
+ llassert(new_tab_orig_pos != mOriginalTabOrder.end());
+ child_vector_iter_t insert_pos = mTabs.end();
+
+ for (child_vector_iter_t tab_it = mTabs.begin(); tab_it != mTabs.end(); ++tab_it)
+ {
+ tab_order_vector_const_iter_t cur_tab_orig_pos =
+ std::find(mOriginalTabOrder.begin(), mOriginalTabOrder.end(), (*tab_it)->getName());
+ llassert(cur_tab_orig_pos != mOriginalTabOrder.end());
+
+ if (new_tab_orig_pos < cur_tab_orig_pos)
+ {
+ insert_pos = tab_it;
+ break;
+ }
+ }
+
+ mTabs.insert(insert_pos, tab);
+ }
+
+ // Add the button to the buttons panel so that it's drawn again.
+ mButtonsPanel->addChildInBack(btn);
+
+ // Arrange tabs after inserting a new one.
+ arrange();
+
+ return true;
+}
void LLSideTray::createButtons ()
{
@@ -414,12 +700,12 @@ void LLSideTray::createButtons ()
// The "OpenClose" button will open/close the whole panel
if (name == "sidebar_openclose")
{
- mCollapseButton = createButton("",sidebar_tab->mImage,sidebar_tab->getTabTitle(),
+ mCollapseButton = createButton(name,sidebar_tab->mImage,sidebar_tab->getTabTitle(),
boost::bind(&LLSideTray::onToggleCollapse, this));
}
else
{
- LLButton* button = createButton("",sidebar_tab->mImage,sidebar_tab->getTabTitle(),
+ LLButton* button = createButton(name,sidebar_tab->mImage,sidebar_tab->getTabTitle(),
boost::bind(&LLSideTray::onTabButtonClick, this, name));
mTabButtons[name] = button;
}
@@ -536,6 +822,9 @@ void LLSideTray::arrange()
LLSideTrayTab* sidebar_tab = *child_it;
sidebar_tab->setShape(getLocalRect());
}
+
+ // The tab buttons should be shown only if there is at least one non-detached tab.
+ mButtonsPanel->setVisible(hasTabs());
}
void LLSideTray::collapseSideBar()
diff --git a/indra/newview/llsidetray.h b/indra/newview/llsidetray.h
index 4ff560d83b..f0cc2c1146 100644
--- a/indra/newview/llsidetray.h
+++ b/indra/newview/llsidetray.h
@@ -68,6 +68,8 @@ protected:
typedef child_vector_t::const_iterator child_vector_const_iter_t;
typedef child_vector_t::reverse_iterator child_vector_reverse_iter_t;
typedef child_vector_t::const_reverse_iterator child_vector_const_reverse_iter_t;
+ typedef std::vector<std::string> tab_order_vector_t;
+ typedef tab_order_vector_t::const_iterator tab_order_vector_const_iter_t;
public:
@@ -144,6 +146,8 @@ public:
void onToggleCollapse();
bool addChild (LLView* view, S32 tab_group);
+ bool removeTab (LLSideTrayTab* tab); // Used to detach tabs temporarily
+ bool addTab (LLSideTrayTab* tab); // Used to re-attach tabs
BOOL handleMouseDown (S32 x, S32 y, MASK mask);
@@ -157,10 +161,15 @@ public:
void handleLoginComplete();
-protected:
LLSideTrayTab* getTab (const std::string& name);
+ bool isTabAttached (const std::string& name);
+
+protected:
+ bool hasTabs ();
+
void createButtons ();
+
LLButton* createButton (const std::string& name,const std::string& image,const std::string& tooltip,
LLUICtrl::commit_callback_t callback);
void arrange ();
@@ -179,10 +188,15 @@ private:
private:
+ typedef std::pair<LLButton*, LLSideTrayTab*> detached_tab_t;
+ typedef std::map<std::string, detached_tab_t> detached_tab_map_t;
+
LLPanel* mButtonsPanel;
typedef std::map<std::string,LLButton*> button_map_t;
button_map_t mTabButtons;
child_vector_t mTabs;
+ detached_tab_map_t mDetachedTabs;
+ tab_order_vector_t mOriginalTabOrder;
LLSideTrayTab* mActiveTab;
commit_signal_t mCollapseSignal;
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index b572a8cff6..8728298575 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -234,6 +234,7 @@ void LLViewerFloaterReg::registerFloaters()
LLFloaterReg::add("script_limits", "floater_script_limits.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptLimits>);
LLFloaterReg::add("sell_land", "floater_sell_land.xml", &LLFloaterSellLand::buildFloater);
LLFloaterReg::add("settings_debug", "floater_settings_debug.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSettingsDebug>);
+ LLFloaterReg::add("side_bar_tab", "floater_side_bar_tab.xml",&LLFloaterReg::build<LLFloater>);
LLFloaterReg::add("stats", "floater_stats.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloater>);
LLFloaterReg::add("start_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterRunQueue>);
LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterNotRunQueue>);
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index b6055d82e3..1a5d7289f4 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -43,6 +43,7 @@
#include "llhudeffecttrail.h"
#include "llhudmanager.h"
#include "llinventoryfunctions.h"
+#include "llmenugl.h"
#include "llnotificationsutil.h"
#include "llselectmgr.h"
#include "lltoolgrab.h" // for needsRenderBeam
@@ -240,58 +241,58 @@ BOOL LLVOAvatarSelf::buildMenus()
gAttachBodyPartPieMenus[0] = NULL;
LLContextMenu::Params params;
- params.label(LLTrans::getString("BodyPartsRightArm") + " >");
+ params.label(LLTrans::getString("BodyPartsRightArm") + " " + LLMenuGL::BRANCH_SUFFIX);
params.name(params.label);
params.visible(false);
gAttachBodyPartPieMenus[1] = LLUICtrlFactory::create<LLContextMenu> (params);
- params.label(LLTrans::getString("BodyPartsHead") + " >");
+ params.label(LLTrans::getString("BodyPartsHead") + " " + LLMenuGL::BRANCH_SUFFIX);
params.name(params.label);
gAttachBodyPartPieMenus[2] = LLUICtrlFactory::create<LLContextMenu> (params);
- params.label(LLTrans::getString("BodyPartsLeftArm") + " >");
+ params.label(LLTrans::getString("BodyPartsLeftArm") + " " + LLMenuGL::BRANCH_SUFFIX);
params.name(params.label);
gAttachBodyPartPieMenus[3] = LLUICtrlFactory::create<LLContextMenu> (params);
gAttachBodyPartPieMenus[4] = NULL;
- params.label(LLTrans::getString("BodyPartsLeftLeg") + " >");
+ params.label(LLTrans::getString("BodyPartsLeftLeg") + " " + LLMenuGL::BRANCH_SUFFIX);
params.name(params.label);
gAttachBodyPartPieMenus[5] = LLUICtrlFactory::create<LLContextMenu> (params);
- params.label(LLTrans::getString("BodyPartsTorso") + " >");
+ params.label(LLTrans::getString("BodyPartsTorso") + " " + LLMenuGL::BRANCH_SUFFIX);
params.name(params.label);
gAttachBodyPartPieMenus[6] = LLUICtrlFactory::create<LLContextMenu> (params);
- params.label(LLTrans::getString("BodyPartsRightLeg") + " >");
+ params.label(LLTrans::getString("BodyPartsRightLeg") + " " + LLMenuGL::BRANCH_SUFFIX);
params.name(params.label);
gAttachBodyPartPieMenus[7] = LLUICtrlFactory::create<LLContextMenu> (params);
gDetachBodyPartPieMenus[0] = NULL;
- params.label(LLTrans::getString("BodyPartsRightArm") + " >");
+ params.label(LLTrans::getString("BodyPartsRightArm") + " " + LLMenuGL::BRANCH_SUFFIX);
params.name(params.label);
gDetachBodyPartPieMenus[1] = LLUICtrlFactory::create<LLContextMenu> (params);
- params.label(LLTrans::getString("BodyPartsHead") + " >");
+ params.label(LLTrans::getString("BodyPartsHead") + " " + LLMenuGL::BRANCH_SUFFIX);
params.name(params.label);
gDetachBodyPartPieMenus[2] = LLUICtrlFactory::create<LLContextMenu> (params);
- params.label(LLTrans::getString("BodyPartsLeftArm") + " >");
+ params.label(LLTrans::getString("BodyPartsLeftArm") + " " + LLMenuGL::BRANCH_SUFFIX);
params.name(params.label);
gDetachBodyPartPieMenus[3] = LLUICtrlFactory::create<LLContextMenu> (params);
gDetachBodyPartPieMenus[4] = NULL;
- params.label(LLTrans::getString("BodyPartsLeftLeg") + " >");
+ params.label(LLTrans::getString("BodyPartsLeftLeg") + " " + LLMenuGL::BRANCH_SUFFIX);
params.name(params.label);
gDetachBodyPartPieMenus[5] = LLUICtrlFactory::create<LLContextMenu> (params);
- params.label(LLTrans::getString("BodyPartsTorso") + " >");
+ params.label(LLTrans::getString("BodyPartsTorso") + " " + LLMenuGL::BRANCH_SUFFIX);
params.name(params.label);
gDetachBodyPartPieMenus[6] = LLUICtrlFactory::create<LLContextMenu> (params);
- params.label(LLTrans::getString("BodyPartsRightLeg") + " >");
+ params.label(LLTrans::getString("BodyPartsRightLeg") + " " + LLMenuGL::BRANCH_SUFFIX);
params.name(params.label);
gDetachBodyPartPieMenus[7] = LLUICtrlFactory::create<LLContextMenu> (params);
diff --git a/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml b/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml
new file mode 100644
index 0000000000..1466c2d2a5
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_side_bar_tab.xml
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<floater
+ can_close="false"
+ can_resize="true">
+</floater>
diff --git a/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml b/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml
index 0a9c70303e..60c2e0830c 100644
--- a/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml
+++ b/indra/newview/skins/default/xui/en/panel_side_tray_tab_caption.xml
@@ -20,7 +20,19 @@
value="Side Panel"
width="255" />
<button
- follows="left|right|top"
+ follows="right|top"
+ height="16"
+ image_selected="Icon_Dock_Press"
+ image_unselected="Icon_Dock_Foreground"
+ image_disabled="Icon_Dock_Press"
+ layout="topleft"
+ name="dock"
+ top="10"
+ right="-28"
+ width="16"
+ tool_tip="Dock/Undock tab" />
+ <button
+ follows="right|top"
height="16"
image_selected="Icon_Help_Press"
image_unselected="Icon_Help_Foreground"
diff --git a/indra/newview/tests/llagentaccess_test.cpp b/indra/newview/tests/llagentaccess_test.cpp
index a0a9659475..c970d79975 100644
--- a/indra/newview/tests/llagentaccess_test.cpp
+++ b/indra/newview/tests/llagentaccess_test.cpp
@@ -74,7 +74,7 @@ namespace tut
typedef test_group<agentaccess> agentaccess_t;
typedef agentaccess_t::object agentaccess_object_t;
- tut::agentaccess_t tut_agentaccess("agentaccess");
+ tut::agentaccess_t tut_agentaccess("LLAgentAccess");
template<> template<>
void agentaccess_object_t::test<1>()
diff --git a/indra/newview/tests/lldateutil_test.cpp b/indra/newview/tests/lldateutil_test.cpp
index 530171b87e..99b346cff8 100644
--- a/indra/newview/tests/lldateutil_test.cpp
+++ b/indra/newview/tests/lldateutil_test.cpp
@@ -103,7 +103,7 @@ namespace tut
typedef test_group<dateutil> dateutil_t;
typedef dateutil_t::object dateutil_object_t;
- tut::dateutil_t tut_dateutil("dateutil");
+ tut::dateutil_t tut_dateutil("LLDateUtil");
template<> template<>
void dateutil_object_t::test<1>()
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index a0697af6c3..55823fc386 100644
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -314,7 +314,7 @@ namespace tut
typedef test_group<lllogininstance_data> lllogininstance_group;
typedef lllogininstance_group::object lllogininstance_object;
- lllogininstance_group llsdmgr("lllogininstance");
+ lllogininstance_group llsdmgr("LLLoginInstance");
template<> template<>
void lllogininstance_object::test<1>()
diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp
index 5f3dc5b162..0254c5881f 100644
--- a/indra/newview/tests/llmediadataclient_test.cpp
+++ b/indra/newview/tests/llmediadataclient_test.cpp
@@ -236,7 +236,7 @@ namespace tut
typedef test_group<mediadataclient> mediadataclient_t;
typedef mediadataclient_t::object mediadataclient_object_t;
- tut::mediadataclient_t tut_mediadataclient("mediadataclient");
+ tut::mediadataclient_t tut_mediadataclient("LLMediaDataClient");
void ensure(const std::string &msg, int value, int expected)
{
diff --git a/indra/newview/tests/llsecapi_test.cpp b/indra/newview/tests/llsecapi_test.cpp
index 90cacfe3c9..703603e2db 100644
--- a/indra/newview/tests/llsecapi_test.cpp
+++ b/indra/newview/tests/llsecapi_test.cpp
@@ -87,7 +87,7 @@ namespace tut
// Tut templating thingamagic: test group, object and test instance
typedef test_group<secapiTest> secapiTestFactory;
typedef secapiTestFactory::object secapiTestObject;
- tut::secapiTestFactory tut_test("llsecapi");
+ tut::secapiTestFactory tut_test("LLSecAPI");
// ---------------------------------------------------------------------------------------
// Test functions
diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp
index c48498ebcd..daa10819fc 100644
--- a/indra/newview/tests/llsechandler_basic_test.cpp
+++ b/indra/newview/tests/llsechandler_basic_test.cpp
@@ -311,7 +311,7 @@ namespace tut
// Tut templating thingamagic: test group, object and test instance
typedef test_group<sechandler_basic_test> sechandler_basic_test_factory;
typedef sechandler_basic_test_factory::object sechandler_basic_test_object;
- tut::sechandler_basic_test_factory tut_test("llsechandler_basic");
+ tut::sechandler_basic_test_factory tut_test("LLSecHandler");
// ---------------------------------------------------------------------------------------
// Test functions
diff --git a/indra/newview/tests/llslurl_test.cpp b/indra/newview/tests/llslurl_test.cpp
index 40425a5caf..f96f79006a 100644
--- a/indra/newview/tests/llslurl_test.cpp
+++ b/indra/newview/tests/llslurl_test.cpp
@@ -101,7 +101,7 @@ namespace tut
// Tut templating thingamagic: test group, object and test instance
typedef test_group<slurlTest> slurlTestFactory;
typedef slurlTestFactory::object slurlTestObject;
- tut::slurlTestFactory tut_test("llslurl");
+ tut::slurlTestFactory tut_test("LLSlurl");
// ---------------------------------------------------------------------------------------
// Test functions
diff --git a/indra/newview/tests/lltextureinfo_test.cpp b/indra/newview/tests/lltextureinfo_test.cpp
index 7fa8602adc..73ace1de37 100644
--- a/indra/newview/tests/lltextureinfo_test.cpp
+++ b/indra/newview/tests/lltextureinfo_test.cpp
@@ -68,7 +68,7 @@ namespace tut
// Tut templating thingamagic: test group, object and test instance
typedef test_group<textureinfo_test> textureinfo_t;
typedef textureinfo_t::object textureinfo_object_t;
- tut::textureinfo_t tut_textureinfo("textureinfo");
+ tut::textureinfo_t tut_textureinfo("LLTectureInfo");
// ---------------------------------------------------------------------------------------
diff --git a/indra/newview/tests/lltextureinfodetails_test.cpp b/indra/newview/tests/lltextureinfodetails_test.cpp
index 3cd4c10da2..31ec5f9d4e 100644
--- a/indra/newview/tests/lltextureinfodetails_test.cpp
+++ b/indra/newview/tests/lltextureinfodetails_test.cpp
@@ -67,7 +67,7 @@ namespace tut
// Tut templating thingamagic: test group, object and test instance
typedef test_group<textureinfodetails_test> textureinfodetails_t;
typedef textureinfodetails_t::object textureinfodetails_object_t;
- tut::textureinfodetails_t tut_textureinfodetails("textureinfodetails");
+ tut::textureinfodetails_t tut_textureinfodetails("LLTextureInfoDetails");
// ---------------------------------------------------------------------------------------
diff --git a/indra/newview/tests/lltexturestatsuploader_test.cpp b/indra/newview/tests/lltexturestatsuploader_test.cpp
index caeabd08b3..cfb2c267cc 100644
--- a/indra/newview/tests/lltexturestatsuploader_test.cpp
+++ b/indra/newview/tests/lltexturestatsuploader_test.cpp
@@ -90,7 +90,7 @@ namespace tut
// Tut templating thingamagic: test group, object and test instance
typedef test_group<texturestatsuploader_test> texturestatsuploader_t;
typedef texturestatsuploader_t::object texturestatsuploader_object_t;
- tut::texturestatsuploader_t tut_texturestatsuploader("texturestatsuploader");
+ tut::texturestatsuploader_t tut_texturestatsuploader("LLTextureStatsUploader");
// ---------------------------------------------------------------------------------------
diff --git a/indra/newview/tests/llviewerhelputil_test.cpp b/indra/newview/tests/llviewerhelputil_test.cpp
index 4c71f15db1..a0f1d1c3c3 100644
--- a/indra/newview/tests/llviewerhelputil_test.cpp
+++ b/indra/newview/tests/llviewerhelputil_test.cpp
@@ -109,7 +109,7 @@ namespace tut
typedef test_group<viewerhelputil> viewerhelputil_t;
typedef viewerhelputil_t::object viewerhelputil_object_t;
- tut::viewerhelputil_t tut_viewerhelputil("viewerhelputil");
+ tut::viewerhelputil_t tut_viewerhelputil("LLViewerHelpUtil");
template<> template<>
void viewerhelputil_object_t::test<1>()
diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp
index d5d6ca671d..dd7761475e 100644
--- a/indra/newview/tests/llviewernetwork_test.cpp
+++ b/indra/newview/tests/llviewernetwork_test.cpp
@@ -127,7 +127,7 @@ namespace tut
// Tut templating thingamagic: test group, object and test instance
typedef test_group<viewerNetworkTest> viewerNetworkTestFactory;
typedef viewerNetworkTestFactory::object viewerNetworkTestObject;
- tut::viewerNetworkTestFactory tut_test("llviewernetwork");
+ tut::viewerNetworkTestFactory tut_test("LLViewerNetwork");
// ---------------------------------------------------------------------------------------
// Test functions
diff --git a/indra/newview/tests/llworldmap_test.cpp b/indra/newview/tests/llworldmap_test.cpp
index 443279c062..b976ac5ea9 100644
--- a/indra/newview/tests/llworldmap_test.cpp
+++ b/indra/newview/tests/llworldmap_test.cpp
@@ -144,15 +144,15 @@ namespace tut
// Tut templating thingamagic: test group, object and test instance
typedef test_group<iteminfo_test> iteminfo_t;
typedef iteminfo_t::object iteminfo_object_t;
- tut::iteminfo_t tut_iteminfo("iteminfo");
+ tut::iteminfo_t tut_iteminfo("LLItemInfo");
typedef test_group<siminfo_test> siminfo_t;
typedef siminfo_t::object siminfo_object_t;
- tut::siminfo_t tut_siminfo("siminfo");
+ tut::siminfo_t tut_siminfo("LLSimInfo");
typedef test_group<worldmap_test> worldmap_t;
typedef worldmap_t::object worldmap_object_t;
- tut::worldmap_t tut_worldmap("worldmap");
+ tut::worldmap_t tut_worldmap("LLWorldMap");
// ---------------------------------------------------------------------------------------
// Test functions
diff --git a/indra/newview/tests/llworldmipmap_test.cpp b/indra/newview/tests/llworldmipmap_test.cpp
index 272e59061d..54887ae219 100644
--- a/indra/newview/tests/llworldmipmap_test.cpp
+++ b/indra/newview/tests/llworldmipmap_test.cpp
@@ -89,7 +89,7 @@ namespace tut
// Tut templating thingamagic: test group, object and test instance
typedef test_group<worldmipmap_test> worldmipmap_t;
typedef worldmipmap_t::object worldmipmap_object_t;
- tut::worldmipmap_t tut_worldmipmap("worldmipmap");
+ tut::worldmipmap_t tut_worldmipmap("LLWorldMipmap");
// ---------------------------------------------------------------------------------------
// Test functions