summaryrefslogtreecommitdiff
path: root/indra/newview/llsidetray.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview/llsidetray.cpp')
-rw-r--r--indra/newview/llsidetray.cpp1270
1 files changed, 0 insertions, 1270 deletions
diff --git a/indra/newview/llsidetray.cpp b/indra/newview/llsidetray.cpp
deleted file mode 100644
index 2905e369f1..0000000000
--- a/indra/newview/llsidetray.cpp
+++ /dev/null
@@ -1,1270 +0,0 @@
-/**
- * @file llsidetray.cpp
- * @brief SideBar implementation
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
- *
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "lltextbox.h"
-
-#include "llagentcamera.h"
-#include "llappviewer.h"
-#include "llbottomtray.h"
-#include "llfloaterreg.h"
-#include "llfirstuse.h"
-#include "llhints.h"
-#include "llsidetray.h"
-#include "llviewerwindow.h"
-#include "llaccordionctrl.h"
-#include "llfocusmgr.h"
-#include "llrootview.h"
-#include "llnavigationbar.h"
-
-#include "llaccordionctrltab.h"
-
-#include "llfloater.h" //for gFloaterView
-#include "lliconctrl.h"//for OpenClose tab icon
-#include "llsidetraypanelcontainer.h"
-#include "llscreenchannel.h"
-#include "llchannelmanager.h"
-#include "llwindow.h"//for SetCursor
-#include "lltransientfloatermgr.h"
-
-#include "llsidepanelappearance.h"
-
-//#include "llscrollcontainer.h"
-
-using namespace std;
-using namespace LLNotificationsUI;
-
-static LLRootViewRegistry::Register<LLSideTray> t1("side_tray");
-static LLDefaultChildRegistry::Register<LLSideTrayTab> t2("sidetray_tab");
-
-static const S32 BOTTOM_BAR_PAD = 5;
-
-static const std::string COLLAPSED_NAME = "<<";
-static const std::string EXPANDED_NAME = ">>";
-
-static const std::string TAB_PANEL_CAPTION_NAME = "sidetray_tab_panel";
-static const std::string TAB_PANEL_CAPTION_TITLE_BOX = "sidetray_tab_title";
-
-LLSideTray* LLSideTray::sInstance = 0;
-
-// static
-LLSideTray* LLSideTray::getInstance()
-{
- if (!sInstance)
- {
- sInstance = LLUICtrlFactory::createFromFile<LLSideTray>("panel_side_tray.xml",NULL, LLRootView::child_registry_t::instance());
- sInstance->setXMLFilename("panel_side_tray.xml");
- }
-
- return sInstance;
-}
-
-// static
-bool LLSideTray::instanceCreated ()
-{
- return sInstance!=0;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// LLSideTrayTab
-// Represents a single tab in the side tray, only used by LLSideTray
-//////////////////////////////////////////////////////////////////////////////
-
-class LLSideTrayTab: public LLPanel
-{
- friend class LLUICtrlFactory;
- friend class LLSideTray;
-public:
-
- struct Params
- : public LLInitParam::Block<Params, LLPanel::Params>
- {
- // image name
- Optional<std::string> image;
- Optional<std::string> image_selected;
- Optional<std::string> tab_title;
- Optional<std::string> description;
- Params()
- : image("image"),
- image_selected("image_selected"),
- tab_title("tab_title","no title"),
- description("description","no description")
- {};
- };
-protected:
- LLSideTrayTab(const Params& params);
-
- void dock();
- void undock(LLFloater* floater_tab);
-
- LLSideTray* getSideTray();
-
-public:
- virtual ~LLSideTrayTab();
-
- /*virtual*/ BOOL postBuild ();
- /*virtual*/ bool addChild (LLView* view, S32 tab_group);
-
-
- void reshape (S32 width, S32 height, BOOL called_from_parent = TRUE);
-
- static LLSideTrayTab* createInstance ();
-
- const std::string& getDescription () const { return mDescription;}
- const std::string& getTabTitle() const { return mTabTitle;}
-
- void onOpen (const LLSD& key);
-
- void toggleTabDocked();
-
- LLPanel *getPanel();
-private:
- std::string mTabTitle;
- std::string mImage;
- std::string mImageSelected;
- std::string mDescription;
-
- LLView* mMainPanel;
-};
-
-LLSideTrayTab::LLSideTrayTab(const Params& p)
-: LLPanel(),
- mTabTitle(p.tab_title),
- mImage(p.image),
- mImageSelected(p.image_selected),
- mDescription(p.description),
- mMainPanel(NULL)
-{
- // Necessary for focus movement among child controls
- setFocusRoot(TRUE);
-}
-
-LLSideTrayTab::~LLSideTrayTab()
-{
-}
-
-bool LLSideTrayTab::addChild(LLView* view, S32 tab_group)
-{
- if(mMainPanel == 0 && TAB_PANEL_CAPTION_NAME != view->getName())//skip our caption panel
- mMainPanel = view;
- return LLPanel::addChild(view,tab_group);
- //return res;
-}
-
-
-
-//virtual
-BOOL LLSideTrayTab::postBuild()
-{
- LLPanel* title_panel = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>("panel_side_tray_tab_caption.xml",this, child_registry_t::instance());
- string name = title_panel->getName();
- LLPanel::addChild(title_panel);
-
- title_panel->getChild<LLTextBox>(TAB_PANEL_CAPTION_TITLE_BOX)->setValue(mTabTitle);
-
- getChild<LLButton>("undock")->setCommitCallback(boost::bind(&LLSideTrayTab::toggleTabDocked, this));
- getChild<LLButton>("dock")->setCommitCallback(boost::bind(&LLSideTrayTab::toggleTabDocked, this));
-
- return true;
-}
-
-static const S32 splitter_margin = 1;
-
-void LLSideTrayTab::reshape (S32 width, S32 height, BOOL called_from_parent )
-{
- LLPanel::reshape(width, height, called_from_parent);
- LLView* title_panel = findChildView(TAB_PANEL_CAPTION_NAME, true);
- if (!title_panel)
- {
- // not fully constructed yet
- return;
- }
-
- S32 title_height = title_panel->getRect().getHeight();
- title_panel->setOrigin( 0, height - title_height );
- title_panel->reshape(width,title_height);
-
- LLRect sRect;
- sRect.setLeftTopAndSize( splitter_margin, height - title_height - splitter_margin,
- width - 2*splitter_margin, height - title_height - 2*splitter_margin);
- mMainPanel->setShape(sRect);
-}
-
-void LLSideTrayTab::onOpen (const LLSD& key)
-{
- LLPanel *panel = getPanel();
- if(panel)
- panel->onOpen(key);
-}
-
-// Attempts to get the existing side tray instance.
-// Needed to avoid recursive calls of LLSideTray::getInstance().
-LLSideTray* LLSideTrayTab::getSideTray()
-{
- // First, check if the side tray is our parent (i.e. we're attached).
- LLSideTray* side_tray = dynamic_cast<LLSideTray*>(getParent());
- if (!side_tray)
- {
- // Detached? Ok, check if the instance exists at all/
- if (LLSideTray::instanceCreated())
- {
- side_tray = LLSideTray::getInstance();
- }
- else
- {
- llerrs << "No safe way to get the side tray instance" << llendl;
- }
- }
-
- return side_tray;
-}
-
-void LLSideTrayTab::toggleTabDocked()
-{
- std::string tab_name = getName();
-
- LLFloater* floater_tab = LLFloaterReg::getInstance("side_bar_tab", tab_name);
- if (!floater_tab) return;
-
- bool docking = LLFloater::isShown(floater_tab);
-
- // Hide the "Tear Off" button when a tab gets undocked
- // and show "Dock" button instead.
- getChild<LLButton>("undock")->setVisible(docking);
- getChild<LLButton>("dock")->setVisible(!docking);
-
- if (docking)
- {
- dock();
- }
- else
- {
- undock(floater_tab);
- }
-
- // Open/close the floater *after* we reparent the tab panel,
- // so that it doesn't receive redundant visibility change notifications.
- LLFloaterReg::toggleInstance("side_bar_tab", tab_name);
-}
-
-void LLSideTrayTab::dock()
-{
- LLSideTray* side_tray = getSideTray();
- if (!side_tray) return;
-
- 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(false);
- }
-}
-
-static void on_minimize(LLSidepanelAppearance* panel, LLSD minimized)
-{
- if (!panel) return;
- bool visible = !minimized.asBoolean();
- LLSD visibility;
- visibility["visible"] = visible;
- // Do not reset accordion state on minimize (STORM-375)
- visibility["reset_accordion"] = false;
- panel->updateToVisibility(visibility);
-}
-
-void LLSideTrayTab::undock(LLFloater* floater_tab)
-{
- LLSideTray* side_tray = getSideTray();
- if (!side_tray) return;
-
- // Remember whether the tab have been active before detaching
- // because removeTab() will change active tab.
- bool was_active = side_tray->getActiveTab() == this;
-
- // 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;
- }
-
- // If we're undocking while side tray is collapsed we need to explicitly show the panel.
- if (!getVisible())
- {
- setVisible(true);
- }
-
- floater_tab->addChild(this);
- floater_tab->setTitle(mTabTitle);
- floater_tab->setName(getName());
-
- // Resize handles get obscured by added panel so move them to front.
- floater_tab->moveResizeHandlesToFront();
-
- // Reshape the floater if needed.
- LLRect floater_rect;
- if (floater_tab->hasSavedRect())
- {
- // We've got saved rect for the floater, hence no need to reshape it.
- floater_rect = floater_tab->getLocalRect();
- }
- else
- {
- // Detaching for the first time. Reshape the floater.
- floater_rect = side_tray->getLocalRect();
-
- // Reduce detached floater height by small BOTTOM_BAR_PAD not to make it flush with the bottom bar.
- floater_rect.mBottom += LLBottomTray::getInstance()->getRect().getHeight() + BOTTOM_BAR_PAD;
- floater_rect.makeValid();
- floater_tab->reshape(floater_rect.getWidth(), floater_rect.getHeight());
- }
-
- // Reshape the panel.
- {
- LLRect panel_rect = floater_tab->getLocalRect();
- panel_rect.mTop -= floater_tab->getHeaderHeight();
- panel_rect.makeValid();
- setRect(panel_rect);
- reshape(panel_rect.getWidth(), panel_rect.getHeight());
- }
-
- // Set FOLLOWS_ALL flag for the tab to follow floater dimensions upon resizing.
- setFollowsAll();
-
- // Camera view may need to be changed for appearance panel(STORM-301) on minimize of floater,
- // so setting callback here.
- if (getName() == "sidebar_appearance")
- {
- LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance*>(getPanel());
- if(panel_appearance)
- {
- floater_tab->setMinimizeCallback(boost::bind(&on_minimize, panel_appearance, _2));
- }
- }
-
- if (!side_tray->getCollapsed())
- {
- side_tray->collapseSideBar();
- }
-
- if (!was_active)
- {
- // When a tab other then current active tab is detached from Side Tray
- // onOpen() should be called as tab visibility is changed.
- onOpen(LLSD());
- }
-}
-
-LLPanel* LLSideTrayTab::getPanel()
-{
- LLPanel* panel = dynamic_cast<LLPanel*>(mMainPanel);
- return panel;
-}
-
-LLSideTrayTab* LLSideTrayTab::createInstance ()
-{
- LLSideTrayTab::Params tab_params;
- tab_params.tab_title("openclose");
-
- LLSideTrayTab* tab = LLUICtrlFactory::create<LLSideTrayTab>(tab_params);
- return tab;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-// 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", tab->getName());
- 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
-//////////////////////////////////////////////////////////////////////////////
-
-LLSideTray::Params::Params()
-: collapsed("collapsed",false),
- tab_btn_image_normal("tab_btn_image",LLUI::getUIImage("sidebar_tab_left.tga")),
- tab_btn_image_selected("tab_btn_image_selected",LLUI::getUIImage("button_enabled_selected_32x128.tga")),
- default_button_width("tab_btn_width",32),
- default_button_height("tab_btn_height",32),
- default_button_margin("tab_btn_margin",0)
-{}
-
-//virtual
-LLSideTray::LLSideTray(const Params& params)
- : LLPanel(params)
- ,mActiveTab(0)
- ,mCollapsed(false)
- ,mCollapseButton(0)
-{
- mCollapsed=params.collapsed;
-
- LLUICtrl::CommitCallbackRegistry::Registrar& commit = LLUICtrl::CommitCallbackRegistry::currentRegistrar();
-
- // register handler function to process data from the xml.
- // panel_name should be specified via "parameter" attribute.
- commit.add("SideTray.ShowPanel", boost::bind(&LLSideTray::showPanel, this, _2, LLUUID::null));
- LLTransientFloaterMgr::getInstance()->addControlView(this);
- LLView* side_bar_tabs = gViewerWindow->getRootView()->getChildView("side_bar_tabs");
- if (side_bar_tabs != NULL)
- {
- LLTransientFloaterMgr::getInstance()->addControlView(side_bar_tabs);
- }
-
- LLPanel::Params p;
- p.name = "buttons_panel";
- p.mouse_opaque = false;
- mButtonsPanel = LLUICtrlFactory::create<LLPanel>(p);
-}
-
-
-BOOL LLSideTray::postBuild()
-{
- createButtons();
-
- arrange();
- selectTabByName("sidebar_home");
-
- if(mCollapsed)
- collapseSideBar();
-
- setMouseOpaque(false);
-
- 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();
- for(std::vector<LLChannelManager::ChannelElem>::iterator it = channels.begin();it!=channels.end();++it)
- {
- if ((*it).channel)
- {
- getCollapseSignal().connect(boost::bind(&LLScreenChannelBase::resetPositionAndSize, (*it).channel, _2));
- }
- }
-
- return true;
-}
-
-void LLSideTray::handleLoginComplete()
-{
- //reset tab to "home" tab if it was changesd during login process
- selectTabByName("sidebar_home");
-
- detachTabs();
-}
-
-LLSideTrayTab* LLSideTray::getTab(const std::string& name)
-{
- return findChild<LLSideTrayTab>(name,false);
-}
-
-bool LLSideTray::isTabAttached(const std::string& name)
-{
- LLSideTrayTab* tab = getTab(name);
- if (!tab) return false;
-
- 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)
-{
- if(tab == NULL)
- return;
- std::string name = tab->getName();
- std::map<std::string,LLButton*>::iterator it = mTabButtons.find(name);
- if(it != mTabButtons.end())
- {
- LLButton* btn = it->second;
- bool new_state = !btn->getToggleState();
- btn->setToggleState(new_state);
- // Only highlight the tab if side tray is expanded (STORM-157).
- btn->setImageOverlay( new_state && !getCollapsed() ? tab->mImageSelected : tab->mImage );
- }
-}
-
-LLPanel* LLSideTray::openChildPanel(LLSideTrayTab* tab, const std::string& panel_name, const LLSD& params)
-{
- LLView* view = tab->findChildView(panel_name, true);
- if (!view) return NULL;
-
- std::string tab_name = tab->getName();
-
- // Select tab and expand Side Tray only when a tab is attached.
- if (isTabAttached(tab_name))
- {
- selectTabByName(tab_name);
- if (mCollapsed)
- expandSideBar();
- }
- else
- {
- LLFloater* floater_tab = LLFloaterReg::getInstance("side_bar_tab", tab_name);
- if (!floater_tab) return NULL;
-
- // Restore the floater if it was minimized.
- if (floater_tab->isMinimized())
- {
- floater_tab->setMinimized(FALSE);
- }
-
- // Send the floater to the front.
- floater_tab->setFrontmost();
- }
-
- LLSideTrayPanelContainer* container = dynamic_cast<LLSideTrayPanelContainer*>(view->getParent());
- if (container)
- {
- LLSD new_params = params;
- new_params[LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME] = panel_name;
- container->onOpen(new_params);
-
- return container->getCurrentPanel();
- }
-
- LLPanel* panel = dynamic_cast<LLPanel*>(view);
- if (panel)
- {
- panel->onOpen(params);
- }
-
- return panel;
-}
-
-bool LLSideTray::selectTabByIndex(size_t index)
-{
- if(index>=mTabs.size())
- return false;
-
- LLSideTrayTab* sidebar_tab = mTabs[index];
- return selectTabByName(sidebar_tab->getName());
-}
-
-bool LLSideTray::selectTabByName(const std::string& name, bool keep_prev_visible)
-{
- LLSideTrayTab* tab_to_keep_visible = NULL;
- LLSideTrayTab* new_tab = getTab(name);
- if (!new_tab) return false;
-
- // Bail out if already selected.
- if (new_tab == mActiveTab)
- return false;
-
- //deselect old tab
- if (mActiveTab)
- {
- // Keep previously active tab visible if requested.
- if (keep_prev_visible) tab_to_keep_visible = mActiveTab;
- toggleTabButton(mActiveTab);
- }
-
- //select new tab
- mActiveTab = new_tab;
-
- if (mActiveTab)
- {
- toggleTabButton(mActiveTab);
- LLSD key;//empty
- mActiveTab->onOpen(key);
- }
-
- //arrange();
-
- //hide all tabs - show active tab
- child_vector_const_iter_t child_it;
- for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
- {
- LLSideTrayTab* sidebar_tab = *child_it;
-
- bool vis = sidebar_tab == mActiveTab;
-
- // Force keeping the tab visible if requested.
- vis |= sidebar_tab == tab_to_keep_visible;
-
- // 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.
- vis &= (*child_it)->getName() != "sidebar_openclose";
-
- sidebar_tab->setVisible(vis);
- }
- return true;
-}
-
-LLButton* LLSideTray::createButton (const std::string& name,const std::string& image,const std::string& tooltip,
- LLUICtrl::commit_callback_t callback)
-{
- static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());
-
- LLButton::Params bparams;
-
- LLRect rect;
- rect.setOriginAndSize(0, 0, sidetray_params.default_button_width, sidetray_params.default_button_height);
-
- bparams.name(name);
- bparams.follows.flags (FOLLOWS_LEFT | FOLLOWS_TOP);
- bparams.rect (rect);
- bparams.tab_stop(false);
- bparams.image_unselected(sidetray_params.tab_btn_image_normal);
- bparams.image_selected(sidetray_params.tab_btn_image_selected);
- bparams.image_disabled(sidetray_params.tab_btn_image_normal);
- bparams.image_disabled_selected(sidetray_params.tab_btn_image_selected);
-
- 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);
-
- if(image.length())
- {
- button->setImageOverlay(image);
- }
-
- mButtonsPanel->addChildInBack(button);
-
- return button;
-}
-
-bool LLSideTray::addChild(LLView* view, S32 tab_group)
-{
- LLSideTrayTab* tab_panel = dynamic_cast<LLSideTrayTab*>(view);
-
- if (tab_panel)
- {
- mTabs.push_back(tab_panel);
- }
-
- 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)
- {
- // Select the next tab (or first one, if we're removing the last tab),
- // skipping the fake open/close tab (STORM-155).
- child_vector_iter_t next_tab_it = tab_it;
- do
- {
- next_tab_it = (next_tab_it < (mTabs.end() - 1)) ? next_tab_it + 1 : mTabs.begin();
- }
- while ((*next_tab_it)->getName() == "sidebar_openclose");
-
- selectTabByName((*next_tab_it)->getName(), true); // Don't hide the tab being removed.
- }
-
- // Remove the tab.
- removeChild(tab);
- mTabs.erase(tab_it);
-
- // Add the tab to detached tabs list.
- mDetachedTabs.push_back(tab);
-
- // 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();
-
- // Remove the tab from the list of detached tabs.
- child_vector_iter_t tab_it = std::find(mDetachedTabs.begin(), mDetachedTabs.end(), tab);
- if (tab_it != mDetachedTabs.end())
- {
- mDetachedTabs.erase(tab_it);
- }
-
- return true;
-}
-
-void LLSideTray::createButtons ()
-{
- //create buttons for tabs
- child_vector_const_iter_t child_it = mTabs.begin();
- for ( ; child_it != mTabs.end(); ++child_it)
- {
- LLSideTrayTab* sidebar_tab = *child_it;
-
- std::string name = sidebar_tab->getName();
-
- // The "OpenClose" button will open/close the whole panel
- if (name == "sidebar_openclose")
- {
- mCollapseButton = createButton(name,sidebar_tab->mImage,sidebar_tab->getTabTitle(),
- boost::bind(&LLSideTray::onToggleCollapse, this));
- LLHints::registerHintTarget("side_panel_btn", mCollapseButton->getHandle());
- }
- else
- {
- LLButton* button = createButton(name,sidebar_tab->mImage,sidebar_tab->getTabTitle(),
- boost::bind(&LLSideTray::onTabButtonClick, this, name));
- mTabButtons[name] = button;
- }
- }
- LLHints::registerHintTarget("inventory_btn", mTabButtons["sidebar_inventory"]->getHandle());
- LLHints::registerHintTarget("dest_guide_btn", mTabButtons["sidebar_places"]->getHandle());
-}
-
-void LLSideTray::processTriState ()
-{
- if(mCollapsed)
- expandSideBar();
- else
- {
-#if 0 // *TODO: EXT-2092
-
- // Tell the active task panel to switch to its default view
- // or collapse side tray if already on the default view.
- LLSD info;
- info["task-panel-action"] = "handle-tri-state";
- mActiveTab->notifyChildren(info);
-#else
- collapseSideBar();
-#endif
- }
-}
-
-void LLSideTray::onTabButtonClick(string name)
-{
- LLSideTrayTab* tab = getTab(name);
- if (!tab) return;
-
- if(tab == mActiveTab)
- {
- processTriState ();
- return;
- }
- selectTabByName (name);
- if(mCollapsed)
- expandSideBar();
-}
-
-void LLSideTray::onToggleCollapse()
-{
- LLFirstUse::notUsingSidePanel(false);
- if(mCollapsed)
- {
- expandSideBar();
- //selectTabByName("sidebar_openclose");
- }
- else
- collapseSideBar();
-}
-
-
-void LLSideTray::reflectCollapseChange()
-{
- updateSidetrayVisibility();
-
- if(mCollapsed)
- {
- gFloaterView->setSnapOffsetRight(0);
- setFocus(FALSE);
- }
- else
- {
- gFloaterView->setSnapOffsetRight(getRect().getWidth());
- setFocus(TRUE);
- }
-
- gFloaterView->refresh();
-
- LLSD new_value = mCollapsed;
- mCollapseSignal(this,new_value);
-}
-
-void LLSideTray::arrange()
-{
- static LLSideTray::Params sidetray_params(LLUICtrlFactory::getDefaultParams<LLSideTray>());
-
- updateSidetrayVisibility();
-
- LLRect ctrl_rect;
- ctrl_rect.setLeftTopAndSize(0,
- mButtonsPanel->getRect().getHeight() - sidetray_params.default_button_width,
- sidetray_params.default_button_width,
- sidetray_params.default_button_height);
-
- mCollapseButton->setRect(ctrl_rect);
-
- //arrange tab buttons
- //arrange tab buttons
- child_vector_const_iter_t child_it;
- int offset = (sidetray_params.default_button_height+sidetray_params.default_button_margin)*2;
- for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
- {
- LLSideTrayTab* sidebar_tab = *child_it;
-
- ctrl_rect.setLeftTopAndSize(0,
- mButtonsPanel->getRect().getHeight()-offset,
- sidetray_params.default_button_width,
- sidetray_params.default_button_height);
-
- if(mTabButtons.find(sidebar_tab->getName()) == mTabButtons.end())
- continue;
-
- LLButton* btn = mTabButtons[sidebar_tab->getName()];
-
- btn->setRect(ctrl_rect);
- offset+=sidetray_params.default_button_height;
- offset+=sidetray_params.default_button_margin;
-
- btn->setVisible(ctrl_rect.mBottom > 0);
- }
-
- //arrange tabs
- for ( child_vector_t::iterator child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
- {
- 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.
- // Also hide them in mouse-look mode.
- mButtonsPanel->setVisible(hasTabs() && !gAgentCamera.cameraMouselook());
-}
-
-// Detach those tabs that were detached when the viewer exited last time.
-void LLSideTray::detachTabs()
-{
- // copy mTabs because LLSideTray::toggleTabDocked() modifies it.
- child_vector_t tabs = mTabs;
-
- for (child_vector_const_iter_t it = tabs.begin(); it != tabs.end(); ++it)
- {
- LLSideTrayTab* tab = *it;
-
- std::string floater_ctrl_name = LLFloater::getControlName("side_bar_tab", LLSD(tab->getName()));
- std::string vis_ctrl_name = LLFloaterReg::getVisibilityControlName(floater_ctrl_name);
- if (!LLFloater::getControlGroup()->controlExists(vis_ctrl_name)) continue;
-
- bool is_visible = LLFloater::getControlGroup()->getBOOL(vis_ctrl_name);
- if (!is_visible) continue;
-
- llassert(isTabAttached(tab->getName()));
- tab->toggleTabDocked();
- }
-}
-
-void LLSideTray::collapseSideBar()
-{
- mCollapsed = true;
- // Reset all overlay images, because there is no "selected" tab when the
- // whole side tray is hidden.
- child_vector_const_iter_t it = mTabs.begin();
- for ( ; it != mTabs.end(); ++it )
- {
- LLSideTrayTab* tab = *it;
- std::string name = tab->getName();
- std::map<std::string,LLButton*>::const_iterator btn_it =
- mTabButtons.find(name);
- if (btn_it != mTabButtons.end())
- {
- LLButton* btn = btn_it->second;
- btn->setImageOverlay( tab->mImage );
- }
- }
-
- // OpenClose tab doesn't put its button in mTabButtons
- LLSideTrayTab* openclose_tab = getTab("sidebar_openclose");
- if (openclose_tab)
- {
- mCollapseButton->setImageOverlay( openclose_tab->mImage );
- }
- //mActiveTab->setVisible(FALSE);
- reflectCollapseChange();
- setFocus( FALSE );
-}
-
-void LLSideTray::expandSideBar(bool open_active)
-{
- mCollapsed = false;
- LLSideTrayTab* openclose_tab = getTab("sidebar_openclose");
- if (openclose_tab)
- {
- mCollapseButton->setImageOverlay( openclose_tab->mImageSelected );
- }
-
- if (open_active)
- {
- mActiveTab->onOpen(LLSD());
- }
-
- reflectCollapseChange();
-
-
- std::string name = mActiveTab->getName();
- std::map<std::string,LLButton*>::const_iterator btn_it =
- mTabButtons.find(name);
- if (btn_it != mTabButtons.end())
- {
- LLButton* btn = btn_it->second;
- btn->setImageOverlay( mActiveTab->mImageSelected );
- }
-}
-
-void LLSideTray::highlightFocused()
-{
- /* uncomment in case something change
- if(!mActiveTab)
- return;
- BOOL dependent_has_focus = gFocusMgr.childHasKeyboardFocus(this);
- setBackgroundOpaque( dependent_has_focus );
- mActiveTab->setBackgroundOpaque( dependent_has_focus );
- */
-}
-
-//virtual
-BOOL LLSideTray::handleMouseDown (S32 x, S32 y, MASK mask)
-{
- BOOL ret = LLPanel::handleMouseDown(x,y,mask);
- if(ret)
- setFocus(true);
- return ret;
-}
-
-void LLSideTray::reshape(S32 width, S32 height, BOOL called_from_parent)
-{
- LLPanel::reshape(width, height, called_from_parent);
- if(!mActiveTab)
- return;
-
- arrange();
-}
-
-/**
- * Activate tab with "panel_name" panel
- * if no such tab - return false, otherwise true.
- * TODO* In some cases a pointer to a panel of
- * a specific class may be needed so this method
- * would need to use templates.
- */
-LLPanel* LLSideTray::showPanel (const std::string& panel_name, const LLSD& params)
-{
- // Look up the tab in the list of detached tabs.
- child_vector_const_iter_t child_it;
- for ( child_it = mDetachedTabs.begin(); child_it != mDetachedTabs.end(); ++child_it)
- {
- LLPanel* panel = openChildPanel(*child_it, panel_name, params);
- if (panel) return panel;
- }
-
- // Look up the tab in the list of attached tabs.
- for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
- {
- LLPanel* panel = openChildPanel(*child_it, panel_name, params);
- if (panel) return panel;
- }
- return NULL;
-}
-
-void LLSideTray::togglePanel(LLPanel* &sub_panel, const std::string& panel_name, const LLSD& params)
-{
- if(!sub_panel)
- return;
-
- // If a panel is visible and attached to Side Tray (has LLSideTray among its ancestors)
- // it should be toggled off by collapsing Side Tray.
- if (sub_panel->isInVisibleChain() && sub_panel->hasAncestor(this))
- {
- LLSideTray::getInstance()->collapseSideBar();
- }
- else
- {
- LLSideTray::getInstance()->showPanel(panel_name, params);
- }
-}
-
-// This is just LLView::findChildView specialized to restrict the search to LLPanels.
-// Optimization for EXT-4068 to avoid searching down to the individual item level
-// when inventories are large.
-LLPanel *findChildPanel(LLPanel *panel, const std::string& name, bool recurse)
-{
- for (LLView::child_list_const_iter_t child_it = panel->beginChild();
- child_it != panel->endChild(); ++child_it)
- {
- LLPanel *child_panel = dynamic_cast<LLPanel*>(*child_it);
- if (!child_panel)
- continue;
- if (child_panel->getName() == name)
- return child_panel;
- }
- if (recurse)
- {
- for (LLView::child_list_const_iter_t child_it = panel->beginChild();
- child_it != panel->endChild(); ++child_it)
- {
- LLPanel *child_panel = dynamic_cast<LLPanel*>(*child_it);
- if (!child_panel)
- continue;
- LLPanel *found_panel = findChildPanel(child_panel,name,recurse);
- if (found_panel)
- {
- return found_panel;
- }
- }
- }
- return NULL;
-}
-
-LLPanel* LLSideTray::getPanel(const std::string& panel_name)
-{
- // Look up the panel in the list of detached tabs.
- for ( child_vector_const_iter_t child_it = mDetachedTabs.begin(); child_it != mDetachedTabs.end(); ++child_it)
- {
- LLPanel *panel = findChildPanel(*child_it,panel_name,true);
- if(panel)
- {
- return panel;
- }
- }
-
- // Look up the panel in the list of attached tabs.
- for ( child_vector_const_iter_t child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
- {
- LLPanel *panel = findChildPanel(*child_it,panel_name,true);
- if(panel)
- {
- return panel;
- }
- }
- return NULL;
-}
-
-LLPanel* LLSideTray::getActivePanel()
-{
- if (mActiveTab && !mCollapsed)
- {
- return mActiveTab->getPanel();
- }
- return NULL;
-}
-
-bool LLSideTray::isPanelActive(const std::string& panel_name)
-{
- LLPanel *panel = getActivePanel();
- if (!panel) return false;
- return (panel->getName() == panel_name);
-}
-
-void LLSideTray::updateSidetrayVisibility()
-{
- // set visibility of parent container based on collapsed state
- if (getParent())
- {
- getParent()->setVisible(!mCollapsed && !gAgentCamera.cameraMouselook());
- }
-}
-