Skip to content
Snippets Groups Projects
lltabcontainer.cpp 51.5 KiB
Newer Older
James Cook's avatar
James Cook committed
/** 
 * @file lltabcontainer.cpp
James Cook's avatar
James Cook committed
 *
 * $LicenseInfo:firstyear=2001&license=viewergpl$
 * 
 * Copyright (c) 2001-2009, 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$
James Cook's avatar
James Cook committed
 */

#include "linden_common.h"
James Cook's avatar
James Cook committed
#include "lltabcontainer.h"
James Cook's avatar
James Cook committed
#include "llfocusmgr.h"
#include "llbutton.h"
James Cook's avatar
James Cook committed
#include "llrect.h"
#include "llresizehandle.h"
#include "lltextbox.h"
#include "llcriticaldamp.h"
#include "lluictrlfactory.h"
#include "llrender.h"

//----------------------------------------------------------------------------

// Implementation Notes:
//  - Each tab points to a LLPanel (see LLTabTuple below)
//  - When a tab is selected, the validation callback
//    (LLUICtrl::mValidateSignal) is called
//  -  If the validation callback returns true (or none is provided),
//     the tab is changed and the commit callback
//     (LLUICtrl::mCommitSignal) is called
//  - Callbacks pass the LLTabContainer as the control,
//    and the NAME of the selected PANEL as the LLSD data

//----------------------------------------------------------------------------
James Cook's avatar
James Cook committed

const F32 SCROLL_STEP_TIME = 0.4f;
const F32 SCROLL_DELAY_TIME = 0.5f;

void LLTabContainer::TabPositions::declareValues()
{
	declare("top", LLTabContainer::TOP);
	declare("bottom", LLTabContainer::BOTTOM);
	declare("left", LLTabContainer::LEFT);
}

//----------------------------------------------------------------------------

// Structure used to map tab buttons to and from tab panels
class LLTabTuple
{
public:
	LLTabTuple( LLTabContainer* c, LLPanel* p, LLButton* b, LLTextBox* placeholder = NULL)
		:
		mTabContainer(c),
		mTabPanel(p),
		mButton(b),
		mOldState(FALSE),
		mPlaceholderText(placeholder),
		mPadding(0)
	{}

	LLTabContainer*  mTabContainer;
	LLPanel*		 mTabPanel;
	LLButton*		 mButton;
	BOOL			 mOldState;
	LLTextBox*		 mPlaceholderText;
	S32				 mPadding;
};

//----------------------------------------------------------------------------

struct LLPlaceHolderPanel : public LLPanel
{
	// create dummy param block to register with "placeholder" nane
	struct Params : public LLPanel::Params{};
	LLPlaceHolderPanel(const Params& p) : LLPanel(p)
	{}
};
static LLDefaultChildRegistry::Register<LLPlaceHolderPanel> r1("placeholder");
static LLDefaultChildRegistry::Register<LLTabContainer> r2("tab_container");
LLTabContainer::TabParams::TabParams()
:	tab_top_image_unselected("tab_top_image_unselected"),
	tab_top_image_selected("tab_top_image_selected"),
	tab_bottom_image_unselected("tab_bottom_image_unselected"),
	tab_bottom_image_selected("tab_bottom_image_selected"),
	tab_left_image_unselected("tab_left_image_unselected"),
	tab_left_image_selected("tab_left_image_selected")
{}

LLTabContainer::Params::Params()
:	tab_width("tab_width"),
	tab_min_width("tab_min_width"),
	tab_max_width("tab_max_width"),
	tab_height("tab_height"),
	tab_position("tab_position"),
	hide_tabs("hide_tabs", false),
	first_tab("first_tab"),
	middle_tab("middle_tab"),
	last_tab("last_tab")
{
	name(std::string("tab_container"));
	mouse_opaque = false;
}

LLTabContainer::LLTabContainer(const LLTabContainer::Params& p)
:	LLPanel(p),
James Cook's avatar
James Cook committed
	mCurrentTabIdx(-1),
	mTabsHidden(p.hide_tabs),
James Cook's avatar
James Cook committed
	mScrolled(FALSE),
	mScrollPos(0),
	mScrollPosPixels(0),
	mMaxScrollPos(0),
	mTitleBox(NULL),
	mTopBorderHeight(LLPANEL_BORDER_WIDTH),
	mMinTabWidth(0),
	mMaxTabWidth(p.tab_max_width),
	mTabHeight(p.tab_height),
	mIsVertical( p.tab_position == LEFT ),
	// Horizontal Specific
	mJumpPrevArrowBtn(NULL),
	mJumpNextArrowBtn(NULL),
	mRightTabBtnOffset(p.tab_padding_right),
	mTotalTabWidth(0),
	mTabPosition(p.tab_position),
	mFontHalign(p.font_halign),
	mFirstTabParams(p.first_tab),
	mMiddleTabParams(p.middle_tab),
	mLastTabParams(p.last_tab)
{
	static LLUICachedControl<S32> tabcntr_vert_tab_min_width ("UITabCntrVertTabMinWidth", 0);

	mDragAndDropDelayTimer.stop();

	if (p.tab_width.isProvided())
	{
		mMinTabWidth = p.tab_width;
	}
	else if (!mIsVertical)
		mMinTabWidth = p.tab_min_width;
	else
	{
		// *HACK: support default min width for legacy vertical
		// tab containers
		mMinTabWidth = tabcntr_vert_tab_min_width;
	}

LLTabContainer::~LLTabContainer()
{
	std::for_each(mTabList.begin(), mTabList.end(), DeletePointer());
}
James Cook's avatar
James Cook committed

//virtual
void LLTabContainer::setValue(const LLSD& value)
James Cook's avatar
James Cook committed
{
	selectTab((S32) value.asInteger());
}

//virtual
void LLTabContainer::reshape(S32 width, S32 height, BOOL called_from_parent)
James Cook's avatar
James Cook committed
{
	LLPanel::reshape( width, height, called_from_parent );
	updateMaxScrollPos();
Loading
Loading full blame...