llsidetray.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:18k
- /**
- * @file llsidetray.cpp
- * @brief SideBar implementation
- *
- * $LicenseInfo:firstyear=2009&license=viewergpl$
- *
- * Copyright (c) 2009-2010, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "llviewerprecompiledheaders.h"
- #include "lltextbox.h"
- #include "llagent.h"
- #include "llbottomtray.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 "llwindow.h"//for SetCursor
- #include "lltransientfloatermgr.h"
- //#include "llscrollcontainer.h"
- using namespace std;
- static LLRootViewRegistry::Register<LLSideTray> t1("side_tray");
- static LLDefaultChildRegistry::Register<LLSideTrayTab> t2("sidetray_tab");
- 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;
- 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;
- }
- 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);
-
-
- 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);
-
- 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);
- 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);
- }
- 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;
- }
- //////////////////////////////////////////////////////////////////////////////
- // LLSideTray
- //////////////////////////////////////////////////////////////////////////////
- LLSideTray::Params::Params()
- : collapsed("collapsed",false),
- tab_btn_image_normal("tab_btn_image","sidebar_tab_left.tga"),
- tab_btn_image_selected("tab_btn_image_selected","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(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);
- return true;
- }
- LLSideTrayTab* LLSideTray::getTab(const std::string& name)
- {
- return getChild<LLSideTrayTab>(name,false);
- }
- 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);
- btn->setImageOverlay( new_state ? tab->mImageSelected : tab->mImage );
- }
- }
- 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)
- {
- LLSideTrayTab* side_bar = getTab(name);
- if(side_bar == mActiveTab)
- return false;
- //deselect old tab
- toggleTabButton(mActiveTab);
- if(mActiveTab)
- mActiveTab->setVisible(false);
- //select new tab
- mActiveTab = side_bar;
- toggleTabButton(mActiveTab);
- LLSD key;//empty
- mActiveTab->onOpen(key);
- mActiveTab->setVisible(true);
- //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;
- sidebar_tab->setVisible(sidebar_tab == mActiveTab);
- }
- 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.name(sidetray_params.tab_btn_image_normal);
- bparams.image_selected.name(sidetray_params.tab_btn_image_selected);
- bparams.image_disabled.name(sidetray_params.tab_btn_image_normal);
- bparams.image_disabled_selected.name(sidetray_params.tab_btn_image_selected);
- LLButton* button = LLUICtrlFactory::create<LLButton> (bparams);
- button->setLabel(name);
- 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);
- }
- 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("",sidebar_tab->mImage,sidebar_tab->getTabTitle(),
- boost::bind(&LLSideTray::onToggleCollapse, this));
- }
- else
- {
- LLButton* button = createButton("",sidebar_tab->mImage,sidebar_tab->getTabTitle(),
- boost::bind(&LLSideTray::onTabButtonClick, this, name));
- mTabButtons[name] = button;
- }
- }
- }
- 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* side_bar = getTab(name);
- if(side_bar == mActiveTab)
- {
- processTriState ();
- return;
- }
- selectTabByName (name);
- if(mCollapsed)
- expandSideBar();
- }
- void LLSideTray::onToggleCollapse()
- {
- 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();
- }
- 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());
- }
- }
- 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()
- {
- mCollapsed = false;
- LLSideTrayTab* openclose_tab = getTab("sidebar_openclose");
- if (openclose_tab)
- {
- mCollapseButton->setImageOverlay( openclose_tab->mImageSelected );
- }
- LLSD key;//empty
- mActiveTab->onOpen(key);
- 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)
- {
- //arrange tabs
- child_vector_const_iter_t child_it;
- for ( child_it = mTabs.begin(); child_it != mTabs.end(); ++child_it)
- {
- LLView* view = (*child_it)->findChildView(panel_name,true);
- if(view)
- {
- selectTabByName ((*child_it)->getName());
- if(mCollapsed)
- expandSideBar();
- 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;
- }
- }
- return NULL;
- }
- void LLSideTray::togglePanel(LLPanel* &sub_panel, const std::string& panel_name, const LLSD& params)
- {
- if(!sub_panel)
- return;
- if (sub_panel->isInVisibleChain())
- {
- 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)
- {
- 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);
- }
- // *TODO: Eliminate magic constants.
- static const S32 fake_offset = 132;
- static const S32 fake_top_offset = 18;
- void LLSideTray::updateSidetrayVisibility()
- {
- // set visibility of parent container based on collapsed state
- if (getParent())
- {
- getParent()->setVisible(!mCollapsed && !gAgent.cameraMouselook());
- }
- }